diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_base.cc b/quiche/quic/core/batch_writer/quic_batch_writer_base.cc
new file mode 100644
index 0000000..0b39823
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_base.cc
@@ -0,0 +1,181 @@
+// Copyright (c) 2019 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 "quiche/quic/core/batch_writer/quic_batch_writer_base.h"
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+
+namespace quic {
+
+QuicBatchWriterBase::QuicBatchWriterBase(
+    std::unique_ptr<QuicBatchWriterBuffer> batch_buffer)
+    : write_blocked_(false), batch_buffer_(std::move(batch_buffer)) {}
+
+WriteResult QuicBatchWriterBase::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  const WriteResult result =
+      InternalWritePacket(buffer, buf_len, self_address, peer_address, options);
+
+  if (IsWriteBlockedStatus(result.status)) {
+    write_blocked_ = true;
+  }
+
+  return result;
+}
+
+WriteResult QuicBatchWriterBase::InternalWritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  if (buf_len > kMaxOutgoingPacketSize) {
+    return WriteResult(WRITE_STATUS_MSG_TOO_BIG, EMSGSIZE);
+  }
+
+  ReleaseTime release_time{0, QuicTime::Delta::Zero()};
+  if (SupportsReleaseTime()) {
+    release_time = GetReleaseTime(options);
+    if (release_time.release_time_offset >= QuicTime::Delta::Zero()) {
+      QUIC_SERVER_HISTOGRAM_TIMES(
+          "batch_writer_positive_release_time_offset",
+          release_time.release_time_offset.ToMicroseconds(), 1, 100000, 50,
+          "Duration from ideal release time to actual "
+          "release time, in microseconds.");
+    } else {
+      QUIC_SERVER_HISTOGRAM_TIMES(
+          "batch_writer_negative_release_time_offset",
+          -release_time.release_time_offset.ToMicroseconds(), 1, 100000, 50,
+          "Duration from actual release time to ideal "
+          "release time, in microseconds.");
+    }
+  }
+
+  const CanBatchResult can_batch_result =
+      CanBatch(buffer, buf_len, self_address, peer_address, options,
+               release_time.actual_release_time);
+
+  bool buffered = false;
+  bool flush = can_batch_result.must_flush;
+
+  if (can_batch_result.can_batch) {
+    QuicBatchWriterBuffer::PushResult push_result =
+        batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
+                                         peer_address, options,
+                                         release_time.actual_release_time);
+    if (push_result.succeeded) {
+      buffered = true;
+      // If there's no space left after the packet is buffered, force a flush.
+      flush = flush || (batch_buffer_->GetNextWriteLocation() == nullptr);
+    } else {
+      // If there's no space without this packet, force a flush.
+      flush = true;
+    }
+  }
+
+  if (!flush) {
+    WriteResult result(WRITE_STATUS_OK, 0);
+    result.send_time_offset = release_time.release_time_offset;
+    return result;
+  }
+
+  size_t num_buffered_packets = buffered_writes().size();
+  const FlushImplResult flush_result = CheckedFlush();
+  WriteResult result = flush_result.write_result;
+  QUIC_DVLOG(1) << "Internally flushed " << flush_result.num_packets_sent
+                << " out of " << num_buffered_packets
+                << " packets. WriteResult=" << result;
+
+  if (result.status != WRITE_STATUS_OK) {
+    if (IsWriteBlockedStatus(result.status)) {
+      return WriteResult(
+          buffered ? WRITE_STATUS_BLOCKED_DATA_BUFFERED : WRITE_STATUS_BLOCKED,
+          result.error_code);
+    }
+
+    // Drop all packets, including the one being written.
+    size_t dropped_packets =
+        buffered ? buffered_writes().size() : buffered_writes().size() + 1;
+
+    batch_buffer().Clear();
+    result.dropped_packets =
+        dropped_packets > std::numeric_limits<uint16_t>::max()
+            ? std::numeric_limits<uint16_t>::max()
+            : static_cast<uint16_t>(dropped_packets);
+    return result;
+  }
+
+  if (!buffered) {
+    QuicBatchWriterBuffer::PushResult push_result =
+        batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
+                                         peer_address, options,
+                                         release_time.actual_release_time);
+    buffered = push_result.succeeded;
+
+    // Since buffered_writes has been emptied, this write must have been
+    // buffered successfully.
+    QUIC_BUG_IF(quic_bug_10826_1, !buffered)
+        << "Failed to push to an empty batch buffer."
+        << "  self_addr:" << self_address.ToString()
+        << ", peer_addr:" << peer_address.ToString() << ", buf_len:" << buf_len;
+  }
+
+  result.send_time_offset = release_time.release_time_offset;
+  return result;
+}
+
+QuicBatchWriterBase::FlushImplResult QuicBatchWriterBase::CheckedFlush() {
+  if (buffered_writes().empty()) {
+    return FlushImplResult{WriteResult(WRITE_STATUS_OK, 0),
+                           /*num_packets_sent=*/0, /*bytes_written=*/0};
+  }
+
+  const FlushImplResult flush_result = FlushImpl();
+
+  // Either flush_result.write_result.status is not WRITE_STATUS_OK, or it is
+  // WRITE_STATUS_OK and batch_buffer is empty.
+  QUICHE_DCHECK(flush_result.write_result.status != WRITE_STATUS_OK ||
+                buffered_writes().empty());
+
+  // Flush should never return WRITE_STATUS_BLOCKED_DATA_BUFFERED.
+  QUICHE_DCHECK(flush_result.write_result.status !=
+                WRITE_STATUS_BLOCKED_DATA_BUFFERED);
+
+  return flush_result;
+}
+
+WriteResult QuicBatchWriterBase::Flush() {
+  size_t num_buffered_packets = buffered_writes().size();
+  FlushImplResult flush_result = CheckedFlush();
+  QUIC_DVLOG(1) << "Externally flushed " << flush_result.num_packets_sent
+                << " out of " << num_buffered_packets
+                << " packets. WriteResult=" << flush_result.write_result;
+
+  if (IsWriteError(flush_result.write_result.status)) {
+    if (buffered_writes().size() > std::numeric_limits<uint16_t>::max()) {
+      flush_result.write_result.dropped_packets =
+          std::numeric_limits<uint16_t>::max();
+    } else {
+      flush_result.write_result.dropped_packets =
+          static_cast<uint16_t>(buffered_writes().size());
+    }
+    // Treat all errors as non-retryable fatal errors. Drop all buffered packets
+    // to avoid sending them and getting the same error again.
+    batch_buffer().Clear();
+  }
+
+  if (flush_result.write_result.status == WRITE_STATUS_BLOCKED) {
+    write_blocked_ = true;
+  }
+  return flush_result.write_result;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_base.h b/quiche/quic/core/batch_writer/quic_batch_writer_base.h
new file mode 100644
index 0000000..fc776c2
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_base.h
@@ -0,0 +1,158 @@
+// Copyright (c) 2019 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_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
+
+#include <cstdint>
+#include "quiche/quic/core/batch_writer/quic_batch_writer_buffer.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// QuicBatchWriterBase implements logic common to all derived batch writers,
+// including maintaining write blockage state and a skeleton implemention of
+// WritePacket().
+// A derived batch writer must override the FlushImpl() function to send all
+// buffered writes in a batch. It must also override the CanBatch() function
+// to control whether/when a WritePacket() call should flush.
+class QUIC_EXPORT_PRIVATE QuicBatchWriterBase : public QuicPacketWriter {
+ public:
+  explicit QuicBatchWriterBase(
+      std::unique_ptr<QuicBatchWriterBuffer> batch_buffer);
+
+  // ATTENTION: If this write triggered a flush, and the flush failed, all
+  // buffered packets will be dropped to allow the next write to work. The
+  // number of dropped packets can be found in WriteResult.dropped_packets.
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+
+  bool IsWriteBlocked() const final { return write_blocked_; }
+
+  void SetWritable() final { write_blocked_ = false; }
+
+  absl::optional<int> MessageTooBigErrorCode() const override {
+    return EMSGSIZE;
+  }
+
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& /*peer_address*/) const final {
+    return kMaxOutgoingPacketSize;
+  }
+
+  bool SupportsReleaseTime() const override { return false; }
+
+  bool IsBatchMode() const final { return true; }
+
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& /*self_address*/,
+      const QuicSocketAddress& /*peer_address*/) final {
+    // No need to explicitly delete QuicBatchWriterBuffer.
+    return {batch_buffer_->GetNextWriteLocation(), nullptr};
+  }
+
+  WriteResult Flush() override;
+
+ protected:
+  const QuicBatchWriterBuffer& batch_buffer() const { return *batch_buffer_; }
+  QuicBatchWriterBuffer& batch_buffer() { return *batch_buffer_; }
+
+  const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const {
+    return batch_buffer_->buffered_writes();
+  }
+
+  // Given the release delay in |options| and the state of |batch_buffer_|, get
+  // the absolute release time.
+  struct QUIC_NO_EXPORT ReleaseTime {
+    // The actual (absolute) release time.
+    uint64_t actual_release_time = 0;
+    // The difference between |actual_release_time| and ideal release time,
+    // which is (now + |options->release_time_delay|).
+    QuicTime::Delta release_time_offset = QuicTime::Delta::Zero();
+  };
+  virtual ReleaseTime GetReleaseTime(
+      const PerPacketOptions* /*options*/) const {
+    QUICHE_DCHECK(false)
+        << "Should not be called since release time is unsupported.";
+    return ReleaseTime{0, QuicTime::Delta::Zero()};
+  }
+
+  struct QUIC_EXPORT_PRIVATE CanBatchResult {
+    CanBatchResult(bool can_batch, bool must_flush)
+        : can_batch(can_batch), must_flush(must_flush) {}
+    // Whether this write can be batched with existing buffered writes.
+    bool can_batch;
+    // If |can_batch|, whether the caller must flush after this packet is
+    // buffered.
+    // Always true if not |can_batch|.
+    bool must_flush;
+  };
+
+  // Given the existing buffered writes(in buffered_writes()), whether a new
+  // write(in the arguments) can be batched.
+  virtual CanBatchResult CanBatch(const char* buffer,
+                                  size_t buf_len,
+                                  const QuicIpAddress& self_address,
+                                  const QuicSocketAddress& peer_address,
+                                  const PerPacketOptions* options,
+                                  uint64_t release_time) const = 0;
+
+  struct QUIC_EXPORT_PRIVATE FlushImplResult {
+    // The return value of the Flush() interface, which is:
+    // - WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered writes
+    //   were sent successfully.
+    // - WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR, if the batch write is
+    //   blocked or returned an error while sending. If a portion of buffered
+    //   writes were sent successfully, |FlushImplResult.num_packets_sent| and
+    //   |FlushImplResult.bytes_written| contain the number of successfully sent
+    //   packets and their total bytes.
+    WriteResult write_result;
+    int num_packets_sent;
+    // If write_result.status == WRITE_STATUS_OK, |bytes_written| will be equal
+    // to write_result.bytes_written. Otherwise |bytes_written| will be the
+    // number of bytes written before WRITE_BLOCK or WRITE_ERROR happened.
+    int bytes_written;
+  };
+
+  // Send all buffered writes(in buffered_writes()) in a batch.
+  // buffered_writes() is guaranteed to be non-empty when this function is
+  // called.
+  virtual FlushImplResult FlushImpl() = 0;
+
+ private:
+  WriteResult InternalWritePacket(const char* buffer,
+                                  size_t buf_len,
+                                  const QuicIpAddress& self_address,
+                                  const QuicSocketAddress& peer_address,
+                                  PerPacketOptions* options);
+
+  // Calls FlushImpl() and check its post condition.
+  FlushImplResult CheckedFlush();
+
+  bool write_blocked_;
+  std::unique_ptr<QuicBatchWriterBuffer> batch_buffer_;
+};
+
+// QuicUdpBatchWriter is a batch writer backed by a UDP socket.
+class QUIC_EXPORT_PRIVATE QuicUdpBatchWriter : public QuicBatchWriterBase {
+ public:
+  QuicUdpBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+                     int fd)
+      : QuicBatchWriterBase(std::move(batch_buffer)), fd_(fd) {}
+
+  int fd() const { return fd_; }
+
+ private:
+  const int fd_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc
new file mode 100644
index 0000000..1463812
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc
@@ -0,0 +1,156 @@
+// Copyright (c) 2019 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 "quiche/quic/core/batch_writer/quic_batch_writer_buffer.h"
+
+#include <sstream>
+
+namespace quic {
+
+QuicBatchWriterBuffer::QuicBatchWriterBuffer() {
+  memset(buffer_, 0, sizeof(buffer_));
+}
+
+void QuicBatchWriterBuffer::Clear() {
+  buffered_writes_.clear();
+}
+
+std::string QuicBatchWriterBuffer::DebugString() const {
+  std::ostringstream os;
+  os << "{ buffer: " << static_cast<const void*>(buffer_)
+     << " buffer_end: " << static_cast<const void*>(buffer_end())
+     << " buffered_writes_.size(): " << buffered_writes_.size()
+     << " next_write_loc: " << static_cast<const void*>(GetNextWriteLocation())
+     << " SizeInUse: " << SizeInUse() << " }";
+  return os.str();
+}
+
+bool QuicBatchWriterBuffer::Invariants() const {
+  // Buffers in buffered_writes_ should not overlap, and collectively they
+  // should cover a continuous prefix of buffer_.
+  const char* next_buffer = buffer_;
+  for (auto iter = buffered_writes_.begin(); iter != buffered_writes_.end();
+       ++iter) {
+    if ((iter->buffer != next_buffer) ||
+        (iter->buffer + iter->buf_len > buffer_end())) {
+      return false;
+    }
+    next_buffer += iter->buf_len;
+  }
+
+  return static_cast<size_t>(next_buffer - buffer_) == SizeInUse();
+}
+
+char* QuicBatchWriterBuffer::GetNextWriteLocation() const {
+  const char* next_loc =
+      buffered_writes_.empty()
+          ? buffer_
+          : buffered_writes_.back().buffer + buffered_writes_.back().buf_len;
+  if (static_cast<size_t>(buffer_end() - next_loc) < kMaxOutgoingPacketSize) {
+    return nullptr;
+  }
+  return const_cast<char*>(next_loc);
+}
+
+QuicBatchWriterBuffer::PushResult QuicBatchWriterBuffer::PushBufferedWrite(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    const PerPacketOptions* options,
+    uint64_t release_time) {
+  QUICHE_DCHECK(Invariants());
+  QUICHE_DCHECK_LE(buf_len, kMaxOutgoingPacketSize);
+
+  PushResult result = {/*succeeded=*/false, /*buffer_copied=*/false};
+  char* next_write_location = GetNextWriteLocation();
+  if (next_write_location == nullptr) {
+    return result;
+  }
+
+  if (buffer != next_write_location) {
+    if (IsExternalBuffer(buffer, buf_len)) {
+      memcpy(next_write_location, buffer, buf_len);
+    } else if (IsInternalBuffer(buffer, buf_len)) {
+      memmove(next_write_location, buffer, buf_len);
+    } else {
+      QUIC_BUG(quic_bug_10831_1)
+          << "Buffer[" << static_cast<const void*>(buffer) << ", "
+          << static_cast<const void*>(buffer + buf_len)
+          << ") overlaps with internal buffer["
+          << static_cast<const void*>(buffer_) << ", "
+          << static_cast<const void*>(buffer_end()) << ")";
+      return result;
+    }
+    result.buffer_copied = true;
+  } else {
+    // In place push, do nothing.
+  }
+  buffered_writes_.emplace_back(
+      next_write_location, buf_len, self_address, peer_address,
+      options ? options->Clone() : std::unique_ptr<PerPacketOptions>(),
+      release_time);
+
+  QUICHE_DCHECK(Invariants());
+
+  result.succeeded = true;
+  return result;
+}
+
+void QuicBatchWriterBuffer::UndoLastPush() {
+  if (!buffered_writes_.empty()) {
+    buffered_writes_.pop_back();
+  }
+}
+
+QuicBatchWriterBuffer::PopResult QuicBatchWriterBuffer::PopBufferedWrite(
+    int32_t num_buffered_writes) {
+  QUICHE_DCHECK(Invariants());
+  QUICHE_DCHECK_GE(num_buffered_writes, 0);
+  QUICHE_DCHECK_LE(static_cast<size_t>(num_buffered_writes),
+                   buffered_writes_.size());
+
+  PopResult result = {/*num_buffers_popped=*/0,
+                      /*moved_remaining_buffers=*/false};
+
+  result.num_buffers_popped = std::max<int32_t>(num_buffered_writes, 0);
+  result.num_buffers_popped =
+      std::min<int32_t>(result.num_buffers_popped, buffered_writes_.size());
+  buffered_writes_.pop_front_n(result.num_buffers_popped);
+
+  if (!buffered_writes_.empty()) {
+    // If not all buffered writes are erased, the remaining ones will not cover
+    // a continuous prefix of buffer_. We'll fix it by moving the remaining
+    // buffers to the beginning of buffer_ and adjust the buffer pointers in all
+    // remaining buffered writes.
+    // This should happen very rarely, about once per write block.
+    result.moved_remaining_buffers = true;
+    const char* buffer_before_move = buffered_writes_.front().buffer;
+    size_t buffer_len_to_move = buffered_writes_.back().buffer +
+                                buffered_writes_.back().buf_len -
+                                buffer_before_move;
+    memmove(buffer_, buffer_before_move, buffer_len_to_move);
+
+    size_t distance_to_move = buffer_before_move - buffer_;
+    for (BufferedWrite& buffered_write : buffered_writes_) {
+      buffered_write.buffer -= distance_to_move;
+    }
+
+    QUICHE_DCHECK_EQ(buffer_, buffered_writes_.front().buffer);
+  }
+  QUICHE_DCHECK(Invariants());
+
+  return result;
+}
+
+size_t QuicBatchWriterBuffer::SizeInUse() const {
+  if (buffered_writes_.empty()) {
+    return 0;
+  }
+
+  return buffered_writes_.back().buffer + buffered_writes_.back().buf_len -
+         buffer_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h
new file mode 100644
index 0000000..4cf512b
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2019 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_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
+
+#include "absl/base/optimization.h"
+#include "quiche/quic/core/quic_linux_socket_utils.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+// QuicBatchWriterBuffer manages an internal buffer to hold data from multiple
+// packets. Packet data are placed continuously within the internal buffer such
+// that they can be sent by a QuicGsoBatchWriter.
+// This class can also be used by a QuicBatchWriter which uses sendmmsg,
+// although it is not optimized for that use case.
+class QUIC_EXPORT_PRIVATE QuicBatchWriterBuffer {
+ public:
+  QuicBatchWriterBuffer();
+
+  // Clear all buffered writes, but leave the internal buffer intact.
+  void Clear();
+
+  char* GetNextWriteLocation() const;
+
+  // Push a buffered write to the back.
+  struct QUIC_EXPORT_PRIVATE PushResult {
+    bool succeeded;
+    // True in one of the following cases:
+    // 1) The packet buffer is external and copied to the internal buffer, or
+    // 2) The packet buffer is from the internal buffer and moved within it.
+    //    This only happens if PopBufferedWrite is called in the middle of a
+    //    in-place push.
+    // Only valid if |succeeded| is true.
+    bool buffer_copied;
+  };
+
+  PushResult PushBufferedWrite(const char* buffer,
+                               size_t buf_len,
+                               const QuicIpAddress& self_address,
+                               const QuicSocketAddress& peer_address,
+                               const PerPacketOptions* options,
+                               uint64_t release_time);
+
+  void UndoLastPush();
+
+  // Pop |num_buffered_writes| buffered writes from the front.
+  // |num_buffered_writes| will be capped to [0, buffered_writes().size()]
+  // before it is used.
+  struct QUIC_EXPORT_PRIVATE PopResult {
+    int32_t num_buffers_popped;
+    // True if after |num_buffers_popped| buffers are popped from front, the
+    // remaining buffers are moved to the beginning of the internal buffer.
+    // This should normally be false.
+    bool moved_remaining_buffers;
+  };
+  PopResult PopBufferedWrite(int32_t num_buffered_writes);
+
+  const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const {
+    return buffered_writes_;
+  }
+
+  bool IsExternalBuffer(const char* buffer, size_t buf_len) const {
+    return (buffer + buf_len) <= buffer_ || buffer >= buffer_end();
+  }
+  bool IsInternalBuffer(const char* buffer, size_t buf_len) const {
+    return buffer >= buffer_ && (buffer + buf_len) <= buffer_end();
+  }
+
+  // Number of bytes used in |buffer_|.
+  // PushBufferedWrite() increases this; PopBufferedWrite decreases this.
+  size_t SizeInUse() const;
+
+  // Rounded up from |kMaxGsoPacketSize|, which is the maximum allowed
+  // size of a GSO packet.
+  static const size_t kBufferSize = 64 * 1024;
+
+  std::string DebugString() const;
+
+ protected:
+  // Whether the invariants of the buffer are upheld. For debug & test only.
+  bool Invariants() const;
+  const char* buffer_end() const { return buffer_ + sizeof(buffer_); }
+  ABSL_CACHELINE_ALIGNED char buffer_[kBufferSize];
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc b/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
new file mode 100644
index 0000000..c3152b2
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
@@ -0,0 +1,282 @@
+// Copyright (c) 2019 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 "quiche/quic/core/batch_writer/quic_batch_writer_buffer.h"
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QUIC_EXPORT_PRIVATE TestQuicBatchWriterBuffer
+    : public QuicBatchWriterBuffer {
+ public:
+  using QuicBatchWriterBuffer::buffer_;
+  using QuicBatchWriterBuffer::buffered_writes_;
+};
+
+static const size_t kBatchBufferSize = QuicBatchWriterBuffer::kBufferSize;
+
+class QuicBatchWriterBufferTest : public QuicTest {
+ public:
+  QuicBatchWriterBufferTest() { SwitchToNewBuffer(); }
+
+  void SwitchToNewBuffer() {
+    batch_buffer_ = std::make_unique<TestQuicBatchWriterBuffer>();
+  }
+
+  // Fill packet_buffer_ with kMaxOutgoingPacketSize bytes of |c|s.
+  char* FillPacketBuffer(char c) {
+    return FillPacketBuffer(c, packet_buffer_, kMaxOutgoingPacketSize);
+  }
+
+  // Fill |packet_buffer| with kMaxOutgoingPacketSize bytes of |c|s.
+  char* FillPacketBuffer(char c, char* packet_buffer) {
+    return FillPacketBuffer(c, packet_buffer, kMaxOutgoingPacketSize);
+  }
+
+  // Fill |packet_buffer| with |buf_len| bytes of |c|s.
+  char* FillPacketBuffer(char c, char* packet_buffer, size_t buf_len) {
+    memset(packet_buffer, c, buf_len);
+    return packet_buffer;
+  }
+
+  void CheckBufferedWriteContent(int buffered_write_index,
+                                 char buffer_content,
+                                 size_t buf_len,
+                                 const QuicIpAddress& self_addr,
+                                 const QuicSocketAddress& peer_addr,
+                                 const PerPacketOptions* options) {
+    const BufferedWrite& buffered_write =
+        batch_buffer_->buffered_writes()[buffered_write_index];
+    EXPECT_EQ(buf_len, buffered_write.buf_len);
+    for (size_t i = 0; i < buf_len; ++i) {
+      EXPECT_EQ(buffer_content, buffered_write.buffer[i]);
+      if (buffer_content != buffered_write.buffer[i]) {
+        break;
+      }
+    }
+    EXPECT_EQ(self_addr, buffered_write.self_address);
+    EXPECT_EQ(peer_addr, buffered_write.peer_address);
+    if (options == nullptr) {
+      EXPECT_EQ(nullptr, buffered_write.options);
+    } else {
+      EXPECT_EQ(options->release_time_delay,
+                buffered_write.options->release_time_delay);
+    }
+  }
+
+ protected:
+  std::unique_ptr<TestQuicBatchWriterBuffer> batch_buffer_;
+  QuicIpAddress self_addr_;
+  QuicSocketAddress peer_addr_;
+  uint64_t release_time_ = 0;
+  char packet_buffer_[kMaxOutgoingPacketSize];
+};
+
+class BufferSizeSequence {
+ public:
+  explicit BufferSizeSequence(
+      std::vector<std::pair<std::vector<size_t>, size_t>> stages)
+      : stages_(std::move(stages)),
+        total_buf_len_(0),
+        stage_index_(0),
+        sequence_index_(0) {}
+
+  size_t Next() {
+    const std::vector<size_t>& seq = stages_[stage_index_].first;
+    size_t buf_len = seq[sequence_index_++ % seq.size()];
+    total_buf_len_ += buf_len;
+    if (stages_[stage_index_].second <= total_buf_len_) {
+      stage_index_ = std::min(stage_index_ + 1, stages_.size() - 1);
+    }
+    return buf_len;
+  }
+
+ private:
+  const std::vector<std::pair<std::vector<size_t>, size_t>> stages_;
+  size_t total_buf_len_;
+  size_t stage_index_;
+  size_t sequence_index_;
+};
+
+// Test in-place pushes. A in-place push is a push with a buffer address that is
+// equal to the result of GetNextWriteLocation().
+TEST_F(QuicBatchWriterBufferTest, InPlacePushes) {
+  std::vector<BufferSizeSequence> buffer_size_sequences = {
+      // Push large writes until the buffer is near full, then switch to 1-byte
+      // writes. This covers the edge cases when detecting insufficient buffer.
+      BufferSizeSequence({{{1350}, kBatchBufferSize - 3000}, {{1}, 1e6}}),
+      // A sequence that looks real.
+      BufferSizeSequence({{{1, 39, 97, 150, 1350, 1350, 1350, 1350}, 1e6}}),
+  };
+
+  for (auto& buffer_size_sequence : buffer_size_sequences) {
+    SwitchToNewBuffer();
+    int64_t num_push_failures = 0;
+
+    while (batch_buffer_->SizeInUse() < kBatchBufferSize) {
+      size_t buf_len = buffer_size_sequence.Next();
+      const bool has_enough_space =
+          (kBatchBufferSize - batch_buffer_->SizeInUse() >=
+           kMaxOutgoingPacketSize);
+
+      char* buffer = batch_buffer_->GetNextWriteLocation();
+
+      if (has_enough_space) {
+        EXPECT_EQ(batch_buffer_->buffer_ + batch_buffer_->SizeInUse(), buffer);
+      } else {
+        EXPECT_EQ(nullptr, buffer);
+      }
+
+      SCOPED_TRACE(testing::Message()
+                   << "Before Push: buf_len=" << buf_len
+                   << ", has_enough_space=" << has_enough_space
+                   << ", batch_buffer=" << batch_buffer_->DebugString());
+
+      auto push_result = batch_buffer_->PushBufferedWrite(
+          buffer, buf_len, self_addr_, peer_addr_, nullptr, release_time_);
+      if (!push_result.succeeded) {
+        ++num_push_failures;
+      }
+      EXPECT_EQ(has_enough_space, push_result.succeeded);
+      EXPECT_FALSE(push_result.buffer_copied);
+      if (!has_enough_space) {
+        break;
+      }
+    }
+    // Expect one and only one failure from the final push operation.
+    EXPECT_EQ(1, num_push_failures);
+  }
+}
+
+// Test some in-place pushes mixed with pushes with external buffers.
+TEST_F(QuicBatchWriterBufferTest, MixedPushes) {
+  // First, a in-place push.
+  char* buffer = batch_buffer_->GetNextWriteLocation();
+  auto push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('A', buffer), kDefaultMaxPacketSize, self_addr_,
+      peer_addr_, nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_FALSE(push_result.buffer_copied);
+  CheckBufferedWriteContent(0, 'A', kDefaultMaxPacketSize, self_addr_,
+                            peer_addr_, nullptr);
+
+  // Then a push with external buffer.
+  push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('B'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
+      nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_TRUE(push_result.buffer_copied);
+  CheckBufferedWriteContent(1, 'B', kDefaultMaxPacketSize, self_addr_,
+                            peer_addr_, nullptr);
+
+  // Then another in-place push.
+  buffer = batch_buffer_->GetNextWriteLocation();
+  push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('C', buffer), kDefaultMaxPacketSize, self_addr_,
+      peer_addr_, nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_FALSE(push_result.buffer_copied);
+  CheckBufferedWriteContent(2, 'C', kDefaultMaxPacketSize, self_addr_,
+                            peer_addr_, nullptr);
+
+  // Then another push with external buffer.
+  push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('D'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
+      nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_TRUE(push_result.buffer_copied);
+  CheckBufferedWriteContent(3, 'D', kDefaultMaxPacketSize, self_addr_,
+                            peer_addr_, nullptr);
+}
+
+TEST_F(QuicBatchWriterBufferTest, PopAll) {
+  const int kNumBufferedWrites = 10;
+  for (int i = 0; i < kNumBufferedWrites; ++i) {
+    EXPECT_TRUE(batch_buffer_
+                    ->PushBufferedWrite(packet_buffer_, kDefaultMaxPacketSize,
+                                        self_addr_, peer_addr_, nullptr,
+                                        release_time_)
+                    .succeeded);
+  }
+  EXPECT_EQ(kNumBufferedWrites,
+            static_cast<int>(batch_buffer_->buffered_writes().size()));
+
+  auto pop_result = batch_buffer_->PopBufferedWrite(kNumBufferedWrites);
+  EXPECT_EQ(0u, batch_buffer_->buffered_writes().size());
+  EXPECT_EQ(kNumBufferedWrites, pop_result.num_buffers_popped);
+  EXPECT_FALSE(pop_result.moved_remaining_buffers);
+}
+
+TEST_F(QuicBatchWriterBufferTest, PopPartial) {
+  const int kNumBufferedWrites = 10;
+  for (int i = 0; i < kNumBufferedWrites; ++i) {
+    EXPECT_TRUE(batch_buffer_
+                    ->PushBufferedWrite(FillPacketBuffer('A' + i),
+                                        kDefaultMaxPacketSize - i, self_addr_,
+                                        peer_addr_, nullptr, release_time_)
+                    .succeeded);
+  }
+
+  for (size_t i = 0;
+       i < kNumBufferedWrites && !batch_buffer_->buffered_writes().empty();
+       ++i) {
+    const size_t size_before_pop = batch_buffer_->buffered_writes().size();
+    const size_t expect_size_after_pop =
+        size_before_pop < i ? 0 : size_before_pop - i;
+    batch_buffer_->PopBufferedWrite(i);
+    ASSERT_EQ(expect_size_after_pop, batch_buffer_->buffered_writes().size());
+    const char first_write_content =
+        'A' + kNumBufferedWrites - expect_size_after_pop;
+    const size_t first_write_len =
+        kDefaultMaxPacketSize - kNumBufferedWrites + expect_size_after_pop;
+    for (size_t j = 0; j < expect_size_after_pop; ++j) {
+      CheckBufferedWriteContent(j, first_write_content + j, first_write_len - j,
+                                self_addr_, peer_addr_, nullptr);
+    }
+  }
+}
+
+TEST_F(QuicBatchWriterBufferTest, InPlacePushWithPops) {
+  // First, a in-place push.
+  char* buffer = batch_buffer_->GetNextWriteLocation();
+  const size_t first_packet_len = 2;
+  auto push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('A', buffer, first_packet_len), first_packet_len,
+      self_addr_, peer_addr_, nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_FALSE(push_result.buffer_copied);
+  CheckBufferedWriteContent(0, 'A', first_packet_len, self_addr_, peer_addr_,
+                            nullptr);
+
+  // Simulate the case where the writer wants to do another in-place push, but
+  // can't do so because it can't be batched with the first buffer.
+  buffer = batch_buffer_->GetNextWriteLocation();
+  const size_t second_packet_len = 1350;
+
+  // Flush the first buffer.
+  auto pop_result = batch_buffer_->PopBufferedWrite(1);
+  EXPECT_EQ(1, pop_result.num_buffers_popped);
+  EXPECT_FALSE(pop_result.moved_remaining_buffers);
+
+  // Now the second push.
+  push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('B', buffer, second_packet_len), second_packet_len,
+      self_addr_, peer_addr_, nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_TRUE(push_result.buffer_copied);
+  CheckBufferedWriteContent(0, 'B', second_packet_len, self_addr_, peer_addr_,
+                            nullptr);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_test.cc b/quiche/quic/core/batch_writer/quic_batch_writer_test.cc
new file mode 100644
index 0000000..2cd3111
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_test.cc
@@ -0,0 +1,77 @@
+// Copyright (c) 2019 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 "quiche/quic/core/batch_writer/quic_batch_writer_test.h"
+#include "quiche/quic/core/batch_writer/quic_gso_batch_writer.h"
+#include "quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicGsoBatchWriterIOTestDelegate
+    : public QuicUdpBatchWriterIOTestDelegate {
+ public:
+  bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& params) override {
+    QuicUdpSocketApi socket_api;
+    int fd =
+        socket_api.Create(params.address_family,
+                          /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
+                          /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
+    if (fd < 0) {
+      QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
+      return false;  // Let the test fail rather than skip it.
+    }
+    const bool gso_not_supported =
+        QuicLinuxSocketUtils::GetUDPSegmentSize(fd) < 0;
+    socket_api.Destroy(fd);
+
+    if (gso_not_supported) {
+      QUIC_LOG(WARNING) << "Test skipped since GSO is not supported.";
+      return true;
+    }
+
+    QUIC_LOG(WARNING) << "OK: GSO is supported.";
+    return false;
+  }
+
+  void ResetWriter(int fd) override {
+    writer_ = std::make_unique<QuicGsoBatchWriter>(fd);
+  }
+
+  QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
+
+ private:
+  std::unique_ptr<QuicGsoBatchWriter> writer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    QuicGsoBatchWriterTest,
+    QuicUdpBatchWriterIOTest,
+    testing::ValuesIn(
+        MakeQuicBatchWriterTestParams<QuicGsoBatchWriterIOTestDelegate>()));
+
+class QuicSendmmsgBatchWriterIOTestDelegate
+    : public QuicUdpBatchWriterIOTestDelegate {
+ public:
+  void ResetWriter(int fd) override {
+    writer_ = std::make_unique<QuicSendmmsgBatchWriter>(
+        std::make_unique<QuicBatchWriterBuffer>(), fd);
+  }
+
+  QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
+
+ private:
+  std::unique_ptr<QuicSendmmsgBatchWriter> writer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    QuicSendmmsgBatchWriterTest,
+    QuicUdpBatchWriterIOTest,
+    testing::ValuesIn(MakeQuicBatchWriterTestParams<
+                      QuicSendmmsgBatchWriterIOTestDelegate>()));
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_test.h b/quiche/quic/core/batch_writer/quic_batch_writer_test.h
new file mode 100644
index 0000000..71c8aa8
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_test.h
@@ -0,0 +1,287 @@
+// Copyright (c) 2019 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_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <cstddef>
+#include <iostream>
+#include <utility>
+
+#include "absl/base/optimization.h"
+#include "quiche/quic/core/batch_writer/quic_batch_writer_base.h"
+#include "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+static bool IsAddressFamilySupported(int address_family) {
+  static auto check_function = [](int address_family) {
+    int fd = socket(address_family, SOCK_STREAM, 0);
+    if (fd < 0) {
+      QUIC_LOG(ERROR) << "address_family not supported: " << address_family
+                      << ", error: " << strerror(errno);
+      EXPECT_EQ(EAFNOSUPPORT, errno);
+      return false;
+    }
+    close(fd);
+    return true;
+  };
+
+  if (address_family == AF_INET) {
+    static const bool ipv4_supported = check_function(AF_INET);
+    return ipv4_supported;
+  }
+
+  static const bool ipv6_supported = check_function(AF_INET6);
+  return ipv6_supported;
+}
+
+static bool CreateSocket(int family, QuicSocketAddress* address, int* fd) {
+  if (family == AF_INET) {
+    *address = QuicSocketAddress(QuicIpAddress::Loopback4(), 0);
+  } else {
+    QUICHE_DCHECK_EQ(family, AF_INET6);
+    *address = QuicSocketAddress(QuicIpAddress::Loopback6(), 0);
+  }
+
+  QuicUdpSocketApi socket_api;
+  *fd = socket_api.Create(family,
+                          /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
+                          /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
+  if (*fd < 0) {
+    QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
+    return false;
+  }
+  socket_api.EnableDroppedPacketCount(*fd);
+
+  if (!socket_api.Bind(*fd, *address)) {
+    QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
+    return false;
+  }
+
+  if (address->FromSocket(*fd) != 0) {
+    QUIC_LOG(ERROR) << "Unable to get self address.  Error: "
+                    << strerror(errno);
+    return false;
+  }
+  return true;
+}
+
+struct QuicUdpBatchWriterIOTestParams;
+class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestDelegate {
+ public:
+  virtual ~QuicUdpBatchWriterIOTestDelegate() {}
+
+  virtual bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& /*params*/) {
+    return false;
+  }
+
+  virtual void ResetWriter(int fd) = 0;
+
+  virtual QuicUdpBatchWriter* GetWriter() = 0;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestParams {
+  // Use shared_ptr because gtest makes copies of test params.
+  std::shared_ptr<QuicUdpBatchWriterIOTestDelegate> delegate;
+  int address_family;
+  int data_size;
+  int packet_size;
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicUdpBatchWriterIOTestParams& p) {
+    os << "{ address_family: " << p.address_family
+       << " data_size: " << p.data_size << " packet_size: " << p.packet_size
+       << " }";
+    return os;
+  }
+};
+
+template <class QuicUdpBatchWriterIOTestDelegateT>
+static std::vector<QuicUdpBatchWriterIOTestParams>
+MakeQuicBatchWriterTestParams() {
+  static_assert(std::is_base_of<QuicUdpBatchWriterIOTestDelegate,
+                                QuicUdpBatchWriterIOTestDelegateT>::value,
+                "<QuicUdpBatchWriterIOTestDelegateT> needs to derive from "
+                "QuicUdpBatchWriterIOTestDelegate");
+
+  std::vector<QuicUdpBatchWriterIOTestParams> params;
+  for (int address_family : {AF_INET, AF_INET6}) {
+    for (int data_size : {1, 150, 1500, 15000, 64000, 512 * 1024}) {
+      for (int packet_size : {1, 50, 1350, 1452}) {
+        if (packet_size <= data_size && (data_size / packet_size < 2000)) {
+          params.push_back(
+              {std::make_unique<QuicUdpBatchWriterIOTestDelegateT>(),
+               address_family, data_size, packet_size});
+        }
+      }
+    }
+  }
+  return params;
+}
+
+// QuicUdpBatchWriterIOTest is a value parameterized test fixture that can be
+// used by tests of derived classes of QuicUdpBatchWriter, to verify basic
+// packet IO capabilities.
+class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTest
+    : public QuicTestWithParam<QuicUdpBatchWriterIOTestParams> {
+ protected:
+  QuicUdpBatchWriterIOTest()
+      : address_family_(GetParam().address_family),
+        data_size_(GetParam().data_size),
+        packet_size_(GetParam().packet_size),
+        self_socket_(-1),
+        peer_socket_(-1) {
+    QUIC_LOG(INFO) << "QuicUdpBatchWriterIOTestParams: " << GetParam();
+    EXPECT_TRUE(address_family_ == AF_INET || address_family_ == AF_INET6);
+    EXPECT_LE(packet_size_, data_size_);
+    EXPECT_LE(packet_size_, sizeof(packet_buffer_));
+  }
+
+  ~QuicUdpBatchWriterIOTest() override {
+    if (self_socket_ > 0) {
+      close(self_socket_);
+    }
+    if (peer_socket_ > 0) {
+      close(peer_socket_);
+    }
+  }
+
+  // Whether this test should be skipped. A test is passed if skipped.
+  // A test can be skipped when e.g. it exercises a kernel feature that is not
+  // available on the system.
+  bool ShouldSkip() {
+    if (!IsAddressFamilySupported(address_family_)) {
+      QUIC_LOG(WARNING)
+          << "Test skipped since address_family is not supported.";
+      return true;
+    }
+
+    return GetParam().delegate->ShouldSkip(GetParam());
+  }
+
+  // Initialize a test.
+  // To fail the test in Initialize, use ASSERT_xx macros.
+  void Initialize() {
+    ASSERT_TRUE(CreateSocket(address_family_, &self_address_, &self_socket_));
+    ASSERT_TRUE(CreateSocket(address_family_, &peer_address_, &peer_socket_));
+
+    QUIC_DLOG(INFO) << "Self address: " << self_address_.ToString() << ", fd "
+                    << self_socket_;
+    QUIC_DLOG(INFO) << "Peer address: " << peer_address_.ToString() << ", fd "
+                    << peer_socket_;
+    GetParam().delegate->ResetWriter(self_socket_);
+  }
+
+  QuicUdpBatchWriter* GetWriter() { return GetParam().delegate->GetWriter(); }
+
+  void ValidateWrite() {
+    char this_packet_content = '\0';
+    int this_packet_size;
+    int num_writes = 0;
+    size_t bytes_flushed = 0;
+    WriteResult result;
+
+    for (size_t bytes_sent = 0; bytes_sent < data_size_;
+         bytes_sent += this_packet_size, ++this_packet_content) {
+      this_packet_size = std::min(packet_size_, data_size_ - bytes_sent);
+      memset(&packet_buffer_[0], this_packet_content, this_packet_size);
+
+      result = GetWriter()->WritePacket(&packet_buffer_[0], this_packet_size,
+                                        self_address_.host(), peer_address_,
+                                        nullptr);
+
+      ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
+      bytes_flushed += result.bytes_written;
+      ++num_writes;
+
+      QUIC_DVLOG(1) << "[write #" << num_writes
+                    << "] this_packet_size: " << this_packet_size
+                    << ", total_bytes_sent: " << bytes_sent + this_packet_size
+                    << ", bytes_flushed: " << bytes_flushed
+                    << ", pkt content:" << std::hex << int(this_packet_content);
+    }
+
+    result = GetWriter()->Flush();
+    ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
+    bytes_flushed += result.bytes_written;
+    ASSERT_EQ(data_size_, bytes_flushed);
+
+    QUIC_LOG(INFO) << "Sent " << data_size_ << " bytes in " << num_writes
+                   << " writes.";
+  }
+
+  void ValidateRead() {
+    char this_packet_content = '\0';
+    int this_packet_size;
+    int packets_received = 0;
+    for (size_t bytes_received = 0; bytes_received < data_size_;
+         bytes_received += this_packet_size, ++this_packet_content) {
+      this_packet_size = std::min(packet_size_, data_size_ - bytes_received);
+      SCOPED_TRACE(testing::Message()
+                   << "Before ReadPacket: bytes_received=" << bytes_received
+                   << ", this_packet_size=" << this_packet_size);
+
+      QuicUdpSocketApi::ReadPacketResult result;
+      result.packet_buffer = {&packet_buffer_[0], sizeof(packet_buffer_)};
+      result.control_buffer = {&control_buffer_[0], sizeof(control_buffer_)};
+      QuicUdpSocketApi().ReadPacket(
+          peer_socket_,
+          quic::BitMask64(QuicUdpPacketInfoBit::V4_SELF_IP,
+                          QuicUdpPacketInfoBit::V6_SELF_IP,
+                          QuicUdpPacketInfoBit::PEER_ADDRESS),
+          &result);
+      ASSERT_TRUE(result.ok);
+      ASSERT_TRUE(
+          result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
+      QuicSocketAddress read_peer_address = result.packet_info.peer_address();
+      QuicIpAddress read_self_address = read_peer_address.host().IsIPv6()
+                                            ? result.packet_info.self_v6_ip()
+                                            : result.packet_info.self_v4_ip();
+
+      EXPECT_EQ(read_self_address, peer_address_.host());
+      EXPECT_EQ(read_peer_address, self_address_);
+      for (int i = 0; i < this_packet_size; ++i) {
+        EXPECT_EQ(this_packet_content, packet_buffer_[i]);
+      }
+      packets_received += this_packet_size;
+    }
+
+    QUIC_LOG(INFO) << "Received " << data_size_ << " bytes in "
+                   << packets_received << " packets.";
+  }
+
+  QuicSocketAddress self_address_;
+  QuicSocketAddress peer_address_;
+  ABSL_CACHELINE_ALIGNED char packet_buffer_[1500];
+  ABSL_CACHELINE_ALIGNED char
+      control_buffer_[kDefaultUdpPacketControlBufferSize];
+  int address_family_;
+  const size_t data_size_;
+  const size_t packet_size_;
+  int self_socket_;
+  int peer_socket_;
+};
+
+TEST_P(QuicUdpBatchWriterIOTest, WriteAndRead) {
+  if (ShouldSkip()) {
+    return;
+  }
+
+  Initialize();
+
+  ValidateWrite();
+  ValidateRead();
+}
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
diff --git a/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc b/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc
new file mode 100644
index 0000000..297f04e
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc
@@ -0,0 +1,164 @@
+// Copyright (c) 2019 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 "quiche/quic/core/batch_writer/quic_gso_batch_writer.h"
+
+#include <time.h>
+#include <ctime>
+
+#include "quiche/quic/core/quic_linux_socket_utils.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+
+namespace quic {
+
+// static
+std::unique_ptr<QuicBatchWriterBuffer>
+QuicGsoBatchWriter::CreateBatchWriterBuffer() {
+  return std::make_unique<QuicBatchWriterBuffer>();
+}
+
+QuicGsoBatchWriter::QuicGsoBatchWriter(int fd)
+    : QuicGsoBatchWriter(fd, CLOCK_MONOTONIC) {}
+
+QuicGsoBatchWriter::QuicGsoBatchWriter(int fd,
+                                       clockid_t clockid_for_release_time)
+    : QuicUdpBatchWriter(CreateBatchWriterBuffer(), fd),
+      clockid_for_release_time_(clockid_for_release_time),
+      supports_release_time_(
+          GetQuicRestartFlag(quic_support_release_time_for_gso) &&
+          QuicLinuxSocketUtils::EnableReleaseTime(fd,
+                                                  clockid_for_release_time)) {
+  if (supports_release_time_) {
+    QUIC_RESTART_FLAG_COUNT(quic_support_release_time_for_gso);
+    QUIC_LOG_FIRST_N(INFO, 5) << "Release time is enabled.";
+  } else {
+    QUIC_LOG_FIRST_N(INFO, 5) << "Release time is not enabled.";
+  }
+}
+
+QuicGsoBatchWriter::QuicGsoBatchWriter(
+    std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+    int fd,
+    clockid_t clockid_for_release_time,
+    ReleaseTimeForceEnabler /*enabler*/)
+    : QuicUdpBatchWriter(std::move(batch_buffer), fd),
+      clockid_for_release_time_(clockid_for_release_time),
+      supports_release_time_(true) {
+  QUIC_DLOG(INFO) << "Release time forcefully enabled.";
+}
+
+QuicGsoBatchWriter::CanBatchResult QuicGsoBatchWriter::CanBatch(
+    const char* /*buffer*/,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    const PerPacketOptions* options,
+    uint64_t release_time) const {
+  // If there is nothing buffered already, this write will be included in this
+  // batch.
+  if (buffered_writes().empty()) {
+    return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
+  }
+
+  // The new write can be batched if all of the following are true:
+  // [0] The total number of the GSO segments(one write=one segment, including
+  //     the new write) must not exceed |max_segments|.
+  // [1] It has the same source and destination addresses as already buffered
+  //     writes.
+  // [2] It won't cause this batch to exceed kMaxGsoPacketSize.
+  // [3] Already buffered writes all have the same length.
+  // [4] Length of already buffered writes must >= length of the new write.
+  // [5] The new packet can be released without delay, or it has the same
+  //     release time as buffered writes.
+  const BufferedWrite& first = buffered_writes().front();
+  const BufferedWrite& last = buffered_writes().back();
+  // Whether this packet can be sent without delay, regardless of release time.
+  const bool can_burst = !SupportsReleaseTime() || !options ||
+                         options->release_time_delay.IsZero() ||
+                         options->allow_burst;
+  size_t max_segments = MaxSegments(first.buf_len);
+  bool can_batch =
+      buffered_writes().size() < max_segments &&                    // [0]
+      last.self_address == self_address &&                          // [1]
+      last.peer_address == peer_address &&                          // [1]
+      batch_buffer().SizeInUse() + buf_len <= kMaxGsoPacketSize &&  // [2]
+      first.buf_len == last.buf_len &&                              // [3]
+      first.buf_len >= buf_len &&                                   // [4]
+      (can_burst || first.release_time == release_time);            // [5]
+
+  // A flush is required if any of the following is true:
+  // [a] The new write can't be batched.
+  // [b] Length of the new write is different from the length of already
+  //     buffered writes.
+  // [c] The total number of the GSO segments, including the new write, reaches
+  //     |max_segments|.
+  bool must_flush = (!can_batch) ||                                  // [a]
+                    (last.buf_len != buf_len) ||                     // [b]
+                    (buffered_writes().size() + 1 == max_segments);  // [c]
+  return CanBatchResult(can_batch, must_flush);
+}
+
+QuicGsoBatchWriter::ReleaseTime QuicGsoBatchWriter::GetReleaseTime(
+    const PerPacketOptions* options) const {
+  QUICHE_DCHECK(SupportsReleaseTime());
+
+  if (options == nullptr) {
+    return {0, QuicTime::Delta::Zero()};
+  }
+
+  const uint64_t now = NowInNanosForReleaseTime();
+  const uint64_t ideal_release_time =
+      now + options->release_time_delay.ToMicroseconds() * 1000;
+
+  if ((options->release_time_delay.IsZero() || options->allow_burst) &&
+      !buffered_writes().empty() &&
+      // If release time of buffered packets is in the past, flush buffered
+      // packets and buffer this packet at the ideal release time.
+      (buffered_writes().back().release_time >= now)) {
+    // Send as soon as possible, but no sooner than the last buffered packet.
+    const uint64_t actual_release_time = buffered_writes().back().release_time;
+
+    const int64_t offset_ns = actual_release_time - ideal_release_time;
+    ReleaseTime result{actual_release_time,
+                       QuicTime::Delta::FromMicroseconds(offset_ns / 1000)};
+
+    QUIC_DVLOG(1) << "ideal_release_time:" << ideal_release_time
+                  << ", actual_release_time:" << actual_release_time
+                  << ", offset:" << result.release_time_offset;
+    return result;
+  }
+
+  // Send according to the release time delay.
+  return {ideal_release_time, QuicTime::Delta::Zero()};
+}
+
+uint64_t QuicGsoBatchWriter::NowInNanosForReleaseTime() const {
+  struct timespec ts;
+
+  if (clock_gettime(clockid_for_release_time_, &ts) != 0) {
+    return 0;
+  }
+
+  return ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
+}
+
+// static
+void QuicGsoBatchWriter::BuildCmsg(QuicMsgHdr* hdr,
+                                   const QuicIpAddress& self_address,
+                                   uint16_t gso_size,
+                                   uint64_t release_time) {
+  hdr->SetIpInNextCmsg(self_address);
+  if (gso_size > 0) {
+    *hdr->GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = gso_size;
+  }
+  if (release_time != 0) {
+    *hdr->GetNextCmsgData<uint64_t>(SOL_SOCKET, SO_TXTIME) = release_time;
+  }
+}
+
+QuicGsoBatchWriter::FlushImplResult QuicGsoBatchWriter::FlushImpl() {
+  return InternalFlushImpl<kCmsgSpace>(BuildCmsg);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_gso_batch_writer.h b/quiche/quic/core/batch_writer/quic_gso_batch_writer.h
new file mode 100644
index 0000000..6321cb5
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_gso_batch_writer.h
@@ -0,0 +1,117 @@
+// Copyright (c) 2019 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_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
+
+#include "quiche/quic/core/batch_writer/quic_batch_writer_base.h"
+
+namespace quic {
+
+// QuicGsoBatchWriter sends QUIC packets in batches, using UDP socket's generic
+// segmentation offload(GSO) capability.
+class QUIC_EXPORT_PRIVATE QuicGsoBatchWriter : public QuicUdpBatchWriter {
+ public:
+  explicit QuicGsoBatchWriter(int fd);
+
+  // |clockid_for_release_time|: FQ qdisc requires CLOCK_MONOTONIC, EDF requires
+  // CLOCK_TAI.
+  QuicGsoBatchWriter(int fd, clockid_t clockid_for_release_time);
+
+  bool SupportsReleaseTime() const final { return supports_release_time_; }
+
+  CanBatchResult CanBatch(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          const PerPacketOptions* options,
+                          uint64_t release_time) const override;
+
+  FlushImplResult FlushImpl() override;
+
+ protected:
+  // Test only constructor to forcefully enable release time.
+  struct QUIC_EXPORT_PRIVATE ReleaseTimeForceEnabler {};
+  QuicGsoBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+                     int fd,
+                     clockid_t clockid_for_release_time,
+                     ReleaseTimeForceEnabler enabler);
+
+  ReleaseTime GetReleaseTime(const PerPacketOptions* options) const override;
+
+  // Get the current time in nanos from |clockid_for_release_time_|.
+  virtual uint64_t NowInNanosForReleaseTime() const;
+
+  static size_t MaxSegments(size_t gso_size) {
+    // Max segments should be the min of UDP_MAX_SEGMENTS(64) and
+    // (((64KB - sizeof(ip hdr) - sizeof(udp hdr)) / MSS) + 1), in the typical
+    // case of IPv6 packets with 1500-byte MTU, the result is
+    //         ((64KB - 40 - 8) / (1500 - 48)) + 1 = 46
+    // However, due a kernel bug, the limit is much lower for tiny gso_sizes.
+    return gso_size <= 2 ? 16 : 45;
+  }
+
+  static const int kCmsgSpace =
+      kCmsgSpaceForIp + kCmsgSpaceForSegmentSize + kCmsgSpaceForTxTime;
+  static void BuildCmsg(QuicMsgHdr* hdr,
+                        const QuicIpAddress& self_address,
+                        uint16_t gso_size,
+                        uint64_t release_time);
+
+  template <size_t CmsgSpace, typename CmsgBuilderT>
+  FlushImplResult InternalFlushImpl(CmsgBuilderT cmsg_builder) {
+    QUICHE_DCHECK(!IsWriteBlocked());
+    QUICHE_DCHECK(!buffered_writes().empty());
+
+    FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
+                              /*num_packets_sent=*/0, /*bytes_written=*/0};
+    WriteResult& write_result = result.write_result;
+
+    int total_bytes = batch_buffer().SizeInUse();
+    const BufferedWrite& first = buffered_writes().front();
+    char cbuf[CmsgSpace];
+    QuicMsgHdr hdr(first.buffer, total_bytes, first.peer_address, cbuf,
+                   sizeof(cbuf));
+
+    uint16_t gso_size = buffered_writes().size() > 1 ? first.buf_len : 0;
+    cmsg_builder(&hdr, first.self_address, gso_size, first.release_time);
+
+    write_result = QuicLinuxSocketUtils::WritePacket(fd(), hdr);
+    QUIC_DVLOG(1) << "Write GSO packet result: " << write_result
+                  << ", fd: " << fd()
+                  << ", self_address: " << first.self_address.ToString()
+                  << ", peer_address: " << first.peer_address.ToString()
+                  << ", num_segments: " << buffered_writes().size()
+                  << ", total_bytes: " << total_bytes
+                  << ", gso_size: " << gso_size
+                  << ", release_time: " << first.release_time;
+
+    // All segments in a GSO packet share the same fate - if the write failed,
+    // none of them are sent, and it's not needed to call PopBufferedWrite().
+    if (write_result.status != WRITE_STATUS_OK) {
+      return result;
+    }
+
+    result.num_packets_sent = buffered_writes().size();
+
+    write_result.bytes_written = total_bytes;
+    result.bytes_written = total_bytes;
+
+    batch_buffer().PopBufferedWrite(buffered_writes().size());
+
+    QUIC_BUG_IF(quic_bug_12544_1, !buffered_writes().empty())
+        << "All packets should have been written on a successful return";
+    return result;
+  }
+
+ private:
+  static std::unique_ptr<QuicBatchWriterBuffer> CreateBatchWriterBuffer();
+
+  const clockid_t clockid_for_release_time_;
+  const bool supports_release_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
diff --git a/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc b/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc
new file mode 100644
index 0000000..2bf0ffc
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc
@@ -0,0 +1,472 @@
+// Copyright (c) 2019 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 "quiche/quic/core/batch_writer/quic_gso_batch_writer.h"
+
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_mock_syscall_wrapper.h"
+
+using testing::_;
+using testing::Invoke;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+size_t PacketLength(const msghdr* msg) {
+  size_t length = 0;
+  for (size_t i = 0; i < msg->msg_iovlen; ++i) {
+    length += msg->msg_iov[i].iov_len;
+  }
+  return length;
+}
+
+uint64_t MillisToNanos(uint64_t milliseconds) {
+  return milliseconds * 1000000;
+}
+
+class QUIC_EXPORT_PRIVATE TestQuicGsoBatchWriter : public QuicGsoBatchWriter {
+ public:
+  using QuicGsoBatchWriter::batch_buffer;
+  using QuicGsoBatchWriter::buffered_writes;
+  using QuicGsoBatchWriter::CanBatch;
+  using QuicGsoBatchWriter::CanBatchResult;
+  using QuicGsoBatchWriter::GetReleaseTime;
+  using QuicGsoBatchWriter::MaxSegments;
+  using QuicGsoBatchWriter::QuicGsoBatchWriter;
+  using QuicGsoBatchWriter::ReleaseTime;
+
+  static std::unique_ptr<TestQuicGsoBatchWriter>
+  NewInstanceWithReleaseTimeSupport() {
+    return std::unique_ptr<TestQuicGsoBatchWriter>(new TestQuicGsoBatchWriter(
+        std::make_unique<QuicBatchWriterBuffer>(),
+        /*fd=*/-1, CLOCK_MONOTONIC, ReleaseTimeForceEnabler()));
+  }
+
+  uint64_t NowInNanosForReleaseTime() const override {
+    return MillisToNanos(forced_release_time_ms_);
+  }
+
+  void ForceReleaseTimeMs(uint64_t forced_release_time_ms) {
+    forced_release_time_ms_ = forced_release_time_ms;
+  }
+
+ private:
+  uint64_t forced_release_time_ms_ = 1;
+};
+
+struct QUIC_EXPORT_PRIVATE TestPerPacketOptions : public PerPacketOptions {
+  std::unique_ptr<quic::PerPacketOptions> Clone() const override {
+    return std::make_unique<TestPerPacketOptions>(*this);
+  }
+};
+
+// TestBufferedWrite is a copy-constructible BufferedWrite.
+struct QUIC_EXPORT_PRIVATE TestBufferedWrite : public BufferedWrite {
+  using BufferedWrite::BufferedWrite;
+  TestBufferedWrite(const TestBufferedWrite& other)
+      : BufferedWrite(other.buffer,
+                      other.buf_len,
+                      other.self_address,
+                      other.peer_address,
+                      other.options ? other.options->Clone()
+                                    : std::unique_ptr<PerPacketOptions>(),
+                      other.release_time) {}
+};
+
+// Pointed to by all instances of |BatchCriteriaTestData|. Content not used.
+static char unused_packet_buffer[kMaxOutgoingPacketSize];
+
+struct QUIC_EXPORT_PRIVATE BatchCriteriaTestData {
+  BatchCriteriaTestData(size_t buf_len,
+                        const QuicIpAddress& self_address,
+                        const QuicSocketAddress& peer_address,
+                        uint64_t release_time,
+                        bool can_batch,
+                        bool must_flush)
+      : buffered_write(unused_packet_buffer,
+                       buf_len,
+                       self_address,
+                       peer_address,
+                       std::unique_ptr<PerPacketOptions>(),
+                       release_time),
+        can_batch(can_batch),
+        must_flush(must_flush) {}
+
+  TestBufferedWrite buffered_write;
+  // Expected value of CanBatchResult.can_batch when batching |buffered_write|.
+  bool can_batch;
+  // Expected value of CanBatchResult.must_flush when batching |buffered_write|.
+  bool must_flush;
+};
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeDecrease() {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {39,       self_addr,  peer_addr,  0,      true,           true},
+    {39,       self_addr,  peer_addr,  0,      false,          true},
+    {1350,     self_addr,  peer_addr,  0,      false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeIncrease() {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1351,     self_addr,  peer_addr,  0,      false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_AddressChange() {
+  const QuicIpAddress self_addr1 = QuicIpAddress::Loopback4();
+  const QuicIpAddress self_addr2 = QuicIpAddress::Loopback6();
+  const QuicSocketAddress peer_addr1(self_addr1, 666);
+  const QuicSocketAddress peer_addr2(self_addr1, 777);
+  const QuicSocketAddress peer_addr3(self_addr2, 666);
+  const QuicSocketAddress peer_addr4(self_addr2, 777);
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr    t_rel  can_batch       must_flush
+    {1350,     self_addr1, peer_addr1,  0,     true,           false},
+    {1350,     self_addr1, peer_addr1,  0,     true,           false},
+    {1350,     self_addr1, peer_addr1,  0,     true,           false},
+    {1350,     self_addr2, peer_addr1,  0,     false,          true},
+    {1350,     self_addr1, peer_addr2,  0,     false,          true},
+    {1350,     self_addr1, peer_addr3,  0,     false,          true},
+    {1350,     self_addr1, peer_addr4,  0,     false,          true},
+    {1350,     self_addr1, peer_addr4,  0,     false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime1() {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
+    {1350,     self_addr,  peer_addr,  5,      true,           false},
+    {1350,     self_addr,  peer_addr,  5,      true,           false},
+    {1350,     self_addr,  peer_addr,  5,      true,           false},
+    {1350,     self_addr,  peer_addr,  9,      false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime2() {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  9,      false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_MaxSegments(
+    size_t gso_size) {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table;
+  size_t max_segments = TestQuicGsoBatchWriter::MaxSegments(gso_size);
+  for (size_t i = 0; i < max_segments; ++i) {
+    bool is_last_in_batch = (i + 1 == max_segments);
+    test_data_table.push_back({gso_size, self_addr, peer_addr,
+                               /*release_time=*/0, true, is_last_in_batch});
+  }
+  test_data_table.push_back(
+      {gso_size, self_addr, peer_addr, /*release_time=*/0, false, true});
+  return test_data_table;
+}
+
+class QuicGsoBatchWriterTest : public QuicTest {
+ protected:
+  WriteResult WritePacket(QuicGsoBatchWriter* writer, size_t packet_size) {
+    return writer->WritePacket(&packet_buffer_[0], packet_size, self_address_,
+                               peer_address_, nullptr);
+  }
+
+  WriteResult WritePacketWithOptions(QuicGsoBatchWriter* writer,
+                                     PerPacketOptions* options) {
+    return writer->WritePacket(&packet_buffer_[0], 1350, self_address_,
+                               peer_address_, options);
+  }
+
+  QuicIpAddress self_address_ = QuicIpAddress::Any4();
+  QuicSocketAddress peer_address_{QuicIpAddress::Any4(), 443};
+  char packet_buffer_[1500];
+  StrictMock<MockQuicSyscallWrapper> mock_syscalls_;
+  ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
+};
+
+TEST_F(QuicGsoBatchWriterTest, BatchCriteria) {
+  std::unique_ptr<TestQuicGsoBatchWriter> writer;
+
+  std::vector<std::vector<BatchCriteriaTestData>> test_data_tables;
+  test_data_tables.emplace_back(BatchCriteriaTestData_SizeDecrease());
+  test_data_tables.emplace_back(BatchCriteriaTestData_SizeIncrease());
+  test_data_tables.emplace_back(BatchCriteriaTestData_AddressChange());
+  test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime1());
+  test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime2());
+  test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1));
+  test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(2));
+  test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1350));
+
+  for (size_t i = 0; i < test_data_tables.size(); ++i) {
+    writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
+
+    const auto& test_data_table = test_data_tables[i];
+    for (size_t j = 0; j < test_data_table.size(); ++j) {
+      const BatchCriteriaTestData& test_data = test_data_table[j];
+      SCOPED_TRACE(testing::Message() << "i=" << i << ", j=" << j);
+      TestPerPacketOptions options;
+      options.release_time_delay = QuicTime::Delta::FromMicroseconds(
+          test_data.buffered_write.release_time);
+      TestQuicGsoBatchWriter::CanBatchResult result = writer->CanBatch(
+          test_data.buffered_write.buffer, test_data.buffered_write.buf_len,
+          test_data.buffered_write.self_address,
+          test_data.buffered_write.peer_address, &options,
+          test_data.buffered_write.release_time);
+
+      ASSERT_EQ(test_data.can_batch, result.can_batch);
+      ASSERT_EQ(test_data.must_flush, result.must_flush);
+
+      if (result.can_batch) {
+        ASSERT_TRUE(writer->batch_buffer()
+                        .PushBufferedWrite(
+                            test_data.buffered_write.buffer,
+                            test_data.buffered_write.buf_len,
+                            test_data.buffered_write.self_address,
+                            test_data.buffered_write.peer_address, &options,
+                            test_data.buffered_write.release_time)
+                        .succeeded);
+      }
+    }
+  }
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteSuccess) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 1000));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(1100u, PacketLength(msg));
+        return 1100;
+      }));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 1100), WritePacket(&writer, 100));
+  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteBlockDataNotBuffered) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(200u, PacketLength(msg));
+        errno = EWOULDBLOCK;
+        return -1;
+      }));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
+            WritePacket(&writer, 150));
+  ASSERT_EQ(200u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(2u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteBlockDataBuffered) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(250u, PacketLength(msg));
+        errno = EWOULDBLOCK;
+        return -1;
+      }));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED_DATA_BUFFERED, EWOULDBLOCK),
+            WritePacket(&writer, 50));
+
+  EXPECT_TRUE(writer.IsWriteBlocked());
+
+  ASSERT_EQ(250u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(3u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteErrorWithoutDataBuffered) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(200u, PacketLength(msg));
+        errno = EPERM;
+        return -1;
+      }));
+  WriteResult error_result = WritePacket(&writer, 150);
+  ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
+
+  ASSERT_EQ(3u, error_result.dropped_packets);
+  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteErrorAfterDataBuffered) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(250u, PacketLength(msg));
+        errno = EPERM;
+        return -1;
+      }));
+  WriteResult error_result = WritePacket(&writer, 50);
+  ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
+
+  ASSERT_EQ(3u, error_result.dropped_packets);
+  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, FlushError) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(200u, PacketLength(msg));
+        errno = EINVAL;
+        return -1;
+      }));
+  WriteResult error_result = writer.Flush();
+  ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL), error_result);
+
+  ASSERT_EQ(2u, error_result.dropped_packets);
+  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, ReleaseTimeNullOptions) {
+  auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
+  EXPECT_EQ(0u, writer->GetReleaseTime(nullptr).actual_release_time);
+}
+
+TEST_F(QuicGsoBatchWriterTest, ReleaseTime) {
+  const WriteResult write_buffered(WRITE_STATUS_OK, 0);
+
+  auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
+
+  TestPerPacketOptions options;
+  EXPECT_TRUE(options.release_time_delay.IsZero());
+  EXPECT_FALSE(options.allow_burst);
+  EXPECT_EQ(MillisToNanos(1),
+            writer->GetReleaseTime(&options).actual_release_time);
+
+  // The 1st packet has no delay.
+  WriteResult result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(write_buffered, result);
+  EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
+
+  // The 2nd packet has some delay, but allows burst.
+  options.release_time_delay = QuicTime::Delta::FromMilliseconds(3);
+  options.allow_burst = true;
+  result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(write_buffered, result);
+  EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::FromMilliseconds(-3));
+
+  // The 3rd packet has more delay and does not allow burst.
+  // The first 2 packets are flushed due to different release time.
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(2700u, PacketLength(msg));
+        errno = 0;
+        return 0;
+      }));
+  options.release_time_delay = QuicTime::Delta::FromMilliseconds(5);
+  options.allow_burst = false;
+  result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 2700), result);
+  EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
+
+  // The 4th packet has same delay, but allows burst.
+  options.allow_burst = true;
+  result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(write_buffered, result);
+  EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
+
+  // The 5th packet has same delay, allows burst, but is shorter.
+  // Packets 3,4 and 5 are flushed.
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(3000u, PacketLength(msg));
+        errno = 0;
+        return 0;
+      }));
+  options.allow_burst = true;
+  EXPECT_EQ(MillisToNanos(6),
+            writer->GetReleaseTime(&options).actual_release_time);
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 3000),
+            writer->WritePacket(&packet_buffer_[0], 300, self_address_,
+                                peer_address_, &options));
+  EXPECT_TRUE(writer->buffered_writes().empty());
+
+  // Pretend 1ms has elapsed and the 6th packet has 1ms less delay. In other
+  // words, the release time should still be the same as packets 3-5.
+  writer->ForceReleaseTimeMs(2);
+  options.release_time_delay = QuicTime::Delta::FromMilliseconds(4);
+  result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(write_buffered, result);
+  EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
new file mode 100644
index 0000000..e03aed0
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2019 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 "quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
+
+namespace quic {
+
+QuicSendmmsgBatchWriter::QuicSendmmsgBatchWriter(
+    std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+    int fd)
+    : QuicUdpBatchWriter(std::move(batch_buffer), fd) {}
+
+QuicSendmmsgBatchWriter::CanBatchResult QuicSendmmsgBatchWriter::CanBatch(
+    const char* /*buffer*/,
+    size_t /*buf_len*/,
+    const QuicIpAddress& /*self_address*/,
+    const QuicSocketAddress& /*peer_address*/,
+    const PerPacketOptions* /*options*/,
+    uint64_t /*release_time*/) const {
+  return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
+}
+
+QuicSendmmsgBatchWriter::FlushImplResult QuicSendmmsgBatchWriter::FlushImpl() {
+  return InternalFlushImpl(
+      kCmsgSpaceForIp,
+      [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+        mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+      });
+}
+
+QuicSendmmsgBatchWriter::FlushImplResult
+QuicSendmmsgBatchWriter::InternalFlushImpl(size_t cmsg_space,
+                                           const CmsgBuilder& cmsg_builder) {
+  QUICHE_DCHECK(!IsWriteBlocked());
+  QUICHE_DCHECK(!buffered_writes().empty());
+
+  FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
+                            /*num_packets_sent=*/0, /*bytes_written=*/0};
+  WriteResult& write_result = result.write_result;
+
+  auto first = buffered_writes().cbegin();
+  const auto last = buffered_writes().cend();
+  while (first != last) {
+    QuicMMsgHdr mhdr(first, last, cmsg_space, cmsg_builder);
+
+    int num_packets_sent;
+    write_result = QuicLinuxSocketUtils::WriteMultiplePackets(
+        fd(), &mhdr, &num_packets_sent);
+    QUIC_DVLOG(1) << "WriteMultiplePackets sent " << num_packets_sent
+                  << " out of " << mhdr.num_msgs()
+                  << " packets. WriteResult=" << write_result;
+
+    if (write_result.status != WRITE_STATUS_OK) {
+      QUICHE_DCHECK_EQ(0, num_packets_sent);
+      break;
+    } else if (num_packets_sent == 0) {
+      QUIC_BUG(quic_bug_10825_1)
+          << "WriteMultiplePackets returned OK, but no packets were sent.";
+      write_result = WriteResult(WRITE_STATUS_ERROR, EIO);
+      break;
+    }
+
+    first += num_packets_sent;
+
+    result.num_packets_sent += num_packets_sent;
+    result.bytes_written += write_result.bytes_written;
+  }
+
+  // Call PopBufferedWrite() even if write_result.status is not WRITE_STATUS_OK,
+  // to deal with partial writes.
+  batch_buffer().PopBufferedWrite(result.num_packets_sent);
+
+  if (write_result.status != WRITE_STATUS_OK) {
+    return result;
+  }
+
+  QUIC_BUG_IF(quic_bug_12537_1, !buffered_writes().empty())
+      << "All packets should have been written on a successful return";
+  write_result.bytes_written = result.bytes_written;
+  return result;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
new file mode 100644
index 0000000..afbec10
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2019 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_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
+
+#include "quiche/quic/core/batch_writer/quic_batch_writer_base.h"
+#include "quiche/quic/core/quic_linux_socket_utils.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicSendmmsgBatchWriter : public QuicUdpBatchWriter {
+ public:
+  QuicSendmmsgBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+                          int fd);
+
+  CanBatchResult CanBatch(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          const PerPacketOptions* options,
+                          uint64_t release_time) const override;
+
+  FlushImplResult FlushImpl() override;
+
+ protected:
+  using CmsgBuilder = QuicMMsgHdr::ControlBufferInitializer;
+  FlushImplResult InternalFlushImpl(size_t cmsg_space,
+                                    const CmsgBuilder& cmsg_builder);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
diff --git a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
new file mode 100644
index 0000000..c8a213a
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2019 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 "quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Add tests here.
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/chlo_extractor.cc b/quiche/quic/core/chlo_extractor.cc
new file mode 100644
index 0000000..7cd6ec9
--- /dev/null
+++ b/quiche/quic/core/chlo_extractor.cc
@@ -0,0 +1,364 @@
+// Copyright (c) 2016 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 "quiche/quic/core/chlo_extractor.h"
+
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+
+namespace {
+
+class ChloFramerVisitor : public QuicFramerVisitorInterface,
+                          public CryptoFramerVisitorInterface {
+ public:
+  ChloFramerVisitor(QuicFramer* framer,
+                    const QuicTagVector& create_session_tag_indicators,
+                    ChloExtractor::Delegate* delegate);
+
+  ~ChloFramerVisitor() override = default;
+
+  // QuicFramerVisitorInterface implementation
+  void OnError(QuicFramer* /*framer*/) override {}
+  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
+  void OnPacket() override {}
+  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& /*packet*/) override {}
+  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
+                     QuicConnectionId /*new_connection_id*/,
+                     absl::string_view /*retry_token*/,
+                     absl::string_view /*retry_integrity_tag*/,
+                     absl::string_view /*retry_without_tag*/) override {}
+  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
+  void OnDecryptedPacket(size_t /*length*/,
+                         EncryptionLevel /*level*/) override {}
+  bool OnPacketHeader(const QuicPacketHeader& header) override;
+  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
+  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                             EncryptionLevel decryption_level,
+                             bool has_decryption_key) override;
+  bool OnStreamFrame(const QuicStreamFrame& frame) override;
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time) override;
+  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
+  bool OnAckTimestamp(QuicPacketNumber packet_number,
+                      QuicTime timestamp) override;
+  bool OnAckFrameEnd(QuicPacketNumber start) override;
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
+  bool OnPingFrame(const QuicPingFrame& frame) override;
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
+  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) override;
+  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
+  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
+  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
+  bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
+  bool OnMessageFrame(const QuicMessageFrame& frame) override;
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& farme) override;
+  void OnPacketComplete() override {}
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const override;
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& /*packet*/) override {}
+  void OnKeyUpdate(KeyUpdateReason /*reason*/) override;
+  void OnDecryptedFirstPacketInKeyPhase() override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+
+  // CryptoFramerVisitorInterface implementation.
+  void OnError(CryptoFramer* framer) override;
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+
+  // Shared implementation between OnStreamFrame and OnCryptoFrame.
+  bool OnHandshakeData(absl::string_view data);
+
+  bool found_chlo() { return found_chlo_; }
+  bool chlo_contains_tags() { return chlo_contains_tags_; }
+
+ private:
+  QuicFramer* framer_;
+  const QuicTagVector& create_session_tag_indicators_;
+  ChloExtractor::Delegate* delegate_;
+  bool found_chlo_;
+  bool chlo_contains_tags_;
+  QuicConnectionId connection_id_;
+};
+
+ChloFramerVisitor::ChloFramerVisitor(
+    QuicFramer* framer,
+    const QuicTagVector& create_session_tag_indicators,
+    ChloExtractor::Delegate* delegate)
+    : framer_(framer),
+      create_session_tag_indicators_(create_session_tag_indicators),
+      delegate_(delegate),
+      found_chlo_(false),
+      chlo_contains_tags_(false),
+      connection_id_(EmptyQuicConnectionId()) {}
+
+bool ChloFramerVisitor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
+  if (!framer_->IsSupportedVersion(version)) {
+    return false;
+  }
+  framer_->set_version(version);
+  return true;
+}
+
+bool ChloFramerVisitor::OnUnauthenticatedPublicHeader(
+    const QuicPacketHeader& header) {
+  connection_id_ = header.destination_connection_id;
+  // QuicFramer creates a NullEncrypter and NullDecrypter at level
+  // ENCRYPTION_INITIAL. While those are the correct ones to use with some
+  // versions of QUIC, others use the IETF-style initial crypters, so those need
+  // to be created and installed.
+  framer_->SetInitialObfuscators(header.destination_connection_id);
+  return true;
+}
+bool ChloFramerVisitor::OnUnauthenticatedHeader(
+    const QuicPacketHeader& /*header*/) {
+  return true;
+}
+bool ChloFramerVisitor::OnPacketHeader(const QuicPacketHeader& /*header*/) {
+  return true;
+}
+
+void ChloFramerVisitor::OnCoalescedPacket(
+    const QuicEncryptedPacket& /*packet*/) {}
+
+void ChloFramerVisitor::OnUndecryptablePacket(
+    const QuicEncryptedPacket& /*packet*/,
+    EncryptionLevel /*decryption_level*/,
+    bool /*has_decryption_key*/) {}
+
+bool ChloFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
+  if (QuicVersionUsesCryptoFrames(framer_->transport_version())) {
+    // CHLO will be sent in CRYPTO frames in v47 and above.
+    return false;
+  }
+  absl::string_view data(frame.data_buffer, frame.data_length);
+  if (QuicUtils::IsCryptoStreamId(framer_->transport_version(),
+                                  frame.stream_id) &&
+      frame.offset == 0 && absl::StartsWith(data, "CHLO")) {
+    return OnHandshakeData(data);
+  }
+  return true;
+}
+
+bool ChloFramerVisitor::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  if (!QuicVersionUsesCryptoFrames(framer_->transport_version())) {
+    // CHLO will be in stream frames before v47.
+    return false;
+  }
+  absl::string_view data(frame.data_buffer, frame.data_length);
+  if (frame.offset == 0 && absl::StartsWith(data, "CHLO")) {
+    return OnHandshakeData(data);
+  }
+  return true;
+}
+
+bool ChloFramerVisitor::OnHandshakeData(absl::string_view data) {
+  CryptoFramer crypto_framer;
+  crypto_framer.set_visitor(this);
+  if (!crypto_framer.ProcessInput(data)) {
+    return false;
+  }
+  // Interrogate the crypto framer and see if there are any
+  // intersecting tags between what we saw in the maybe-CHLO and the
+  // indicator set.
+  for (const QuicTag tag : create_session_tag_indicators_) {
+    if (crypto_framer.HasTag(tag)) {
+      chlo_contains_tags_ = true;
+    }
+  }
+  if (chlo_contains_tags_ && delegate_) {
+    // Unfortunately, because this is a partial CHLO,
+    // OnHandshakeMessage was never called, so the ALPN was never
+    // extracted. Fake it up a bit and send it to the delegate so that
+    // the correct dispatch can happen.
+    crypto_framer.ForceHandshake();
+  }
+
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
+                                        QuicTime::Delta /*ack_delay_time*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckRange(QuicPacketNumber /*start*/,
+                                   QuicPacketNumber /*end*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckTimestamp(QuicPacketNumber /*packet_number*/,
+                                       QuicTime /*timestamp*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckFrameEnd(QuicPacketNumber /*start*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnStopWaitingFrame(
+    const QuicStopWaitingFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnPingFrame(const QuicPingFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnConnectionCloseFrame(
+    const QuicConnectionCloseFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnStopSendingFrame(
+    const QuicStopSendingFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnPathChallengeFrame(
+    const QuicPathChallengeFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnPathResponseFrame(
+    const QuicPathResponseFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnWindowUpdateFrame(
+    const QuicWindowUpdateFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnNewConnectionIdFrame(
+    const QuicNewConnectionIdFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnRetireConnectionIdFrame(
+    const QuicRetireConnectionIdFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnMessageFrame(const QuicMessageFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnHandshakeDoneFrame(
+    const QuicHandshakeDoneFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckFrequencyFrame(
+    const QuicAckFrequencyFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::IsValidStatelessResetToken(
+    const StatelessResetToken& /*token*/) const {
+  return false;
+}
+
+bool ChloFramerVisitor::OnMaxStreamsFrame(
+    const QuicMaxStreamsFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& /*frame*/) {
+  return true;
+}
+
+void ChloFramerVisitor::OnKeyUpdate(KeyUpdateReason /*reason*/) {}
+
+void ChloFramerVisitor::OnDecryptedFirstPacketInKeyPhase() {}
+
+std::unique_ptr<QuicDecrypter>
+ChloFramerVisitor::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return nullptr;
+}
+
+std::unique_ptr<QuicEncrypter>
+ChloFramerVisitor::CreateCurrentOneRttEncrypter() {
+  return nullptr;
+}
+
+void ChloFramerVisitor::OnError(CryptoFramer* /*framer*/) {}
+
+void ChloFramerVisitor::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  if (delegate_ != nullptr) {
+    delegate_->OnChlo(framer_->transport_version(), connection_id_, message);
+  }
+  found_chlo_ = true;
+}
+
+}  // namespace
+
+// static
+bool ChloExtractor::Extract(const QuicEncryptedPacket& packet,
+                            ParsedQuicVersion version,
+                            const QuicTagVector& create_session_tag_indicators,
+                            Delegate* delegate,
+                            uint8_t connection_id_length) {
+  QUIC_DVLOG(1) << "Extracting CHLO using version " << version;
+  QuicFramer framer({version}, QuicTime::Zero(), Perspective::IS_SERVER,
+                    connection_id_length);
+  ChloFramerVisitor visitor(&framer, create_session_tag_indicators, delegate);
+  framer.set_visitor(&visitor);
+  if (!framer.ProcessPacket(packet)) {
+    return false;
+  }
+  return visitor.found_chlo() || visitor.chlo_contains_tags();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/chlo_extractor.h b/quiche/quic/core/chlo_extractor.h
new file mode 100644
index 0000000..c2604c8
--- /dev/null
+++ b/quiche/quic/core/chlo_extractor.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2016 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_CHLO_EXTRACTOR_H_
+#define QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
+
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+// A utility for extracting QUIC Client Hello messages from packets,
+// without needs to spin up a full QuicSession.
+class QUIC_NO_EXPORT ChloExtractor {
+ public:
+  class QUIC_NO_EXPORT Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // Called when a CHLO message is found in the packets.
+    virtual void OnChlo(QuicTransportVersion version,
+                        QuicConnectionId connection_id,
+                        const CryptoHandshakeMessage& chlo) = 0;
+  };
+
+  // Extracts a CHLO message from |packet| and invokes the OnChlo
+  // method of |delegate|. Return true if a CHLO message was found,
+  // and false otherwise. If non-empty,
+  // |create_session_tag_indicators| contains a list of QUIC tags that
+  // if found will result in the session being created early, to
+  // enable support for multi-packet CHLOs.
+  static bool Extract(const QuicEncryptedPacket& packet,
+                      ParsedQuicVersion version,
+                      const QuicTagVector& create_session_tag_indicators,
+                      Delegate* delegate,
+                      uint8_t connection_id_length);
+
+  ChloExtractor(const ChloExtractor&) = delete;
+  ChloExtractor operator=(const ChloExtractor&) = delete;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
diff --git a/quiche/quic/core/chlo_extractor_test.cc b/quiche/quic/core/chlo_extractor_test.cc
new file mode 100644
index 0000000..c8268f8
--- /dev/null
+++ b/quiche/quic/core/chlo_extractor_test.cc
@@ -0,0 +1,179 @@
+// Copyright (c) 2016 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 "quiche/quic/core/chlo_extractor.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/first_flight.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestDelegate : public ChloExtractor::Delegate {
+ public:
+  TestDelegate() = default;
+  ~TestDelegate() override = default;
+
+  // ChloExtractor::Delegate implementation
+  void OnChlo(QuicTransportVersion version,
+              QuicConnectionId connection_id,
+              const CryptoHandshakeMessage& chlo) override {
+    version_ = version;
+    connection_id_ = connection_id;
+    chlo_ = chlo.DebugString();
+    absl::string_view alpn_value;
+    if (chlo.GetStringPiece(kALPN, &alpn_value)) {
+      alpn_ = std::string(alpn_value);
+    }
+  }
+
+  QuicConnectionId connection_id() const { return connection_id_; }
+  QuicTransportVersion transport_version() const { return version_; }
+  const std::string& chlo() const { return chlo_; }
+  const std::string& alpn() const { return alpn_; }
+
+ private:
+  QuicConnectionId connection_id_;
+  QuicTransportVersion version_;
+  std::string chlo_;
+  std::string alpn_;
+};
+
+class ChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  ChloExtractorTest() : version_(GetParam()) {}
+
+  void MakePacket(absl::string_view data,
+                  bool munge_offset,
+                  bool munge_stream_id) {
+    QuicPacketHeader header;
+    header.destination_connection_id = TestConnectionId();
+    header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+    header.version_flag = true;
+    header.version = version_;
+    header.reset_flag = false;
+    header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
+    header.packet_number = QuicPacketNumber(1);
+    if (version_.HasLongHeaderLengths()) {
+      header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+      header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    }
+    QuicFrames frames;
+    size_t offset = 0;
+    if (munge_offset) {
+      offset++;
+    }
+    QuicFramer framer(SupportedVersions(version_), QuicTime::Zero(),
+                      Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+    framer.SetInitialObfuscators(TestConnectionId());
+    if (!version_.UsesCryptoFrames() || munge_stream_id) {
+      QuicStreamId stream_id =
+          QuicUtils::GetCryptoStreamId(version_.transport_version);
+      if (munge_stream_id) {
+        stream_id++;
+      }
+      frames.push_back(
+          QuicFrame(QuicStreamFrame(stream_id, false, offset, data)));
+    } else {
+      frames.push_back(
+          QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, offset, data)));
+    }
+    std::unique_ptr<QuicPacket> packet(
+        BuildUnsizedDataPacket(&framer, header, frames));
+    EXPECT_TRUE(packet != nullptr);
+    size_t encrypted_length =
+        framer.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *packet,
+                              buffer_, ABSL_ARRAYSIZE(buffer_));
+    ASSERT_NE(0u, encrypted_length);
+    packet_ = std::make_unique<QuicEncryptedPacket>(buffer_, encrypted_length);
+    EXPECT_TRUE(packet_ != nullptr);
+    DeleteFrames(&frames);
+  }
+
+ protected:
+  ParsedQuicVersion version_;
+  TestDelegate delegate_;
+  std::unique_ptr<QuicEncryptedPacket> packet_;
+  char buffer_[kMaxOutgoingPacketSize];
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    ChloExtractorTests,
+    ChloExtractorTest,
+    ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
+    ::testing::PrintToStringParamName());
+
+TEST_P(ChloExtractorTest, FindsValidChlo) {
+  CryptoHandshakeMessage client_hello;
+  client_hello.set_tag(kCHLO);
+
+  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
+
+  MakePacket(client_hello_str, /*munge_offset=*/false,
+             /*munge_stream_id=*/false);
+  EXPECT_TRUE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
+                                     kQuicDefaultConnectionIdLength));
+  EXPECT_EQ(version_.transport_version, delegate_.transport_version());
+  EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
+  EXPECT_EQ(client_hello.DebugString(), delegate_.chlo());
+}
+
+TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongStream) {
+  if (version_.UsesCryptoFrames()) {
+    // When crypto frames are in use we do not use stream frames.
+    return;
+  }
+  CryptoHandshakeMessage client_hello;
+  client_hello.set_tag(kCHLO);
+
+  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
+  MakePacket(client_hello_str,
+             /*munge_offset=*/false, /*munge_stream_id=*/true);
+  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
+                                      kQuicDefaultConnectionIdLength));
+}
+
+TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) {
+  CryptoHandshakeMessage client_hello;
+  client_hello.set_tag(kCHLO);
+
+  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
+  MakePacket(client_hello_str, /*munge_offset=*/true,
+             /*munge_stream_id=*/false);
+  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
+                                      kQuicDefaultConnectionIdLength));
+}
+
+TEST_P(ChloExtractorTest, DoesNotFindInvalidChlo) {
+  MakePacket("foo", /*munge_offset=*/false,
+             /*munge_stream_id=*/false);
+  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
+                                      kQuicDefaultConnectionIdLength));
+}
+
+TEST_P(ChloExtractorTest, FirstFlight) {
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+      GetFirstFlightOfPackets(version_);
+  ASSERT_EQ(packets.size(), 1u);
+  EXPECT_TRUE(ChloExtractor::Extract(*packets[0], version_, {}, &delegate_,
+                                     kQuicDefaultConnectionIdLength));
+  EXPECT_EQ(version_.transport_version, delegate_.transport_version());
+  EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
+  EXPECT_EQ(AlpnForVersion(version_), delegate_.alpn());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bandwidth_sampler.cc b/quiche/quic/core/congestion_control/bandwidth_sampler.cc
new file mode 100644
index 0000000..1a8a591
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bandwidth_sampler.cc
@@ -0,0 +1,589 @@
+// Copyright 2016 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 "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+
+#include <algorithm>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+std::ostream& operator<<(std::ostream& os, const SendTimeState& s) {
+  os << "{valid:" << s.is_valid << ", app_limited:" << s.is_app_limited
+     << ", total_sent:" << s.total_bytes_sent
+     << ", total_acked:" << s.total_bytes_acked
+     << ", total_lost:" << s.total_bytes_lost
+     << ", inflight:" << s.bytes_in_flight << "}";
+  return os;
+}
+
+QuicByteCount MaxAckHeightTracker::Update(
+    QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
+    QuicRoundTripCount round_trip_count,
+    QuicPacketNumber last_sent_packet_number,
+    QuicPacketNumber last_acked_packet_number, QuicTime ack_time,
+    QuicByteCount bytes_acked) {
+  bool force_new_epoch = false;
+
+  if (reduce_extra_acked_on_bandwidth_increase_ && is_new_max_bandwidth) {
+    // Save and clear existing entries.
+    ExtraAckedEvent best = max_ack_height_filter_.GetBest();
+    ExtraAckedEvent second_best = max_ack_height_filter_.GetSecondBest();
+    ExtraAckedEvent third_best = max_ack_height_filter_.GetThirdBest();
+    max_ack_height_filter_.Clear();
+
+    // Reinsert the heights into the filter after recalculating.
+    QuicByteCount expected_bytes_acked = bandwidth_estimate * best.time_delta;
+    if (expected_bytes_acked < best.bytes_acked) {
+      best.extra_acked = best.bytes_acked - expected_bytes_acked;
+      max_ack_height_filter_.Update(best, best.round);
+    }
+    expected_bytes_acked = bandwidth_estimate * second_best.time_delta;
+    if (expected_bytes_acked < second_best.bytes_acked) {
+      QUICHE_DCHECK_LE(best.round, second_best.round);
+      second_best.extra_acked = second_best.bytes_acked - expected_bytes_acked;
+      max_ack_height_filter_.Update(second_best, second_best.round);
+    }
+    expected_bytes_acked = bandwidth_estimate * third_best.time_delta;
+    if (expected_bytes_acked < third_best.bytes_acked) {
+      QUICHE_DCHECK_LE(second_best.round, third_best.round);
+      third_best.extra_acked = third_best.bytes_acked - expected_bytes_acked;
+      max_ack_height_filter_.Update(third_best, third_best.round);
+    }
+  }
+
+  // If any packet sent after the start of the epoch has been acked, start a new
+  // epoch.
+  if (start_new_aggregation_epoch_after_full_round_ &&
+      last_sent_packet_number_before_epoch_.IsInitialized() &&
+      last_acked_packet_number.IsInitialized() &&
+      last_acked_packet_number > last_sent_packet_number_before_epoch_) {
+    QUIC_DVLOG(3) << "Force starting a new aggregation epoch. "
+                     "last_sent_packet_number_before_epoch_:"
+                  << last_sent_packet_number_before_epoch_
+                  << ", last_acked_packet_number:" << last_acked_packet_number;
+    if (reduce_extra_acked_on_bandwidth_increase_) {
+      QUIC_BUG(quic_bwsampler_46)
+          << "A full round of aggregation should never "
+          << "pass with startup_include_extra_acked(B204) enabled.";
+    }
+    force_new_epoch = true;
+  }
+  if (aggregation_epoch_start_time_ == QuicTime::Zero() || force_new_epoch) {
+    aggregation_epoch_bytes_ = bytes_acked;
+    aggregation_epoch_start_time_ = ack_time;
+    last_sent_packet_number_before_epoch_ = last_sent_packet_number;
+    ++num_ack_aggregation_epochs_;
+    return 0;
+  }
+
+  // Compute how many bytes are expected to be delivered, assuming max bandwidth
+  // is correct.
+  QuicTime::Delta aggregation_delta = ack_time - aggregation_epoch_start_time_;
+  QuicByteCount expected_bytes_acked = bandwidth_estimate * aggregation_delta;
+  // Reset the current aggregation epoch as soon as the ack arrival rate is less
+  // than or equal to the max bandwidth.
+  if (aggregation_epoch_bytes_ <=
+      ack_aggregation_bandwidth_threshold_ * expected_bytes_acked) {
+    QUIC_DVLOG(3) << "Starting a new aggregation epoch because "
+                     "aggregation_epoch_bytes_ "
+                  << aggregation_epoch_bytes_
+                  << " is smaller than expected. "
+                     "ack_aggregation_bandwidth_threshold_:"
+                  << ack_aggregation_bandwidth_threshold_
+                  << ", expected_bytes_acked:" << expected_bytes_acked
+                  << ", bandwidth_estimate:" << bandwidth_estimate
+                  << ", aggregation_duration:" << aggregation_delta
+                  << ", new_aggregation_epoch:" << ack_time
+                  << ", new_aggregation_bytes_acked:" << bytes_acked;
+    // Reset to start measuring a new aggregation epoch.
+    aggregation_epoch_bytes_ = bytes_acked;
+    aggregation_epoch_start_time_ = ack_time;
+    last_sent_packet_number_before_epoch_ = last_sent_packet_number;
+    ++num_ack_aggregation_epochs_;
+    return 0;
+  }
+
+  aggregation_epoch_bytes_ += bytes_acked;
+
+  // Compute how many extra bytes were delivered vs max bandwidth.
+  QuicByteCount extra_bytes_acked =
+      aggregation_epoch_bytes_ - expected_bytes_acked;
+  QUIC_DVLOG(3) << "Updating MaxAckHeight. ack_time:" << ack_time
+                << ", last sent packet:" << last_sent_packet_number
+                << ", bandwidth_estimate:" << bandwidth_estimate
+                << ", bytes_acked:" << bytes_acked
+                << ", expected_bytes_acked:" << expected_bytes_acked
+                << ", aggregation_epoch_bytes_:" << aggregation_epoch_bytes_
+                << ", extra_bytes_acked:" << extra_bytes_acked;
+  ExtraAckedEvent new_event;
+  new_event.extra_acked = extra_bytes_acked;
+  new_event.bytes_acked = aggregation_epoch_bytes_;
+  new_event.time_delta = aggregation_delta;
+  max_ack_height_filter_.Update(new_event, round_trip_count);
+  return extra_bytes_acked;
+}
+
+BandwidthSampler::BandwidthSampler(
+    const QuicUnackedPacketMap* unacked_packet_map,
+    QuicRoundTripCount max_height_tracker_window_length)
+    : total_bytes_sent_(0),
+      total_bytes_acked_(0),
+      total_bytes_lost_(0),
+      total_bytes_neutered_(0),
+      total_bytes_sent_at_last_acked_packet_(0),
+      last_acked_packet_sent_time_(QuicTime::Zero()),
+      last_acked_packet_ack_time_(QuicTime::Zero()),
+      is_app_limited_(true),
+      connection_state_map_(),
+      max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
+      unacked_packet_map_(unacked_packet_map),
+      max_ack_height_tracker_(max_height_tracker_window_length),
+      total_bytes_acked_after_last_ack_event_(0),
+      overestimate_avoidance_(false),
+      limit_max_ack_height_tracker_by_send_rate_(false) {}
+
+BandwidthSampler::BandwidthSampler(const BandwidthSampler& other)
+    : total_bytes_sent_(other.total_bytes_sent_),
+      total_bytes_acked_(other.total_bytes_acked_),
+      total_bytes_lost_(other.total_bytes_lost_),
+      total_bytes_neutered_(other.total_bytes_neutered_),
+      total_bytes_sent_at_last_acked_packet_(
+          other.total_bytes_sent_at_last_acked_packet_),
+      last_acked_packet_sent_time_(other.last_acked_packet_sent_time_),
+      last_acked_packet_ack_time_(other.last_acked_packet_ack_time_),
+      last_sent_packet_(other.last_sent_packet_),
+      last_acked_packet_(other.last_acked_packet_),
+      is_app_limited_(other.is_app_limited_),
+      end_of_app_limited_phase_(other.end_of_app_limited_phase_),
+      connection_state_map_(other.connection_state_map_),
+      recent_ack_points_(other.recent_ack_points_),
+      a0_candidates_(other.a0_candidates_),
+      max_tracked_packets_(other.max_tracked_packets_),
+      unacked_packet_map_(other.unacked_packet_map_),
+      max_ack_height_tracker_(other.max_ack_height_tracker_),
+      total_bytes_acked_after_last_ack_event_(
+          other.total_bytes_acked_after_last_ack_event_),
+      overestimate_avoidance_(other.overestimate_avoidance_),
+      limit_max_ack_height_tracker_by_send_rate_(
+          other.limit_max_ack_height_tracker_by_send_rate_) {}
+
+void BandwidthSampler::EnableOverestimateAvoidance() {
+  if (overestimate_avoidance_) {
+    return;
+  }
+
+  overestimate_avoidance_ = true;
+  // TODO(wub): Change the default value of
+  // --quic_ack_aggregation_bandwidth_threshold to 2.0.
+  max_ack_height_tracker_.SetAckAggregationBandwidthThreshold(2.0);
+}
+
+BandwidthSampler::~BandwidthSampler() {}
+
+void BandwidthSampler::OnPacketSent(
+    QuicTime sent_time,
+    QuicPacketNumber packet_number,
+    QuicByteCount bytes,
+    QuicByteCount bytes_in_flight,
+    HasRetransmittableData has_retransmittable_data) {
+  last_sent_packet_ = packet_number;
+
+  if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
+    return;
+  }
+
+  total_bytes_sent_ += bytes;
+
+  // If there are no packets in flight, the time at which the new transmission
+  // opens can be treated as the A_0 point for the purpose of bandwidth
+  // sampling. This underestimates bandwidth to some extent, and produces some
+  // artificially low samples for most packets in flight, but it provides with
+  // samples at important points where we would not have them otherwise, most
+  // importantly at the beginning of the connection.
+  if (bytes_in_flight == 0) {
+    last_acked_packet_ack_time_ = sent_time;
+    if (overestimate_avoidance_) {
+      recent_ack_points_.Clear();
+      recent_ack_points_.Update(sent_time, total_bytes_acked_);
+      a0_candidates_.clear();
+      a0_candidates_.push_back(recent_ack_points_.MostRecentPoint());
+    }
+    total_bytes_sent_at_last_acked_packet_ = total_bytes_sent_;
+
+    // In this situation ack compression is not a concern, set send rate to
+    // effectively infinite.
+    last_acked_packet_sent_time_ = sent_time;
+  }
+
+  if (!connection_state_map_.IsEmpty() &&
+      packet_number >
+          connection_state_map_.last_packet() + max_tracked_packets_) {
+    if (unacked_packet_map_ != nullptr && !unacked_packet_map_->empty()) {
+      QuicPacketNumber maybe_least_unacked =
+          unacked_packet_map_->GetLeastUnacked();
+      QUIC_BUG(quic_bug_10437_1)
+          << "BandwidthSampler in-flight packet map has exceeded maximum "
+             "number of tracked packets("
+          << max_tracked_packets_
+          << ").  First tracked: " << connection_state_map_.first_packet()
+          << "; last tracked: " << connection_state_map_.last_packet()
+          << "; entry_slots_used: " << connection_state_map_.entry_slots_used()
+          << "; number_of_present_entries: "
+          << connection_state_map_.number_of_present_entries()
+          << "; packet number: " << packet_number
+          << "; unacked_map: " << unacked_packet_map_->DebugString()
+          << "; total_bytes_sent: " << total_bytes_sent_
+          << "; total_bytes_acked: " << total_bytes_acked_
+          << "; total_bytes_lost: " << total_bytes_lost_
+          << "; total_bytes_neutered: " << total_bytes_neutered_
+          << "; last_acked_packet_sent_time: " << last_acked_packet_sent_time_
+          << "; total_bytes_sent_at_last_acked_packet: "
+          << total_bytes_sent_at_last_acked_packet_
+          << "; least_unacked_packet_info: "
+          << (unacked_packet_map_->IsUnacked(maybe_least_unacked)
+                  ? unacked_packet_map_
+                        ->GetTransmissionInfo(maybe_least_unacked)
+                        .DebugString()
+                  : "n/a");
+    } else {
+      QUIC_BUG(quic_bug_10437_2)
+          << "BandwidthSampler in-flight packet map has exceeded maximum "
+             "number of tracked packets.";
+    }
+  }
+
+  bool success = connection_state_map_.Emplace(packet_number, sent_time, bytes,
+                                               bytes_in_flight + bytes, *this);
+  QUIC_BUG_IF(quic_bug_10437_3, !success)
+      << "BandwidthSampler failed to insert the packet "
+         "into the map, most likely because it's already "
+         "in it.";
+}
+
+void BandwidthSampler::OnPacketNeutered(QuicPacketNumber packet_number) {
+  connection_state_map_.Remove(
+      packet_number, [&](const ConnectionStateOnSentPacket& sent_packet) {
+        QUIC_CODE_COUNT(quic_bandwidth_sampler_packet_neutered);
+        total_bytes_neutered_ += sent_packet.size;
+      });
+}
+
+BandwidthSamplerInterface::CongestionEventSample
+BandwidthSampler::OnCongestionEvent(QuicTime ack_time,
+                                    const AckedPacketVector& acked_packets,
+                                    const LostPacketVector& lost_packets,
+                                    QuicBandwidth max_bandwidth,
+                                    QuicBandwidth est_bandwidth_upper_bound,
+                                    QuicRoundTripCount round_trip_count) {
+  CongestionEventSample event_sample;
+
+  SendTimeState last_lost_packet_send_state;
+
+  for (const LostPacket& packet : lost_packets) {
+    SendTimeState send_state =
+        OnPacketLost(packet.packet_number, packet.bytes_lost);
+    if (send_state.is_valid) {
+      last_lost_packet_send_state = send_state;
+    }
+  }
+
+  if (acked_packets.empty()) {
+    // Only populate send state for a loss-only event.
+    event_sample.last_packet_send_state = last_lost_packet_send_state;
+    return event_sample;
+  }
+
+  SendTimeState last_acked_packet_send_state;
+  QuicBandwidth max_send_rate = QuicBandwidth::Zero();
+  for (const auto& packet : acked_packets) {
+    BandwidthSample sample =
+        OnPacketAcknowledged(ack_time, packet.packet_number);
+    if (!sample.state_at_send.is_valid) {
+      continue;
+    }
+
+    last_acked_packet_send_state = sample.state_at_send;
+
+    if (!sample.rtt.IsZero()) {
+      event_sample.sample_rtt = std::min(event_sample.sample_rtt, sample.rtt);
+    }
+    if (sample.bandwidth > event_sample.sample_max_bandwidth) {
+      event_sample.sample_max_bandwidth = sample.bandwidth;
+      event_sample.sample_is_app_limited = sample.state_at_send.is_app_limited;
+    }
+    if (!sample.send_rate.IsInfinite()) {
+      max_send_rate = std::max(max_send_rate, sample.send_rate);
+    }
+    const QuicByteCount inflight_sample =
+        total_bytes_acked() - last_acked_packet_send_state.total_bytes_acked;
+    if (inflight_sample > event_sample.sample_max_inflight) {
+      event_sample.sample_max_inflight = inflight_sample;
+    }
+  }
+
+  if (!last_lost_packet_send_state.is_valid) {
+    event_sample.last_packet_send_state = last_acked_packet_send_state;
+  } else if (!last_acked_packet_send_state.is_valid) {
+    event_sample.last_packet_send_state = last_lost_packet_send_state;
+  } else {
+    // If two packets are inflight and an alarm is armed to lose a packet and it
+    // wakes up late, then the first of two in flight packets could have been
+    // acknowledged before the wakeup, which re-evaluates loss detection, and
+    // could declare the later of the two lost.
+    event_sample.last_packet_send_state =
+        lost_packets.back().packet_number > acked_packets.back().packet_number
+            ? last_lost_packet_send_state
+            : last_acked_packet_send_state;
+  }
+
+  bool is_new_max_bandwidth = event_sample.sample_max_bandwidth > max_bandwidth;
+  max_bandwidth = std::max(max_bandwidth, event_sample.sample_max_bandwidth);
+  if (limit_max_ack_height_tracker_by_send_rate_) {
+    max_bandwidth = std::max(max_bandwidth, max_send_rate);
+  }
+  // TODO(ianswett): Why is the min being passed in here?
+  event_sample.extra_acked =
+      OnAckEventEnd(std::min(est_bandwidth_upper_bound, max_bandwidth),
+                    is_new_max_bandwidth, round_trip_count);
+
+  return event_sample;
+}
+
+QuicByteCount BandwidthSampler::OnAckEventEnd(
+    QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
+    QuicRoundTripCount round_trip_count) {
+  const QuicByteCount newly_acked_bytes =
+      total_bytes_acked_ - total_bytes_acked_after_last_ack_event_;
+
+  if (newly_acked_bytes == 0) {
+    return 0;
+  }
+  total_bytes_acked_after_last_ack_event_ = total_bytes_acked_;
+  QuicByteCount extra_acked = max_ack_height_tracker_.Update(
+      bandwidth_estimate, is_new_max_bandwidth, round_trip_count,
+      last_sent_packet_, last_acked_packet_, last_acked_packet_ack_time_,
+      newly_acked_bytes);
+  // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack
+  // aggregation epoch, save LessRecentPoint, which is the last ack point of the
+  // previous epoch, as a A0 candidate.
+  if (overestimate_avoidance_ && extra_acked == 0) {
+    a0_candidates_.push_back(recent_ack_points_.LessRecentPoint());
+    QUIC_DVLOG(1) << "New a0_candidate:" << a0_candidates_.back();
+  }
+  return extra_acked;
+}
+
+BandwidthSample BandwidthSampler::OnPacketAcknowledged(
+    QuicTime ack_time,
+    QuicPacketNumber packet_number) {
+  last_acked_packet_ = packet_number;
+  ConnectionStateOnSentPacket* sent_packet_pointer =
+      connection_state_map_.GetEntry(packet_number);
+  if (sent_packet_pointer == nullptr) {
+    // See the TODO below.
+    return BandwidthSample();
+  }
+  BandwidthSample sample =
+      OnPacketAcknowledgedInner(ack_time, packet_number, *sent_packet_pointer);
+  return sample;
+}
+
+BandwidthSample BandwidthSampler::OnPacketAcknowledgedInner(
+    QuicTime ack_time,
+    QuicPacketNumber packet_number,
+    const ConnectionStateOnSentPacket& sent_packet) {
+  total_bytes_acked_ += sent_packet.size;
+  total_bytes_sent_at_last_acked_packet_ =
+      sent_packet.send_time_state.total_bytes_sent;
+  last_acked_packet_sent_time_ = sent_packet.sent_time;
+  last_acked_packet_ack_time_ = ack_time;
+  if (overestimate_avoidance_) {
+    recent_ack_points_.Update(ack_time, total_bytes_acked_);
+  }
+
+  if (is_app_limited_) {
+    // Exit app-limited phase in two cases:
+    // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all
+    // packets are sent while there are buffered packets or pending data.
+    // (2) The current acked packet is after the sent packet marked as the end
+    // of the app limit phase.
+    if (!end_of_app_limited_phase_.IsInitialized() ||
+        packet_number > end_of_app_limited_phase_) {
+      is_app_limited_ = false;
+    }
+  }
+
+  // There might have been no packets acknowledged at the moment when the
+  // current packet was sent. In that case, there is no bandwidth sample to
+  // make.
+  if (sent_packet.last_acked_packet_sent_time == QuicTime::Zero()) {
+    QUIC_BUG(quic_bug_10437_4)
+        << "sent_packet.last_acked_packet_sent_time is zero";
+    return BandwidthSample();
+  }
+
+  // Infinite rate indicates that the sampler is supposed to discard the
+  // current send rate sample and use only the ack rate.
+  QuicBandwidth send_rate = QuicBandwidth::Infinite();
+  if (sent_packet.sent_time > sent_packet.last_acked_packet_sent_time) {
+    send_rate = QuicBandwidth::FromBytesAndTimeDelta(
+        sent_packet.send_time_state.total_bytes_sent -
+            sent_packet.total_bytes_sent_at_last_acked_packet,
+        sent_packet.sent_time - sent_packet.last_acked_packet_sent_time);
+  }
+
+  AckPoint a0;
+  if (overestimate_avoidance_ &&
+      ChooseA0Point(sent_packet.send_time_state.total_bytes_acked, &a0)) {
+    QUIC_DVLOG(2) << "Using a0 point: " << a0;
+  } else {
+    a0.ack_time = sent_packet.last_acked_packet_ack_time,
+    a0.total_bytes_acked = sent_packet.send_time_state.total_bytes_acked;
+  }
+
+  // During the slope calculation, ensure that ack time of the current packet is
+  // always larger than the time of the previous packet, otherwise division by
+  // zero or integer underflow can occur.
+  if (ack_time <= a0.ack_time) {
+    // TODO(wub): Compare this code count before and after fixing clock jitter
+    // issue.
+    if (a0.ack_time == sent_packet.sent_time) {
+      // This is the 1st packet after quiescense.
+      QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 1, 2);
+    } else {
+      QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 2, 2);
+    }
+    QUIC_LOG_EVERY_N_SEC(ERROR, 60)
+        << "Time of the previously acked packet:"
+        << a0.ack_time.ToDebuggingValue()
+        << " is larger than the ack time of the current packet:"
+        << ack_time.ToDebuggingValue()
+        << ". acked packet number:" << packet_number
+        << ", total_bytes_acked_:" << total_bytes_acked_
+        << ", overestimate_avoidance_:" << overestimate_avoidance_
+        << ", sent_packet:" << sent_packet;
+    return BandwidthSample();
+  }
+  QuicBandwidth ack_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      total_bytes_acked_ - a0.total_bytes_acked, ack_time - a0.ack_time);
+
+  BandwidthSample sample;
+  sample.bandwidth = std::min(send_rate, ack_rate);
+  // Note: this sample does not account for delayed acknowledgement time.  This
+  // means that the RTT measurements here can be artificially high, especially
+  // on low bandwidth connections.
+  sample.rtt = ack_time - sent_packet.sent_time;
+  sample.send_rate = send_rate;
+  SentPacketToSendTimeState(sent_packet, &sample.state_at_send);
+
+  if (sample.bandwidth.IsZero()) {
+    QUIC_LOG_EVERY_N_SEC(ERROR, 60)
+        << "ack_rate: " << ack_rate << ", send_rate: " << send_rate
+        << ". acked packet number:" << packet_number
+        << ", overestimate_avoidance_:" << overestimate_avoidance_ << "a1:{"
+        << total_bytes_acked_ << "@" << ack_time << "}, a0:{"
+        << a0.total_bytes_acked << "@" << a0.ack_time
+        << "}, sent_packet:" << sent_packet;
+  }
+  return sample;
+}
+
+bool BandwidthSampler::ChooseA0Point(QuicByteCount total_bytes_acked,
+                                     AckPoint* a0) {
+  if (a0_candidates_.empty()) {
+    QUIC_BUG(quic_bug_10437_5)
+        << "No A0 point candicates. total_bytes_acked:" << total_bytes_acked;
+    return false;
+  }
+
+  if (a0_candidates_.size() == 1) {
+    *a0 = a0_candidates_.front();
+    return true;
+  }
+
+  for (size_t i = 1; i < a0_candidates_.size(); ++i) {
+    if (a0_candidates_[i].total_bytes_acked > total_bytes_acked) {
+      *a0 = a0_candidates_[i - 1];
+      if (i > 1) {
+        a0_candidates_.pop_front_n(i - 1);
+      }
+      return true;
+    }
+  }
+
+  // All candidates' total_bytes_acked is <= |total_bytes_acked|.
+  *a0 = a0_candidates_.back();
+  a0_candidates_.pop_front_n(a0_candidates_.size() - 1);
+  return true;
+}
+
+SendTimeState BandwidthSampler::OnPacketLost(QuicPacketNumber packet_number,
+                                             QuicPacketLength bytes_lost) {
+  // TODO(vasilvv): see the comment for the case of missing packets in
+  // BandwidthSampler::OnPacketAcknowledged on why this does not raise a
+  // QUIC_BUG when removal fails.
+  SendTimeState send_time_state;
+
+  total_bytes_lost_ += bytes_lost;
+  ConnectionStateOnSentPacket* sent_packet_pointer =
+      connection_state_map_.GetEntry(packet_number);
+  if (sent_packet_pointer != nullptr) {
+    SentPacketToSendTimeState(*sent_packet_pointer, &send_time_state);
+  }
+
+  return send_time_state;
+}
+
+void BandwidthSampler::SentPacketToSendTimeState(
+    const ConnectionStateOnSentPacket& sent_packet,
+    SendTimeState* send_time_state) const {
+  *send_time_state = sent_packet.send_time_state;
+  send_time_state->is_valid = true;
+}
+
+void BandwidthSampler::OnAppLimited() {
+  is_app_limited_ = true;
+  end_of_app_limited_phase_ = last_sent_packet_;
+}
+
+void BandwidthSampler::RemoveObsoletePackets(QuicPacketNumber least_unacked) {
+  // A packet can become obsolete when it is removed from QuicUnackedPacketMap's
+  // view of inflight before it is acked or marked as lost. For example, when
+  // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet,
+  // the packet is removed from QuicUnackedPacketMap's inflight, but is not
+  // marked as acked or lost in the BandwidthSampler.
+  connection_state_map_.RemoveUpTo(least_unacked);
+}
+
+QuicByteCount BandwidthSampler::total_bytes_sent() const {
+  return total_bytes_sent_;
+}
+
+QuicByteCount BandwidthSampler::total_bytes_acked() const {
+  return total_bytes_acked_;
+}
+
+QuicByteCount BandwidthSampler::total_bytes_lost() const {
+  return total_bytes_lost_;
+}
+
+QuicByteCount BandwidthSampler::total_bytes_neutered() const {
+  return total_bytes_neutered_;
+}
+
+bool BandwidthSampler::is_app_limited() const {
+  return is_app_limited_;
+}
+
+QuicPacketNumber BandwidthSampler::end_of_app_limited_phase() const {
+  return end_of_app_limited_phase_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bandwidth_sampler.h b/quiche/quic/core/congestion_control/bandwidth_sampler.h
new file mode 100644
index 0000000..56a3bab
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bandwidth_sampler.h
@@ -0,0 +1,627 @@
+// Copyright 2016 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_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
+
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/windowed_filter.h"
+#include "quiche/quic/core/packet_number_indexed_queue.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class BandwidthSamplerPeer;
+}  // namespace test
+
+// A subset of BandwidthSampler::ConnectionStateOnSentPacket which is returned
+// to the caller when the packet is acked or lost.
+struct QUIC_EXPORT_PRIVATE SendTimeState {
+  SendTimeState()
+      : is_valid(false),
+        is_app_limited(false),
+        total_bytes_sent(0),
+        total_bytes_acked(0),
+        total_bytes_lost(0),
+        bytes_in_flight(0) {}
+
+  SendTimeState(bool is_app_limited,
+                QuicByteCount total_bytes_sent,
+                QuicByteCount total_bytes_acked,
+                QuicByteCount total_bytes_lost,
+                QuicByteCount bytes_in_flight)
+      : is_valid(true),
+        is_app_limited(is_app_limited),
+        total_bytes_sent(total_bytes_sent),
+        total_bytes_acked(total_bytes_acked),
+        total_bytes_lost(total_bytes_lost),
+        bytes_in_flight(bytes_in_flight) {}
+
+  SendTimeState(const SendTimeState& other) = default;
+  SendTimeState& operator=(const SendTimeState& other) = default;
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const SendTimeState& s);
+
+  // Whether other states in this object is valid.
+  bool is_valid;
+
+  // Whether the sender is app limited at the time the packet was sent.
+  // App limited bandwidth sample might be artificially low because the sender
+  // did not have enough data to send in order to saturate the link.
+  bool is_app_limited;
+
+  // Total number of sent bytes at the time the packet was sent.
+  // Includes the packet itself.
+  QuicByteCount total_bytes_sent;
+
+  // Total number of acked bytes at the time the packet was sent.
+  QuicByteCount total_bytes_acked;
+
+  // Total number of lost bytes at the time the packet was sent.
+  QuicByteCount total_bytes_lost;
+
+  // Total number of inflight bytes at the time the packet was sent.
+  // Includes the packet itself.
+  // It should be equal to |total_bytes_sent| minus the sum of
+  // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes.
+  QuicByteCount bytes_in_flight;
+};
+
+struct QUIC_NO_EXPORT ExtraAckedEvent {
+  // The excess bytes acknowlwedged in the time delta for this event.
+  QuicByteCount extra_acked = 0;
+
+  // The bytes acknowledged and time delta from the event.
+  QuicByteCount bytes_acked = 0;
+  QuicTime::Delta time_delta = QuicTime::Delta::Zero();
+  // The round trip of the event.
+  QuicRoundTripCount round = 0;
+
+  bool operator>=(const ExtraAckedEvent& other) const {
+    return extra_acked >= other.extra_acked;
+  }
+  bool operator==(const ExtraAckedEvent& other) const {
+    return extra_acked == other.extra_acked;
+  }
+};
+
+struct QUIC_EXPORT_PRIVATE BandwidthSample {
+  // The bandwidth at that particular sample. Zero if no valid bandwidth sample
+  // is available.
+  QuicBandwidth bandwidth = QuicBandwidth::Zero();
+
+  // The RTT measurement at this particular sample.  Zero if no RTT sample is
+  // available.  Does not correct for delayed ack time.
+  QuicTime::Delta rtt = QuicTime::Delta::Zero();
+
+  // |send_rate| is computed from the current packet being acked('P') and an
+  // earlier packet that is acked before P was sent.
+  QuicBandwidth send_rate = QuicBandwidth::Infinite();
+
+  // States captured when the packet was sent.
+  SendTimeState state_at_send;
+};
+
+// MaxAckHeightTracker is part of the BandwidthSampler. It is called after every
+// ack event to keep track the degree of ack aggregation(a.k.a "ack height").
+class QUIC_EXPORT_PRIVATE MaxAckHeightTracker {
+ public:
+  explicit MaxAckHeightTracker(QuicRoundTripCount initial_filter_window)
+      : max_ack_height_filter_(initial_filter_window, ExtraAckedEvent(), 0) {}
+
+  QuicByteCount Get() const {
+    return max_ack_height_filter_.GetBest().extra_acked;
+  }
+
+  QuicByteCount Update(QuicBandwidth bandwidth_estimate,
+                       bool is_new_max_bandwidth,
+                       QuicRoundTripCount round_trip_count,
+                       QuicPacketNumber last_sent_packet_number,
+                       QuicPacketNumber last_acked_packet_number,
+                       QuicTime ack_time, QuicByteCount bytes_acked);
+
+  void SetFilterWindowLength(QuicRoundTripCount length) {
+    max_ack_height_filter_.SetWindowLength(length);
+  }
+
+  void Reset(QuicByteCount new_height, QuicRoundTripCount new_time) {
+    ExtraAckedEvent new_event;
+    new_event.extra_acked = new_height;
+    new_event.round = new_time;
+    max_ack_height_filter_.Reset(new_event, new_time);
+  }
+
+  void SetAckAggregationBandwidthThreshold(double threshold) {
+    ack_aggregation_bandwidth_threshold_ = threshold;
+  }
+
+  void SetStartNewAggregationEpochAfterFullRound(bool value) {
+    start_new_aggregation_epoch_after_full_round_ = value;
+  }
+
+  void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
+    reduce_extra_acked_on_bandwidth_increase_ = value;
+  }
+
+  double ack_aggregation_bandwidth_threshold() const {
+    return ack_aggregation_bandwidth_threshold_;
+  }
+
+  uint64_t num_ack_aggregation_epochs() const {
+    return num_ack_aggregation_epochs_;
+  }
+
+ private:
+  // Tracks the maximum number of bytes acked faster than the estimated
+  // bandwidth.
+  using MaxAckHeightFilter =
+      WindowedFilter<ExtraAckedEvent, MaxFilter<ExtraAckedEvent>,
+                     QuicRoundTripCount, QuicRoundTripCount>;
+  MaxAckHeightFilter max_ack_height_filter_;
+
+  // The time this aggregation started and the number of bytes acked during it.
+  QuicTime aggregation_epoch_start_time_ = QuicTime::Zero();
+  QuicByteCount aggregation_epoch_bytes_ = 0;
+  // The last sent packet number before the current aggregation epoch started.
+  QuicPacketNumber last_sent_packet_number_before_epoch_;
+  // The number of ack aggregation epochs ever started, including the ongoing
+  // one. Stats only.
+  uint64_t num_ack_aggregation_epochs_ = 0;
+  double ack_aggregation_bandwidth_threshold_ =
+      GetQuicFlag(FLAGS_quic_ack_aggregation_bandwidth_threshold);
+  bool start_new_aggregation_epoch_after_full_round_ = false;
+  bool reduce_extra_acked_on_bandwidth_increase_ = false;
+};
+
+// An interface common to any class that can provide bandwidth samples from the
+// information per individual acknowledged packet.
+class QUIC_EXPORT_PRIVATE BandwidthSamplerInterface {
+ public:
+  virtual ~BandwidthSamplerInterface() {}
+
+  // Inputs the sent packet information into the sampler. Assumes that all
+  // packets are sent in order. The information about the packet will not be
+  // released from the sampler until it the packet is either acknowledged or
+  // declared lost.
+  virtual void OnPacketSent(
+      QuicTime sent_time,
+      QuicPacketNumber packet_number,
+      QuicByteCount bytes,
+      QuicByteCount bytes_in_flight,
+      HasRetransmittableData has_retransmittable_data) = 0;
+
+  virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
+
+  struct QUIC_NO_EXPORT CongestionEventSample {
+    // The maximum bandwidth sample from all acked packets.
+    // QuicBandwidth::Zero() if no samples are available.
+    QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero();
+    // Whether |sample_max_bandwidth| is from a app-limited sample.
+    bool sample_is_app_limited = false;
+    // The minimum rtt sample from all acked packets.
+    // QuicTime::Delta::Infinite() if no samples are available.
+    QuicTime::Delta sample_rtt = QuicTime::Delta::Infinite();
+    // For each packet p in acked packets, this is the max value of INFLIGHT(p),
+    // where INFLIGHT(p) is the number of bytes acked while p is inflight.
+    QuicByteCount sample_max_inflight = 0;
+    // The send state of the largest packet in acked_packets, unless it is
+    // empty. If acked_packets is empty, it's the send state of the largest
+    // packet in lost_packets.
+    SendTimeState last_packet_send_state;
+    // The number of extra bytes acked from this ack event, compared to what is
+    // expected from the flow's bandwidth. Larger value means more ack
+    // aggregation.
+    QuicByteCount extra_acked = 0;
+  };
+  // Notifies the sampler that at |ack_time|, all packets in |acked_packets|
+  // have been acked, and all packets in |lost_packets| have been lost.
+  // See the comments in CongestionEventSample for the return value.
+  // |max_bandwidth| is the windowed maximum observed bandwidth.
+  // |est_bandwidth_upper_bound| is an upper bound of estimated bandwidth used
+  // to calculate extra_acked.
+  virtual CongestionEventSample OnCongestionEvent(
+      QuicTime ack_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      QuicBandwidth max_bandwidth,
+      QuicBandwidth est_bandwidth_upper_bound,
+      QuicRoundTripCount round_trip_count) = 0;
+
+  // Informs the sampler that the connection is currently app-limited, causing
+  // the sampler to enter the app-limited phase.  The phase will expire by
+  // itself.
+  virtual void OnAppLimited() = 0;
+
+  // Remove all the packets lower than the specified packet number.
+  virtual void RemoveObsoletePackets(QuicPacketNumber least_unacked) = 0;
+
+  // Total number of bytes sent/acked/lost/neutered in the connection.
+  virtual QuicByteCount total_bytes_sent() const = 0;
+  virtual QuicByteCount total_bytes_acked() const = 0;
+  virtual QuicByteCount total_bytes_lost() const = 0;
+  virtual QuicByteCount total_bytes_neutered() const = 0;
+
+  // Application-limited information exported for debugging.
+  virtual bool is_app_limited() const = 0;
+
+  virtual QuicPacketNumber end_of_app_limited_phase() const = 0;
+};
+
+// BandwidthSampler keeps track of sent and acknowledged packets and outputs a
+// bandwidth sample for every packet acknowledged. The samples are taken for
+// individual packets, and are not filtered; the consumer has to filter the
+// bandwidth samples itself. In certain cases, the sampler will locally severely
+// underestimate the bandwidth, hence a maximum filter with a size of at least
+// one RTT is recommended.
+//
+// This class bases its samples on the slope of two curves: the number of bytes
+// sent over time, and the number of bytes acknowledged as received over time.
+// It produces a sample of both slopes for every packet that gets acknowledged,
+// based on a slope between two points on each of the corresponding curves. Note
+// that due to the packet loss, the number of bytes on each curve might get
+// further and further away from each other, meaning that it is not feasible to
+// compare byte values coming from different curves with each other.
+//
+// The obvious points for measuring slope sample are the ones corresponding to
+// the packet that was just acknowledged. Let us denote them as S_1 (point at
+// which the current packet was sent) and A_1 (point at which the current packet
+// was acknowledged). However, taking a slope requires two points on each line,
+// so estimating bandwidth requires picking a packet in the past with respect to
+// which the slope is measured.
+//
+// For that purpose, BandwidthSampler always keeps track of the most recently
+// acknowledged packet, and records it together with every outgoing packet.
+// When a packet gets acknowledged (A_1), it has not only information about when
+// it itself was sent (S_1), but also the information about a previously
+// acknowledged packet before it was sent (S_0 and A_0).
+//
+// Based on that data, send and ack rate are estimated as:
+//   send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0))
+//   ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0))
+//
+// Here, the ack rate is intuitively the rate we want to treat as bandwidth.
+// However, in certain cases (e.g. ack compression) the ack rate at a point may
+// end up higher than the rate at which the data was originally sent, which is
+// not indicative of the real bandwidth. Hence, we use the send rate as an upper
+// bound, and the sample value is
+//   rate_sample = min(send_rate, ack_rate)
+//
+// An important edge case handled by the sampler is tracking the app-limited
+// samples. There are multiple meaning of "app-limited" used interchangeably,
+// hence it is important to understand and to be able to distinguish between
+// them.
+//
+// Meaning 1: connection state. The connection is said to be app-limited when
+// there is no outstanding data to send. This means that certain bandwidth
+// samples in the future would not be an accurate indication of the link
+// capacity, and it is important to inform consumer about that. Whenever
+// connection becomes app-limited, the sampler is notified via OnAppLimited()
+// method.
+//
+// Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth
+// sampler becomes notified about the connection being app-limited, it enters
+// app-limited phase. In that phase, all *sent* packets are marked as
+// app-limited. Note that the connection itself does not have to be
+// app-limited during the app-limited phase, and in fact it will not be
+// (otherwise how would it send packets?). The boolean flag below indicates
+// whether the sampler is in that phase.
+//
+// Meaning 3: a flag on the sent packet and on the sample. If a sent packet is
+// sent during the app-limited phase, the resulting sample related to the
+// packet will be marked as app-limited.
+//
+// With the terminology issue out of the way, let us consider the question of
+// what kind of situation it addresses.
+//
+// Consider a scenario where we first send packets 1 to 20 at a regular
+// bandwidth, and then immediately run out of data. After a few seconds, we send
+// packets 21 to 60, and only receive ack for 21 between sending packets 40 and
+// 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0
+// we use to compute the slope is going to be packet 20, a few seconds apart
+// from the current packet, hence the resulting estimate would be extremely low
+// and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21,
+// meaning that the bandwidth sample would exclude the quiescence.
+//
+// Based on the analysis of that scenario, we implement the following rule: once
+// OnAppLimited() is called, all sent packets will produce app-limited samples
+// up until an ack for a packet that was sent after OnAppLimited() was called.
+// Note that while the scenario above is not the only scenario when the
+// connection is app-limited, the approach works in other cases too.
+class QUIC_EXPORT_PRIVATE BandwidthSampler : public BandwidthSamplerInterface {
+ public:
+  BandwidthSampler(const QuicUnackedPacketMap* unacked_packet_map,
+                   QuicRoundTripCount max_height_tracker_window_length);
+
+  // Copy states from |other|. This is useful when changing send algorithms in
+  // the middle of a connection.
+  BandwidthSampler(const BandwidthSampler& other);
+  ~BandwidthSampler() override;
+
+  void OnPacketSent(QuicTime sent_time,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    QuicByteCount bytes_in_flight,
+                    HasRetransmittableData has_retransmittable_data) override;
+  void OnPacketNeutered(QuicPacketNumber packet_number) override;
+
+  CongestionEventSample OnCongestionEvent(
+      QuicTime ack_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      QuicBandwidth max_bandwidth,
+      QuicBandwidth est_bandwidth_upper_bound,
+      QuicRoundTripCount round_trip_count) override;
+  QuicByteCount OnAckEventEnd(QuicBandwidth bandwidth_estimate,
+                              bool is_new_max_bandwidth,
+                              QuicRoundTripCount round_trip_count);
+
+  void OnAppLimited() override;
+
+  void RemoveObsoletePackets(QuicPacketNumber least_unacked) override;
+
+  QuicByteCount total_bytes_sent() const override;
+  QuicByteCount total_bytes_acked() const override;
+  QuicByteCount total_bytes_lost() const override;
+  QuicByteCount total_bytes_neutered() const override;
+
+  bool is_app_limited() const override;
+
+  QuicPacketNumber end_of_app_limited_phase() const override;
+
+  QuicByteCount max_ack_height() const { return max_ack_height_tracker_.Get(); }
+
+  uint64_t num_ack_aggregation_epochs() const {
+    return max_ack_height_tracker_.num_ack_aggregation_epochs();
+  }
+
+  void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount length) {
+    max_ack_height_tracker_.SetFilterWindowLength(length);
+  }
+
+  void ResetMaxAckHeightTracker(QuicByteCount new_height,
+                                QuicRoundTripCount new_time) {
+    max_ack_height_tracker_.Reset(new_height, new_time);
+  }
+
+  void SetStartNewAggregationEpochAfterFullRound(bool value) {
+    max_ack_height_tracker_.SetStartNewAggregationEpochAfterFullRound(value);
+  }
+
+  void SetLimitMaxAckHeightTrackerBySendRate(bool value) {
+    limit_max_ack_height_tracker_by_send_rate_ = value;
+  }
+
+  void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
+    max_ack_height_tracker_.SetReduceExtraAckedOnBandwidthIncrease(value);
+  }
+
+  // AckPoint represents a point on the ack line.
+  struct QUIC_NO_EXPORT AckPoint {
+    QuicTime ack_time = QuicTime::Zero();
+    QuicByteCount total_bytes_acked = 0;
+
+    friend QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
+                                                   const AckPoint& ack_point) {
+      return os << ack_point.ack_time << ":" << ack_point.total_bytes_acked;
+    }
+  };
+
+  // RecentAckPoints maintains the most recent 2 ack points at distinct times.
+  class QUIC_NO_EXPORT RecentAckPoints {
+   public:
+    void Update(QuicTime ack_time, QuicByteCount total_bytes_acked) {
+      QUICHE_DCHECK_GE(total_bytes_acked, ack_points_[1].total_bytes_acked);
+
+      if (ack_time < ack_points_[1].ack_time) {
+        // This can only happen when time goes backwards, we use the smaller
+        // timestamp for the most recent ack point in that case.
+        // TODO(wub): Add a QUIC_BUG if ack time stops going backwards.
+        ack_points_[1].ack_time = ack_time;
+      } else if (ack_time > ack_points_[1].ack_time) {
+        ack_points_[0] = ack_points_[1];
+        ack_points_[1].ack_time = ack_time;
+      }
+
+      ack_points_[1].total_bytes_acked = total_bytes_acked;
+    }
+
+    void Clear() { ack_points_[0] = ack_points_[1] = AckPoint(); }
+
+    const AckPoint& MostRecentPoint() const { return ack_points_[1]; }
+
+    const AckPoint& LessRecentPoint() const {
+      if (ack_points_[0].total_bytes_acked != 0) {
+        return ack_points_[0];
+      }
+
+      return ack_points_[1];
+    }
+
+   private:
+    AckPoint ack_points_[2];
+  };
+
+  void EnableOverestimateAvoidance();
+  bool IsOverestimateAvoidanceEnabled() const {
+    return overestimate_avoidance_;
+  }
+
+ private:
+  friend class test::BandwidthSamplerPeer;
+
+  // ConnectionStateOnSentPacket represents the information about a sent packet
+  // and the state of the connection at the moment the packet was sent,
+  // specifically the information about the most recently acknowledged packet at
+  // that moment.
+  struct QUIC_EXPORT_PRIVATE ConnectionStateOnSentPacket {
+    // Time at which the packet is sent.
+    QuicTime sent_time;
+
+    // Size of the packet.
+    QuicByteCount size;
+
+    // The value of |total_bytes_sent_at_last_acked_packet_| at the time the
+    // packet was sent.
+    QuicByteCount total_bytes_sent_at_last_acked_packet;
+
+    // The value of |last_acked_packet_sent_time_| at the time the packet was
+    // sent.
+    QuicTime last_acked_packet_sent_time;
+
+    // The value of |last_acked_packet_ack_time_| at the time the packet was
+    // sent.
+    QuicTime last_acked_packet_ack_time;
+
+    // Send time states that are returned to the congestion controller when the
+    // packet is acked or lost.
+    SendTimeState send_time_state;
+
+    // Snapshot constructor. Records the current state of the bandwidth
+    // sampler.
+    // |bytes_in_flight| is the bytes in flight right after the packet is sent.
+    ConnectionStateOnSentPacket(QuicTime sent_time,
+                                QuicByteCount size,
+                                QuicByteCount bytes_in_flight,
+                                const BandwidthSampler& sampler)
+        : sent_time(sent_time),
+          size(size),
+          total_bytes_sent_at_last_acked_packet(
+              sampler.total_bytes_sent_at_last_acked_packet_),
+          last_acked_packet_sent_time(sampler.last_acked_packet_sent_time_),
+          last_acked_packet_ack_time(sampler.last_acked_packet_ack_time_),
+          send_time_state(sampler.is_app_limited_,
+                          sampler.total_bytes_sent_,
+                          sampler.total_bytes_acked_,
+                          sampler.total_bytes_lost_,
+                          bytes_in_flight) {}
+
+    // Default constructor.  Required to put this structure into
+    // PacketNumberIndexedQueue.
+    ConnectionStateOnSentPacket()
+        : sent_time(QuicTime::Zero()),
+          size(0),
+          total_bytes_sent_at_last_acked_packet(0),
+          last_acked_packet_sent_time(QuicTime::Zero()),
+          last_acked_packet_ack_time(QuicTime::Zero()) {}
+
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os,
+        const ConnectionStateOnSentPacket& p) {
+      os << "{sent_time:" << p.sent_time << ", size:" << p.size
+         << ", total_bytes_sent_at_last_acked_packet:"
+         << p.total_bytes_sent_at_last_acked_packet
+         << ", last_acked_packet_sent_time:" << p.last_acked_packet_sent_time
+         << ", last_acked_packet_ack_time:" << p.last_acked_packet_ack_time
+         << ", send_time_state:" << p.send_time_state << "}";
+      return os;
+    }
+  };
+
+  BandwidthSample OnPacketAcknowledged(QuicTime ack_time,
+                                       QuicPacketNumber packet_number);
+
+  SendTimeState OnPacketLost(QuicPacketNumber packet_number,
+                             QuicPacketLength bytes_lost);
+
+  // Copy a subset of the (private) ConnectionStateOnSentPacket to the (public)
+  // SendTimeState. Always set send_time_state->is_valid to true.
+  void SentPacketToSendTimeState(const ConnectionStateOnSentPacket& sent_packet,
+                                 SendTimeState* send_time_state) const;
+
+  // Choose the best a0 from |a0_candidates_| to calculate the ack rate.
+  // |total_bytes_acked| is the total bytes acked when the packet being acked is
+  // sent. The best a0 is chosen as follows:
+  // - If there's only one candidate, use it.
+  // - If there are multiple candidates, let a[n] be the nth candidate, and
+  //   a[n-1].total_bytes_acked <= |total_bytes_acked| < a[n].total_bytes_acked,
+  //   use a[n-1].
+  // - If all candidates's total_bytes_acked is > |total_bytes_acked|, use a[0].
+  //   This may happen when acks are received out of order, and ack[n] caused
+  //   some candidates of ack[n-x] to be removed.
+  // - If all candidates's total_bytes_acked is <= |total_bytes_acked|, use
+  //   a[a.size()-1].
+  bool ChooseA0Point(QuicByteCount total_bytes_acked, AckPoint* a0);
+
+  // The total number of congestion controlled bytes sent during the connection.
+  QuicByteCount total_bytes_sent_;
+
+  // The total number of congestion controlled bytes which were acknowledged.
+  QuicByteCount total_bytes_acked_;
+
+  // The total number of congestion controlled bytes which were lost.
+  QuicByteCount total_bytes_lost_;
+
+  // The total number of congestion controlled bytes which have been neutered.
+  QuicByteCount total_bytes_neutered_;
+
+  // The value of |total_bytes_sent_| at the time the last acknowledged packet
+  // was sent. Valid only when |last_acked_packet_sent_time_| is valid.
+  QuicByteCount total_bytes_sent_at_last_acked_packet_;
+
+  // The time at which the last acknowledged packet was sent. Set to
+  // QuicTime::Zero() if no valid timestamp is available.
+  QuicTime last_acked_packet_sent_time_;
+
+  // The time at which the most recent packet was acknowledged.
+  QuicTime last_acked_packet_ack_time_;
+
+  // The most recently sent packet.
+  QuicPacketNumber last_sent_packet_;
+
+  // The most recently acked packet.
+  QuicPacketNumber last_acked_packet_;
+
+  // Indicates whether the bandwidth sampler is currently in an app-limited
+  // phase.
+  bool is_app_limited_;
+
+  // The packet that will be acknowledged after this one will cause the sampler
+  // to exit the app-limited phase.
+  QuicPacketNumber end_of_app_limited_phase_;
+
+  // Record of the connection state at the point where each packet in flight was
+  // sent, indexed by the packet number.
+  PacketNumberIndexedQueue<ConnectionStateOnSentPacket> connection_state_map_;
+
+  RecentAckPoints recent_ack_points_;
+  quiche::QuicheCircularDeque<AckPoint> a0_candidates_;
+
+  // Maximum number of tracked packets.
+  const QuicPacketCount max_tracked_packets_;
+
+  // The main unacked packet map.  Used for outputting extra debugging details.
+  // May be null.
+  // TODO(vasilvv): remove this once it's no longer useful for debugging.
+  const QuicUnackedPacketMap* unacked_packet_map_;
+
+  // Handles the actual bandwidth calculations, whereas the outer method handles
+  // retrieving and removing |sent_packet|.
+  BandwidthSample OnPacketAcknowledgedInner(
+      QuicTime ack_time,
+      QuicPacketNumber packet_number,
+      const ConnectionStateOnSentPacket& sent_packet);
+
+  MaxAckHeightTracker max_ack_height_tracker_;
+  QuicByteCount total_bytes_acked_after_last_ack_event_;
+
+  // True if connection option 'BSAO' is set.
+  bool overestimate_avoidance_;
+
+  // True if connection option 'BBRB' is set.
+  bool limit_max_ack_height_tracker_by_send_rate_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
diff --git a/quiche/quic/core/congestion_control/bandwidth_sampler_test.cc b/quiche/quic/core/congestion_control/bandwidth_sampler_test.cc
new file mode 100644
index 0000000..6089232
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bandwidth_sampler_test.cc
@@ -0,0 +1,889 @@
+// Copyright 2016 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 "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include <cstdint>
+#include <set>
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class BandwidthSamplerPeer {
+ public:
+  static size_t GetNumberOfTrackedPackets(const BandwidthSampler& sampler) {
+    return sampler.connection_state_map_.number_of_present_entries();
+  }
+
+  static QuicByteCount GetPacketSize(const BandwidthSampler& sampler,
+                                     QuicPacketNumber packet_number) {
+    return sampler.connection_state_map_.GetEntry(packet_number)->size;
+  }
+};
+
+const QuicByteCount kRegularPacketSize = 1280;
+// Enforce divisibility for some of the tests.
+static_assert((kRegularPacketSize & 31) == 0,
+              "kRegularPacketSize has to be five times divisible by 2");
+
+struct TestParameters {
+  bool overestimate_avoidance;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParameters& p) {
+  return p.overestimate_avoidance ? "enable_overestimate_avoidance"
+                                  : "no_enable_overestimate_avoidance";
+}
+
+// A test fixture with utility methods for BandwidthSampler tests.
+class BandwidthSamplerTest : public QuicTestWithParam<TestParameters> {
+ protected:
+  BandwidthSamplerTest()
+      : sampler_(nullptr, /*max_height_tracker_window_length=*/0),
+        sampler_app_limited_at_start_(sampler_.is_app_limited()),
+        bytes_in_flight_(0),
+        max_bandwidth_(QuicBandwidth::Zero()),
+        est_bandwidth_upper_bound_(QuicBandwidth::Infinite()),
+        round_trip_count_(0) {
+    // Ensure that the clock does not start at zero.
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    if (GetParam().overestimate_avoidance) {
+      sampler_.EnableOverestimateAvoidance();
+    }
+  }
+
+  MockClock clock_;
+  BandwidthSampler sampler_;
+  bool sampler_app_limited_at_start_;
+  QuicByteCount bytes_in_flight_;
+  QuicBandwidth max_bandwidth_;  // Max observed bandwidth from acks.
+  QuicBandwidth est_bandwidth_upper_bound_;
+  QuicRoundTripCount round_trip_count_;  // Needed to calculate extra_acked.
+
+  QuicByteCount PacketsToBytes(QuicPacketCount packet_count) {
+    return packet_count * kRegularPacketSize;
+  }
+
+  void SendPacketInner(uint64_t packet_number,
+                       QuicByteCount bytes,
+                       HasRetransmittableData has_retransmittable_data) {
+    sampler_.OnPacketSent(clock_.Now(), QuicPacketNumber(packet_number), bytes,
+                          bytes_in_flight_, has_retransmittable_data);
+    if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA) {
+      bytes_in_flight_ += bytes;
+    }
+  }
+
+  void SendPacket(uint64_t packet_number) {
+    SendPacketInner(packet_number, kRegularPacketSize,
+                    HAS_RETRANSMITTABLE_DATA);
+  }
+
+  BandwidthSample AckPacketInner(uint64_t packet_number) {
+    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
+        sampler_, QuicPacketNumber(packet_number));
+    bytes_in_flight_ -= size;
+    BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
+        clock_.Now(), {MakeAckedPacket(packet_number)}, {}, max_bandwidth_,
+        est_bandwidth_upper_bound_, round_trip_count_);
+    max_bandwidth_ = std::max(max_bandwidth_, sample.sample_max_bandwidth);
+    BandwidthSample bandwidth_sample;
+    bandwidth_sample.bandwidth = sample.sample_max_bandwidth;
+    bandwidth_sample.rtt = sample.sample_rtt;
+    bandwidth_sample.state_at_send = sample.last_packet_send_state;
+    EXPECT_TRUE(bandwidth_sample.state_at_send.is_valid);
+    return bandwidth_sample;
+  }
+
+  AckedPacket MakeAckedPacket(uint64_t packet_number) const {
+    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
+        sampler_, QuicPacketNumber(packet_number));
+    return AckedPacket(QuicPacketNumber(packet_number), size, clock_.Now());
+  }
+
+  LostPacket MakeLostPacket(uint64_t packet_number) const {
+    return LostPacket(QuicPacketNumber(packet_number),
+                      BandwidthSamplerPeer::GetPacketSize(
+                          sampler_, QuicPacketNumber(packet_number)));
+  }
+
+  // Acknowledge receipt of a packet and expect it to be not app-limited.
+  QuicBandwidth AckPacket(uint64_t packet_number) {
+    BandwidthSample sample = AckPacketInner(packet_number);
+    return sample.bandwidth;
+  }
+
+  BandwidthSampler::CongestionEventSample OnCongestionEvent(
+      std::set<uint64_t> acked_packet_numbers,
+      std::set<uint64_t> lost_packet_numbers) {
+    AckedPacketVector acked_packets;
+    for (auto it = acked_packet_numbers.begin();
+         it != acked_packet_numbers.end(); ++it) {
+      acked_packets.push_back(MakeAckedPacket(*it));
+      bytes_in_flight_ -= acked_packets.back().bytes_acked;
+    }
+
+    LostPacketVector lost_packets;
+    for (auto it = lost_packet_numbers.begin(); it != lost_packet_numbers.end();
+         ++it) {
+      lost_packets.push_back(MakeLostPacket(*it));
+      bytes_in_flight_ -= lost_packets.back().bytes_lost;
+    }
+
+    BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
+        clock_.Now(), acked_packets, lost_packets, max_bandwidth_,
+        est_bandwidth_upper_bound_, round_trip_count_);
+    max_bandwidth_ = std::max(max_bandwidth_, sample.sample_max_bandwidth);
+    return sample;
+  }
+
+  SendTimeState LosePacket(uint64_t packet_number) {
+    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
+        sampler_, QuicPacketNumber(packet_number));
+    bytes_in_flight_ -= size;
+    LostPacket lost_packet(QuicPacketNumber(packet_number), size);
+    BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
+        clock_.Now(), {}, {lost_packet}, max_bandwidth_,
+        est_bandwidth_upper_bound_, round_trip_count_);
+    EXPECT_TRUE(sample.last_packet_send_state.is_valid);
+    EXPECT_EQ(sample.sample_max_bandwidth, QuicBandwidth::Zero());
+    EXPECT_EQ(sample.sample_rtt, QuicTime::Delta::Infinite());
+    return sample.last_packet_send_state;
+  }
+
+  // Sends one packet and acks it.  Then, send 20 packets.  Finally, send
+  // another 20 packets while acknowledging previous 20.
+  void Send40PacketsAndAckFirst20(QuicTime::Delta time_between_packets) {
+    // Send 20 packets at a constant inter-packet time.
+    for (int i = 1; i <= 20; i++) {
+      SendPacket(i);
+      clock_.AdvanceTime(time_between_packets);
+    }
+
+    // Ack packets 1 to 20, while sending new packets at the same rate as
+    // before.
+    for (int i = 1; i <= 20; i++) {
+      AckPacket(i);
+      SendPacket(i + 20);
+      clock_.AdvanceTime(time_between_packets);
+    }
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    BandwidthSamplerTests,
+    BandwidthSamplerTest,
+    testing::Values(TestParameters{/*overestimate_avoidance=*/false},
+                    TestParameters{/*overestimate_avoidance=*/true}),
+    testing::PrintToStringParamName());
+
+// Test the sampler in a simple stop-and-wait sender setting.
+TEST_P(BandwidthSamplerTest, SendAndWait) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromBytesPerSecond(kRegularPacketSize * 100);
+
+  // Send packets at the constant bandwidth.
+  for (int i = 1; i < 20; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+    QuicBandwidth current_sample = AckPacket(i);
+    EXPECT_EQ(expected_bandwidth, current_sample);
+  }
+
+  // Send packets at the exponentially decreasing bandwidth.
+  for (int i = 20; i < 25; i++) {
+    time_between_packets = time_between_packets * 2;
+    expected_bandwidth = expected_bandwidth * 0.5;
+
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+    QuicBandwidth current_sample = AckPacket(i);
+    EXPECT_EQ(expected_bandwidth, current_sample);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(25));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+TEST_P(BandwidthSamplerTest, SendTimeState) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+
+  // Send packets 1-5.
+  for (int i = 1; i <= 5; i++) {
+    SendPacket(i);
+    EXPECT_EQ(PacketsToBytes(i), sampler_.total_bytes_sent());
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack packet 1.
+  SendTimeState send_time_state = AckPacketInner(1).state_at_send;
+  EXPECT_EQ(PacketsToBytes(1), send_time_state.total_bytes_sent);
+  EXPECT_EQ(0u, send_time_state.total_bytes_acked);
+  EXPECT_EQ(0u, send_time_state.total_bytes_lost);
+  EXPECT_EQ(PacketsToBytes(1), sampler_.total_bytes_acked());
+
+  // Lose packet 2.
+  send_time_state = LosePacket(2);
+  EXPECT_EQ(PacketsToBytes(2), send_time_state.total_bytes_sent);
+  EXPECT_EQ(0u, send_time_state.total_bytes_acked);
+  EXPECT_EQ(0u, send_time_state.total_bytes_lost);
+  EXPECT_EQ(PacketsToBytes(1), sampler_.total_bytes_lost());
+
+  // Lose packet 3.
+  send_time_state = LosePacket(3);
+  EXPECT_EQ(PacketsToBytes(3), send_time_state.total_bytes_sent);
+  EXPECT_EQ(0u, send_time_state.total_bytes_acked);
+  EXPECT_EQ(0u, send_time_state.total_bytes_lost);
+  EXPECT_EQ(PacketsToBytes(2), sampler_.total_bytes_lost());
+
+  // Send packets 6-10.
+  for (int i = 6; i <= 10; i++) {
+    SendPacket(i);
+    EXPECT_EQ(PacketsToBytes(i), sampler_.total_bytes_sent());
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack all inflight packets.
+  QuicPacketCount acked_packet_count = 1;
+  EXPECT_EQ(PacketsToBytes(acked_packet_count), sampler_.total_bytes_acked());
+  for (int i = 4; i <= 10; i++) {
+    send_time_state = AckPacketInner(i).state_at_send;
+    ++acked_packet_count;
+    EXPECT_EQ(PacketsToBytes(acked_packet_count), sampler_.total_bytes_acked());
+    EXPECT_EQ(PacketsToBytes(i), send_time_state.total_bytes_sent);
+    if (i <= 5) {
+      EXPECT_EQ(0u, send_time_state.total_bytes_acked);
+      EXPECT_EQ(0u, send_time_state.total_bytes_lost);
+    } else {
+      EXPECT_EQ(PacketsToBytes(1), send_time_state.total_bytes_acked);
+      EXPECT_EQ(PacketsToBytes(2), send_time_state.total_bytes_lost);
+    }
+
+    // This equation works because there is no neutered bytes.
+    EXPECT_EQ(send_time_state.total_bytes_sent -
+                  send_time_state.total_bytes_acked -
+                  send_time_state.total_bytes_lost,
+              send_time_state.bytes_in_flight);
+
+    clock_.AdvanceTime(time_between_packets);
+  }
+}
+
+// Test the sampler during regular windowed sender scenario with fixed
+// CWND of 20.
+TEST_P(BandwidthSamplerTest, SendPaced) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
+
+  Send40PacketsAndAckFirst20(time_between_packets);
+
+  // Ack the packets 21 to 40, arriving at the correct bandwidth.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  for (int i = 21; i <= 40; i++) {
+    last_bandwidth = AckPacket(i);
+    EXPECT_EQ(expected_bandwidth, last_bandwidth) << "i is " << i;
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Test the sampler in a scenario where 50% of packets is consistently lost.
+TEST_P(BandwidthSamplerTest, SendWithLosses) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize) * 0.5;
+
+  // Send 20 packets, each 1 ms apart.
+  for (int i = 1; i <= 20; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack packets 1 to 20, losing every even-numbered packet, while sending new
+  // packets at the same rate as before.
+  for (int i = 1; i <= 20; i++) {
+    if (i % 2 == 0) {
+      AckPacket(i);
+    } else {
+      LosePacket(i);
+    }
+    SendPacket(i + 20);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack the packets 21 to 40 with the same loss pattern.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  for (int i = 21; i <= 40; i++) {
+    if (i % 2 == 0) {
+      last_bandwidth = AckPacket(i);
+      EXPECT_EQ(expected_bandwidth, last_bandwidth);
+    } else {
+      LosePacket(i);
+    }
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Test the sampler in a scenario where the 50% of packets are not
+// congestion controlled (specifically, non-retransmittable data is not
+// congestion controlled).  Should be functionally consistent in behavior with
+// the SendWithLosses test.
+TEST_P(BandwidthSamplerTest, NotCongestionControlled) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize) * 0.5;
+
+  // Send 20 packets, each 1 ms apart. Every even packet is not congestion
+  // controlled.
+  for (int i = 1; i <= 20; i++) {
+    SendPacketInner(
+        i, kRegularPacketSize,
+        i % 2 == 0 ? HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ensure only congestion controlled packets are tracked.
+  EXPECT_EQ(10u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+
+  // Ack packets 2 to 21, ignoring every even-numbered packet, while sending new
+  // packets at the same rate as before.
+  for (int i = 1; i <= 20; i++) {
+    if (i % 2 == 0) {
+      AckPacket(i);
+    }
+    SendPacketInner(
+        i + 20, kRegularPacketSize,
+        i % 2 == 0 ? HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack the packets 22 to 41 with the same congestion controlled pattern.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  for (int i = 21; i <= 40; i++) {
+    if (i % 2 == 0) {
+      last_bandwidth = AckPacket(i);
+      EXPECT_EQ(expected_bandwidth, last_bandwidth);
+    }
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
+
+  // Since only congestion controlled packets are entered into the map, it has
+  // to be empty at this point.
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Simulate a situation where ACKs arrive in burst and earlier than usual, thus
+// producing an ACK rate which is higher than the original send rate.
+TEST_P(BandwidthSamplerTest, CompressedAck) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
+
+  Send40PacketsAndAckFirst20(time_between_packets);
+
+  // Simulate an RTT somewhat lower than the one for 1-to-21 transmission.
+  clock_.AdvanceTime(time_between_packets * 15);
+
+  // Ack the packets 21 to 40 almost immediately at once.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  QuicTime::Delta ridiculously_small_time_delta =
+      QuicTime::Delta::FromMicroseconds(20);
+  for (int i = 21; i <= 40; i++) {
+    last_bandwidth = AckPacket(i);
+    clock_.AdvanceTime(ridiculously_small_time_delta);
+  }
+  EXPECT_EQ(expected_bandwidth, last_bandwidth);
+
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Tests receiving ACK packets in the reverse order.
+TEST_P(BandwidthSamplerTest, ReorderedAck) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
+
+  Send40PacketsAndAckFirst20(time_between_packets);
+
+  // Ack the packets 21 to 40 in the reverse order, while sending packets 41 to
+  // 60.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  for (int i = 0; i < 20; i++) {
+    last_bandwidth = AckPacket(40 - i);
+    EXPECT_EQ(expected_bandwidth, last_bandwidth);
+    SendPacket(41 + i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack the packets 41 to 60, now in the regular order.
+  for (int i = 41; i <= 60; i++) {
+    last_bandwidth = AckPacket(i);
+    EXPECT_EQ(expected_bandwidth, last_bandwidth);
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(61));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Test the app-limited logic.
+TEST_P(BandwidthSamplerTest, AppLimited) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
+
+  // Send 20 packets at a constant inter-packet time.
+  for (int i = 1; i <= 20; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack packets 1 to 20, while sending new packets at the same rate as
+  // before.
+  for (int i = 1; i <= 20; i++) {
+    BandwidthSample sample = AckPacketInner(i);
+    EXPECT_EQ(sample.state_at_send.is_app_limited,
+              sampler_app_limited_at_start_);
+    SendPacket(i + 20);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // We are now app-limited. Ack 21 to 40 as usual, but do not send anything for
+  // now.
+  sampler_.OnAppLimited();
+  for (int i = 21; i <= 40; i++) {
+    BandwidthSample sample = AckPacketInner(i);
+    EXPECT_FALSE(sample.state_at_send.is_app_limited);
+    EXPECT_EQ(expected_bandwidth, sample.bandwidth);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Enter quiescence.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+  // Send packets 41 to 60, all of which would be marked as app-limited.
+  for (int i = 41; i <= 60; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack packets 41 to 60, while sending packets 61 to 80.  41 to 60 should be
+  // app-limited and underestimate the bandwidth due to that.
+  for (int i = 41; i <= 60; i++) {
+    BandwidthSample sample = AckPacketInner(i);
+    EXPECT_TRUE(sample.state_at_send.is_app_limited);
+    EXPECT_LT(sample.bandwidth, 0.7f * expected_bandwidth);
+
+    SendPacket(i + 20);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Run out of packets, and then ack packet 61 to 80, all of which should have
+  // correct non-app-limited samples.
+  for (int i = 61; i <= 80; i++) {
+    BandwidthSample sample = AckPacketInner(i);
+    EXPECT_FALSE(sample.state_at_send.is_app_limited);
+    EXPECT_EQ(sample.bandwidth, expected_bandwidth);
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(81));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Test the samples taken at the first flight of packets sent.
+TEST_P(BandwidthSamplerTest, FirstRoundTrip) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  const QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(800);
+  const int num_packets = 10;
+  const QuicByteCount num_bytes = kRegularPacketSize * num_packets;
+  const QuicBandwidth real_bandwidth =
+      QuicBandwidth::FromBytesAndTimeDelta(num_bytes, rtt);
+
+  for (int i = 1; i <= 10; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  clock_.AdvanceTime(rtt - num_packets * time_between_packets);
+
+  QuicBandwidth last_sample = QuicBandwidth::Zero();
+  for (int i = 1; i <= 10; i++) {
+    QuicBandwidth sample = AckPacket(i);
+    EXPECT_GT(sample, last_sample);
+    last_sample = sample;
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // The final measured sample for the first flight of sample is expected to be
+  // smaller than the real bandwidth, yet it should not lose more than 10%. The
+  // specific value of the error depends on the difference between the RTT and
+  // the time it takes to exhaust the congestion window (i.e. in the limit when
+  // all packets are sent simultaneously, last sample would indicate the real
+  // bandwidth).
+  EXPECT_LT(last_sample, real_bandwidth);
+  EXPECT_GT(last_sample, 0.9f * real_bandwidth);
+}
+
+// Test sampler's ability to remove obsolete packets.
+TEST_P(BandwidthSamplerTest, RemoveObsoletePackets) {
+  SendPacket(1);
+  SendPacket(2);
+  SendPacket(3);
+  SendPacket(4);
+  SendPacket(5);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+
+  EXPECT_EQ(5u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(4));
+  EXPECT_EQ(2u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  LosePacket(4);
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(5));
+
+  EXPECT_EQ(1u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  AckPacket(5);
+
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(6));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+}
+
+TEST_P(BandwidthSamplerTest, NeuterPacket) {
+  SendPacket(1);
+  EXPECT_EQ(0u, sampler_.total_bytes_neutered());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  sampler_.OnPacketNeutered(QuicPacketNumber(1));
+  EXPECT_LT(0u, sampler_.total_bytes_neutered());
+  EXPECT_EQ(0u, sampler_.total_bytes_acked());
+
+  // If packet 1 is acked it should not produce a bandwidth sample.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
+      clock_.Now(),
+      {AckedPacket(QuicPacketNumber(1), kRegularPacketSize, clock_.Now())}, {},
+      max_bandwidth_, est_bandwidth_upper_bound_, round_trip_count_);
+  EXPECT_EQ(0u, sampler_.total_bytes_acked());
+  EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
+  EXPECT_FALSE(sample.sample_is_app_limited);
+  EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
+  EXPECT_EQ(0u, sample.sample_max_inflight);
+  EXPECT_EQ(0u, sample.extra_acked);
+}
+
+TEST_P(BandwidthSamplerTest, CongestionEventSampleDefaultValues) {
+  // Make sure a default constructed CongestionEventSample has the correct
+  // initial values for BandwidthSampler::OnCongestionEvent() to work.
+  BandwidthSampler::CongestionEventSample sample;
+
+  EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
+  EXPECT_FALSE(sample.sample_is_app_limited);
+  EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
+  EXPECT_EQ(0u, sample.sample_max_inflight);
+  EXPECT_EQ(0u, sample.extra_acked);
+}
+
+// 1) Send 2 packets, 2) Ack both in 1 event, 3) Repeat.
+TEST_P(BandwidthSamplerTest, TwoAckedPacketsPerEvent) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+  QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      kRegularPacketSize, time_between_packets);
+
+  for (uint64_t i = 1; i < 21; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+    if (i % 2 != 0) {
+      continue;
+    }
+
+    BandwidthSampler::CongestionEventSample sample =
+        OnCongestionEvent({i - 1, i}, {});
+    EXPECT_EQ(sending_rate, sample.sample_max_bandwidth);
+    EXPECT_EQ(time_between_packets, sample.sample_rtt);
+    EXPECT_EQ(2 * kRegularPacketSize, sample.sample_max_inflight);
+    EXPECT_TRUE(sample.last_packet_send_state.is_valid);
+    EXPECT_EQ(2 * kRegularPacketSize,
+              sample.last_packet_send_state.bytes_in_flight);
+    EXPECT_EQ(i * kRegularPacketSize,
+              sample.last_packet_send_state.total_bytes_sent);
+    EXPECT_EQ((i - 2) * kRegularPacketSize,
+              sample.last_packet_send_state.total_bytes_acked);
+    EXPECT_EQ(0u, sample.last_packet_send_state.total_bytes_lost);
+    sampler_.RemoveObsoletePackets(QuicPacketNumber(i - 2));
+  }
+}
+
+TEST_P(BandwidthSamplerTest, LoseEveryOtherPacket) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+  QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      kRegularPacketSize, time_between_packets);
+
+  for (uint64_t i = 1; i < 21; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+    if (i % 2 != 0) {
+      continue;
+    }
+
+    // Ack packet i and lose i-1.
+    BandwidthSampler::CongestionEventSample sample =
+        OnCongestionEvent({i}, {i - 1});
+    // Losing 50% packets means sending rate is twice the bandwidth.
+    EXPECT_EQ(sending_rate, sample.sample_max_bandwidth * 2);
+    EXPECT_EQ(time_between_packets, sample.sample_rtt);
+    EXPECT_EQ(kRegularPacketSize, sample.sample_max_inflight);
+    EXPECT_TRUE(sample.last_packet_send_state.is_valid);
+    EXPECT_EQ(2 * kRegularPacketSize,
+              sample.last_packet_send_state.bytes_in_flight);
+    EXPECT_EQ(i * kRegularPacketSize,
+              sample.last_packet_send_state.total_bytes_sent);
+    EXPECT_EQ((i - 2) * kRegularPacketSize / 2,
+              sample.last_packet_send_state.total_bytes_acked);
+    EXPECT_EQ((i - 2) * kRegularPacketSize / 2,
+              sample.last_packet_send_state.total_bytes_lost);
+    sampler_.RemoveObsoletePackets(QuicPacketNumber(i - 2));
+  }
+}
+
+TEST_P(BandwidthSamplerTest, AckHeightRespectBandwidthEstimateUpperBound) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+  QuicBandwidth first_packet_sending_rate =
+      QuicBandwidth::FromBytesAndTimeDelta(kRegularPacketSize,
+                                           time_between_packets);
+
+  // Send packets 1 to 4 and ack packet 1.
+  SendPacket(1);
+  clock_.AdvanceTime(time_between_packets);
+  SendPacket(2);
+  SendPacket(3);
+  SendPacket(4);
+  BandwidthSampler::CongestionEventSample sample = OnCongestionEvent({1}, {});
+  EXPECT_EQ(first_packet_sending_rate, sample.sample_max_bandwidth);
+  EXPECT_EQ(first_packet_sending_rate, max_bandwidth_);
+
+  // Ack packet 2, 3 and 4, all of which uses S(1) to calculate ack rate since
+  // there were no acks at the time they were sent.
+  round_trip_count_++;
+  est_bandwidth_upper_bound_ = first_packet_sending_rate * 0.3;
+  clock_.AdvanceTime(time_between_packets);
+  sample = OnCongestionEvent({2, 3, 4}, {});
+  EXPECT_EQ(first_packet_sending_rate * 2, sample.sample_max_bandwidth);
+  EXPECT_EQ(max_bandwidth_, sample.sample_max_bandwidth);
+
+  EXPECT_LT(2 * kRegularPacketSize, sample.extra_acked);
+}
+
+class MaxAckHeightTrackerTest : public QuicTest {
+ protected:
+  MaxAckHeightTrackerTest() : tracker_(/*initial_filter_window=*/10) {
+    tracker_.SetAckAggregationBandwidthThreshold(1.8);
+    tracker_.SetStartNewAggregationEpochAfterFullRound(true);
+  }
+
+  // Run a full aggregation episode, which is one or more aggregated acks,
+  // followed by a quiet period in which no ack happens.
+  // After this function returns, the time is set to the earliest point at which
+  // any ack event will cause tracker_.Update() to start a new aggregation.
+  void AggregationEpisode(QuicBandwidth aggregation_bandwidth,
+                          QuicTime::Delta aggregation_duration,
+                          QuicByteCount bytes_per_ack,
+                          bool expect_new_aggregation_epoch) {
+    ASSERT_GE(aggregation_bandwidth, bandwidth_);
+    const QuicTime start_time = now_;
+
+    const QuicByteCount aggregation_bytes =
+        aggregation_bandwidth * aggregation_duration;
+
+    const int num_acks = aggregation_bytes / bytes_per_ack;
+    ASSERT_EQ(aggregation_bytes, num_acks * bytes_per_ack)
+        << "aggregation_bytes: " << aggregation_bytes << " ["
+        << aggregation_bandwidth << " in " << aggregation_duration
+        << "], bytes_per_ack: " << bytes_per_ack;
+
+    const QuicTime::Delta time_between_acks = QuicTime::Delta::FromMicroseconds(
+        aggregation_duration.ToMicroseconds() / num_acks);
+    ASSERT_EQ(aggregation_duration, num_acks * time_between_acks)
+        << "aggregation_bytes: " << aggregation_bytes
+        << ", num_acks: " << num_acks
+        << ", time_between_acks: " << time_between_acks;
+
+    // The total duration of aggregation time and quiet period.
+    const QuicTime::Delta total_duration = QuicTime::Delta::FromMicroseconds(
+        aggregation_bytes * 8 * 1000000 / bandwidth_.ToBitsPerSecond());
+    ASSERT_EQ(aggregation_bytes, total_duration * bandwidth_)
+        << "total_duration: " << total_duration
+        << ", bandwidth_: " << bandwidth_;
+
+    QuicByteCount last_extra_acked = 0;
+    for (QuicByteCount bytes = 0; bytes < aggregation_bytes;
+         bytes += bytes_per_ack) {
+      QuicByteCount extra_acked = tracker_.Update(
+          bandwidth_, true, RoundTripCount(), last_sent_packet_number_,
+          last_acked_packet_number_, now_, bytes_per_ack);
+      QUIC_VLOG(1) << "T" << now_ << ": Update after " << bytes_per_ack
+                   << " bytes acked, " << extra_acked << " extra bytes acked";
+      // |extra_acked| should be 0 if either
+      // [1] We are at the beginning of a aggregation epoch(bytes==0) and the
+      //     the current tracker implementation can identify it, or
+      // [2] We are not really aggregating acks.
+      if ((bytes == 0 && expect_new_aggregation_epoch) ||  // [1]
+          (aggregation_bandwidth == bandwidth_)) {         // [2]
+        EXPECT_EQ(0u, extra_acked);
+      } else {
+        EXPECT_LT(last_extra_acked, extra_acked);
+      }
+      now_ = now_ + time_between_acks;
+      last_extra_acked = extra_acked;
+    }
+
+    // Advance past the quiet period.
+    const QuicTime time_after_aggregation = now_;
+    now_ = start_time + total_duration;
+    QUIC_VLOG(1) << "Advanced time from " << time_after_aggregation << " to "
+                 << now_ << ". Aggregation time["
+                 << (time_after_aggregation - start_time) << "], Quiet time["
+                 << (now_ - time_after_aggregation) << "].";
+  }
+
+  QuicRoundTripCount RoundTripCount() const {
+    return (now_ - QuicTime::Zero()).ToMicroseconds() / rtt_.ToMicroseconds();
+  }
+
+  MaxAckHeightTracker tracker_;
+  QuicBandwidth bandwidth_ = QuicBandwidth::FromBytesPerSecond(10 * 1000);
+  QuicTime now_ = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
+  QuicTime::Delta rtt_ = QuicTime::Delta::FromMilliseconds(60);
+  QuicPacketNumber last_sent_packet_number_;
+  QuicPacketNumber last_acked_packet_number_;
+};
+
+TEST_F(MaxAckHeightTrackerTest, VeryAggregatedLargeAck) {
+  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                     1200, true);
+  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                     1200, true);
+  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
+
+  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
+    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                       1200, true);
+    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
+  } else {
+    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                       1200, false);
+    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+  }
+}
+
+TEST_F(MaxAckHeightTrackerTest, VeryAggregatedSmallAcks) {
+  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6), 300,
+                     true);
+  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6), 300,
+                     true);
+  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
+
+  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
+    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                       300, true);
+    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
+  } else {
+    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                       300, false);
+    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+  }
+}
+
+TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedLargeAck) {
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                     1000, true);
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                     1000, true);
+  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
+
+  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
+    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                       1000, true);
+    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
+  } else {
+    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                       1000, false);
+    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+  }
+}
+
+TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedSmallAcks) {
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
+                     true);
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
+                     true);
+  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
+
+  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
+    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                       100, true);
+    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
+  } else {
+    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                       100, false);
+    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+  }
+}
+
+TEST_F(MaxAckHeightTrackerTest, NotAggregated) {
+  AggregationEpisode(bandwidth_, QuicTime::Delta::FromMilliseconds(100), 100,
+                     true);
+  EXPECT_LT(2u, tracker_.num_ack_aggregation_epochs());
+}
+
+TEST_F(MaxAckHeightTrackerTest, StartNewEpochAfterAFullRound) {
+  last_sent_packet_number_ = QuicPacketNumber(10);
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
+                     true);
+
+  last_acked_packet_number_ = QuicPacketNumber(11);
+  // Update with a tiny bandwidth causes a very low expected bytes acked, which
+  // in turn causes the current epoch to continue if the |tracker_| doesn't
+  // check the packet numbers.
+  tracker_.Update(bandwidth_ * 0.1, true, RoundTripCount(),
+                  last_sent_packet_number_, last_acked_packet_number_, now_,
+                  100);
+
+  EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_drain.cc b/quiche/quic/core/congestion_control/bbr2_drain.cc
new file mode 100644
index 0000000..6fb9c94
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_drain.cc
@@ -0,0 +1,62 @@
+// Copyright 2019 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 "quiche/quic/core/congestion_control/bbr2_drain.h"
+
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+Bbr2Mode Bbr2DrainMode::OnCongestionEvent(
+    QuicByteCount /*prior_in_flight*/,
+    QuicTime /*event_time*/,
+    const AckedPacketVector& /*acked_packets*/,
+    const LostPacketVector& /*lost_packets*/,
+    const Bbr2CongestionEvent& congestion_event) {
+  model_->set_pacing_gain(Params().drain_pacing_gain);
+
+  // Only STARTUP can transition to DRAIN, both of them use the same cwnd gain.
+  QUICHE_DCHECK_EQ(model_->cwnd_gain(), Params().drain_cwnd_gain);
+  model_->set_cwnd_gain(Params().drain_cwnd_gain);
+
+  QuicByteCount drain_target = DrainTarget();
+  if (congestion_event.bytes_in_flight <= drain_target) {
+    QUIC_DVLOG(3) << sender_ << " Exiting DRAIN. bytes_in_flight:"
+                  << congestion_event.bytes_in_flight
+                  << ", bdp:" << model_->BDP()
+                  << ", drain_target:" << drain_target << "  @ "
+                  << congestion_event.event_time;
+    return Bbr2Mode::PROBE_BW;
+  }
+
+  QUIC_DVLOG(3) << sender_ << " Staying in DRAIN. bytes_in_flight:"
+                << congestion_event.bytes_in_flight << ", bdp:" << model_->BDP()
+                << ", drain_target:" << drain_target << "  @ "
+                << congestion_event.event_time;
+  return Bbr2Mode::DRAIN;
+}
+
+QuicByteCount Bbr2DrainMode::DrainTarget() const {
+  QuicByteCount bdp = model_->BDP();
+  return std::max<QuicByteCount>(bdp, sender_->GetMinimumCongestionWindow());
+}
+
+Bbr2DrainMode::DebugState Bbr2DrainMode::ExportDebugState() const {
+  DebugState s;
+  s.drain_target = DrainTarget();
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2DrainMode::DebugState& state) {
+  os << "[DRAIN] drain_target: " << state.drain_target << "\n";
+  return os;
+}
+
+const Bbr2Params& Bbr2DrainMode::Params() const {
+  return sender_->Params();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_drain.h b/quiche/quic/core/congestion_control/bbr2_drain.h
new file mode 100644
index 0000000..418035c
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_drain.h
@@ -0,0 +1,61 @@
+// Copyright 2019 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_CONGESTION_CONTROL_BBR2_DRAIN_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2DrainMode final : public Bbr2ModeBase {
+ public:
+  using Bbr2ModeBase::Bbr2ModeBase;
+
+  void Enter(QuicTime /*now*/,
+             const Bbr2CongestionEvent* /*congestion_event*/) override {}
+  void Leave(QuicTime /*now*/,
+             const Bbr2CongestionEvent* /*congestion_event*/) override {}
+
+  Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) override;
+
+  Limits<QuicByteCount> GetCwndLimits() const override {
+    return NoGreaterThan(model_->inflight_lo());
+  }
+
+  bool IsProbingForBandwidth() const override { return false; }
+
+  Bbr2Mode OnExitQuiescence(QuicTime /*now*/,
+                            QuicTime /*quiescence_start_time*/) override {
+    return Bbr2Mode::DRAIN;
+  }
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    QuicByteCount drain_target;
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  const Bbr2Params& Params() const;
+
+  QuicByteCount DrainTarget() const;
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2DrainMode::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_misc.cc b/quiche/quic/core/congestion_control/bbr2_misc.cc
new file mode 100644
index 0000000..a912d5a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_misc.cc
@@ -0,0 +1,454 @@
+// Copyright 2019 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 "quiche/quic/core/congestion_control/bbr2_misc.h"
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+RoundTripCounter::RoundTripCounter() : round_trip_count_(0) {}
+
+void RoundTripCounter::OnPacketSent(QuicPacketNumber packet_number) {
+  QUICHE_DCHECK(!last_sent_packet_.IsInitialized() ||
+                last_sent_packet_ < packet_number);
+  last_sent_packet_ = packet_number;
+}
+
+bool RoundTripCounter::OnPacketsAcked(QuicPacketNumber last_acked_packet) {
+  if (!end_of_round_trip_.IsInitialized() ||
+      last_acked_packet > end_of_round_trip_) {
+    round_trip_count_++;
+    end_of_round_trip_ = last_sent_packet_;
+    return true;
+  }
+  return false;
+}
+
+void RoundTripCounter::RestartRound() {
+  end_of_round_trip_ = last_sent_packet_;
+}
+
+MinRttFilter::MinRttFilter(QuicTime::Delta initial_min_rtt,
+                           QuicTime initial_min_rtt_timestamp)
+    : min_rtt_(initial_min_rtt),
+      min_rtt_timestamp_(initial_min_rtt_timestamp) {}
+
+void MinRttFilter::Update(QuicTime::Delta sample_rtt, QuicTime now) {
+  if (sample_rtt < min_rtt_ || min_rtt_timestamp_ == QuicTime::Zero()) {
+    min_rtt_ = sample_rtt;
+    min_rtt_timestamp_ = now;
+  }
+}
+
+void MinRttFilter::ForceUpdate(QuicTime::Delta sample_rtt, QuicTime now) {
+  min_rtt_ = sample_rtt;
+  min_rtt_timestamp_ = now;
+}
+
+Bbr2NetworkModel::Bbr2NetworkModel(const Bbr2Params* params,
+                                   QuicTime::Delta initial_rtt,
+                                   QuicTime initial_rtt_timestamp,
+                                   float cwnd_gain,
+                                   float pacing_gain,
+                                   const BandwidthSampler* old_sampler)
+    : params_(params),
+      bandwidth_sampler_([](QuicRoundTripCount max_height_tracker_window_length,
+                            const BandwidthSampler* old_sampler) {
+        if (old_sampler != nullptr) {
+          return BandwidthSampler(*old_sampler);
+        }
+        return BandwidthSampler(/*unacked_packet_map=*/nullptr,
+                                max_height_tracker_window_length);
+      }(params->initial_max_ack_height_filter_window, old_sampler)),
+      min_rtt_filter_(initial_rtt, initial_rtt_timestamp),
+      cwnd_gain_(cwnd_gain),
+      pacing_gain_(pacing_gain) {}
+
+void Bbr2NetworkModel::OnPacketSent(QuicTime sent_time,
+                                    QuicByteCount bytes_in_flight,
+                                    QuicPacketNumber packet_number,
+                                    QuicByteCount bytes,
+                                    HasRetransmittableData is_retransmittable) {
+  round_trip_counter_.OnPacketSent(packet_number);
+
+  bandwidth_sampler_.OnPacketSent(sent_time, packet_number, bytes,
+                                  bytes_in_flight, is_retransmittable);
+}
+
+void Bbr2NetworkModel::OnCongestionEventStart(
+    QuicTime event_time,
+    const AckedPacketVector& acked_packets,
+    const LostPacketVector& lost_packets,
+    Bbr2CongestionEvent* congestion_event) {
+  const QuicByteCount prior_bytes_acked = total_bytes_acked();
+  const QuicByteCount prior_bytes_lost = total_bytes_lost();
+
+  congestion_event->event_time = event_time;
+  congestion_event->end_of_round_trip =
+      acked_packets.empty() ? false
+                            : round_trip_counter_.OnPacketsAcked(
+                                  acked_packets.rbegin()->packet_number);
+
+  BandwidthSamplerInterface::CongestionEventSample sample =
+      bandwidth_sampler_.OnCongestionEvent(event_time, acked_packets,
+                                           lost_packets, MaxBandwidth(),
+                                           bandwidth_lo(), RoundTripCount());
+
+  if (sample.extra_acked == 0) {
+    cwnd_limited_before_aggregation_epoch_ =
+        congestion_event->prior_bytes_in_flight >= congestion_event->prior_cwnd;
+  }
+
+  if (sample.last_packet_send_state.is_valid) {
+    congestion_event->last_packet_send_state = sample.last_packet_send_state;
+  }
+
+  // Avoid updating |max_bandwidth_filter_| if a) this is a loss-only event, or
+  // b) all packets in |acked_packets| did not generate valid samples. (e.g. ack
+  // of ack-only packets). In both cases, total_bytes_acked() will not change.
+  if (prior_bytes_acked != total_bytes_acked()) {
+    QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
+        << total_bytes_acked() - prior_bytes_acked << " bytes from "
+        << acked_packets.size()
+        << " packets have been acked, but sample_max_bandwidth is zero.";
+    congestion_event->sample_max_bandwidth = sample.sample_max_bandwidth;
+    if (!sample.sample_is_app_limited ||
+        sample.sample_max_bandwidth > MaxBandwidth()) {
+      max_bandwidth_filter_.Update(congestion_event->sample_max_bandwidth);
+    }
+  }
+
+  if (!sample.sample_rtt.IsInfinite()) {
+    congestion_event->sample_min_rtt = sample.sample_rtt;
+    min_rtt_filter_.Update(congestion_event->sample_min_rtt, event_time);
+  }
+
+  congestion_event->bytes_acked = total_bytes_acked() - prior_bytes_acked;
+  congestion_event->bytes_lost = total_bytes_lost() - prior_bytes_lost;
+
+  if (congestion_event->prior_bytes_in_flight >=
+      congestion_event->bytes_acked + congestion_event->bytes_lost) {
+    congestion_event->bytes_in_flight =
+        congestion_event->prior_bytes_in_flight -
+        congestion_event->bytes_acked - congestion_event->bytes_lost;
+  } else {
+    QUIC_LOG_FIRST_N(ERROR, 1)
+        << "prior_bytes_in_flight:" << congestion_event->prior_bytes_in_flight
+        << " is smaller than the sum of bytes_acked:"
+        << congestion_event->bytes_acked
+        << " and bytes_lost:" << congestion_event->bytes_lost;
+    congestion_event->bytes_in_flight = 0;
+  }
+
+  if (congestion_event->bytes_lost > 0) {
+    bytes_lost_in_round_ += congestion_event->bytes_lost;
+    loss_events_in_round_++;
+  }
+
+  if (congestion_event->bytes_acked > 0 &&
+      congestion_event->last_packet_send_state.is_valid &&
+      total_bytes_acked() >
+          congestion_event->last_packet_send_state.total_bytes_acked) {
+    QuicByteCount bytes_delivered =
+        total_bytes_acked() -
+        congestion_event->last_packet_send_state.total_bytes_acked;
+    max_bytes_delivered_in_round_ =
+        std::max(max_bytes_delivered_in_round_, bytes_delivered);
+    // TODO(ianswett) Consider treating any bytes lost as decreasing inflight,
+    // because it's a sign of overutilization, not underutilization.
+    if (min_bytes_in_flight_in_round_ == 0 ||
+        congestion_event->bytes_in_flight < min_bytes_in_flight_in_round_) {
+      min_bytes_in_flight_in_round_ = congestion_event->bytes_in_flight;
+    }
+  }
+
+  // |bandwidth_latest_| and |inflight_latest_| only increased within a round.
+  if (sample.sample_max_bandwidth > bandwidth_latest_) {
+    bandwidth_latest_ = sample.sample_max_bandwidth;
+  }
+
+  if (sample.sample_max_inflight > inflight_latest_) {
+    inflight_latest_ = sample.sample_max_inflight;
+  }
+
+  // Adapt lower bounds(bandwidth_lo and inflight_lo).
+  AdaptLowerBounds(*congestion_event);
+
+  if (!congestion_event->end_of_round_trip) {
+    return;
+  }
+
+  if (!sample.sample_max_bandwidth.IsZero()) {
+    bandwidth_latest_ = sample.sample_max_bandwidth;
+  }
+
+  if (sample.sample_max_inflight > 0) {
+    inflight_latest_ = sample.sample_max_inflight;
+  }
+}
+
+void Bbr2NetworkModel::AdaptLowerBounds(
+    const Bbr2CongestionEvent& congestion_event) {
+  if (Params().bw_lo_mode_ == Bbr2Params::DEFAULT) {
+    if (!congestion_event.end_of_round_trip ||
+        congestion_event.is_probing_for_bandwidth) {
+      return;
+    }
+
+    if (bytes_lost_in_round_ > 0) {
+      if (bandwidth_lo_.IsInfinite()) {
+        bandwidth_lo_ = MaxBandwidth();
+      }
+      bandwidth_lo_ =
+          std::max(bandwidth_latest_, bandwidth_lo_ * (1.0 - Params().beta));
+      QUIC_DVLOG(3) << "bandwidth_lo_ updated to " << bandwidth_lo_
+                    << ", bandwidth_latest_ is " << bandwidth_latest_;
+
+      if (Params().ignore_inflight_lo) {
+        return;
+      }
+      if (inflight_lo_ == inflight_lo_default()) {
+        inflight_lo_ = congestion_event.prior_cwnd;
+      }
+      inflight_lo_ = std::max<QuicByteCount>(
+          inflight_latest_, inflight_lo_ * (1.0 - Params().beta));
+    }
+    return;
+  }
+
+  // Params().bw_lo_mode_ != Bbr2Params::DEFAULT
+  if (congestion_event.bytes_lost == 0) {
+    return;
+  }
+  // Ignore losses from packets sent when probing for more bandwidth in
+  // STARTUP or PROBE_UP when they're lost in DRAIN or PROBE_DOWN.
+  if (pacing_gain_ < 1) {
+    return;
+  }
+  // Decrease bandwidth_lo whenever there is loss.
+  // Set bandwidth_lo_ if it is not yet set.
+  if (bandwidth_lo_.IsInfinite()) {
+    bandwidth_lo_ = MaxBandwidth();
+  }
+  // Save bandwidth_lo_ if it hasn't already been saved.
+  if (prior_bandwidth_lo_.IsZero()) {
+    prior_bandwidth_lo_ = bandwidth_lo_;
+  }
+  switch (Params().bw_lo_mode_) {
+    case Bbr2Params::MIN_RTT_REDUCTION:
+      bandwidth_lo_ =
+          bandwidth_lo_ - QuicBandwidth::FromBytesAndTimeDelta(
+                              congestion_event.bytes_lost, MinRtt());
+      break;
+    case Bbr2Params::INFLIGHT_REDUCTION: {
+      // Use a max of BDP and inflight to avoid starving app-limited flows.
+      const QuicByteCount effective_inflight =
+          std::max(BDP(), congestion_event.prior_bytes_in_flight);
+      // This could use bytes_lost_in_round if the bandwidth_lo_ was saved
+      // when entering 'recovery', but this BBRv2 implementation doesn't have
+      // recovery defined.
+      bandwidth_lo_ =
+          bandwidth_lo_ * ((effective_inflight - congestion_event.bytes_lost) /
+                           static_cast<double>(effective_inflight));
+      break;
+    }
+    case Bbr2Params::CWND_REDUCTION:
+      bandwidth_lo_ =
+          bandwidth_lo_ *
+          ((congestion_event.prior_cwnd - congestion_event.bytes_lost) /
+           static_cast<double>(congestion_event.prior_cwnd));
+      break;
+    case Bbr2Params::DEFAULT:
+      QUIC_BUG(quic_bug_10466_1) << "Unreachable case DEFAULT.";
+  }
+  QuicBandwidth last_bandwidth = bandwidth_latest_;
+  // sample_max_bandwidth will be Zero() if the loss is triggered by a timer
+  // expiring.  Ideally we'd use the most recent bandwidth sample,
+  // but bandwidth_latest is safer than Zero().
+  if (!congestion_event.sample_max_bandwidth.IsZero()) {
+    // bandwidth_latest_ is the max bandwidth for the round, but to allow
+    // fast, conservation style response to loss, use the last sample.
+    last_bandwidth = congestion_event.sample_max_bandwidth;
+  }
+  if (pacing_gain_ > Params().startup_full_bw_threshold) {
+    // In STARTUP, pacing_gain_ is applied to bandwidth_lo_ in
+    // UpdatePacingRate, so this backs that multiplication out to allow the
+    // pacing rate to decrease, but not below
+    // last_bandwidth * startup_full_bw_threshold.
+    // TODO(ianswett): Consider altering pacing_gain_ when in STARTUP instead.
+    bandwidth_lo_ = std::max(
+        bandwidth_lo_,
+        last_bandwidth * (Params().startup_full_bw_threshold / pacing_gain_));
+  } else {
+    // Ensure bandwidth_lo isn't lower than last_bandwidth.
+    bandwidth_lo_ = std::max(bandwidth_lo_, last_bandwidth);
+  }
+  // If it's the end of the round, ensure bandwidth_lo doesn't decrease more
+  // than beta.
+  if (congestion_event.end_of_round_trip) {
+    bandwidth_lo_ =
+        std::max(bandwidth_lo_, prior_bandwidth_lo_ * (1.0 - Params().beta));
+    prior_bandwidth_lo_ = QuicBandwidth::Zero();
+  }
+  // These modes ignore inflight_lo as well.
+}
+
+void Bbr2NetworkModel::OnCongestionEventFinish(
+    QuicPacketNumber least_unacked_packet,
+    const Bbr2CongestionEvent& congestion_event) {
+  if (congestion_event.end_of_round_trip) {
+    OnNewRound();
+  }
+
+  bandwidth_sampler_.RemoveObsoletePackets(least_unacked_packet);
+}
+
+void Bbr2NetworkModel::UpdateNetworkParameters(QuicTime::Delta rtt) {
+  if (!rtt.IsZero()) {
+    min_rtt_filter_.Update(rtt, MinRttTimestamp());
+  }
+}
+
+bool Bbr2NetworkModel::MaybeExpireMinRtt(
+    const Bbr2CongestionEvent& congestion_event) {
+  if (congestion_event.event_time <
+      (MinRttTimestamp() + Params().probe_rtt_period)) {
+    return false;
+  }
+  if (congestion_event.sample_min_rtt.IsInfinite()) {
+    return false;
+  }
+  QUIC_DVLOG(3) << "Replacing expired min rtt of " << min_rtt_filter_.Get()
+                << " by " << congestion_event.sample_min_rtt << "  @ "
+                << congestion_event.event_time;
+  min_rtt_filter_.ForceUpdate(congestion_event.sample_min_rtt,
+                              congestion_event.event_time);
+  return true;
+}
+
+bool Bbr2NetworkModel::IsInflightTooHigh(
+    const Bbr2CongestionEvent& congestion_event,
+    int64_t max_loss_events) const {
+  const SendTimeState& send_state = congestion_event.last_packet_send_state;
+  if (!send_state.is_valid) {
+    // Not enough information.
+    return false;
+  }
+
+  if (loss_events_in_round() < max_loss_events) {
+    return false;
+  }
+
+  const QuicByteCount inflight_at_send = BytesInFlight(send_state);
+  // TODO(wub): Consider total_bytes_lost() - send_state.total_bytes_lost, which
+  // is the total bytes lost when the largest numbered packet was inflight.
+  // bytes_lost_in_round_, OTOH, is the total bytes lost in the "current" round.
+  const QuicByteCount bytes_lost_in_round = bytes_lost_in_round_;
+
+  QUIC_DVLOG(3) << "IsInflightTooHigh: loss_events_in_round:"
+                << loss_events_in_round()
+
+                << " bytes_lost_in_round:" << bytes_lost_in_round
+                << ", lost_in_round_threshold:"
+                << inflight_at_send * Params().loss_threshold;
+
+  if (inflight_at_send > 0 && bytes_lost_in_round > 0) {
+    QuicByteCount lost_in_round_threshold =
+        inflight_at_send * Params().loss_threshold;
+    if (bytes_lost_in_round > lost_in_round_threshold) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void Bbr2NetworkModel::RestartRoundEarly() {
+  OnNewRound();
+  round_trip_counter_.RestartRound();
+}
+
+void Bbr2NetworkModel::OnNewRound() {
+  bytes_lost_in_round_ = 0;
+  loss_events_in_round_ = 0;
+  max_bytes_delivered_in_round_ = 0;
+  min_bytes_in_flight_in_round_ = 0;
+}
+
+void Bbr2NetworkModel::cap_inflight_lo(QuicByteCount cap) {
+  if (Params().ignore_inflight_lo) {
+    return;
+  }
+  if (inflight_lo_ != inflight_lo_default() && inflight_lo_ > cap) {
+    inflight_lo_ = cap;
+  }
+}
+
+QuicByteCount Bbr2NetworkModel::inflight_hi_with_headroom() const {
+  QuicByteCount headroom = inflight_hi_ * Params().inflight_hi_headroom;
+
+  return inflight_hi_ > headroom ? inflight_hi_ - headroom : 0;
+}
+
+bool Bbr2NetworkModel::HasBandwidthGrowth(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK(!full_bandwidth_reached_);
+  QUICHE_DCHECK(congestion_event.end_of_round_trip);
+
+  QuicBandwidth threshold =
+      full_bandwidth_baseline_ * Params().startup_full_bw_threshold;
+
+  if (MaxBandwidth() >= threshold) {
+    QUIC_DVLOG(3) << " CheckBandwidthGrowth at end of round. max_bandwidth:"
+                  << MaxBandwidth() << ", threshold:" << threshold
+                  << " (Still growing)  @ " << congestion_event.event_time;
+    full_bandwidth_baseline_ = MaxBandwidth();
+    rounds_without_bandwidth_growth_ = 0;
+    return true;
+  }
+  ++rounds_without_bandwidth_growth_;
+
+  // full_bandwidth_reached is only set to true when not app-limited, except
+  // when exit_startup_on_persistent_queue is true.
+  if (rounds_without_bandwidth_growth_ >= Params().startup_full_bw_rounds &&
+      !congestion_event.last_packet_send_state.is_app_limited) {
+    full_bandwidth_reached_ = true;
+  }
+  QUIC_DVLOG(3) << " CheckBandwidthGrowth at end of round. max_bandwidth:"
+                << MaxBandwidth() << ", threshold:" << threshold
+                << " rounds_without_growth:" << rounds_without_bandwidth_growth_
+                << " full_bw_reached:" << full_bandwidth_reached_ << "  @ "
+                << congestion_event.event_time;
+
+  return false;
+}
+
+bool Bbr2NetworkModel::CheckPersistentQueue(
+    const Bbr2CongestionEvent& congestion_event, float bdp_gain) {
+  QUICHE_DCHECK(congestion_event.end_of_round_trip);
+  QuicByteCount target = bdp_gain * BDP();
+  if (bdp_gain >= 2) {
+    // Use a more conservative threshold for STARTUP because CWND gain is 2.
+    if (target <= QueueingThresholdExtraBytes()) {
+      return false;
+    }
+    target -= QueueingThresholdExtraBytes();
+  } else {
+    target += QueueingThresholdExtraBytes();
+  }
+  if (min_bytes_in_flight_in_round_ > target) {
+    full_bandwidth_reached_ = true;
+    return true;
+  }
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_misc.h b/quiche/quic/core/congestion_control/bbr2_misc.h
new file mode 100644
index 0000000..a7efaed
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_misc.h
@@ -0,0 +1,674 @@
+// Copyright 2019 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_CONGESTION_CONTROL_BBR2_MISC_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
+
+#include <algorithm>
+#include <limits>
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/windowed_filter.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+template <typename T>
+class QUIC_EXPORT_PRIVATE Limits {
+ public:
+  Limits(T min, T max) : min_(min), max_(max) {}
+
+  // If [min, max] is an empty range, i.e. min > max, this function returns max,
+  // because typically a value larger than max means "risky".
+  T ApplyLimits(T raw_value) const {
+    return std::min(max_, std::max(min_, raw_value));
+  }
+
+  T Min() const { return min_; }
+  T Max() const { return max_; }
+
+ private:
+  T min_;
+  T max_;
+};
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline Limits<T> MinMax(T min, T max) {
+  return Limits<T>(min, max);
+}
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline Limits<T> NoLessThan(T min) {
+  return Limits<T>(min, std::numeric_limits<T>::max());
+}
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline Limits<T> NoGreaterThan(T max) {
+  return Limits<T>(std::numeric_limits<T>::min(), max);
+}
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline Limits<T> Unlimited() {
+  return Limits<T>(std::numeric_limits<T>::min(),
+                   std::numeric_limits<T>::max());
+}
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& os,
+                                                    const Limits<T>& limits) {
+  return os << "[" << limits.Min() << ", " << limits.Max() << "]";
+}
+
+// Bbr2Params contains all parameters of a Bbr2Sender.
+struct QUIC_EXPORT_PRIVATE Bbr2Params {
+  Bbr2Params(QuicByteCount cwnd_min, QuicByteCount cwnd_max)
+      : cwnd_limits(cwnd_min, cwnd_max) {}
+
+  /*
+   * STARTUP parameters.
+   */
+
+  // The gain for both CWND and PacingRate at startup.
+  float startup_cwnd_gain = 2.0;
+  // TODO(wub): Maybe change to the newly derived value of 2.773 (4 * ln(2)).
+  float startup_pacing_gain = 2.885;
+
+  // Full bandwidth is declared if the total bandwidth growth is less than
+  // |startup_full_bw_threshold| times in the last |startup_full_bw_rounds|
+  // round trips.
+  float startup_full_bw_threshold = 1.25;
+
+  QuicRoundTripCount startup_full_bw_rounds = 3;
+
+  // The minimum number of loss marking events to exit STARTUP.
+  int64_t startup_full_loss_count =
+      GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count);
+
+  // If true, always exit STARTUP on loss, even if bandwidth exceeds threshold.
+  // If false, exit STARTUP on loss only if bandwidth is below threshold.
+  bool always_exit_startup_on_excess_loss = false;
+
+  // If true, include extra acked during STARTUP and proactively reduce extra
+  // acked when bandwidth increases.
+  bool startup_include_extra_acked = false;
+
+  // If true, exit STARTUP if bytes in flight has not gone below 2 * BDP at
+  // any point in the last round.
+  bool exit_startup_on_persistent_queue = false;
+
+  /*
+   * DRAIN parameters.
+   */
+  float drain_cwnd_gain = 2.0;
+  float drain_pacing_gain = 1.0 / 2.885;
+
+  /*
+   * PROBE_BW parameters.
+   */
+  // Max amount of randomness to inject in round counting for Reno-coexistence.
+  QuicRoundTripCount probe_bw_max_probe_rand_rounds = 2;
+
+  // Max number of rounds before probing for Reno-coexistence.
+  uint32_t probe_bw_probe_max_rounds = 63;
+
+  // Multiplier to get Reno-style probe epoch duration as: k * BDP round trips.
+  // If zero, disables Reno-style BDP-scaled coexistence mechanism.
+  float probe_bw_probe_reno_gain = 1.0;
+
+  // Minimum duration for BBR-native probes.
+  QuicTime::Delta probe_bw_probe_base_duration =
+      QuicTime::Delta::FromMilliseconds(
+          GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_base_duration_ms));
+
+  // The upper bound of the random amount of BBR-native probes.
+  QuicTime::Delta probe_bw_probe_max_rand_duration =
+      QuicTime::Delta::FromMilliseconds(
+          GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_max_rand_duration_ms));
+
+  // The minimum number of loss marking events to exit the PROBE_UP phase.
+  int64_t probe_bw_full_loss_count =
+      GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_full_loss_count);
+
+  // Multiplier to get target inflight (as multiple of BDP) for PROBE_UP phase.
+  float probe_bw_probe_inflight_gain = 1.25;
+
+  // When attempting to grow inflight_hi in PROBE_UP, check whether we are cwnd
+  // limited before the current aggregation epoch, instead of before the current
+  // ack event.
+  bool probe_bw_check_cwnd_limited_before_aggregation_epoch = false;
+
+  // Pacing gains.
+  float probe_bw_probe_up_pacing_gain = 1.25;
+  float probe_bw_probe_down_pacing_gain = 0.75;
+  float probe_bw_default_pacing_gain = 1.0;
+
+  float probe_bw_cwnd_gain = 2.0;
+
+  /*
+   * PROBE_UP parameters.
+   */
+  bool probe_up_includes_acks_after_cwnd_limited = false;
+  bool probe_up_dont_exit_if_no_queue_ = false;
+  bool probe_up_ignore_inflight_hi = false;
+
+  /*
+   * PROBE_RTT parameters.
+   */
+  float probe_rtt_inflight_target_bdp_fraction = 0.5;
+  QuicTime::Delta probe_rtt_period = QuicTime::Delta::FromMilliseconds(
+      GetQuicFlag(FLAGS_quic_bbr2_default_probe_rtt_period_ms));
+  QuicTime::Delta probe_rtt_duration = QuicTime::Delta::FromMilliseconds(200);
+
+  /*
+   * Parameters used by multiple modes.
+   */
+
+  // The initial value of the max ack height filter's window length.
+  QuicRoundTripCount initial_max_ack_height_filter_window =
+      GetQuicFlag(FLAGS_quic_bbr2_default_initial_ack_height_filter_window);
+
+  // Fraction of unutilized headroom to try to leave in path upon high loss.
+  float inflight_hi_headroom =
+      GetQuicFlag(FLAGS_quic_bbr2_default_inflight_hi_headroom);
+
+  // Estimate startup/bw probing has gone too far if loss rate exceeds this.
+  float loss_threshold = GetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold);
+
+  // A common factor for multiplicative decreases. Used for adjusting
+  // bandwidth_lo, inflight_lo and inflight_hi upon losses.
+  float beta = 0.3;
+
+  Limits<QuicByteCount> cwnd_limits;
+
+  /*
+   * Experimental flags from QuicConfig.
+   */
+
+  // Can be disabled by connection option 'B2NA'.
+  bool add_ack_height_to_queueing_threshold = true;
+
+  // Can be disabled by connection option 'B2RP'.
+  bool avoid_unnecessary_probe_rtt = true;
+
+  // Can be enabled by connection option 'B2LO'.
+  bool ignore_inflight_lo = false;
+
+  // Can be enabled by connection option 'B2H2'.
+  bool limit_inflight_hi_by_max_delivered = false;
+
+  // Can be disabled by connection option 'B2SL'.
+  bool startup_loss_exit_use_max_delivered_for_inflight_hi = true;
+
+  // Can be enabled by connection option 'B2DL'.
+  bool use_bytes_delivered_for_inflight_hi = false;
+
+  // Can be disabled by connection option 'B2RC'.
+  bool enable_reno_coexistence = true;
+
+  // For experimentation to improve fast convergence upon loss.
+  enum QuicBandwidthLoMode : uint8_t {
+    DEFAULT = 0,
+    MIN_RTT_REDUCTION = 1,   // 'BBQ7'
+    INFLIGHT_REDUCTION = 2,  // 'BBQ8'
+    CWND_REDUCTION = 3,      // 'BBQ9'
+  };
+
+  // Different modes change bandwidth_lo_ differently upon loss.
+  QuicBandwidthLoMode bw_lo_mode_ = QuicBandwidthLoMode::DEFAULT;
+
+  // Set the pacing gain to 25% larger than the recent BW increase in STARTUP.
+  bool decrease_startup_pacing_at_end_of_round = false;
+};
+
+class QUIC_EXPORT_PRIVATE RoundTripCounter {
+ public:
+  RoundTripCounter();
+
+  QuicRoundTripCount Count() const { return round_trip_count_; }
+
+  QuicPacketNumber last_sent_packet() const { return last_sent_packet_; }
+
+  // Must be called in ascending packet number order.
+  void OnPacketSent(QuicPacketNumber packet_number);
+
+  // Return whether a round trip has just completed.
+  bool OnPacketsAcked(QuicPacketNumber last_acked_packet);
+
+  void RestartRound();
+
+ private:
+  QuicRoundTripCount round_trip_count_;
+  QuicPacketNumber last_sent_packet_;
+  // The last sent packet number of the current round trip.
+  QuicPacketNumber end_of_round_trip_;
+};
+
+class QUIC_EXPORT_PRIVATE MinRttFilter {
+ public:
+  MinRttFilter(QuicTime::Delta initial_min_rtt,
+               QuicTime initial_min_rtt_timestamp);
+
+  void Update(QuicTime::Delta sample_rtt, QuicTime now);
+
+  void ForceUpdate(QuicTime::Delta sample_rtt, QuicTime now);
+
+  QuicTime::Delta Get() const { return min_rtt_; }
+
+  QuicTime GetTimestamp() const { return min_rtt_timestamp_; }
+
+ private:
+  QuicTime::Delta min_rtt_;
+  // Time when the current value of |min_rtt_| was assigned.
+  QuicTime min_rtt_timestamp_;
+};
+
+class QUIC_EXPORT_PRIVATE Bbr2MaxBandwidthFilter {
+ public:
+  void Update(QuicBandwidth sample) {
+    max_bandwidth_[1] = std::max(sample, max_bandwidth_[1]);
+  }
+
+  void Advance() {
+    if (max_bandwidth_[1].IsZero()) {
+      return;
+    }
+
+    max_bandwidth_[0] = max_bandwidth_[1];
+    max_bandwidth_[1] = QuicBandwidth::Zero();
+  }
+
+  QuicBandwidth Get() const {
+    return std::max(max_bandwidth_[0], max_bandwidth_[1]);
+  }
+
+ private:
+  QuicBandwidth max_bandwidth_[2] = {QuicBandwidth::Zero(),
+                                     QuicBandwidth::Zero()};
+};
+
+// Information that are meaningful only when Bbr2Sender::OnCongestionEvent is
+// running.
+struct QUIC_EXPORT_PRIVATE Bbr2CongestionEvent {
+  QuicTime event_time = QuicTime::Zero();
+
+  // The congestion window prior to the processing of the ack/loss events.
+  QuicByteCount prior_cwnd;
+
+  // Total bytes inflight before the processing of the ack/loss events.
+  QuicByteCount prior_bytes_in_flight = 0;
+
+  // Total bytes inflight after the processing of the ack/loss events.
+  QuicByteCount bytes_in_flight = 0;
+
+  // Total bytes acked from acks in this event.
+  QuicByteCount bytes_acked = 0;
+
+  // Total bytes lost from losses in this event.
+  QuicByteCount bytes_lost = 0;
+
+  // Whether acked_packets indicates the end of a round trip.
+  bool end_of_round_trip = false;
+
+  // When the event happened, whether the sender is probing for bandwidth.
+  bool is_probing_for_bandwidth = false;
+
+  // Minimum rtt of all bandwidth samples from acked_packets.
+  // QuicTime::Delta::Infinite() if acked_packets is empty.
+  QuicTime::Delta sample_min_rtt = QuicTime::Delta::Infinite();
+
+  // Maximum bandwidth of all bandwidth samples from acked_packets.
+  // This sample may be app-limited, and will be Zero() if there are no newly
+  // acknowledged inflight packets.
+  QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero();
+
+  // The send state of the largest packet in acked_packets, unless it is empty.
+  // If acked_packets is empty, it's the send state of the largest packet in
+  // lost_packets.
+  SendTimeState last_packet_send_state;
+};
+
+// Bbr2NetworkModel takes low level congestion signals(packets sent/acked/lost)
+// as input and produces BBRv2 model parameters like inflight_(hi|lo),
+// bandwidth_(hi|lo), bandwidth and rtt estimates, etc.
+class QUIC_EXPORT_PRIVATE Bbr2NetworkModel {
+ public:
+  Bbr2NetworkModel(const Bbr2Params* params,
+                   QuicTime::Delta initial_rtt,
+                   QuicTime initial_rtt_timestamp,
+                   float cwnd_gain,
+                   float pacing_gain,
+                   const BandwidthSampler* old_sampler);
+
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData is_retransmittable);
+
+  void OnCongestionEventStart(QuicTime event_time,
+                              const AckedPacketVector& acked_packets,
+                              const LostPacketVector& lost_packets,
+                              Bbr2CongestionEvent* congestion_event);
+
+  void OnCongestionEventFinish(QuicPacketNumber least_unacked_packet,
+                               const Bbr2CongestionEvent& congestion_event);
+
+  // Update the model without a congestion event.
+  // Min rtt is updated if |rtt| is non-zero and smaller than existing min rtt.
+  void UpdateNetworkParameters(QuicTime::Delta rtt);
+
+  // Update inflight/bandwidth short-term lower bounds.
+  void AdaptLowerBounds(const Bbr2CongestionEvent& congestion_event);
+
+  // Restart the current round trip as if it is starting now.
+  void RestartRoundEarly();
+
+  void AdvanceMaxBandwidthFilter() { max_bandwidth_filter_.Advance(); }
+
+  void OnApplicationLimited() { bandwidth_sampler_.OnAppLimited(); }
+
+  // Calculates BDP using the current MaxBandwidth.
+  QuicByteCount BDP() const { return BDP(MaxBandwidth()); }
+
+  QuicByteCount BDP(QuicBandwidth bandwidth) const {
+    return bandwidth * MinRtt();
+  }
+
+  QuicByteCount BDP(QuicBandwidth bandwidth, float gain) const {
+    return bandwidth * MinRtt() * gain;
+  }
+
+  QuicTime::Delta MinRtt() const { return min_rtt_filter_.Get(); }
+
+  QuicTime MinRttTimestamp() const { return min_rtt_filter_.GetTimestamp(); }
+
+  // TODO(wub): If we do this too frequently, we can potentailly postpone
+  // PROBE_RTT indefinitely. Observe how it works in production and improve it.
+  void PostponeMinRttTimestamp(QuicTime::Delta duration) {
+    min_rtt_filter_.ForceUpdate(MinRtt(), MinRttTimestamp() + duration);
+  }
+
+  QuicBandwidth MaxBandwidth() const { return max_bandwidth_filter_.Get(); }
+
+  QuicByteCount MaxAckHeight() const {
+    return bandwidth_sampler_.max_ack_height();
+  }
+
+  // 2 packets.  Used to indicate the typical number of bytes ACKed at once.
+  QuicByteCount QueueingThresholdExtraBytes() const {
+    return 2 * kDefaultTCPMSS;
+  }
+
+  bool cwnd_limited_before_aggregation_epoch() const {
+    return cwnd_limited_before_aggregation_epoch_;
+  }
+
+  void EnableOverestimateAvoidance() {
+    bandwidth_sampler_.EnableOverestimateAvoidance();
+  }
+
+  bool IsBandwidthOverestimateAvoidanceEnabled() const {
+    return bandwidth_sampler_.IsOverestimateAvoidanceEnabled();
+  }
+
+  void OnPacketNeutered(QuicPacketNumber packet_number) {
+    bandwidth_sampler_.OnPacketNeutered(packet_number);
+  }
+
+  uint64_t num_ack_aggregation_epochs() const {
+    return bandwidth_sampler_.num_ack_aggregation_epochs();
+  }
+
+  void SetStartNewAggregationEpochAfterFullRound(bool value) {
+    bandwidth_sampler_.SetStartNewAggregationEpochAfterFullRound(value);
+  }
+
+  void SetLimitMaxAckHeightTrackerBySendRate(bool value) {
+    bandwidth_sampler_.SetLimitMaxAckHeightTrackerBySendRate(value);
+  }
+
+  void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount value) {
+    bandwidth_sampler_.SetMaxAckHeightTrackerWindowLength(value);
+  }
+
+  void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
+    bandwidth_sampler_.SetReduceExtraAckedOnBandwidthIncrease(value);
+  }
+
+  bool MaybeExpireMinRtt(const Bbr2CongestionEvent& congestion_event);
+
+  QuicBandwidth BandwidthEstimate() const {
+    return std::min(MaxBandwidth(), bandwidth_lo_);
+  }
+
+  QuicRoundTripCount RoundTripCount() const {
+    return round_trip_counter_.Count();
+  }
+
+  // Return true if the number of loss events exceeds max_loss_events and
+  // fraction of bytes lost exceed the loss threshold.
+  bool IsInflightTooHigh(const Bbr2CongestionEvent& congestion_event,
+                         int64_t max_loss_events) const;
+
+  // Check bandwidth growth in the past round. Must be called at the end of a
+  // round. Returns true if there was sufficient bandwidth growth and false
+  // otherwise.  If it's been too many rounds without growth, also sets
+  // |full_bandwidth_reached_| to true.
+  bool HasBandwidthGrowth(const Bbr2CongestionEvent& congestion_event);
+
+  // Returns true if the minimum bytes in flight during the round is greater
+  // than the BDP * |bdp_gain|.
+  bool CheckPersistentQueue(const Bbr2CongestionEvent& congestion_event,
+                            float bdp_gain);
+
+  QuicPacketNumber last_sent_packet() const {
+    return round_trip_counter_.last_sent_packet();
+  }
+
+  QuicByteCount total_bytes_acked() const {
+    return bandwidth_sampler_.total_bytes_acked();
+  }
+
+  QuicByteCount total_bytes_lost() const {
+    return bandwidth_sampler_.total_bytes_lost();
+  }
+
+  QuicByteCount total_bytes_sent() const {
+    return bandwidth_sampler_.total_bytes_sent();
+  }
+
+  int64_t loss_events_in_round() const { return loss_events_in_round_; }
+
+  QuicByteCount max_bytes_delivered_in_round() const {
+    return max_bytes_delivered_in_round_;
+  }
+
+  QuicByteCount min_bytes_in_flight_in_round() const {
+    return min_bytes_in_flight_in_round_;
+  }
+
+  QuicPacketNumber end_of_app_limited_phase() const {
+    return bandwidth_sampler_.end_of_app_limited_phase();
+  }
+
+  QuicBandwidth bandwidth_latest() const { return bandwidth_latest_; }
+  QuicBandwidth bandwidth_lo() const { return bandwidth_lo_; }
+  static QuicBandwidth bandwidth_lo_default() {
+    return QuicBandwidth::Infinite();
+  }
+  void clear_bandwidth_lo() { bandwidth_lo_ = bandwidth_lo_default(); }
+
+  QuicByteCount inflight_latest() const { return inflight_latest_; }
+  QuicByteCount inflight_lo() const { return inflight_lo_; }
+  static QuicByteCount inflight_lo_default() {
+    return std::numeric_limits<QuicByteCount>::max();
+  }
+  void clear_inflight_lo() { inflight_lo_ = inflight_lo_default(); }
+  void cap_inflight_lo(QuicByteCount cap);
+
+  QuicByteCount inflight_hi_with_headroom() const;
+  QuicByteCount inflight_hi() const { return inflight_hi_; }
+  static QuicByteCount inflight_hi_default() {
+    return std::numeric_limits<QuicByteCount>::max();
+  }
+  void set_inflight_hi(QuicByteCount inflight_hi) {
+    inflight_hi_ = inflight_hi;
+  }
+
+  float cwnd_gain() const { return cwnd_gain_; }
+  void set_cwnd_gain(float cwnd_gain) { cwnd_gain_ = cwnd_gain; }
+
+  float pacing_gain() const { return pacing_gain_; }
+  void set_pacing_gain(float pacing_gain) { pacing_gain_ = pacing_gain; }
+
+  bool full_bandwidth_reached() const { return full_bandwidth_reached_; }
+  void set_full_bandwidth_reached() { full_bandwidth_reached_ = true; }
+  QuicBandwidth full_bandwidth_baseline() const {
+    return full_bandwidth_baseline_;
+  }
+  QuicRoundTripCount rounds_without_bandwidth_growth() const {
+    return rounds_without_bandwidth_growth_;
+  }
+
+ private:
+  // Called when a new round trip starts.
+  void OnNewRound();
+
+  const Bbr2Params& Params() const { return *params_; }
+  const Bbr2Params* const params_;
+  RoundTripCounter round_trip_counter_;
+
+  // Bandwidth sampler provides BBR with the bandwidth measurements at
+  // individual points.
+  BandwidthSampler bandwidth_sampler_;
+  // The filter that tracks the maximum bandwidth over multiple recent round
+  // trips.
+  Bbr2MaxBandwidthFilter max_bandwidth_filter_;
+  MinRttFilter min_rtt_filter_;
+
+  // Bytes lost in the current round. Updated once per congestion event.
+  QuicByteCount bytes_lost_in_round_ = 0;
+  // Number of loss marking events in the current round.
+  int64_t loss_events_in_round_ = 0;
+
+  // A max of bytes delivered among all congestion events in the current round.
+  // A congestions event's bytes delivered is the total bytes acked between time
+  // Ts and Ta, which is the time when the largest acked packet(within the
+  // congestion event) was sent and acked, respectively.
+  QuicByteCount max_bytes_delivered_in_round_ = 0;
+
+  // The minimum bytes in flight during this round.
+  QuicByteCount min_bytes_in_flight_in_round_ = 0;
+
+  // Max bandwidth in the current round. Updated once per congestion event.
+  QuicBandwidth bandwidth_latest_ = QuicBandwidth::Zero();
+  // Max bandwidth of recent rounds. Updated once per round.
+  QuicBandwidth bandwidth_lo_ = bandwidth_lo_default();
+  // bandwidth_lo_ at the beginning of a round with loss. Only used when the
+  // bw_lo_mode is non-default.
+  QuicBandwidth prior_bandwidth_lo_ = QuicBandwidth::Zero();
+
+  // Max inflight in the current round. Updated once per congestion event.
+  QuicByteCount inflight_latest_ = 0;
+  // Max inflight of recent rounds. Updated once per round.
+  QuicByteCount inflight_lo_ = inflight_lo_default();
+  QuicByteCount inflight_hi_ = inflight_hi_default();
+
+  float cwnd_gain_;
+  float pacing_gain_;
+
+  // Whether we are cwnd limited prior to the start of the current aggregation
+  // epoch.
+  bool cwnd_limited_before_aggregation_epoch_ = false;
+
+  // STARTUP-centric fields which experimentally used by PROBE_UP.
+  bool full_bandwidth_reached_ = false;
+  QuicBandwidth full_bandwidth_baseline_ = QuicBandwidth::Zero();
+  QuicRoundTripCount rounds_without_bandwidth_growth_ = 0;
+};
+
+enum class Bbr2Mode : uint8_t {
+  // Startup phase of the connection.
+  STARTUP,
+  // After achieving the highest possible bandwidth during the startup, lower
+  // the pacing rate in order to drain the queue.
+  DRAIN,
+  // Cruising mode.
+  PROBE_BW,
+  // Temporarily slow down sending in order to empty the buffer and measure
+  // the real minimum RTT.
+  PROBE_RTT,
+};
+
+QUIC_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& os,
+                                                    const Bbr2Mode& mode) {
+  switch (mode) {
+    case Bbr2Mode::STARTUP:
+      return os << "STARTUP";
+    case Bbr2Mode::DRAIN:
+      return os << "DRAIN";
+    case Bbr2Mode::PROBE_BW:
+      return os << "PROBE_BW";
+    case Bbr2Mode::PROBE_RTT:
+      return os << "PROBE_RTT";
+  }
+  return os << "<Invalid Mode>";
+}
+
+// The base class for all BBRv2 modes. A Bbr2Sender is in one mode at a time,
+// this interface is used to implement mode-specific behaviors.
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2ModeBase {
+ public:
+  Bbr2ModeBase(const Bbr2Sender* sender, Bbr2NetworkModel* model)
+      : sender_(sender), model_(model) {}
+
+  virtual ~Bbr2ModeBase() = default;
+
+  // Called when entering/leaving this mode.
+  // congestion_event != nullptr means BBRv2 is switching modes in the context
+  // of a ack and/or loss.
+  virtual void Enter(QuicTime now,
+                     const Bbr2CongestionEvent* congestion_event) = 0;
+  virtual void Leave(QuicTime now,
+                     const Bbr2CongestionEvent* congestion_event) = 0;
+
+  virtual Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) = 0;
+
+  virtual Limits<QuicByteCount> GetCwndLimits() const = 0;
+
+  virtual bool IsProbingForBandwidth() const = 0;
+
+  virtual Bbr2Mode OnExitQuiescence(QuicTime now,
+                                    QuicTime quiescence_start_time) = 0;
+
+ protected:
+  const Bbr2Sender* const sender_;
+  Bbr2NetworkModel* model_;
+};
+
+QUIC_EXPORT_PRIVATE inline QuicByteCount BytesInFlight(
+    const SendTimeState& send_state) {
+  QUICHE_DCHECK(send_state.is_valid);
+  if (send_state.bytes_in_flight != 0) {
+    return send_state.bytes_in_flight;
+  }
+  return send_state.total_bytes_sent - send_state.total_bytes_acked -
+         send_state.total_bytes_lost;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_probe_bw.cc b/quiche/quic/core/congestion_control/bbr2_probe_bw.cc
new file mode 100644
index 0000000..48d98de
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_probe_bw.cc
@@ -0,0 +1,677 @@
+// Copyright 2019 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 "quiche/quic/core/congestion_control/bbr2_probe_bw.h"
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+void Bbr2ProbeBwMode::Enter(QuicTime now,
+                            const Bbr2CongestionEvent* /*congestion_event*/) {
+  if (cycle_.phase == CyclePhase::PROBE_NOT_STARTED) {
+    // First time entering PROBE_BW. Start a new probing cycle.
+    EnterProbeDown(/*probed_too_high=*/false, /*stopped_risky_probe=*/false,
+                   now);
+  } else {
+    // Transitioning from PROBE_RTT to PROBE_BW. Re-enter the last phase before
+    // PROBE_RTT.
+    QUICHE_DCHECK(cycle_.phase == CyclePhase::PROBE_CRUISE ||
+                  cycle_.phase == CyclePhase::PROBE_REFILL);
+    cycle_.cycle_start_time = now;
+    if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
+      EnterProbeCruise(now);
+    } else if (cycle_.phase == CyclePhase::PROBE_REFILL) {
+      EnterProbeRefill(cycle_.probe_up_rounds, now);
+    }
+  }
+}
+
+Bbr2Mode Bbr2ProbeBwMode::OnCongestionEvent(
+    QuicByteCount prior_in_flight, QuicTime event_time,
+    const AckedPacketVector& /*acked_packets*/,
+    const LostPacketVector& /*lost_packets*/,
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_NE(cycle_.phase, CyclePhase::PROBE_NOT_STARTED);
+
+  if (congestion_event.end_of_round_trip) {
+    if (cycle_.cycle_start_time != event_time) {
+      ++cycle_.rounds_since_probe;
+    }
+    if (cycle_.phase_start_time != event_time) {
+      ++cycle_.rounds_in_phase;
+    }
+  }
+
+  bool switch_to_probe_rtt = false;
+
+  if (cycle_.phase == CyclePhase::PROBE_UP) {
+    UpdateProbeUp(prior_in_flight, congestion_event);
+  } else if (cycle_.phase == CyclePhase::PROBE_DOWN) {
+    UpdateProbeDown(prior_in_flight, congestion_event);
+    // Maybe transition to PROBE_RTT at the end of this cycle.
+    if (cycle_.phase != CyclePhase::PROBE_DOWN &&
+        model_->MaybeExpireMinRtt(congestion_event)) {
+      switch_to_probe_rtt = true;
+    }
+  } else if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
+    UpdateProbeCruise(congestion_event);
+  } else if (cycle_.phase == CyclePhase::PROBE_REFILL) {
+    UpdateProbeRefill(congestion_event);
+  }
+
+  // Do not need to set the gains if switching to PROBE_RTT, they will be set
+  // when Bbr2ProbeRttMode::Enter is called.
+  if (!switch_to_probe_rtt) {
+    model_->set_pacing_gain(PacingGainForPhase(cycle_.phase));
+    model_->set_cwnd_gain(Params().probe_bw_cwnd_gain);
+  }
+
+  return switch_to_probe_rtt ? Bbr2Mode::PROBE_RTT : Bbr2Mode::PROBE_BW;
+}
+
+Limits<QuicByteCount> Bbr2ProbeBwMode::GetCwndLimits() const {
+  if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
+    return NoGreaterThan(
+        std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom()));
+  }
+  if (Params().probe_up_ignore_inflight_hi &&
+      cycle_.phase == CyclePhase::PROBE_UP) {
+    // Similar to STARTUP.
+    return NoGreaterThan(model_->inflight_lo());
+  }
+
+  return NoGreaterThan(std::min(model_->inflight_lo(), model_->inflight_hi()));
+}
+
+bool Bbr2ProbeBwMode::IsProbingForBandwidth() const {
+  return cycle_.phase == CyclePhase::PROBE_REFILL ||
+         cycle_.phase == CyclePhase::PROBE_UP;
+}
+
+Bbr2Mode Bbr2ProbeBwMode::OnExitQuiescence(QuicTime now,
+                                           QuicTime quiescence_start_time) {
+  QUIC_DVLOG(3) << sender_ << " Postponing min_rtt_timestamp("
+                << model_->MinRttTimestamp() << ") by "
+                << now - quiescence_start_time;
+  model_->PostponeMinRttTimestamp(now - quiescence_start_time);
+  return Bbr2Mode::PROBE_BW;
+}
+
+// TODO(ianswett): Remove prior_in_flight from UpdateProbeDown.
+void Bbr2ProbeBwMode::UpdateProbeDown(
+    QuicByteCount prior_in_flight,
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_DOWN);
+
+  if (cycle_.rounds_in_phase == 1 && congestion_event.end_of_round_trip) {
+    cycle_.is_sample_from_probing = false;
+
+    if (!congestion_event.last_packet_send_state.is_app_limited) {
+      QUIC_DVLOG(2)
+          << sender_
+          << " Advancing max bw filter after one round in PROBE_DOWN.";
+      model_->AdvanceMaxBandwidthFilter();
+      cycle_.has_advanced_max_bw = true;
+    }
+
+    if (last_cycle_stopped_risky_probe_ && !last_cycle_probed_too_high_) {
+      EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
+      return;
+    }
+  }
+
+  MaybeAdaptUpperBounds(congestion_event);
+
+  if (IsTimeToProbeBandwidth(congestion_event)) {
+    EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
+    return;
+  }
+
+  if (HasStayedLongEnoughInProbeDown(congestion_event)) {
+    QUIC_DVLOG(3) << sender_ << " Proportional time based PROBE_DOWN exit";
+    EnterProbeCruise(congestion_event.event_time);
+    return;
+  }
+
+  const QuicByteCount inflight_with_headroom =
+      model_->inflight_hi_with_headroom();
+  QUIC_DVLOG(3)
+      << sender_
+      << " Checking if have enough inflight headroom. prior_in_flight:"
+      << prior_in_flight << " congestion_event.bytes_in_flight:"
+      << congestion_event.bytes_in_flight
+      << ", inflight_with_headroom:" << inflight_with_headroom;
+  QuicByteCount bytes_in_flight = congestion_event.bytes_in_flight;
+
+  if (bytes_in_flight > inflight_with_headroom) {
+    // Stay in PROBE_DOWN.
+    return;
+  }
+
+  // Transition to PROBE_CRUISE iff we've drained to target.
+  QuicByteCount bdp = model_->BDP();
+  QUIC_DVLOG(3) << sender_ << " Checking if drained to target. bytes_in_flight:"
+                << bytes_in_flight << ", bdp:" << bdp;
+  if (bytes_in_flight < bdp) {
+    EnterProbeCruise(congestion_event.event_time);
+  }
+}
+
+Bbr2ProbeBwMode::AdaptUpperBoundsResult Bbr2ProbeBwMode::MaybeAdaptUpperBounds(
+    const Bbr2CongestionEvent& congestion_event) {
+  const SendTimeState& send_state = congestion_event.last_packet_send_state;
+  if (!send_state.is_valid) {
+    QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                  << ": NOT_ADAPTED_INVALID_SAMPLE";
+    return NOT_ADAPTED_INVALID_SAMPLE;
+  }
+
+  // TODO(ianswett): Rename to bytes_delivered if
+  // use_bytes_delivered_for_inflight_hi is default enabled.
+  QuicByteCount inflight_at_send = BytesInFlight(send_state);
+  if (Params().use_bytes_delivered_for_inflight_hi) {
+    if (congestion_event.last_packet_send_state.total_bytes_acked <=
+        model_->total_bytes_acked()) {
+      inflight_at_send =
+          model_->total_bytes_acked() -
+          congestion_event.last_packet_send_state.total_bytes_acked;
+    } else {
+      QUIC_BUG(quic_bug_10436_1)
+          << "Total_bytes_acked(" << model_->total_bytes_acked()
+          << ") < send_state.total_bytes_acked("
+          << congestion_event.last_packet_send_state.total_bytes_acked << ")";
+    }
+  }
+  // TODO(ianswett): Inflight too high is really checking for loss, not
+  // inflight.
+  if (model_->IsInflightTooHigh(congestion_event,
+                                Params().probe_bw_full_loss_count)) {
+    if (cycle_.is_sample_from_probing) {
+      cycle_.is_sample_from_probing = false;
+      if (!send_state.is_app_limited ||
+          Params().probe_up_dont_exit_if_no_queue_) {
+        if (send_state.is_app_limited) {
+          // If there's excess loss or a queue is building, exit even if the
+          // last sample was app limited.
+          QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_no_probe_up_exit_if_no_queue,
+                                       2, 2);
+        }
+        const QuicByteCount inflight_target =
+            sender_->GetTargetBytesInflight() * (1.0 - Params().beta);
+        if (inflight_at_send >= inflight_target) {
+          // The new code does not change behavior.
+          QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_noop);
+        } else {
+          // The new code actually cuts inflight_hi slower than before.
+          QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_in_effect);
+        }
+        if (Params().limit_inflight_hi_by_max_delivered) {
+          QuicByteCount new_inflight_hi =
+              std::max(inflight_at_send, inflight_target);
+          if (new_inflight_hi >= model_->max_bytes_delivered_in_round()) {
+            QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_noop);
+          } else {
+            QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_in_effect);
+            new_inflight_hi = model_->max_bytes_delivered_in_round();
+          }
+          QUIC_DVLOG(3) << sender_
+                        << " Setting inflight_hi due to loss. new_inflight_hi:"
+                        << new_inflight_hi
+                        << ", inflight_at_send:" << inflight_at_send
+                        << ", inflight_target:" << inflight_target
+                        << ", max_bytes_delivered_in_round:"
+                        << model_->max_bytes_delivered_in_round() << "  @ "
+                        << congestion_event.event_time;
+          model_->set_inflight_hi(new_inflight_hi);
+        } else {
+          model_->set_inflight_hi(std::max(inflight_at_send, inflight_target));
+        }
+      }
+
+      QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                    << ": ADAPTED_PROBED_TOO_HIGH";
+      return ADAPTED_PROBED_TOO_HIGH;
+    }
+    return ADAPTED_OK;
+  }
+
+  if (model_->inflight_hi() == model_->inflight_hi_default()) {
+    QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                  << ": NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET";
+    return NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET;
+  }
+
+  // Raise the upper bound for inflight.
+  if (inflight_at_send > model_->inflight_hi()) {
+    QUIC_DVLOG(3)
+        << sender_ << " " << cycle_.phase
+        << ": Adapting inflight_hi from inflight_at_send. inflight_at_send:"
+        << inflight_at_send << ", old inflight_hi:" << model_->inflight_hi();
+    model_->set_inflight_hi(inflight_at_send);
+  }
+
+  return ADAPTED_OK;
+}
+
+bool Bbr2ProbeBwMode::IsTimeToProbeBandwidth(
+    const Bbr2CongestionEvent& congestion_event) const {
+  if (HasCycleLasted(cycle_.probe_wait_time, congestion_event)) {
+    return true;
+  }
+
+  if (IsTimeToProbeForRenoCoexistence(1.0, congestion_event)) {
+    ++sender_->connection_stats_->bbr_num_short_cycles_for_reno_coexistence;
+    return true;
+  }
+  return false;
+}
+
+// QUIC only. Used to prevent a Bbr2 flow from staying in PROBE_DOWN for too
+// long, as seen in some multi-sender simulator tests.
+bool Bbr2ProbeBwMode::HasStayedLongEnoughInProbeDown(
+    const Bbr2CongestionEvent& congestion_event) const {
+  // Stay in PROBE_DOWN for at most the time of a min rtt, as it is done in
+  // BBRv1.
+  // TODO(wub): Consider exit after a full round instead, which typically
+  // indicates most(if not all) packets sent during PROBE_UP have been acked.
+  return HasPhaseLasted(model_->MinRtt(), congestion_event);
+}
+
+bool Bbr2ProbeBwMode::HasCycleLasted(
+    QuicTime::Delta duration,
+    const Bbr2CongestionEvent& congestion_event) const {
+  bool result =
+      (congestion_event.event_time - cycle_.cycle_start_time) > duration;
+  QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                << ": HasCycleLasted=" << result << ". elapsed:"
+                << (congestion_event.event_time - cycle_.cycle_start_time)
+                << ", duration:" << duration;
+  return result;
+}
+
+bool Bbr2ProbeBwMode::HasPhaseLasted(
+    QuicTime::Delta duration,
+    const Bbr2CongestionEvent& congestion_event) const {
+  bool result =
+      (congestion_event.event_time - cycle_.phase_start_time) > duration;
+  QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                << ": HasPhaseLasted=" << result << ". elapsed:"
+                << (congestion_event.event_time - cycle_.phase_start_time)
+                << ", duration:" << duration;
+  return result;
+}
+
+bool Bbr2ProbeBwMode::IsTimeToProbeForRenoCoexistence(
+    double probe_wait_fraction,
+    const Bbr2CongestionEvent& /*congestion_event*/) const {
+  if (!Params().enable_reno_coexistence) {
+    return false;
+  }
+
+  uint64_t rounds = Params().probe_bw_probe_max_rounds;
+  if (Params().probe_bw_probe_reno_gain > 0.0) {
+    QuicByteCount target_bytes_inflight = sender_->GetTargetBytesInflight();
+    uint64_t reno_rounds = Params().probe_bw_probe_reno_gain *
+                           target_bytes_inflight / kDefaultTCPMSS;
+    rounds = std::min(rounds, reno_rounds);
+  }
+  bool result = cycle_.rounds_since_probe >= (rounds * probe_wait_fraction);
+  QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                << ": IsTimeToProbeForRenoCoexistence=" << result
+                << ". rounds_since_probe:" << cycle_.rounds_since_probe
+                << ", rounds:" << rounds
+                << ", probe_wait_fraction:" << probe_wait_fraction;
+  return result;
+}
+
+void Bbr2ProbeBwMode::RaiseInflightHighSlope() {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
+  uint64_t growth_this_round = 1 << cycle_.probe_up_rounds;
+  // The number 30 below means |growth_this_round| is capped at 1G and the lower
+  // bound of |probe_up_bytes| is (practically) 1 mss, at this speed inflight_hi
+  // grows by approximately 1 packet per packet acked.
+  cycle_.probe_up_rounds = std::min<uint64_t>(cycle_.probe_up_rounds + 1, 30);
+  uint64_t probe_up_bytes = sender_->GetCongestionWindow() / growth_this_round;
+  cycle_.probe_up_bytes =
+      std::max<QuicByteCount>(probe_up_bytes, kDefaultTCPMSS);
+  QUIC_DVLOG(3) << sender_ << " Rasing inflight_hi slope. probe_up_rounds:"
+                << cycle_.probe_up_rounds
+                << ", probe_up_bytes:" << cycle_.probe_up_bytes;
+}
+
+void Bbr2ProbeBwMode::ProbeInflightHighUpward(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
+  if (Params().probe_up_ignore_inflight_hi) {
+    // When inflight_hi is disabled in PROBE_UP, it increases when
+    // the number of bytes delivered in a round is larger inflight_hi.
+    return;
+  }
+  if (Params().probe_bw_check_cwnd_limited_before_aggregation_epoch) {
+    if (!model_->cwnd_limited_before_aggregation_epoch()) {
+      QUIC_DVLOG(3) << sender_
+                    << " Raising inflight_hi early return: Not cwnd limited "
+                       "before aggregation epoch.";
+      // Not fully utilizing cwnd, so can't safely grow.
+      return;
+    }
+  } else if (Params().probe_up_includes_acks_after_cwnd_limited) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_bbr2_add_bytes_acked_after_inflight_hi_limited);
+    // Don't continue adding bytes to probe_up_acked if the sender was not
+    // app-limited after being inflight_hi limited at least once.
+    if (!cycle_.probe_up_app_limited_since_inflight_hi_limited_ ||
+        congestion_event.last_packet_send_state.is_app_limited) {
+      cycle_.probe_up_app_limited_since_inflight_hi_limited_ = false;
+      if (congestion_event.prior_bytes_in_flight <
+          congestion_event.prior_cwnd) {
+        QUIC_DVLOG(3) << sender_
+                      << " Raising inflight_hi early return: Not cwnd limited.";
+        // Not fully utilizing cwnd, so can't safely grow.
+        return;
+      }
+
+      if (congestion_event.prior_cwnd < model_->inflight_hi()) {
+        QUIC_DVLOG(3)
+            << sender_
+            << " Raising inflight_hi early return: inflight_hi not fully used.";
+        // Not fully using inflight_hi, so don't grow it.
+        return;
+      }
+    }
+    // Start a new period of adding bytes_acked, because inflight_hi limited.
+    cycle_.probe_up_app_limited_since_inflight_hi_limited_ = true;
+  } else {
+    if (congestion_event.prior_bytes_in_flight < congestion_event.prior_cwnd) {
+      QUIC_DVLOG(3) << sender_
+                    << " Raising inflight_hi early return: Not cwnd limited.";
+      // Not fully utilizing cwnd, so can't safely grow.
+      return;
+    }
+  }
+
+  if (congestion_event.prior_cwnd < model_->inflight_hi()) {
+    QUIC_DVLOG(3)
+        << sender_
+        << " Raising inflight_hi early return: inflight_hi not fully used.";
+    // Not fully using inflight_hi, so don't grow it.
+    return;
+  }
+
+  // Increase inflight_hi by the number of probe_up_bytes within probe_up_acked.
+  cycle_.probe_up_acked += congestion_event.bytes_acked;
+  if (cycle_.probe_up_acked >= cycle_.probe_up_bytes) {
+    uint64_t delta = cycle_.probe_up_acked / cycle_.probe_up_bytes;
+    cycle_.probe_up_acked -= delta * cycle_.probe_up_bytes;
+    QuicByteCount new_inflight_hi =
+        model_->inflight_hi() + delta * kDefaultTCPMSS;
+    if (new_inflight_hi > model_->inflight_hi()) {
+      QUIC_DVLOG(3) << sender_ << " Raising inflight_hi from "
+                    << model_->inflight_hi() << " to " << new_inflight_hi
+                    << ". probe_up_bytes:" << cycle_.probe_up_bytes
+                    << ", delta:" << delta
+                    << ", (new)probe_up_acked:" << cycle_.probe_up_acked;
+
+      model_->set_inflight_hi(new_inflight_hi);
+    } else {
+      QUIC_BUG(quic_bug_10436_2)
+          << "Not growing inflight_hi due to wrap around. Old value:"
+          << model_->inflight_hi() << ", new value:" << new_inflight_hi;
+    }
+  }
+
+  if (congestion_event.end_of_round_trip) {
+    RaiseInflightHighSlope();
+  }
+}
+
+void Bbr2ProbeBwMode::UpdateProbeCruise(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_CRUISE);
+  MaybeAdaptUpperBounds(congestion_event);
+  QUICHE_DCHECK(!cycle_.is_sample_from_probing);
+
+  if (IsTimeToProbeBandwidth(congestion_event)) {
+    EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
+    return;
+  }
+}
+
+void Bbr2ProbeBwMode::UpdateProbeRefill(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_REFILL);
+  MaybeAdaptUpperBounds(congestion_event);
+  QUICHE_DCHECK(!cycle_.is_sample_from_probing);
+
+  if (cycle_.rounds_in_phase > 0 && congestion_event.end_of_round_trip) {
+    EnterProbeUp(congestion_event.event_time);
+    return;
+  }
+}
+
+void Bbr2ProbeBwMode::UpdateProbeUp(
+    QuicByteCount prior_in_flight,
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
+  if (MaybeAdaptUpperBounds(congestion_event) == ADAPTED_PROBED_TOO_HIGH) {
+    EnterProbeDown(/*probed_too_high=*/true, /*stopped_risky_probe=*/false,
+                   congestion_event.event_time);
+    return;
+  }
+
+  // TODO(wub): Consider exit PROBE_UP after a certain number(e.g. 64) of RTTs.
+
+  ProbeInflightHighUpward(congestion_event);
+
+  bool is_risky = false;
+  bool is_queuing = false;
+  if (last_cycle_probed_too_high_ && prior_in_flight >= model_->inflight_hi()) {
+    is_risky = true;
+    QUIC_DVLOG(3) << sender_
+                  << " Probe is too risky. last_cycle_probed_too_high_:"
+                  << last_cycle_probed_too_high_
+                  << ", prior_in_flight:" << prior_in_flight
+                  << ", inflight_hi:" << model_->inflight_hi();
+    // TCP uses min_rtt instead of a full round:
+    //   HasPhaseLasted(model_->MinRtt(), congestion_event)
+  } else if (cycle_.rounds_in_phase > 0) {
+    if (Params().probe_up_dont_exit_if_no_queue_) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_no_probe_up_exit_if_no_queue, 1,
+                                   2);
+      is_queuing = congestion_event.end_of_round_trip &&
+                   model_->CheckPersistentQueue(
+                       congestion_event, Params().probe_bw_probe_inflight_gain);
+    } else {
+      QuicByteCount queuing_threshold_extra_bytes =
+          model_->QueueingThresholdExtraBytes();
+      if (Params().add_ack_height_to_queueing_threshold) {
+        queuing_threshold_extra_bytes += model_->MaxAckHeight();
+      }
+      QuicByteCount queuing_threshold =
+          (Params().probe_bw_probe_inflight_gain * model_->BDP()) +
+          queuing_threshold_extra_bytes;
+
+      is_queuing = congestion_event.bytes_in_flight >= queuing_threshold;
+
+      QUIC_DVLOG(3) << sender_
+                    << " Checking if building up a queue. prior_in_flight:"
+                    << prior_in_flight
+                    << ", post_in_flight:" << congestion_event.bytes_in_flight
+                    << ", threshold:" << queuing_threshold
+                    << ", is_queuing:" << is_queuing
+                    << ", max_bw:" << model_->MaxBandwidth()
+                    << ", min_rtt:" << model_->MinRtt();
+    }
+  }
+
+  if (is_risky || is_queuing) {
+    EnterProbeDown(/*probed_too_high=*/false, /*stopped_risky_probe=*/is_risky,
+                   congestion_event.event_time);
+  }
+}
+
+void Bbr2ProbeBwMode::EnterProbeDown(bool probed_too_high,
+                                     bool stopped_risky_probe, QuicTime now) {
+  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
+                << CyclePhase::PROBE_DOWN << " after "
+                << now - cycle_.phase_start_time << ", or "
+                << cycle_.rounds_in_phase
+                << " rounds. probed_too_high:" << probed_too_high
+                << ", stopped_risky_probe:" << stopped_risky_probe << "  @ "
+                << now;
+  last_cycle_probed_too_high_ = probed_too_high;
+  last_cycle_stopped_risky_probe_ = stopped_risky_probe;
+
+  cycle_.cycle_start_time = now;
+  cycle_.phase = CyclePhase::PROBE_DOWN;
+  cycle_.rounds_in_phase = 0;
+  cycle_.phase_start_time = now;
+  ++sender_->connection_stats_->bbr_num_cycles;
+  if (Params().bw_lo_mode_ != Bbr2Params::QuicBandwidthLoMode::DEFAULT) {
+    // Clear bandwidth lo if it was set in PROBE_UP, because losses in PROBE_UP
+    // should not permanently change bandwidth_lo.
+    // It's possible for bandwidth_lo to be set during REFILL, but if that was
+    // a valid value, it'll quickly be rediscovered.
+    model_->clear_bandwidth_lo();
+  }
+
+  // Pick probe wait time.
+  cycle_.rounds_since_probe =
+      sender_->RandomUint64(Params().probe_bw_max_probe_rand_rounds);
+  cycle_.probe_wait_time =
+      Params().probe_bw_probe_base_duration +
+      QuicTime::Delta::FromMicroseconds(sender_->RandomUint64(
+          Params().probe_bw_probe_max_rand_duration.ToMicroseconds()));
+
+  cycle_.probe_up_bytes = std::numeric_limits<QuicByteCount>::max();
+  cycle_.probe_up_app_limited_since_inflight_hi_limited_ = false;
+  cycle_.has_advanced_max_bw = false;
+  model_->RestartRoundEarly();
+}
+
+void Bbr2ProbeBwMode::EnterProbeCruise(QuicTime now) {
+  if (cycle_.phase == CyclePhase::PROBE_DOWN) {
+    ExitProbeDown();
+  }
+  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
+                << CyclePhase::PROBE_CRUISE << " after "
+                << now - cycle_.phase_start_time << ", or "
+                << cycle_.rounds_in_phase << " rounds.  @ " << now;
+
+  model_->cap_inflight_lo(model_->inflight_hi());
+  cycle_.phase = CyclePhase::PROBE_CRUISE;
+  cycle_.rounds_in_phase = 0;
+  cycle_.phase_start_time = now;
+  cycle_.is_sample_from_probing = false;
+}
+
+void Bbr2ProbeBwMode::EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now) {
+  if (cycle_.phase == CyclePhase::PROBE_DOWN) {
+    ExitProbeDown();
+  }
+  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
+                << CyclePhase::PROBE_REFILL << " after "
+                << now - cycle_.phase_start_time << ", or "
+                << cycle_.rounds_in_phase
+                << " rounds. probe_up_rounds:" << probe_up_rounds << "  @ "
+                << now;
+  cycle_.phase = CyclePhase::PROBE_REFILL;
+  cycle_.rounds_in_phase = 0;
+  cycle_.phase_start_time = now;
+  cycle_.is_sample_from_probing = false;
+  last_cycle_stopped_risky_probe_ = false;
+
+  model_->clear_bandwidth_lo();
+  model_->clear_inflight_lo();
+  cycle_.probe_up_rounds = probe_up_rounds;
+  cycle_.probe_up_acked = 0;
+  model_->RestartRoundEarly();
+}
+
+void Bbr2ProbeBwMode::EnterProbeUp(QuicTime now) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_REFILL);
+  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
+                << CyclePhase::PROBE_UP << " after "
+                << now - cycle_.phase_start_time << ", or "
+                << cycle_.rounds_in_phase << " rounds.  @ " << now;
+  cycle_.phase = CyclePhase::PROBE_UP;
+  cycle_.rounds_in_phase = 0;
+  cycle_.phase_start_time = now;
+  cycle_.is_sample_from_probing = true;
+  RaiseInflightHighSlope();
+
+  model_->RestartRoundEarly();
+}
+
+void Bbr2ProbeBwMode::ExitProbeDown() {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_DOWN);
+  if (!cycle_.has_advanced_max_bw) {
+    QUIC_DVLOG(2) << sender_ << " Advancing max bw filter at end of cycle.";
+    model_->AdvanceMaxBandwidthFilter();
+    cycle_.has_advanced_max_bw = true;
+  }
+}
+
+// static
+const char* Bbr2ProbeBwMode::CyclePhaseToString(CyclePhase phase) {
+  switch (phase) {
+    case CyclePhase::PROBE_NOT_STARTED:
+      return "PROBE_NOT_STARTED";
+    case CyclePhase::PROBE_UP:
+      return "PROBE_UP";
+    case CyclePhase::PROBE_DOWN:
+      return "PROBE_DOWN";
+    case CyclePhase::PROBE_CRUISE:
+      return "PROBE_CRUISE";
+    case CyclePhase::PROBE_REFILL:
+      return "PROBE_REFILL";
+    default:
+      break;
+  }
+  return "<Invalid CyclePhase>";
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2ProbeBwMode::CyclePhase phase) {
+  return os << Bbr2ProbeBwMode::CyclePhaseToString(phase);
+}
+
+Bbr2ProbeBwMode::DebugState Bbr2ProbeBwMode::ExportDebugState() const {
+  DebugState s;
+  s.phase = cycle_.phase;
+  s.cycle_start_time = cycle_.cycle_start_time;
+  s.phase_start_time = cycle_.phase_start_time;
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2ProbeBwMode::DebugState& state) {
+  os << "[PROBE_BW] phase: " << state.phase << "\n";
+  os << "[PROBE_BW] cycle_start_time: " << state.cycle_start_time << "\n";
+  os << "[PROBE_BW] phase_start_time: " << state.phase_start_time << "\n";
+  return os;
+}
+
+const Bbr2Params& Bbr2ProbeBwMode::Params() const { return sender_->Params(); }
+
+float Bbr2ProbeBwMode::PacingGainForPhase(
+    Bbr2ProbeBwMode::CyclePhase phase) const {
+  if (phase == Bbr2ProbeBwMode::CyclePhase::PROBE_UP) {
+    return Params().probe_bw_probe_up_pacing_gain;
+  }
+  if (phase == Bbr2ProbeBwMode::CyclePhase::PROBE_DOWN) {
+    return Params().probe_bw_probe_down_pacing_gain;
+  }
+  return Params().probe_bw_default_pacing_gain;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_probe_bw.h b/quiche/quic/core/congestion_control/bbr2_probe_bw.h
new file mode 100644
index 0000000..972e2ba
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_probe_bw.h
@@ -0,0 +1,142 @@
+// Copyright 2019 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_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2ProbeBwMode final : public Bbr2ModeBase {
+ public:
+  using Bbr2ModeBase::Bbr2ModeBase;
+
+  void Enter(QuicTime now,
+             const Bbr2CongestionEvent* congestion_event) override;
+  void Leave(QuicTime /*now*/,
+             const Bbr2CongestionEvent* /*congestion_event*/) override {}
+
+  Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) override;
+
+  Limits<QuicByteCount> GetCwndLimits() const override;
+
+  bool IsProbingForBandwidth() const override;
+
+  Bbr2Mode OnExitQuiescence(QuicTime now,
+                            QuicTime quiescence_start_time) override;
+
+  enum class CyclePhase : uint8_t {
+    PROBE_NOT_STARTED,
+    PROBE_UP,
+    PROBE_DOWN,
+    PROBE_CRUISE,
+    PROBE_REFILL,
+  };
+
+  static const char* CyclePhaseToString(CyclePhase phase);
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    CyclePhase phase;
+    QuicTime cycle_start_time = QuicTime::Zero();
+    QuicTime phase_start_time = QuicTime::Zero();
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  const Bbr2Params& Params() const;
+  float PacingGainForPhase(CyclePhase phase) const;
+
+  void UpdateProbeUp(QuicByteCount prior_in_flight,
+                     const Bbr2CongestionEvent& congestion_event);
+  void UpdateProbeDown(QuicByteCount prior_in_flight,
+                       const Bbr2CongestionEvent& congestion_event);
+  void UpdateProbeCruise(const Bbr2CongestionEvent& congestion_event);
+  void UpdateProbeRefill(const Bbr2CongestionEvent& congestion_event);
+
+  enum AdaptUpperBoundsResult : uint8_t {
+    ADAPTED_OK,
+    ADAPTED_PROBED_TOO_HIGH,
+    NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET,
+    NOT_ADAPTED_INVALID_SAMPLE,
+  };
+
+  // Return whether adapted inflight_hi. If inflight is too high, this function
+  // will not adapt inflight_hi and will return false.
+  AdaptUpperBoundsResult MaybeAdaptUpperBounds(
+      const Bbr2CongestionEvent& congestion_event);
+
+  void EnterProbeDown(bool probed_too_high,
+                      bool stopped_risky_probe,
+                      QuicTime now);
+  void EnterProbeCruise(QuicTime now);
+  void EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now);
+  void EnterProbeUp(QuicTime now);
+
+  // Call right before the exit of PROBE_DOWN.
+  void ExitProbeDown();
+
+  float PercentTimeElapsedToProbeBandwidth(
+      const Bbr2CongestionEvent& congestion_event) const;
+
+  bool IsTimeToProbeBandwidth(
+      const Bbr2CongestionEvent& congestion_event) const;
+  bool HasStayedLongEnoughInProbeDown(
+      const Bbr2CongestionEvent& congestion_event) const;
+  bool HasCycleLasted(QuicTime::Delta duration,
+                      const Bbr2CongestionEvent& congestion_event) const;
+  bool HasPhaseLasted(QuicTime::Delta duration,
+                      const Bbr2CongestionEvent& congestion_event) const;
+  bool IsTimeToProbeForRenoCoexistence(
+      double probe_wait_fraction,
+      const Bbr2CongestionEvent& congestion_event) const;
+
+  void RaiseInflightHighSlope();
+  void ProbeInflightHighUpward(const Bbr2CongestionEvent& congestion_event);
+
+  struct QUIC_EXPORT_PRIVATE Cycle {
+    QuicTime cycle_start_time = QuicTime::Zero();
+    CyclePhase phase = CyclePhase::PROBE_NOT_STARTED;
+    uint64_t rounds_in_phase = 0;
+    QuicTime phase_start_time = QuicTime::Zero();
+    QuicRoundTripCount rounds_since_probe = 0;
+    QuicTime::Delta probe_wait_time = QuicTime::Delta::Zero();
+    uint64_t probe_up_rounds = 0;
+    QuicByteCount probe_up_bytes = std::numeric_limits<QuicByteCount>::max();
+    QuicByteCount probe_up_acked = 0;
+    bool probe_up_app_limited_since_inflight_hi_limited_ = false;
+    // Whether max bandwidth filter window has advanced in this cycle. It is
+    // advanced once per cycle.
+    bool has_advanced_max_bw = false;
+    bool is_sample_from_probing = false;
+  } cycle_;
+
+  bool last_cycle_probed_too_high_;
+  bool last_cycle_stopped_risky_probe_;
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2ProbeBwMode::DebugState& state);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2ProbeBwMode::CyclePhase phase);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_probe_rtt.cc b/quiche/quic/core/congestion_control/bbr2_probe_rtt.cc
new file mode 100644
index 0000000..ef5b775
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_probe_rtt.cc
@@ -0,0 +1,83 @@
+// Copyright 2019 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 "quiche/quic/core/congestion_control/bbr2_probe_rtt.h"
+
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+void Bbr2ProbeRttMode::Enter(QuicTime /*now*/,
+                             const Bbr2CongestionEvent* /*congestion_event*/) {
+  model_->set_pacing_gain(1.0);
+  model_->set_cwnd_gain(1.0);
+  exit_time_ = QuicTime::Zero();
+}
+
+Bbr2Mode Bbr2ProbeRttMode::OnCongestionEvent(
+    QuicByteCount /*prior_in_flight*/,
+    QuicTime /*event_time*/,
+    const AckedPacketVector& /*acked_packets*/,
+    const LostPacketVector& /*lost_packets*/,
+    const Bbr2CongestionEvent& congestion_event) {
+  if (exit_time_ == QuicTime::Zero()) {
+    if (congestion_event.bytes_in_flight <= InflightTarget() ||
+        congestion_event.bytes_in_flight <=
+            sender_->GetMinimumCongestionWindow()) {
+      exit_time_ = congestion_event.event_time + Params().probe_rtt_duration;
+      QUIC_DVLOG(2) << sender_ << " PROBE_RTT exit time set to " << exit_time_
+                    << ". bytes_inflight:" << congestion_event.bytes_in_flight
+                    << ", inflight_target:" << InflightTarget()
+                    << ", min_congestion_window:"
+                    << sender_->GetMinimumCongestionWindow() << "  @ "
+                    << congestion_event.event_time;
+    }
+    return Bbr2Mode::PROBE_RTT;
+  }
+
+  return congestion_event.event_time > exit_time_ ? Bbr2Mode::PROBE_BW
+                                                  : Bbr2Mode::PROBE_RTT;
+}
+
+QuicByteCount Bbr2ProbeRttMode::InflightTarget() const {
+  return model_->BDP(model_->MaxBandwidth(),
+                     Params().probe_rtt_inflight_target_bdp_fraction);
+}
+
+Limits<QuicByteCount> Bbr2ProbeRttMode::GetCwndLimits() const {
+  QuicByteCount inflight_upper_bound =
+      std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom());
+  return NoGreaterThan(std::min(inflight_upper_bound, InflightTarget()));
+}
+
+Bbr2Mode Bbr2ProbeRttMode::OnExitQuiescence(
+    QuicTime now,
+    QuicTime /*quiescence_start_time*/) {
+  if (now > exit_time_) {
+    return Bbr2Mode::PROBE_BW;
+  }
+  return Bbr2Mode::PROBE_RTT;
+}
+
+Bbr2ProbeRttMode::DebugState Bbr2ProbeRttMode::ExportDebugState() const {
+  DebugState s;
+  s.inflight_target = InflightTarget();
+  s.exit_time = exit_time_;
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2ProbeRttMode::DebugState& state) {
+  os << "[PROBE_RTT] inflight_target: " << state.inflight_target << "\n";
+  os << "[PROBE_RTT] exit_time: " << state.exit_time << "\n";
+  return os;
+}
+
+const Bbr2Params& Bbr2ProbeRttMode::Params() const {
+  return sender_->Params();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_probe_rtt.h b/quiche/quic/core/congestion_control/bbr2_probe_rtt.h
new file mode 100644
index 0000000..1640c28
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_probe_rtt.h
@@ -0,0 +1,60 @@
+// Copyright 2019 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_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2ProbeRttMode final : public Bbr2ModeBase {
+ public:
+  using Bbr2ModeBase::Bbr2ModeBase;
+
+  void Enter(QuicTime now,
+             const Bbr2CongestionEvent* congestion_event) override;
+  void Leave(QuicTime /*now*/,
+             const Bbr2CongestionEvent* /*congestion_event*/) override {}
+
+  Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) override;
+
+  Limits<QuicByteCount> GetCwndLimits() const override;
+
+  bool IsProbingForBandwidth() const override { return false; }
+
+  Bbr2Mode OnExitQuiescence(QuicTime now,
+                            QuicTime quiescence_start_time) override;
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    QuicByteCount inflight_target;
+    QuicTime exit_time = QuicTime::Zero();
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  const Bbr2Params& Params() const;
+
+  QuicByteCount InflightTarget() const;
+
+  QuicTime exit_time_ = QuicTime::Zero();
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2ProbeRttMode::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_sender.cc b/quiche/quic/core/congestion_control/bbr2_sender.cc
new file mode 100644
index 0000000..6c40e85
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_sender.cc
@@ -0,0 +1,578 @@
+// Copyright 2019 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 "quiche/quic/core/congestion_control/bbr2_sender.h"
+
+#include <cstddef>
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/congestion_control/bbr2_drain.h"
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/print_elements.h"
+
+namespace quic {
+
+namespace {
+// Constants based on TCP defaults.
+// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
+// Does not inflate the pacing rate.
+const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
+
+const float kInitialPacingGain = 2.885f;
+
+const int kMaxModeChangesPerCongestionEvent = 4;
+}  // namespace
+
+// Call |member_function_call| based on the current Bbr2Mode we are in. e.g.
+//
+//   auto result = BBR2_MODE_DISPATCH(Foo());
+//
+// is equivalent to:
+//
+//   Bbr2ModeBase& Bbr2Sender::GetCurrentMode() {
+//     if (mode_ == Bbr2Mode::STARTUP) { return startup_; }
+//     if (mode_ == Bbr2Mode::DRAIN) { return drain_; }
+//     ...
+//   }
+//   auto result = GetCurrentMode().Foo();
+//
+// Except that BBR2_MODE_DISPATCH guarantees the call to Foo() is non-virtual.
+//
+#define BBR2_MODE_DISPATCH(member_function_call)     \
+  (mode_ == Bbr2Mode::STARTUP                        \
+       ? (startup_.member_function_call)             \
+       : (mode_ == Bbr2Mode::PROBE_BW                \
+              ? (probe_bw_.member_function_call)     \
+              : (mode_ == Bbr2Mode::DRAIN            \
+                     ? (drain_.member_function_call) \
+                     : (probe_rtt_or_die().member_function_call))))
+
+Bbr2Sender::Bbr2Sender(QuicTime now,
+                       const RttStats* rtt_stats,
+                       const QuicUnackedPacketMap* unacked_packets,
+                       QuicPacketCount initial_cwnd_in_packets,
+                       QuicPacketCount max_cwnd_in_packets,
+                       QuicRandom* random,
+                       QuicConnectionStats* stats,
+                       BbrSender* old_sender)
+    : mode_(Bbr2Mode::STARTUP),
+      rtt_stats_(rtt_stats),
+      unacked_packets_(unacked_packets),
+      random_(random),
+      connection_stats_(stats),
+      params_(kDefaultMinimumCongestionWindow,
+              max_cwnd_in_packets * kDefaultTCPMSS),
+      model_(&params_,
+             rtt_stats->SmoothedOrInitialRtt(),
+             rtt_stats->last_update_time(),
+             /*cwnd_gain=*/1.0,
+             /*pacing_gain=*/kInitialPacingGain,
+             old_sender ? &old_sender->sampler_ : nullptr),
+      initial_cwnd_(cwnd_limits().ApplyLimits(
+          (old_sender) ? old_sender->GetCongestionWindow()
+                       : (initial_cwnd_in_packets * kDefaultTCPMSS))),
+      cwnd_(initial_cwnd_),
+      pacing_rate_(kInitialPacingGain * QuicBandwidth::FromBytesAndTimeDelta(
+                                            cwnd_,
+                                            rtt_stats->SmoothedOrInitialRtt())),
+      startup_(this, &model_, now),
+      drain_(this, &model_),
+      probe_bw_(this, &model_),
+      probe_rtt_(this, &model_),
+      last_sample_is_app_limited_(false) {
+  QUIC_DVLOG(2) << this << " Initializing Bbr2Sender. mode:" << mode_
+                << ", PacingRate:" << pacing_rate_ << ", Cwnd:" << cwnd_
+                << ", CwndLimits:" << cwnd_limits() << "  @ " << now;
+  QUICHE_DCHECK_EQ(mode_, Bbr2Mode::STARTUP);
+}
+
+void Bbr2Sender::SetFromConfig(const QuicConfig& config,
+                               Perspective perspective) {
+  if (config.HasClientRequestedIndependentOption(kB2NA, perspective)) {
+    params_.add_ack_height_to_queueing_threshold = false;
+  }
+  if (config.HasClientRequestedIndependentOption(kB2RP, perspective)) {
+    params_.avoid_unnecessary_probe_rtt = false;
+  }
+  if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
+    params_.startup_full_bw_rounds = 1;
+  }
+  if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
+    params_.startup_full_bw_rounds = 2;
+  }
+  if (config.HasClientRequestedIndependentOption(kB2HR, perspective)) {
+    params_.inflight_hi_headroom = 0.15;
+  }
+  if (config.HasClientRequestedIndependentOption(kICW1, perspective)) {
+    max_cwnd_when_network_parameters_adjusted_ = 100 * kDefaultTCPMSS;
+  }
+
+  ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
+}
+
+void Bbr2Sender::ApplyConnectionOptions(
+    const QuicTagVector& connection_options) {
+  if (GetQuicReloadableFlag(quic_bbr2_extra_acked_window) &&
+      ContainsQuicTag(connection_options, kBBR4)) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_extra_acked_window, 1, 2);
+    model_.SetMaxAckHeightTrackerWindowLength(20);
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_extra_acked_window) &&
+      ContainsQuicTag(connection_options, kBBR5)) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_extra_acked_window, 2, 2);
+    model_.SetMaxAckHeightTrackerWindowLength(40);
+  }
+  if (ContainsQuicTag(connection_options, kBBQ2)) {
+    params_.startup_cwnd_gain = 2.885;
+    params_.drain_cwnd_gain = 2.885;
+    model_.set_cwnd_gain(params_.startup_cwnd_gain);
+  }
+  if (ContainsQuicTag(connection_options, kB2LO)) {
+    params_.ignore_inflight_lo = true;
+  }
+  if (ContainsQuicTag(connection_options, kB2NE)) {
+    params_.always_exit_startup_on_excess_loss = true;
+  }
+  if (ContainsQuicTag(connection_options, kB2SL)) {
+    params_.startup_loss_exit_use_max_delivered_for_inflight_hi = false;
+  }
+  if (ContainsQuicTag(connection_options, kB2H2)) {
+    params_.limit_inflight_hi_by_max_delivered = true;
+  }
+  if (ContainsQuicTag(connection_options, kB2DL)) {
+    params_.use_bytes_delivered_for_inflight_hi = true;
+  }
+  if (ContainsQuicTag(connection_options, kB2RC)) {
+    params_.enable_reno_coexistence = false;
+  }
+  if (ContainsQuicTag(connection_options, kBSAO)) {
+    model_.EnableOverestimateAvoidance();
+  }
+  if (ContainsQuicTag(connection_options, kBBQ6)) {
+    params_.decrease_startup_pacing_at_end_of_round = true;
+  }
+  if (ContainsQuicTag(connection_options, kBBQ7)) {
+    params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::MIN_RTT_REDUCTION;
+  }
+  if (ContainsQuicTag(connection_options, kBBQ8)) {
+    params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::INFLIGHT_REDUCTION;
+  }
+  if (ContainsQuicTag(connection_options, kBBQ9)) {
+    params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::CWND_REDUCTION;
+  }
+  if (ContainsQuicTag(connection_options, kB201)) {
+    params_.probe_bw_check_cwnd_limited_before_aggregation_epoch = true;
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue) &&
+      ContainsQuicTag(connection_options, kB202)) {
+    params_.probe_up_dont_exit_if_no_queue_ = true;
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up) &&
+      ContainsQuicTag(connection_options, kB203)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_ignore_inflight_hi_in_probe_up);
+    params_.probe_up_ignore_inflight_hi = true;
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_startup_extra_acked) &&
+      ContainsQuicTag(connection_options, kB204)) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_startup_extra_acked, 1, 2);
+    model_.SetReduceExtraAckedOnBandwidthIncrease(true);
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_startup_extra_acked) &&
+      ContainsQuicTag(connection_options, kB205)) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_startup_extra_acked, 2, 2);
+    params_.startup_include_extra_acked = true;
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2) &&
+      ContainsQuicTag(connection_options, kB207)) {
+    params_.exit_startup_on_persistent_queue = true;
+  }
+
+  if (ContainsQuicTag(connection_options, kBBRA)) {
+    model_.SetStartNewAggregationEpochAfterFullRound(true);
+  }
+  if (ContainsQuicTag(connection_options, kBBRB)) {
+    model_.SetLimitMaxAckHeightTrackerBySendRate(true);
+  }
+  if (GetQuicReloadableFlag(
+          quic_bbr2_add_bytes_acked_after_inflight_hi_limited) &&
+      ContainsQuicTag(connection_options, kBBQ0)) {
+    params_.probe_up_includes_acks_after_cwnd_limited = true;
+  }
+
+  if (GetQuicReloadableFlag(quic_bbr2_startup_probe_up_loss_events) &&
+      ContainsQuicTag(connection_options, kB206)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_startup_probe_up_loss_events);
+    params_.startup_full_loss_count = params_.probe_bw_full_loss_count;
+  }
+}
+
+Limits<QuicByteCount> Bbr2Sender::GetCwndLimitsByMode() const {
+  switch (mode_) {
+    case Bbr2Mode::STARTUP:
+      return startup_.GetCwndLimits();
+    case Bbr2Mode::PROBE_BW:
+      return probe_bw_.GetCwndLimits();
+    case Bbr2Mode::DRAIN:
+      return drain_.GetCwndLimits();
+    case Bbr2Mode::PROBE_RTT:
+      return probe_rtt_.GetCwndLimits();
+    default:
+      QUIC_NOTREACHED();
+      return Unlimited<QuicByteCount>();
+  }
+}
+
+const Limits<QuicByteCount>& Bbr2Sender::cwnd_limits() const {
+  return params().cwnd_limits;
+}
+
+void Bbr2Sender::AdjustNetworkParameters(const NetworkParams& params) {
+  model_.UpdateNetworkParameters(params.rtt);
+
+  if (mode_ == Bbr2Mode::STARTUP) {
+    const QuicByteCount prior_cwnd = cwnd_;
+
+    QuicBandwidth effective_bandwidth =
+        std::max(params.bandwidth, model_.BandwidthEstimate());
+    connection_stats_->cwnd_bootstrapping_rtt_us =
+        model_.MinRtt().ToMicroseconds();
+
+    if (params.max_initial_congestion_window > 0) {
+      max_cwnd_when_network_parameters_adjusted_ =
+          params.max_initial_congestion_window * kDefaultTCPMSS;
+    }
+    cwnd_ = cwnd_limits().ApplyLimits(
+        std::min(max_cwnd_when_network_parameters_adjusted_,
+                 model_.BDP(effective_bandwidth)));
+
+    if (!params.allow_cwnd_to_decrease) {
+      cwnd_ = std::max(cwnd_, prior_cwnd);
+    }
+
+    pacing_rate_ = std::max(pacing_rate_, QuicBandwidth::FromBytesAndTimeDelta(
+                                              cwnd_, model_.MinRtt()));
+  }
+}
+
+void Bbr2Sender::SetInitialCongestionWindowInPackets(
+    QuicPacketCount congestion_window) {
+  if (mode_ == Bbr2Mode::STARTUP) {
+    // The cwnd limits is unchanged and still applies to the new cwnd.
+    cwnd_ = cwnd_limits().ApplyLimits(congestion_window * kDefaultTCPMSS);
+  }
+}
+
+void Bbr2Sender::OnCongestionEvent(bool /*rtt_updated*/,
+                                   QuicByteCount prior_in_flight,
+                                   QuicTime event_time,
+                                   const AckedPacketVector& acked_packets,
+                                   const LostPacketVector& lost_packets) {
+  QUIC_DVLOG(3) << this
+                << " OnCongestionEvent. prior_in_flight:" << prior_in_flight
+                << " prior_cwnd:" << cwnd_ << "  @ " << event_time;
+  Bbr2CongestionEvent congestion_event;
+  congestion_event.prior_cwnd = cwnd_;
+  congestion_event.prior_bytes_in_flight = prior_in_flight;
+  congestion_event.is_probing_for_bandwidth =
+      BBR2_MODE_DISPATCH(IsProbingForBandwidth());
+
+  model_.OnCongestionEventStart(event_time, acked_packets, lost_packets,
+                                &congestion_event);
+
+  if (InSlowStart()) {
+    if (!lost_packets.empty()) {
+      connection_stats_->slowstart_packets_lost += lost_packets.size();
+      connection_stats_->slowstart_bytes_lost += congestion_event.bytes_lost;
+    }
+    if (congestion_event.end_of_round_trip) {
+      ++connection_stats_->slowstart_num_rtts;
+    }
+  }
+
+  // Number of mode changes allowed for this congestion event.
+  int mode_changes_allowed = kMaxModeChangesPerCongestionEvent;
+  while (true) {
+    Bbr2Mode next_mode = BBR2_MODE_DISPATCH(
+        OnCongestionEvent(prior_in_flight, event_time, acked_packets,
+                          lost_packets, congestion_event));
+
+    if (next_mode == mode_) {
+      break;
+    }
+
+    QUIC_DVLOG(2) << this << " Mode change:  " << mode_ << " ==> " << next_mode
+                  << "  @ " << event_time;
+    BBR2_MODE_DISPATCH(Leave(event_time, &congestion_event));
+    mode_ = next_mode;
+    BBR2_MODE_DISPATCH(Enter(event_time, &congestion_event));
+    --mode_changes_allowed;
+    if (mode_changes_allowed < 0) {
+      QUIC_BUG(quic_bug_10443_1)
+          << "Exceeded max number of mode changes per congestion event.";
+      break;
+    }
+  }
+
+  UpdatePacingRate(congestion_event.bytes_acked);
+  QUIC_BUG_IF(quic_bug_10443_2, pacing_rate_.IsZero())
+      << "Pacing rate must not be zero!";
+
+  UpdateCongestionWindow(congestion_event.bytes_acked);
+  QUIC_BUG_IF(quic_bug_10443_3, cwnd_ == 0u)
+      << "Congestion window must not be zero!";
+
+  model_.OnCongestionEventFinish(unacked_packets_->GetLeastUnacked(),
+                                 congestion_event);
+  last_sample_is_app_limited_ =
+      congestion_event.last_packet_send_state.is_app_limited;
+  if (!last_sample_is_app_limited_) {
+    has_non_app_limited_sample_ = true;
+  }
+  if (congestion_event.bytes_in_flight == 0 &&
+      params().avoid_unnecessary_probe_rtt) {
+    OnEnterQuiescence(event_time);
+  }
+
+  QUIC_DVLOG(3)
+      << this
+      << " END CongestionEvent(acked:" << quiche::PrintElements(acked_packets)
+      << ", lost:" << lost_packets.size() << ") "
+      << ", Mode:" << mode_ << ", RttCount:" << model_.RoundTripCount()
+      << ", BytesInFlight:" << congestion_event.bytes_in_flight
+      << ", PacingRate:" << PacingRate(0) << ", CWND:" << GetCongestionWindow()
+      << ", PacingGain:" << model_.pacing_gain()
+      << ", CwndGain:" << model_.cwnd_gain()
+      << ", BandwidthEstimate(kbps):" << BandwidthEstimate().ToKBitsPerSecond()
+      << ", MinRTT(us):" << model_.MinRtt().ToMicroseconds()
+      << ", BDP:" << model_.BDP(BandwidthEstimate())
+      << ", BandwidthLatest(kbps):"
+      << model_.bandwidth_latest().ToKBitsPerSecond()
+      << ", BandwidthLow(kbps):" << model_.bandwidth_lo().ToKBitsPerSecond()
+      << ", BandwidthHigh(kbps):" << model_.MaxBandwidth().ToKBitsPerSecond()
+      << ", InflightLatest:" << model_.inflight_latest()
+      << ", InflightLow:" << model_.inflight_lo()
+      << ", InflightHigh:" << model_.inflight_hi()
+      << ", TotalAcked:" << model_.total_bytes_acked()
+      << ", TotalLost:" << model_.total_bytes_lost()
+      << ", TotalSent:" << model_.total_bytes_sent() << "  @ " << event_time;
+}
+
+void Bbr2Sender::UpdatePacingRate(QuicByteCount bytes_acked) {
+  if (BandwidthEstimate().IsZero()) {
+    return;
+  }
+
+  if (model_.total_bytes_acked() == bytes_acked) {
+    // After the first ACK, cwnd_ is still the initial congestion window.
+    pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta(cwnd_, model_.MinRtt());
+    return;
+  }
+
+  QuicBandwidth target_rate = model_.pacing_gain() * model_.BandwidthEstimate();
+  if (model_.full_bandwidth_reached()) {
+    pacing_rate_ = target_rate;
+    return;
+  }
+  if (params_.decrease_startup_pacing_at_end_of_round &&
+      model_.pacing_gain() < Params().startup_pacing_gain) {
+    pacing_rate_ = target_rate;
+    return;
+  }
+  if (params_.bw_lo_mode_ != Bbr2Params::DEFAULT &&
+      model_.loss_events_in_round() > 0) {
+    pacing_rate_ = target_rate;
+    return;
+  }
+
+  // By default, the pacing rate never decreases in STARTUP.
+  if (target_rate > pacing_rate_) {
+    pacing_rate_ = target_rate;
+  }
+}
+
+void Bbr2Sender::UpdateCongestionWindow(QuicByteCount bytes_acked) {
+  QuicByteCount target_cwnd = GetTargetCongestionWindow(model_.cwnd_gain());
+
+  const QuicByteCount prior_cwnd = cwnd_;
+  if (model_.full_bandwidth_reached() || Params().startup_include_extra_acked) {
+    target_cwnd += model_.MaxAckHeight();
+    cwnd_ = std::min(prior_cwnd + bytes_acked, target_cwnd);
+  } else if (prior_cwnd < target_cwnd || prior_cwnd < 2 * initial_cwnd_) {
+    cwnd_ = prior_cwnd + bytes_acked;
+  }
+  const QuicByteCount desired_cwnd = cwnd_;
+
+  cwnd_ = GetCwndLimitsByMode().ApplyLimits(cwnd_);
+  const QuicByteCount model_limited_cwnd = cwnd_;
+
+  cwnd_ = cwnd_limits().ApplyLimits(cwnd_);
+
+  QUIC_DVLOG(3) << this << " Updating CWND. target_cwnd:" << target_cwnd
+                << ", max_ack_height:" << model_.MaxAckHeight()
+                << ", full_bw:" << model_.full_bandwidth_reached()
+                << ", bytes_acked:" << bytes_acked
+                << ", inflight_lo:" << model_.inflight_lo()
+                << ", inflight_hi:" << model_.inflight_hi() << ". (prior_cwnd) "
+                << prior_cwnd << " => (desired_cwnd) " << desired_cwnd
+                << " => (model_limited_cwnd) " << model_limited_cwnd
+                << " => (final_cwnd) " << cwnd_;
+}
+
+QuicByteCount Bbr2Sender::GetTargetCongestionWindow(float gain) const {
+  return std::max(model_.BDP(model_.BandwidthEstimate(), gain),
+                  cwnd_limits().Min());
+}
+
+void Bbr2Sender::OnPacketSent(QuicTime sent_time,
+                              QuicByteCount bytes_in_flight,
+                              QuicPacketNumber packet_number,
+                              QuicByteCount bytes,
+                              HasRetransmittableData is_retransmittable) {
+  QUIC_DVLOG(3) << this << " OnPacketSent: pkn:" << packet_number
+                << ", bytes:" << bytes << ", cwnd:" << cwnd_
+                << ", inflight:" << bytes_in_flight + bytes
+                << ", total_sent:" << model_.total_bytes_sent() + bytes
+                << ", total_acked:" << model_.total_bytes_acked()
+                << ", total_lost:" << model_.total_bytes_lost() << "  @ "
+                << sent_time;
+  if (InSlowStart()) {
+    ++connection_stats_->slowstart_packets_sent;
+    connection_stats_->slowstart_bytes_sent += bytes;
+  }
+  if (bytes_in_flight == 0 && params().avoid_unnecessary_probe_rtt) {
+    OnExitQuiescence(sent_time);
+  }
+  model_.OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes,
+                      is_retransmittable);
+}
+
+void Bbr2Sender::OnPacketNeutered(QuicPacketNumber packet_number) {
+  model_.OnPacketNeutered(packet_number);
+}
+
+bool Bbr2Sender::CanSend(QuicByteCount bytes_in_flight) {
+  const bool result = bytes_in_flight < GetCongestionWindow();
+  return result;
+}
+
+QuicByteCount Bbr2Sender::GetCongestionWindow() const {
+  // TODO(wub): Implement Recovery?
+  return cwnd_;
+}
+
+QuicBandwidth Bbr2Sender::PacingRate(QuicByteCount /*bytes_in_flight*/) const {
+  return pacing_rate_;
+}
+
+void Bbr2Sender::OnApplicationLimited(QuicByteCount bytes_in_flight) {
+  if (bytes_in_flight >= GetCongestionWindow()) {
+    return;
+  }
+
+  model_.OnApplicationLimited();
+  QUIC_DVLOG(2) << this << " Becoming application limited. Last sent packet: "
+                << model_.last_sent_packet()
+                << ", CWND: " << GetCongestionWindow();
+}
+
+QuicByteCount Bbr2Sender::GetTargetBytesInflight() const {
+  QuicByteCount bdp = model_.BDP(model_.BandwidthEstimate());
+  return std::min(bdp, GetCongestionWindow());
+}
+
+void Bbr2Sender::PopulateConnectionStats(QuicConnectionStats* stats) const {
+  stats->num_ack_aggregation_epochs = model_.num_ack_aggregation_epochs();
+}
+
+void Bbr2Sender::OnEnterQuiescence(QuicTime now) {
+  last_quiescence_start_ = now;
+}
+
+void Bbr2Sender::OnExitQuiescence(QuicTime now) {
+  if (last_quiescence_start_ != QuicTime::Zero()) {
+    Bbr2Mode next_mode = BBR2_MODE_DISPATCH(
+        OnExitQuiescence(now, std::min(now, last_quiescence_start_)));
+    if (next_mode != mode_) {
+      BBR2_MODE_DISPATCH(Leave(now, nullptr));
+      mode_ = next_mode;
+      BBR2_MODE_DISPATCH(Enter(now, nullptr));
+    }
+    last_quiescence_start_ = QuicTime::Zero();
+  }
+}
+
+bool Bbr2Sender::ShouldSendProbingPacket() const {
+  // TODO(wub): Implement ShouldSendProbingPacket properly.
+  return BBR2_MODE_DISPATCH(IsProbingForBandwidth());
+}
+
+std::string Bbr2Sender::GetDebugState() const {
+  std::ostringstream stream;
+  stream << ExportDebugState();
+  return stream.str();
+}
+
+Bbr2Sender::DebugState Bbr2Sender::ExportDebugState() const {
+  DebugState s;
+  s.mode = mode_;
+  s.round_trip_count = model_.RoundTripCount();
+  s.bandwidth_hi = model_.MaxBandwidth();
+  s.bandwidth_lo = model_.bandwidth_lo();
+  s.bandwidth_est = BandwidthEstimate();
+  s.inflight_hi = model_.inflight_hi();
+  s.inflight_lo = model_.inflight_lo();
+  s.max_ack_height = model_.MaxAckHeight();
+  s.min_rtt = model_.MinRtt();
+  s.min_rtt_timestamp = model_.MinRttTimestamp();
+  s.congestion_window = cwnd_;
+  s.pacing_rate = pacing_rate_;
+  s.last_sample_is_app_limited = last_sample_is_app_limited_;
+  s.end_of_app_limited_phase = model_.end_of_app_limited_phase();
+
+  s.startup = startup_.ExportDebugState();
+  s.drain = drain_.ExportDebugState();
+  s.probe_bw = probe_bw_.ExportDebugState();
+  s.probe_rtt = probe_rtt_.ExportDebugState();
+
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os, const Bbr2Sender::DebugState& s) {
+  os << "mode: " << s.mode << "\n";
+  os << "round_trip_count: " << s.round_trip_count << "\n";
+  os << "bandwidth_hi ~ lo ~ est: " << s.bandwidth_hi << " ~ " << s.bandwidth_lo
+     << " ~ " << s.bandwidth_est << "\n";
+  os << "min_rtt: " << s.min_rtt << "\n";
+  os << "min_rtt_timestamp: " << s.min_rtt_timestamp << "\n";
+  os << "congestion_window: " << s.congestion_window << "\n";
+  os << "pacing_rate: " << s.pacing_rate << "\n";
+  os << "last_sample_is_app_limited: " << s.last_sample_is_app_limited << "\n";
+
+  if (s.mode == Bbr2Mode::STARTUP) {
+    os << s.startup;
+  }
+
+  if (s.mode == Bbr2Mode::DRAIN) {
+    os << s.drain;
+  }
+
+  if (s.mode == Bbr2Mode::PROBE_BW) {
+    os << s.probe_bw;
+  }
+
+  if (s.mode == Bbr2Mode::PROBE_RTT) {
+    os << s.probe_rtt;
+  }
+
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_sender.h b/quiche/quic/core/congestion_control/bbr2_sender.h
new file mode 100644
index 0000000..7529171
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_sender.h
@@ -0,0 +1,222 @@
+// Copyright 2019 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_CONGESTION_CONTROL_BBR2_SENDER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/congestion_control/bbr2_drain.h"
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/congestion_control/bbr2_probe_bw.h"
+#include "quiche/quic/core/congestion_control/bbr2_probe_rtt.h"
+#include "quiche/quic/core/congestion_control/bbr2_startup.h"
+#include "quiche/quic/core/congestion_control/bbr_sender.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/windowed_filter.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE Bbr2Sender final : public SendAlgorithmInterface {
+ public:
+  Bbr2Sender(QuicTime now,
+             const RttStats* rtt_stats,
+             const QuicUnackedPacketMap* unacked_packets,
+             QuicPacketCount initial_cwnd_in_packets,
+             QuicPacketCount max_cwnd_in_packets,
+             QuicRandom* random,
+             QuicConnectionStats* stats,
+             BbrSender* old_sender);
+
+  ~Bbr2Sender() override = default;
+
+  // Start implementation of SendAlgorithmInterface.
+  bool InSlowStart() const override { return mode_ == Bbr2Mode::STARTUP; }
+
+  bool InRecovery() const override {
+    // TODO(wub): Implement Recovery.
+    return false;
+  }
+
+  bool ShouldSendProbingPacket() const override;
+
+  void SetFromConfig(const QuicConfig& config,
+                     Perspective perspective) override;
+
+  void ApplyConnectionOptions(const QuicTagVector& connection_options) override;
+
+  void AdjustNetworkParameters(const NetworkParams& params) override;
+
+  void SetInitialCongestionWindowInPackets(
+      QuicPacketCount congestion_window) override;
+
+  void OnCongestionEvent(bool rtt_updated,
+                         QuicByteCount prior_in_flight,
+                         QuicTime event_time,
+                         const AckedPacketVector& acked_packets,
+                         const LostPacketVector& lost_packets) override;
+
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData is_retransmittable) override;
+
+  void OnPacketNeutered(QuicPacketNumber packet_number) override;
+
+  void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
+
+  void OnConnectionMigration() override {}
+
+  bool CanSend(QuicByteCount bytes_in_flight) override;
+
+  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
+
+  QuicBandwidth BandwidthEstimate() const override {
+    return model_.BandwidthEstimate();
+  }
+
+  bool HasGoodBandwidthEstimateForResumption() const override {
+    return has_non_app_limited_sample_;
+  }
+
+  QuicByteCount GetCongestionWindow() const override;
+
+  QuicByteCount GetSlowStartThreshold() const override { return 0; }
+
+  CongestionControlType GetCongestionControlType() const override {
+    return kBBRv2;
+  }
+
+  std::string GetDebugState() const override;
+
+  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
+
+  void PopulateConnectionStats(QuicConnectionStats* stats) const override;
+  // End implementation of SendAlgorithmInterface.
+
+  const Bbr2Params& Params() const { return params_; }
+
+  QuicByteCount GetMinimumCongestionWindow() const {
+    return cwnd_limits().Min();
+  }
+
+  // Returns the min of BDP and congestion window.
+  QuicByteCount GetTargetBytesInflight() const;
+
+  bool IsBandwidthOverestimateAvoidanceEnabled() const {
+    return model_.IsBandwidthOverestimateAvoidanceEnabled();
+  }
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    Bbr2Mode mode;
+
+    // Shared states.
+    QuicRoundTripCount round_trip_count;
+    QuicBandwidth bandwidth_hi = QuicBandwidth::Zero();
+    QuicBandwidth bandwidth_lo = QuicBandwidth::Zero();
+    QuicBandwidth bandwidth_est = QuicBandwidth::Zero();
+    QuicByteCount inflight_hi;
+    QuicByteCount inflight_lo;
+    QuicByteCount max_ack_height;
+    QuicTime::Delta min_rtt = QuicTime::Delta::Zero();
+    QuicTime min_rtt_timestamp = QuicTime::Zero();
+    QuicByteCount congestion_window;
+    QuicBandwidth pacing_rate = QuicBandwidth::Zero();
+    bool last_sample_is_app_limited;
+    QuicPacketNumber end_of_app_limited_phase;
+
+    // Mode-specific debug states.
+    Bbr2StartupMode::DebugState startup;
+    Bbr2DrainMode::DebugState drain;
+    Bbr2ProbeBwMode::DebugState probe_bw;
+    Bbr2ProbeRttMode::DebugState probe_rtt;
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  void UpdatePacingRate(QuicByteCount bytes_acked);
+  void UpdateCongestionWindow(QuicByteCount bytes_acked);
+  QuicByteCount GetTargetCongestionWindow(float gain) const;
+  void OnEnterQuiescence(QuicTime now);
+  void OnExitQuiescence(QuicTime now);
+
+  // Helper function for BBR2_MODE_DISPATCH.
+  Bbr2ProbeRttMode& probe_rtt_or_die() {
+    QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
+    return probe_rtt_;
+  }
+
+  const Bbr2ProbeRttMode& probe_rtt_or_die() const {
+    QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
+    return probe_rtt_;
+  }
+
+  uint64_t RandomUint64(uint64_t max) const {
+    return random_->RandUint64() % max;
+  }
+
+  // Cwnd limits imposed by the current Bbr2 mode.
+  Limits<QuicByteCount> GetCwndLimitsByMode() const;
+
+  // Cwnd limits imposed by caller.
+  const Limits<QuicByteCount>& cwnd_limits() const;
+
+  const Bbr2Params& params() const { return params_; }
+
+  Bbr2Mode mode_;
+
+  const RttStats* const rtt_stats_;
+  const QuicUnackedPacketMap* const unacked_packets_;
+  QuicRandom* random_;
+  QuicConnectionStats* connection_stats_;
+
+  // Don't use it directly outside of SetFromConfig and ApplyConnectionOptions.
+  // Instead, use params() to get read-only access.
+  Bbr2Params params_;
+
+  // Max congestion window when adjusting network parameters.
+  QuicByteCount max_cwnd_when_network_parameters_adjusted_ =
+      kMaxInitialCongestionWindow * kDefaultTCPMSS;
+
+  Bbr2NetworkModel model_;
+
+  const QuicByteCount initial_cwnd_;
+
+  // Current cwnd and pacing rate.
+  QuicByteCount cwnd_;
+  QuicBandwidth pacing_rate_;
+
+  QuicTime last_quiescence_start_ = QuicTime::Zero();
+
+  Bbr2StartupMode startup_;
+  Bbr2DrainMode drain_;
+  Bbr2ProbeBwMode probe_bw_;
+  Bbr2ProbeRttMode probe_rtt_;
+
+  bool has_non_app_limited_sample_ = false;
+
+  // Debug only.
+  bool last_sample_is_app_limited_;
+
+  friend class Bbr2StartupMode;
+  friend class Bbr2DrainMode;
+  friend class Bbr2ProbeBwMode;
+  friend class Bbr2ProbeRttMode;
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2Sender::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_simulator_test.cc b/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
new file mode 100644
index 0000000..6eec232
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
@@ -0,0 +1,2298 @@
+// Copyright 2019 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 <memory>
+#include <sstream>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/congestion_control/bbr_sender.h"
+#include "quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/send_algorithm_test_result.pb.h"
+#include "quiche/quic/test_tools/send_algorithm_test_utils.h"
+#include "quiche/quic/test_tools/simulator/link.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+#include "quiche/quic/test_tools/simulator/traffic_policer.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+using testing::AllOf;
+using testing::Ge;
+using testing::Le;
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, quic_bbr2_test_regression_mode, "",
+    "One of a) 'record' to record test result (one file per test), or "
+    "b) 'regress' to regress against recorded results, or "
+    "c) <anything else> for non-regression mode.");
+
+namespace quic {
+
+using CyclePhase = Bbr2ProbeBwMode::CyclePhase;
+
+namespace test {
+
+// Use the initial CWND of 10, as 32 is too much for the test network.
+const uint32_t kDefaultInitialCwndPackets = 10;
+const uint32_t kDefaultInitialCwndBytes =
+    kDefaultInitialCwndPackets * kDefaultTCPMSS;
+
+struct LinkParams {
+  LinkParams(int64_t kilo_bits_per_sec, int64_t delay_us)
+      : bandwidth(QuicBandwidth::FromKBitsPerSecond(kilo_bits_per_sec)),
+        delay(QuicTime::Delta::FromMicroseconds(delay_us)) {}
+  QuicBandwidth bandwidth;
+  QuicTime::Delta delay;
+};
+
+struct TrafficPolicerParams {
+  std::string name = "policer";
+  QuicByteCount initial_burst_size;
+  QuicByteCount max_bucket_size;
+  QuicBandwidth target_bandwidth = QuicBandwidth::Zero();
+};
+
+// All Bbr2DefaultTopologyTests uses the default network topology:
+//
+//            Sender
+//               |
+//               |  <-- local_link
+//               |
+//        Network switch
+//               *  <-- the bottleneck queue in the direction
+//               |          of the receiver
+//               |
+//               |  <-- test_link
+//               |
+//               |
+//           Receiver
+class DefaultTopologyParams {
+ public:
+  LinkParams local_link = {10000, 2000};
+  LinkParams test_link = {4000, 30000};
+
+  const simulator::SwitchPortNumber switch_port_count = 2;
+  // Network switch queue capacity, in number of BDPs.
+  float switch_queue_capacity_in_bdp = 2;
+
+  absl::optional<TrafficPolicerParams> sender_policer_params;
+
+  QuicBandwidth BottleneckBandwidth() const {
+    return std::min(local_link.bandwidth, test_link.bandwidth);
+  }
+
+  // Round trip time of a single full size packet.
+  QuicTime::Delta RTT() const {
+    return 2 * (local_link.delay + test_link.delay +
+                local_link.bandwidth.TransferTime(kMaxOutgoingPacketSize) +
+                test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
+  }
+
+  QuicByteCount BDP() const { return BottleneckBandwidth() * RTT(); }
+
+  QuicByteCount SwitchQueueCapacity() const {
+    return switch_queue_capacity_in_bdp * BDP();
+  }
+
+  std::string ToString() const {
+    std::ostringstream os;
+    os << "{ BottleneckBandwidth: " << BottleneckBandwidth()
+       << " RTT: " << RTT() << " BDP: " << BDP()
+       << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
+    return os.str();
+  }
+};
+
+class Bbr2SimulatorTest : public QuicTest {
+ protected:
+  Bbr2SimulatorTest() : simulator_(&random_) {
+    // Prevent the server(receiver), which only sends acks, from closing
+    // connection due to too many outstanding packets.
+    SetQuicFlag(FLAGS_quic_max_tracked_packet_count, 1000000);
+  }
+
+  void SetUp() override {
+    if (GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode) == "regress") {
+      SendAlgorithmTestResult expected;
+      ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
+      random_seed_ = expected.random_seed();
+    } else {
+      random_seed_ = QuicRandom::GetInstance()->RandUint64();
+    }
+    random_.set_seed(random_seed_);
+    QUIC_LOG(INFO) << "Using random seed: " << random_seed_;
+  }
+
+  ~Bbr2SimulatorTest() override {
+    const std::string regression_mode =
+        GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode);
+    const QuicTime::Delta simulated_duration =
+        SimulatedNow() - QuicTime::Zero();
+    if (regression_mode == "record") {
+      RecordSendAlgorithmTestResult(random_seed_,
+                                    simulated_duration.ToMicroseconds());
+    } else if (regression_mode == "regress") {
+      CompareSendAlgorithmTestResult(simulated_duration.ToMicroseconds());
+    }
+  }
+
+  QuicTime SimulatedNow() const { return simulator_.GetClock()->Now(); }
+
+  uint64_t random_seed_;
+  SimpleRandom random_;
+  simulator::Simulator simulator_;
+};
+
+class Bbr2DefaultTopologyTest : public Bbr2SimulatorTest {
+ protected:
+  Bbr2DefaultTopologyTest()
+      : sender_endpoint_(&simulator_,
+                         "Sender",
+                         "Receiver",
+                         Perspective::IS_CLIENT,
+                         TestConnectionId(42)),
+        receiver_endpoint_(&simulator_,
+                           "Receiver",
+                           "Sender",
+                           Perspective::IS_SERVER,
+                           TestConnectionId(42)) {
+    sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
+  }
+
+  ~Bbr2DefaultTopologyTest() {
+    const auto* test_info =
+        ::testing::UnitTest::GetInstance()->current_test_info();
+    const Bbr2Sender::DebugState& debug_state = sender_->ExportDebugState();
+    QUIC_LOG(INFO) << "Bbr2DefaultTopologyTest." << test_info->name()
+                   << " completed at simulated time: "
+                   << SimulatedNow().ToDebuggingValue() / 1e6
+                   << " sec. packet loss:"
+                   << sender_loss_rate_in_packets() * 100
+                   << "%, bw_hi:" << debug_state.bandwidth_hi;
+  }
+
+  QuicUnackedPacketMap* GetUnackedMap(QuicConnection* connection) {
+    return QuicSentPacketManagerPeer::GetUnackedPacketMap(
+        QuicConnectionPeer::GetSentPacketManager(connection));
+  }
+
+  Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint,
+                              BbrSender* old_sender) {
+    // Ownership of the sender will be overtaken by the endpoint.
+    Bbr2Sender* sender = new Bbr2Sender(
+        endpoint->connection()->clock()->Now(),
+        endpoint->connection()->sent_packet_manager().GetRttStats(),
+        GetUnackedMap(endpoint->connection()), kDefaultInitialCwndPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+        QuicConnectionPeer::GetStats(endpoint->connection()), old_sender);
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    const int kTestMaxPacketSize = 1350;
+    endpoint->connection()->SetMaxPacketLength(kTestMaxPacketSize);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  void CreateNetwork(const DefaultTopologyParams& params) {
+    QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
+                                                  params.switch_port_count,
+                                                  params.SwitchQueueCapacity());
+
+    // WARNING: The order to add links to network_links_ matters, because some
+    // tests adjusts the link bandwidth on the fly.
+
+    // Local link connects sender and port 1.
+    network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+        &sender_endpoint_, switch_->port(1), params.local_link.bandwidth,
+        params.local_link.delay));
+
+    // Test link connects receiver and port 2.
+    if (params.sender_policer_params.has_value()) {
+      const TrafficPolicerParams& policer_params =
+          params.sender_policer_params.value();
+      sender_policer_ = std::make_unique<simulator::TrafficPolicer>(
+          &simulator_, policer_params.name, policer_params.initial_burst_size,
+          policer_params.max_bucket_size, policer_params.target_bandwidth,
+          switch_->port(2));
+      network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+          &receiver_endpoint_, sender_policer_.get(),
+          params.test_link.bandwidth, params.test_link.delay));
+    } else {
+      network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+          &receiver_endpoint_, switch_->port(2), params.test_link.bandwidth,
+          params.test_link.delay));
+    }
+  }
+
+  simulator::SymmetricLink* TestLink() { return network_links_[1].get(); }
+
+  void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta timeout) {
+    sender_endpoint_.AddBytesToTransfer(transfer_size);
+    // TODO(wub): consider rewriting this to run until the receiver actually
+    // receives the intended amount of bytes.
+    bool simulator_result = simulator_.RunUntilOrTimeout(
+        [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+        timeout);
+    EXPECT_TRUE(simulator_result)
+        << "Simple transfer failed.  Bytes remaining: "
+        << sender_endpoint_.bytes_to_transfer();
+    QUIC_LOG(INFO) << "Simple transfer state: " << sender_->ExportDebugState();
+  }
+
+  // Drive the simulator by sending enough data to enter PROBE_BW.
+  void DriveOutOfStartup(const DefaultTopologyParams& params) {
+    ASSERT_FALSE(sender_->ExportDebugState().startup.full_bandwidth_reached);
+    DoSimpleTransfer(1024 * 1024, QuicTime::Delta::FromSeconds(15));
+    EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
+    EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                     sender_->ExportDebugState().bandwidth_hi, 0.02f);
+  }
+
+  // Send |bytes|-sized bursts of data |number_of_bursts| times, waiting for
+  // |wait_time| between each burst.
+  void SendBursts(const DefaultTopologyParams& params,
+                  size_t number_of_bursts,
+                  QuicByteCount bytes,
+                  QuicTime::Delta wait_time) {
+    ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
+    for (size_t i = 0; i < number_of_bursts; i++) {
+      sender_endpoint_.AddBytesToTransfer(bytes);
+
+      // Transfer data and wait for three seconds between each transfer.
+      simulator_.RunFor(wait_time);
+
+      // Ensure the connection did not time out.
+      ASSERT_TRUE(sender_endpoint_.connection()->connected());
+      ASSERT_TRUE(receiver_endpoint_.connection()->connected());
+    }
+
+    simulator_.RunFor(wait_time + params.RTT());
+    ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
+  }
+
+  template <class TerminationPredicate>
+  bool SendUntilOrTimeout(TerminationPredicate termination_predicate,
+                          QuicTime::Delta timeout) {
+    EXPECT_EQ(0u, sender_endpoint_.bytes_to_transfer());
+    const QuicTime deadline = SimulatedNow() + timeout;
+    do {
+      sender_endpoint_.AddBytesToTransfer(4 * kDefaultTCPMSS);
+      if (simulator_.RunUntilOrTimeout(
+              [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+              deadline - SimulatedNow()) &&
+          termination_predicate()) {
+        return true;
+      }
+    } while (SimulatedNow() < deadline);
+    return false;
+  }
+
+  void EnableAggregation(QuicByteCount aggregation_bytes,
+                         QuicTime::Delta aggregation_timeout) {
+    switch_->port_queue(1)->EnableAggregation(aggregation_bytes,
+                                              aggregation_timeout);
+  }
+
+  void SetConnectionOption(QuicTag option) {
+    SetConnectionOption(std::move(option), sender_);
+  }
+
+  void SetConnectionOption(QuicTag option, Bbr2Sender* sender) {
+    QuicConfig config;
+    QuicTagVector options;
+    options.push_back(option);
+    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+    sender->SetFromConfig(config, Perspective::IS_SERVER);
+  }
+
+  bool Bbr2ModeIsOneOf(const std::vector<Bbr2Mode>& expected_modes) const {
+    const Bbr2Mode mode = sender_->ExportDebugState().mode;
+    for (Bbr2Mode expected_mode : expected_modes) {
+      if (mode == expected_mode) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  const RttStats* rtt_stats() {
+    return sender_endpoint_.connection()->sent_packet_manager().GetRttStats();
+  }
+
+  QuicConnection* sender_connection() { return sender_endpoint_.connection(); }
+
+  Bbr2Sender::DebugState sender_debug_state() const {
+    return sender_->ExportDebugState();
+  }
+
+  const QuicConnectionStats& sender_connection_stats() {
+    return sender_connection()->GetStats();
+  }
+
+  QuicUnackedPacketMap* sender_unacked_map() {
+    return GetUnackedMap(sender_connection());
+  }
+
+  float sender_loss_rate_in_packets() {
+    return static_cast<float>(sender_connection_stats().packets_lost) /
+           sender_connection_stats().packets_sent;
+  }
+
+  simulator::QuicEndpoint sender_endpoint_;
+  simulator::QuicEndpoint receiver_endpoint_;
+  Bbr2Sender* sender_;
+
+  std::unique_ptr<simulator::Switch> switch_;
+  std::unique_ptr<simulator::TrafficPolicer> sender_policer_;
+  std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
+};
+
+TEST_F(Bbr2DefaultTopologyTest, NormalStartup) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      3u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207) {
+  SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
+  SetConnectionOption(kB207);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      1u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+}
+
+// Add extra_acked to CWND in STARTUP and exit STARTUP on a persistent queue.
+TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207andB205) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
+  SetConnectionOption(kB205);
+  SetConnectionOption(kB207);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      2u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+}
+
+// Test a simple long data transfer in the default setup.
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // At startup make sure we are at the default.
+  EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // And that window is un-affected.
+  EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
+
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultInitialCwndBytes, rtt_stats()->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // The margin here is quite high, since there exists a possibility that the
+  // connection just exited high gain cycle.
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 1.0f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB2RC) {
+  SetConnectionOption(kB2RC);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB201) {
+  SetConnectionOption(kB201);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB206) {
+  SetQuicReloadableFlag(quic_bbr2_startup_probe_up_loss_events, true);
+  SetConnectionOption(kB206);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB207) {
+  SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
+  SetConnectionOption(kB207);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBRB) {
+  SetConnectionOption(kBBRB);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR4) {
+  SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
+  SetConnectionOption(kBBR4);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR5) {
+  SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
+  SetConnectionOption(kBBR5);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBuffer) {
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+  EXPECT_GE(sender_connection_stats().packets_lost, 0u);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBufferB2H2) {
+  SetConnectionOption(kB2H2);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+  EXPECT_GE(sender_connection_stats().packets_lost, 0u);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) {
+  SetConnectionOption(kBSAO);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
+    EXPECT_EQ(sender_loss_rate_in_packets(), 0);
+  } else {
+    EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  }
+  // The margin here is high, because both link level aggregation and ack
+  // decimation can greatly increase smoothed rtt.
+  EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytesB201) {
+  SetConnectionOption(kB201);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  // TODO(wub): Tighten the error bound once BSAO is default enabled.
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.5f);
+
+  if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
+    EXPECT_LE(sender_loss_rate_in_packets(), 0.01);
+  } else {
+    EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  }
+  // The margin here is high, because both link level aggregation and ack
+  // decimation can greatly increase smoothed rtt.
+  EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferAckDecimation) {
+  SetConnectionOption(kBSAO);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.001);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 3, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.1f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth decrease during a transfer.
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthDecrease)) {
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
+
+  // We can transfer ~12MB in the first 10 seconds. The rest ~8MB needs about
+  // 640 seconds.
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(10));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth decreasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+
+  // Now decrease the bottleneck bandwidth from 10Mbps to 100Kbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(800));
+  EXPECT_TRUE(simulator_result);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer.
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncrease)) {
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseBBQ0)) {
+  SetQuicReloadableFlag(quic_bbr2_add_bytes_acked_after_inflight_hi_limited,
+                        true);
+  SetConnectionOption(kBBQ0);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseBBQ0Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_add_bytes_acked_after_inflight_hi_limited,
+                        true);
+  SetConnectionOption(kBBQ0);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present,
+  // Ideally BSAO or another option would fix this.
+  // TODO(ianswett) Make these bound tighter once overestimation is reduced.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.6f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 10% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.90f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB202)) {
+  SetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue, true);
+  SetConnectionOption(kB202);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.1f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseB202Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue, true);
+  SetConnectionOption(kB202);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present,
+  // Ideally BSAO or another option would fix this.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.6f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 10% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.92f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B203
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB203)) {
+  SetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up, true);
+  SetConnectionOption(kB203);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B203
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseB203Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up, true);
+  SetConnectionOption(kB203);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present,
+  // Ideally BSAO or another option would fix this.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.60f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 10% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.91f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB204)) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetConnectionOption(kB204);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.25);
+  EXPECT_LE(sender_->ExportDebugState().max_ack_height, 2000u);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseB204Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetConnectionOption(kB204);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present, and B204 actually
+  // is increasing overestimation, which is surprising.
+  // Ideally BSAO or another option would fix this.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.60f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
+  EXPECT_LE(sender_->ExportDebugState().max_ack_height, 10000u);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 10% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.95f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB205)) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetConnectionOption(kB205);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.10);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.1f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseB205Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetConnectionOption(kB205);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present,
+  // Ideally BSAO or another option would fix this.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.45f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.15);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 5% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.9f);
+}
+
+// Test the number of losses incurred by the startup phase in a situation when
+// the buffer is less than BDP.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossOnSmallBufferStartup) {
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  // Packet loss is smaller with a CWND gain of 2 than 2.889.
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+}
+
+// Test the number of losses decreases with packet-conservation pacing.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ6SmallBufferStartup) {
+  SetConnectionOption(kBBQ2);  // Increase CWND gain.
+  SetConnectionOption(kBBQ6);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.0575);
+  // bandwidth_lo is cleared exiting STARTUP.
+  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
+            QuicBandwidth::Infinite());
+}
+
+// Test the number of losses decreases with min_rtt packet-conservation pacing.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ7SmallBufferStartup) {
+  SetConnectionOption(kBBQ2);  // Increase CWND gain.
+  SetConnectionOption(kBBQ7);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.06);
+  // bandwidth_lo is cleared exiting STARTUP.
+  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
+            QuicBandwidth::Infinite());
+}
+
+// Test the number of losses decreases with Inflight packet-conservation pacing.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ8SmallBufferStartup) {
+  SetConnectionOption(kBBQ2);  // Increase CWND gain.
+  SetConnectionOption(kBBQ8);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
+  // bandwidth_lo is cleared exiting STARTUP.
+  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
+            QuicBandwidth::Infinite());
+}
+
+// Test the number of losses decreases with CWND packet-conservation pacing.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ9SmallBufferStartup) {
+  SetConnectionOption(kBBQ2);  // Increase CWND gain.
+  SetConnectionOption(kBBQ9);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
+  // bandwidth_lo is cleared exiting STARTUP.
+  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
+            QuicBandwidth::Infinite());
+}
+
+// Verify the behavior of the algorithm in the case when the connection sends
+// small bursts of data after sending continuously for a while.
+TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBursts) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  EXPECT_FALSE(sender_->HasGoodBandwidthEstimateForResumption());
+  DriveOutOfStartup(params);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
+
+  SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
+  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+}
+
+// Verify the behavior of the algorithm in the case when the connection sends
+// small bursts of data and then starts sending continuously.
+TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBurstsWithoutPrior) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  SendBursts(params, 40, 512, QuicTime::Delta::FromSeconds(3));
+  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  DriveOutOfStartup(params);
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Verify that the DRAIN phase works correctly.
+TEST_F(Bbr2DefaultTopologyTest, Drain) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+  // Get the queue at the bottleneck, which is the outgoing queue at the port to
+  // which the receiver is connected.
+  const simulator::Queue* queue = switch_->port_queue(2);
+  bool simulator_result;
+
+  // We have no intention of ever finishing this transfer.
+  sender_endpoint_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Run the startup, and verify that it fills up the queue.
+  ASSERT_EQ(Bbr2Mode::STARTUP, sender_->ExportDebugState().mode);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode != Bbr2Mode::STARTUP;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
+                   sender_->PacingRate(0), 0.01f);
+
+  // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer with
+  // approximately 1 BDP.  Here, we use 0.95 to give some margin for error.
+  EXPECT_GE(queue->bytes_queued(), 0.95 * params.BDP());
+
+  // Observe increased RTT due to bufferbloat.
+  const QuicTime::Delta queueing_delay =
+      params.test_link.bandwidth.TransferTime(queue->bytes_queued());
+  EXPECT_APPROX_EQ(params.RTT() + queueing_delay, rtt_stats()->latest_rtt(),
+                   0.1f);
+
+  // Transition to the drain phase and verify that it makes the queue
+  // have at most a BDP worth of packets.
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().mode != Bbr2Mode::DRAIN; },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_LE(queue->bytes_queued(), params.BDP());
+
+  // Wait for a few round trips and ensure we're in appropriate phase of gain
+  // cycling before taking an RTT measurement.
+  const QuicRoundTripCount start_round_trip =
+      sender_->ExportDebugState().round_trip_count;
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this, start_round_trip]() {
+        const auto& debug_state = sender_->ExportDebugState();
+        QuicRoundTripCount rounds_passed =
+            debug_state.round_trip_count - start_round_trip;
+        return rounds_passed >= 4 && debug_state.mode == Bbr2Mode::PROBE_BW &&
+               debug_state.probe_bw.phase == CyclePhase::PROBE_REFILL;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Observe the bufferbloat go away.
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 0.1f);
+}
+
+// Ensure that a connection that is app-limited and is at sufficiently low
+// bandwidth will not exit high gain phase, and similarly ensure that the
+// connection will exit low gain early if the number of bytes in flight is low.
+TEST_F(Bbr2DefaultTopologyTest, InFlightAwareGainCycling) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+  DriveOutOfStartup(params);
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result;
+
+  // Start a few cycles prior to the high gain one.
+  simulator_result = SendUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().probe_bw.phase ==
+               CyclePhase::PROBE_REFILL;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Send at 10% of available rate.  Run for 3 seconds, checking in the middle
+  // and at the end.  The pacing gain should be high throughout.
+  QuicBandwidth target_bandwidth = 0.1f * params.BottleneckBandwidth();
+  QuicTime::Delta burst_interval = QuicTime::Delta::FromMilliseconds(300);
+  for (int i = 0; i < 2; i++) {
+    SendBursts(params, 5, target_bandwidth * burst_interval, burst_interval);
+    EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
+    EXPECT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
+    EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                     sender_->ExportDebugState().bandwidth_hi, 0.02f);
+  }
+
+  // Now that in-flight is almost zero and the pacing gain is still above 1,
+  // send approximately 1.4 BDPs worth of data. This should cause the PROBE_BW
+  // mode to enter low gain cycle(PROBE_DOWN), and exit it earlier than one
+  // min_rtt due to running out of data to send.
+  sender_endpoint_.AddBytesToTransfer(1.4 * params.BDP());
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().probe_bw.phase ==
+               CyclePhase::PROBE_DOWN;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  simulator_.RunFor(0.75 * sender_->ExportDebugState().min_rtt);
+  EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_EQ(CyclePhase::PROBE_CRUISE,
+            sender_->ExportDebugState().probe_bw.phase);
+}
+
+// Test exiting STARTUP earlier upon loss due to loss.
+TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLoss) {
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      1u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_NE(0u, sender_connection_stats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  EXPECT_GT(sender_->ExportDebugState().inflight_hi, 1.2f * params.BDP());
+}
+
+// Test exiting STARTUP earlier upon loss due to loss when connection option
+// B2SL is used.
+TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2SL) {
+  SetConnectionOption(kB2SL);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      1u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_NE(0u, sender_connection_stats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  EXPECT_APPROX_EQ(sender_->ExportDebugState().inflight_hi, params.BDP(), 0.1f);
+}
+
+// Verifies that in STARTUP, if we exceed loss threshold in a round, we exit
+// STARTUP at the end of the round even if there's enough bandwidth growth.
+TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2NE) {
+  // Set up flags such that any loss will be considered "too high".
+  SetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count, 0);
+  SetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold, 0.0);
+
+  sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
+
+  SetConnectionOption(kB2NE);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(sender_->ExportDebugState().round_trip_count, max_bw_round);
+  EXPECT_EQ(
+      0u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_NE(0u, sender_connection_stats().packets_lost);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SenderPoliced) {
+  DefaultTopologyParams params;
+  params.sender_policer_params = TrafficPolicerParams();
+  params.sender_policer_params->initial_burst_size = 1000 * 10;
+  params.sender_policer_params->max_bucket_size = 1000 * 100;
+  params.sender_policer_params->target_bandwidth =
+      params.BottleneckBandwidth() * 0.25;
+
+  CreateNetwork(params);
+
+  ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
+
+  DoSimpleTransfer(3 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  // TODO(wub): Fix (long-term) bandwidth overestimation in policer mode, then
+  // reduce the loss rate upper bound.
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+}
+
+// TODO(wub): Add other slowstart stats to BBRv2.
+TEST_F(Bbr2DefaultTopologyTest, StartupStats) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  ASSERT_FALSE(sender_->InSlowStart());
+
+  const QuicConnectionStats& stats = sender_connection_stats();
+  // The test explicitly replaces the default-created send algorithm with the
+  // one created by the test. slowstart_count increaments every time a BBR
+  // sender is created.
+  EXPECT_GE(stats.slowstart_count, 1u);
+  EXPECT_FALSE(stats.slowstart_duration.IsRunning());
+  EXPECT_THAT(stats.slowstart_duration.GetTotalElapsedTime(),
+              AllOf(Ge(QuicTime::Delta::FromMilliseconds(500)),
+                    Le(QuicTime::Delta::FromMilliseconds(1500))));
+  EXPECT_EQ(stats.slowstart_duration.GetTotalElapsedTime(),
+            QuicConnectionPeer::GetSentPacketManager(sender_connection())
+                ->GetSlowStartDuration());
+}
+
+TEST_F(Bbr2DefaultTopologyTest, ProbeUpAdaptInflightHiGradually) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+
+  AckedPacketVector acked_packets;
+  QuicPacketNumber acked_packet_number =
+      sender_unacked_map()->GetLeastUnacked();
+  for (auto& info : *sender_unacked_map()) {
+    acked_packets.emplace_back(acked_packet_number++, info.bytes_sent,
+                               SimulatedNow());
+  }
+
+  // Advance time significantly so the OnCongestionEvent enters PROBE_REFILL.
+  QuicTime now = SimulatedNow() + QuicTime::Delta::FromSeconds(5);
+  auto next_packet_number = sender_unacked_map()->largest_sent_packet() + 1;
+  sender_->OnCongestionEvent(
+      /*rtt_updated=*/true, sender_unacked_map()->bytes_in_flight(), now,
+      acked_packets, {});
+  ASSERT_EQ(CyclePhase::PROBE_REFILL,
+            sender_->ExportDebugState().probe_bw.phase);
+
+  // Send and Ack one packet to exit app limited and enter PROBE_UP.
+  sender_->OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
+                        kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
+  now = now + params.RTT();
+  sender_->OnCongestionEvent(
+      /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
+      {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)}, {});
+  ASSERT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
+
+  // Send 2 packets and lose the first one(50% loss) to exit PROBE_UP.
+  for (uint64_t i = 0; i < 2; ++i) {
+    sender_->OnPacketSent(now, /*bytes_in_flight=*/i * kDefaultMaxPacketSize,
+                          next_packet_number++, kDefaultMaxPacketSize,
+                          HAS_RETRANSMITTABLE_DATA);
+  }
+  now = now + params.RTT();
+  sender_->OnCongestionEvent(
+      /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
+      {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)},
+      {LostPacket(next_packet_number - 2, kDefaultMaxPacketSize)});
+
+  QuicByteCount inflight_hi = sender_->ExportDebugState().inflight_hi;
+  EXPECT_LT(2 * kDefaultMaxPacketSize, inflight_hi);
+}
+
+// Ensures bandwidth estimate does not change after a loss only event.
+TEST_F(Bbr2DefaultTopologyTest, LossOnlyCongestionEvent) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // Send some bursts, each burst increments round count by 1, since it only
+  // generates small, app-limited samples, the max_bandwidth_filter_ will not be
+  // updated.
+  SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
+
+  // Run until we have something in flight.
+  sender_endpoint_.AddBytesToTransfer(50 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [&]() { return sender_unacked_map()->bytes_in_flight() > 0; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+
+  const QuicBandwidth prior_bandwidth_estimate = sender_->BandwidthEstimate();
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(), prior_bandwidth_estimate,
+                   0.01f);
+
+  // Lose the least unacked packet.
+  LostPacketVector lost_packets;
+  lost_packets.emplace_back(
+      sender_connection()->sent_packet_manager().GetLeastUnacked(),
+      kDefaultMaxPacketSize);
+
+  QuicTime now = simulator_.GetClock()->Now() + params.RTT() * 0.25;
+  sender_->OnCongestionEvent(false, sender_unacked_map()->bytes_in_flight(),
+                             now, {}, lost_packets);
+
+  // Bandwidth estimate should not change for the loss only event.
+  EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
+}
+
+// After quiescence, if the sender is in PROBE_RTT, it should transition to
+// PROBE_BW immediately on the first sent packet after quiescence.
+TEST_F(Bbr2DefaultTopologyTest, ProbeRttAfterQuiescenceImmediatelyExits) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(15);
+  bool simulator_result;
+
+  // Keep sending until reach PROBE_RTT.
+  simulator_result = SendUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Wait for entering a quiescence of 5 seconds.
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_unacked_map()->bytes_in_flight() == 0 &&
+               sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
+      },
+      timeout));
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(5));
+
+  // Send one packet to exit quiescence.
+  EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_RTT);
+  sender_->OnPacketSent(SimulatedNow(), /*bytes_in_flight=*/0,
+                        sender_unacked_map()->largest_sent_packet() + 1,
+                        kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
+
+  EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_BW);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, ProbeBwAfterQuiescencePostponeMinRttTimestamp) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result;
+
+  // Keep sending until reach PROBE_REFILL.
+  simulator_result = SendUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().probe_bw.phase ==
+               CyclePhase::PROBE_REFILL;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  const QuicTime min_rtt_timestamp_before_idle =
+      sender_->ExportDebugState().min_rtt_timestamp;
+
+  // Wait for entering a quiescence of 15 seconds.
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() { return sender_unacked_map()->bytes_in_flight() == 0; },
+      params.RTT() + timeout));
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+
+  // Send some data to exit quiescence.
+  SendBursts(params, 1, kDefaultTCPMSS, QuicTime::Delta::Zero());
+  const QuicTime min_rtt_timestamp_after_idle =
+      sender_->ExportDebugState().min_rtt_timestamp;
+
+  EXPECT_LT(min_rtt_timestamp_before_idle + QuicTime::Delta::FromSeconds(14),
+            min_rtt_timestamp_after_idle);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SwitchToBbr2MidConnection) {
+  QuicTime now = QuicTime::Zero();
+  BbrSender old_sender(sender_connection()->clock()->Now(),
+                       sender_connection()->sent_packet_manager().GetRttStats(),
+                       GetUnackedMap(sender_connection()),
+                       kDefaultInitialCwndPackets + 1,
+                       GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+                       QuicConnectionPeer::GetStats(sender_connection()));
+
+  QuicPacketNumber next_packet_number(1);
+
+  // Send packets 1-4.
+  while (next_packet_number < QuicPacketNumber(5)) {
+    now = now + QuicTime::Delta::FromMilliseconds(10);
+
+    old_sender.OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
+                            /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
+  }
+
+  // Switch from |old_sender| to |sender_|.
+  const QuicByteCount old_sender_cwnd = old_sender.GetCongestionWindow();
+  sender_ = SetupBbr2Sender(&sender_endpoint_, &old_sender);
+  EXPECT_EQ(old_sender_cwnd, sender_->GetCongestionWindow());
+
+  // Send packets 5-7.
+  now = now + QuicTime::Delta::FromMilliseconds(10);
+  sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
+                        /*bytes=*/23, NO_RETRANSMITTABLE_DATA);
+
+  now = now + QuicTime::Delta::FromMilliseconds(10);
+  sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
+                        /*bytes=*/767, HAS_RETRANSMITTABLE_DATA);
+
+  QuicByteCount bytes_in_flight = 767;
+  while (next_packet_number < QuicPacketNumber(30)) {
+    now = now + QuicTime::Delta::FromMilliseconds(10);
+    bytes_in_flight += 1350;
+    sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
+                          /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
+  }
+
+  // Ack 1 & 2.
+  AckedPacketVector acked = {
+      AckedPacket(QuicPacketNumber(1), /*bytes_acked=*/0, QuicTime::Zero()),
+      AckedPacket(QuicPacketNumber(2), /*bytes_acked=*/0, QuicTime::Zero()),
+  };
+  now = now + QuicTime::Delta::FromMilliseconds(2000);
+  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
+
+  // Send 30-41.
+  while (next_packet_number < QuicPacketNumber(42)) {
+    now = now + QuicTime::Delta::FromMilliseconds(10);
+    bytes_in_flight += 1350;
+    sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
+                          /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
+  }
+
+  // Ack 3.
+  acked = {
+      AckedPacket(QuicPacketNumber(3), /*bytes_acked=*/0, QuicTime::Zero()),
+  };
+  now = now + QuicTime::Delta::FromMilliseconds(2000);
+  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
+
+  // Send 42.
+  now = now + QuicTime::Delta::FromMilliseconds(10);
+  bytes_in_flight += 1350;
+  sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
+                        /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
+
+  // Ack 4-7.
+  acked = {
+      AckedPacket(QuicPacketNumber(4), /*bytes_acked=*/0, QuicTime::Zero()),
+      AckedPacket(QuicPacketNumber(5), /*bytes_acked=*/0, QuicTime::Zero()),
+      AckedPacket(QuicPacketNumber(6), /*bytes_acked=*/767, QuicTime::Zero()),
+      AckedPacket(QuicPacketNumber(7), /*bytes_acked=*/1350, QuicTime::Zero()),
+  };
+  now = now + QuicTime::Delta::FromMilliseconds(2000);
+  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
+  EXPECT_FALSE(sender_->BandwidthEstimate().IsZero());
+}
+
+TEST_F(Bbr2DefaultTopologyTest, AdjustNetworkParameters) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  QUIC_LOG(INFO) << "Initial cwnd: " << sender_debug_state().congestion_window
+                 << "\nInitial pacing rate: " << sender_->PacingRate(0)
+                 << "\nInitial bandwidth estimate: "
+                 << sender_->BandwidthEstimate()
+                 << "\nInitial rtt: " << sender_debug_state().min_rtt;
+
+  sender_connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(params.BottleneckBandwidth(),
+                                            params.RTT(),
+                                            /*allow_cwnd_to_decrease=*/false));
+
+  EXPECT_EQ(params.BDP(), sender_->ExportDebugState().congestion_window);
+
+  EXPECT_EQ(params.BottleneckBandwidth(),
+            sender_->PacingRate(/*bytes_in_flight=*/0));
+  EXPECT_NE(params.BottleneckBandwidth(), sender_->BandwidthEstimate());
+
+  EXPECT_APPROX_EQ(params.RTT(), sender_->ExportDebugState().min_rtt, 0.01f);
+
+  DriveOutOfStartup(params);
+}
+
+TEST_F(Bbr2DefaultTopologyTest,
+       200InitialCongestionWindowWithNetworkParameterAdjusted) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
+
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  sender_connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
+                                            QuicTime::Delta::Zero(), false));
+
+  // Verify cwnd is capped at 200.
+  EXPECT_EQ(200 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
+}
+
+TEST_F(Bbr2DefaultTopologyTest,
+       100InitialCongestionWindowFromNetworkParameter) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  SendAlgorithmInterface::NetworkParams network_params(
+      1024 * params.BottleneckBandwidth(), QuicTime::Delta::Zero(), false);
+  network_params.max_initial_congestion_window = 100;
+  sender_connection()->AdjustNetworkParameters(network_params);
+
+  // Verify cwnd is capped at 100.
+  EXPECT_EQ(100 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
+}
+
+TEST_F(Bbr2DefaultTopologyTest,
+       100InitialCongestionWindowWithNetworkParameterAdjusted) {
+  SetConnectionOption(kICW1);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  sender_connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
+                                            QuicTime::Delta::Zero(), false));
+
+  // Verify cwnd is capped at 100.
+  EXPECT_EQ(100 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
+}
+
+// All Bbr2MultiSenderTests uses the following network topology:
+//
+//   Sender 0  (A Bbr2Sender)
+//       |
+//       | <-- local_links[0]
+//       |
+//       |  Sender N (1 <= N < kNumLocalLinks) (May or may not be a Bbr2Sender)
+//       |      |
+//       |      | <-- local_links[N]
+//       |      |
+//    Network switch
+//           *  <-- the bottleneck queue in the direction
+//           |          of the receiver
+//           |
+//           |  <-- test_link
+//           |
+//           |
+//       Receiver
+class MultiSenderTopologyParams {
+ public:
+  static constexpr size_t kNumLocalLinks = 8;
+  std::array<LinkParams, kNumLocalLinks> local_links = {
+      LinkParams(10000, 1987), LinkParams(10000, 1993), LinkParams(10000, 1997),
+      LinkParams(10000, 1999), LinkParams(10000, 2003), LinkParams(10000, 2011),
+      LinkParams(10000, 2017), LinkParams(10000, 2027),
+  };
+
+  LinkParams test_link = LinkParams(4000, 30000);
+
+  const simulator::SwitchPortNumber switch_port_count = kNumLocalLinks + 1;
+
+  // Network switch queue capacity, in number of BDPs.
+  float switch_queue_capacity_in_bdp = 2;
+
+  QuicBandwidth BottleneckBandwidth() const {
+    // Make sure all local links have a higher bandwidth than the test link.
+    for (size_t i = 0; i < local_links.size(); ++i) {
+      QUICHE_CHECK_GT(local_links[i].bandwidth, test_link.bandwidth);
+    }
+    return test_link.bandwidth;
+  }
+
+  // Sender n's round trip time of a single full size packet.
+  QuicTime::Delta Rtt(size_t n) const {
+    return 2 * (local_links[n].delay + test_link.delay +
+                local_links[n].bandwidth.TransferTime(kMaxOutgoingPacketSize) +
+                test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
+  }
+
+  QuicByteCount Bdp(size_t n) const { return BottleneckBandwidth() * Rtt(n); }
+
+  QuicByteCount SwitchQueueCapacity() const {
+    return switch_queue_capacity_in_bdp * Bdp(1);
+  }
+
+  std::string ToString() const {
+    std::ostringstream os;
+    os << "{ BottleneckBandwidth: " << BottleneckBandwidth();
+    for (size_t i = 0; i < local_links.size(); ++i) {
+      os << " RTT_" << i << ": " << Rtt(i) << " BDP_" << i << ": " << Bdp(i);
+    }
+    os << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
+    return os.str();
+  }
+};
+
+class Bbr2MultiSenderTest : public Bbr2SimulatorTest {
+ protected:
+  Bbr2MultiSenderTest() {
+    uint64_t first_connection_id = 42;
+    std::vector<simulator::QuicEndpointBase*> receiver_endpoint_pointers;
+    for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
+      std::string sender_name = absl::StrCat("Sender", i + 1);
+      std::string receiver_name = absl::StrCat("Receiver", i + 1);
+      sender_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
+          &simulator_, sender_name, receiver_name, Perspective::IS_CLIENT,
+          TestConnectionId(first_connection_id + i)));
+      receiver_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
+          &simulator_, receiver_name, sender_name, Perspective::IS_SERVER,
+          TestConnectionId(first_connection_id + i)));
+      receiver_endpoint_pointers.push_back(receiver_endpoints_.back().get());
+    }
+    receiver_multiplexer_ =
+        std::make_unique<simulator::QuicEndpointMultiplexer>(
+            "Receiver multiplexer", receiver_endpoint_pointers);
+    sender_0_ = SetupBbr2Sender(sender_endpoints_[0].get());
+  }
+
+  ~Bbr2MultiSenderTest() {
+    const auto* test_info =
+        ::testing::UnitTest::GetInstance()->current_test_info();
+    QUIC_LOG(INFO) << "Bbr2MultiSenderTest." << test_info->name()
+                   << " completed at simulated time: "
+                   << SimulatedNow().ToDebuggingValue() / 1e6
+                   << " sec. Per sender stats:";
+    for (size_t i = 0; i < sender_endpoints_.size(); ++i) {
+      QUIC_LOG(INFO) << "sender[" << i << "]: "
+                     << sender_connection(i)
+                            ->sent_packet_manager()
+                            .GetSendAlgorithm()
+                            ->GetCongestionControlType()
+                     << ", packet_loss:"
+                     << 100.0 * sender_loss_rate_in_packets(i) << "%";
+    }
+  }
+
+  Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint) {
+    // Ownership of the sender will be overtaken by the endpoint.
+    Bbr2Sender* sender = new Bbr2Sender(
+        endpoint->connection()->clock()->Now(),
+        endpoint->connection()->sent_packet_manager().GetRttStats(),
+        QuicSentPacketManagerPeer::GetUnackedPacketMap(
+            QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
+        kDefaultInitialCwndPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+        QuicConnectionPeer::GetStats(endpoint->connection()), nullptr);
+    // TODO(ianswett): Add dedicated tests for this option until it becomes
+    // the default behavior.
+    SetConnectionOption(sender, kBBRA);
+
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  BbrSender* SetupBbrSender(simulator::QuicEndpoint* endpoint) {
+    // Ownership of the sender will be overtaken by the endpoint.
+    BbrSender* sender = new BbrSender(
+        endpoint->connection()->clock()->Now(),
+        endpoint->connection()->sent_packet_manager().GetRttStats(),
+        QuicSentPacketManagerPeer::GetUnackedPacketMap(
+            QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
+        kDefaultInitialCwndPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+        QuicConnectionPeer::GetStats(endpoint->connection()));
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  // reno => Reno. !reno => Cubic.
+  TcpCubicSenderBytes* SetupTcpSender(simulator::QuicEndpoint* endpoint,
+                                      bool reno) {
+    // Ownership of the sender will be overtaken by the endpoint.
+    TcpCubicSenderBytes* sender = new TcpCubicSenderBytes(
+        endpoint->connection()->clock(),
+        endpoint->connection()->sent_packet_manager().GetRttStats(), reno,
+        kDefaultInitialCwndPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window),
+        QuicConnectionPeer::GetStats(endpoint->connection()));
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  void SetConnectionOption(SendAlgorithmInterface* sender, QuicTag option) {
+    QuicConfig config;
+    QuicTagVector options;
+    options.push_back(option);
+    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+    sender->SetFromConfig(config, Perspective::IS_SERVER);
+  }
+
+  void CreateNetwork(const MultiSenderTopologyParams& params) {
+    QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
+                                                  params.switch_port_count,
+                                                  params.SwitchQueueCapacity());
+
+    network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+        receiver_multiplexer_.get(), switch_->port(1),
+        params.test_link.bandwidth, params.test_link.delay));
+    for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
+      simulator::SwitchPortNumber port_number = i + 2;
+      network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+          sender_endpoints_[i].get(), switch_->port(port_number),
+          params.local_links[i].bandwidth, params.local_links[i].delay));
+    }
+  }
+
+  QuicConnection* sender_connection(size_t which) {
+    return sender_endpoints_[which]->connection();
+  }
+
+  const QuicConnectionStats& sender_connection_stats(size_t which) {
+    return sender_connection(which)->GetStats();
+  }
+
+  float sender_loss_rate_in_packets(size_t which) {
+    return static_cast<float>(sender_connection_stats(which).packets_lost) /
+           sender_connection_stats(which).packets_sent;
+  }
+
+  std::vector<std::unique_ptr<simulator::QuicEndpoint>> sender_endpoints_;
+  std::vector<std::unique_ptr<simulator::QuicEndpoint>> receiver_endpoints_;
+  std::unique_ptr<simulator::QuicEndpointMultiplexer> receiver_multiplexer_;
+  Bbr2Sender* sender_0_;
+
+  std::unique_ptr<simulator::Switch> switch_;
+  std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
+};
+
+TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2) {
+  SetupBbr2Sender(sender_endpoints_[1].get());
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(MultipleBbr2s)) {
+  const int kTotalNumSenders = 6;
+  for (int i = 1; i < kTotalNumSenders; ++i) {
+    SetupBbr2Sender(sender_endpoints_[i].get());
+  }
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time
+                 << ". Now: " << SimulatedNow();
+
+  // Start all transfers.
+  for (int i = 0; i < kTotalNumSenders; ++i) {
+    if (i != 0) {
+      const QuicTime sender_start_time =
+          SimulatedNow() + QuicTime::Delta::FromSeconds(2);
+      bool simulator_result = simulator_.RunUntilOrTimeout(
+          [&]() { return SimulatedNow() >= sender_start_time; }, transfer_time);
+      ASSERT_TRUE(simulator_result);
+    }
+
+    sender_endpoints_[i]->AddBytesToTransfer(transfer_size);
+  }
+
+  // Wait for all transfers to finish.
+  QuicTime::Delta expected_total_transfer_time_upper_bound =
+      QuicTime::Delta::FromMicroseconds(kTotalNumSenders *
+                                        transfer_time.ToMicroseconds() * 1.1);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        for (int i = 0; i < kTotalNumSenders; ++i) {
+          if (receiver_endpoints_[i]->bytes_received() < transfer_size) {
+            return false;
+          }
+        }
+        return true;
+      },
+      expected_total_transfer_time_upper_bound);
+  ASSERT_TRUE(simulator_result)
+      << "Expected upper bound: " << expected_total_transfer_time_upper_bound;
+}
+
+/* The first 11 packets are sent at the same time, but the duration between the
+ * acks of the 1st and the 11th packet is 49 milliseconds, causing very low bw
+ * samples. This happens for both large and small buffers.
+ */
+/*
+TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2LargeRttTinyBuffer) {
+  SetupBbr2Sender(sender_endpoints_[1].get());
+
+  MultiSenderTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.05;
+  params.test_link.delay = QuicTime::Delta::FromSeconds(1);
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+*/
+
+TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr1) {
+  SetupBbrSender(sender_endpoints_[1].get());
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsReno)) {
+  SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsRenoB2RC)) {
+  SetConnectionOption(sender_0_, kB2RC);
+  SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsCubic)) {
+  SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/false);
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 50 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_startup.cc b/quiche/quic/core/congestion_control/bbr2_startup.cc
new file mode 100644
index 0000000..7091353
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_startup.cc
@@ -0,0 +1,157 @@
+// Copyright 2019 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 "quiche/quic/core/congestion_control/bbr2_startup.h"
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+Bbr2StartupMode::Bbr2StartupMode(const Bbr2Sender* sender,
+                                 Bbr2NetworkModel* model,
+                                 QuicTime now)
+    : Bbr2ModeBase(sender, model) {
+  // Increment, instead of reset startup stats, so we don't lose data recorded
+  // before QuicConnection switched send algorithm to BBRv2.
+  ++sender_->connection_stats_->slowstart_count;
+  if (!sender_->connection_stats_->slowstart_duration.IsRunning()) {
+    sender_->connection_stats_->slowstart_duration.Start(now);
+  }
+  // Enter() is never called for Startup, so the gains needs to be set here.
+  model_->set_pacing_gain(Params().startup_pacing_gain);
+  model_->set_cwnd_gain(Params().startup_cwnd_gain);
+}
+
+void Bbr2StartupMode::Enter(QuicTime /*now*/,
+                            const Bbr2CongestionEvent* /*congestion_event*/) {
+  QUIC_BUG(quic_bug_10463_1) << "Bbr2StartupMode::Enter should not be called";
+}
+
+void Bbr2StartupMode::Leave(QuicTime now,
+                            const Bbr2CongestionEvent* /*congestion_event*/) {
+  sender_->connection_stats_->slowstart_duration.Stop(now);
+  // Clear bandwidth_lo if it's set during STARTUP.
+  model_->clear_bandwidth_lo();
+}
+
+Bbr2Mode Bbr2StartupMode::OnCongestionEvent(
+    QuicByteCount /*prior_in_flight*/,
+    QuicTime /*event_time*/,
+    const AckedPacketVector& /*acked_packets*/,
+    const LostPacketVector& /*lost_packets*/,
+    const Bbr2CongestionEvent& congestion_event) {
+  if (model_->full_bandwidth_reached()) {
+    QUIC_BUG() << "In STARTUP, but full_bandwidth_reached is true.";
+    return Bbr2Mode::DRAIN;
+  }
+  if (!congestion_event.end_of_round_trip) {
+    return Bbr2Mode::STARTUP;
+  }
+  bool has_bandwidth_growth = model_->HasBandwidthGrowth(congestion_event);
+  if (Params().exit_startup_on_persistent_queue && !has_bandwidth_growth) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_exit_startup_on_persistent_queue2);
+    model_->CheckPersistentQueue(congestion_event, Params().startup_cwnd_gain);
+  }
+  // TCP BBR always exits upon excessive losses. QUIC BBRv1 does not exit
+  // upon excessive losses, if enough bandwidth growth is observed or if the
+  // sample was app limited.
+  if (Params().always_exit_startup_on_excess_loss ||
+      (!congestion_event.last_packet_send_state.is_app_limited &&
+       !has_bandwidth_growth)) {
+    CheckExcessiveLosses(congestion_event);
+  }
+
+  if (Params().decrease_startup_pacing_at_end_of_round) {
+    QUICHE_DCHECK_GT(model_->pacing_gain(), 0);
+    if (!congestion_event.last_packet_send_state.is_app_limited) {
+      // Multiply by startup_pacing_gain, so if the bandwidth doubles,
+      // the pacing gain will be the full startup_pacing_gain.
+      if (max_bw_at_round_beginning_ > QuicBandwidth::Zero()) {
+        const float bandwidth_ratio =
+            std::max(1., model_->MaxBandwidth().ToBitsPerSecond() /
+                             static_cast<double>(
+                                 max_bw_at_round_beginning_.ToBitsPerSecond()));
+        // Even when bandwidth isn't increasing, use a gain large enough to
+        // cause a startup_full_bw_threshold increase.
+        const float new_gain =
+            ((bandwidth_ratio - 1) * (Params().startup_pacing_gain -
+                                      Params().startup_full_bw_threshold)) +
+            Params().startup_full_bw_threshold;
+        // Allow the pacing gain to decrease.
+        model_->set_pacing_gain(
+            std::min(Params().startup_pacing_gain, new_gain));
+        // Clear bandwidth_lo if it's less than the pacing rate.
+        // This avoids a constantly app-limited flow from having it's pacing
+        // gain effectively decreased below 1.25.
+        if (model_->bandwidth_lo() <
+            model_->MaxBandwidth() * model_->pacing_gain()) {
+          model_->clear_bandwidth_lo();
+        }
+      }
+      max_bw_at_round_beginning_ = model_->MaxBandwidth();
+    }
+  }
+
+  // TODO(wub): Maybe implement STARTUP => PROBE_RTT.
+  return model_->full_bandwidth_reached() ? Bbr2Mode::DRAIN : Bbr2Mode::STARTUP;
+}
+
+void Bbr2StartupMode::CheckExcessiveLosses(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK(congestion_event.end_of_round_trip);
+
+  if (model_->full_bandwidth_reached()) {
+    return;
+  }
+
+  // At the end of a round trip. Check if loss is too high in this round.
+  if (model_->IsInflightTooHigh(congestion_event,
+                                Params().startup_full_loss_count)) {
+    QuicByteCount new_inflight_hi = model_->BDP();
+    if (Params().startup_loss_exit_use_max_delivered_for_inflight_hi) {
+      if (new_inflight_hi < model_->max_bytes_delivered_in_round()) {
+        new_inflight_hi = model_->max_bytes_delivered_in_round();
+      }
+    }
+    QUIC_DVLOG(3) << sender_ << " Exiting STARTUP due to loss at round "
+                  << model_->RoundTripCount()
+                  << ". inflight_hi:" << new_inflight_hi;
+    // TODO(ianswett): Add a shared method to set inflight_hi in the model.
+    model_->set_inflight_hi(new_inflight_hi);
+    model_->set_full_bandwidth_reached();
+    sender_->connection_stats_->bbr_exit_startup_due_to_loss = true;
+  }
+}
+
+Bbr2StartupMode::DebugState Bbr2StartupMode::ExportDebugState() const {
+  DebugState s;
+  s.full_bandwidth_reached = model_->full_bandwidth_reached();
+  s.full_bandwidth_baseline = model_->full_bandwidth_baseline();
+  s.round_trips_without_bandwidth_growth =
+      model_->rounds_without_bandwidth_growth();
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2StartupMode::DebugState& state) {
+  os << "[STARTUP] full_bandwidth_reached: " << state.full_bandwidth_reached
+     << "\n";
+  os << "[STARTUP] full_bandwidth_baseline: " << state.full_bandwidth_baseline
+     << "\n";
+  os << "[STARTUP] round_trips_without_bandwidth_growth: "
+     << state.round_trips_without_bandwidth_growth << "\n";
+  return os;
+}
+
+const Bbr2Params& Bbr2StartupMode::Params() const {
+  return sender_->Params();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_startup.h b/quiche/quic/core/congestion_control/bbr2_startup.h
new file mode 100644
index 0000000..a041178
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_startup.h
@@ -0,0 +1,71 @@
+// Copyright 2019 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_CONGESTION_CONTROL_BBR2_STARTUP_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2StartupMode final : public Bbr2ModeBase {
+ public:
+  Bbr2StartupMode(const Bbr2Sender* sender,
+                  Bbr2NetworkModel* model,
+                  QuicTime now);
+
+  void Enter(QuicTime now,
+             const Bbr2CongestionEvent* congestion_event) override;
+  void Leave(QuicTime now,
+             const Bbr2CongestionEvent* congestion_event) override;
+
+  Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) override;
+
+  Limits<QuicByteCount> GetCwndLimits() const override {
+    // Inflight_lo is never set in STARTUP.
+    QUICHE_DCHECK_EQ(Bbr2NetworkModel::inflight_lo_default(),
+                     model_->inflight_lo());
+    return NoGreaterThan(model_->inflight_lo());
+  }
+
+  bool IsProbingForBandwidth() const override { return true; }
+
+  Bbr2Mode OnExitQuiescence(QuicTime /*now*/,
+                            QuicTime /*quiescence_start_time*/) override {
+    return Bbr2Mode::STARTUP;
+  }
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    bool full_bandwidth_reached;
+    QuicBandwidth full_bandwidth_baseline = QuicBandwidth::Zero();
+    QuicRoundTripCount round_trips_without_bandwidth_growth;
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  const Bbr2Params& Params() const;
+
+  void CheckExcessiveLosses(const Bbr2CongestionEvent& congestion_event);
+  // Used when the pacing gain can decrease in STARTUP.
+  QuicBandwidth max_bw_at_round_beginning_ = QuicBandwidth::Zero();
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2StartupMode::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
diff --git a/quiche/quic/core/congestion_control/bbr_sender.cc b/quiche/quic/core/congestion_control/bbr_sender.cc
new file mode 100644
index 0000000..022f225
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr_sender.cc
@@ -0,0 +1,914 @@
+// Copyright 2016 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 "quiche/quic/core/congestion_control/bbr_sender.h"
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+
+#include "absl/base/attributes.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_time_accumulator.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+// Constants based on TCP defaults.
+// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
+// Does not inflate the pacing rate.
+const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
+
+// The gain used for the STARTUP, equal to 2/ln(2).
+const float kDefaultHighGain = 2.885f;
+// The newly derived gain for STARTUP, equal to 4 * ln(2)
+const float kDerivedHighGain = 2.773f;
+// The newly derived CWND gain for STARTUP, 2.
+const float kDerivedHighCWNDGain = 2.0f;
+// The cycle of gains used during the PROBE_BW stage.
+const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1};
+
+// The length of the gain cycle.
+const size_t kGainCycleLength = sizeof(kPacingGain) / sizeof(kPacingGain[0]);
+// The size of the bandwidth filter window, in round-trips.
+const QuicRoundTripCount kBandwidthWindowSize = kGainCycleLength + 2;
+
+// The time after which the current min_rtt value expires.
+const QuicTime::Delta kMinRttExpiry = QuicTime::Delta::FromSeconds(10);
+// The minimum time the connection can spend in PROBE_RTT mode.
+const QuicTime::Delta kProbeRttTime = QuicTime::Delta::FromMilliseconds(200);
+// If the bandwidth does not increase by the factor of |kStartupGrowthTarget|
+// within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection
+// will exit the STARTUP mode.
+const float kStartupGrowthTarget = 1.25;
+const QuicRoundTripCount kRoundTripsWithoutGrowthBeforeExitingStartup = 3;
+}  // namespace
+
+BbrSender::DebugState::DebugState(const BbrSender& sender)
+    : mode(sender.mode_),
+      max_bandwidth(sender.max_bandwidth_.GetBest()),
+      round_trip_count(sender.round_trip_count_),
+      gain_cycle_index(sender.cycle_current_offset_),
+      congestion_window(sender.congestion_window_),
+      is_at_full_bandwidth(sender.is_at_full_bandwidth_),
+      bandwidth_at_last_round(sender.bandwidth_at_last_round_),
+      rounds_without_bandwidth_gain(sender.rounds_without_bandwidth_gain_),
+      min_rtt(sender.min_rtt_),
+      min_rtt_timestamp(sender.min_rtt_timestamp_),
+      recovery_state(sender.recovery_state_),
+      recovery_window(sender.recovery_window_),
+      last_sample_is_app_limited(sender.last_sample_is_app_limited_),
+      end_of_app_limited_phase(sender.sampler_.end_of_app_limited_phase()) {}
+
+BbrSender::DebugState::DebugState(const DebugState& state) = default;
+
+BbrSender::BbrSender(QuicTime now,
+                     const RttStats* rtt_stats,
+                     const QuicUnackedPacketMap* unacked_packets,
+                     QuicPacketCount initial_tcp_congestion_window,
+                     QuicPacketCount max_tcp_congestion_window,
+                     QuicRandom* random,
+                     QuicConnectionStats* stats)
+    : rtt_stats_(rtt_stats),
+      unacked_packets_(unacked_packets),
+      random_(random),
+      stats_(stats),
+      mode_(STARTUP),
+      sampler_(unacked_packets, kBandwidthWindowSize),
+      round_trip_count_(0),
+      num_loss_events_in_round_(0),
+      bytes_lost_in_round_(0),
+      max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0),
+      min_rtt_(QuicTime::Delta::Zero()),
+      min_rtt_timestamp_(QuicTime::Zero()),
+      congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
+      initial_congestion_window_(initial_tcp_congestion_window *
+                                 kDefaultTCPMSS),
+      max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS),
+      min_congestion_window_(kDefaultMinimumCongestionWindow),
+      high_gain_(kDefaultHighGain),
+      high_cwnd_gain_(kDefaultHighGain),
+      drain_gain_(1.f / kDefaultHighGain),
+      pacing_rate_(QuicBandwidth::Zero()),
+      pacing_gain_(1),
+      congestion_window_gain_(1),
+      congestion_window_gain_constant_(
+          static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_cwnd_gain))),
+      num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup),
+      cycle_current_offset_(0),
+      last_cycle_start_(QuicTime::Zero()),
+      is_at_full_bandwidth_(false),
+      rounds_without_bandwidth_gain_(0),
+      bandwidth_at_last_round_(QuicBandwidth::Zero()),
+      exiting_quiescence_(false),
+      exit_probe_rtt_at_(QuicTime::Zero()),
+      probe_rtt_round_passed_(false),
+      last_sample_is_app_limited_(false),
+      has_non_app_limited_sample_(false),
+      recovery_state_(NOT_IN_RECOVERY),
+      recovery_window_(max_congestion_window_),
+      slower_startup_(false),
+      rate_based_startup_(false),
+      enable_ack_aggregation_during_startup_(false),
+      expire_ack_aggregation_in_startup_(false),
+      drain_to_target_(false),
+      detect_overshooting_(false),
+      bytes_lost_while_detecting_overshooting_(0),
+      bytes_lost_multiplier_while_detecting_overshooting_(2),
+      cwnd_to_calculate_min_pacing_rate_(initial_congestion_window_),
+      max_congestion_window_with_network_parameters_adjusted_(
+          kMaxInitialCongestionWindow * kDefaultTCPMSS) {
+  if (stats_) {
+    // Clear some startup stats if |stats_| has been used by another sender,
+    // which happens e.g. when QuicConnection switch send algorithms.
+    stats_->slowstart_count = 0;
+    stats_->slowstart_duration = QuicTimeAccumulator();
+  }
+  EnterStartupMode(now);
+  set_high_cwnd_gain(kDerivedHighCWNDGain);
+}
+
+BbrSender::~BbrSender() {}
+
+void BbrSender::SetInitialCongestionWindowInPackets(
+    QuicPacketCount congestion_window) {
+  if (mode_ == STARTUP) {
+    initial_congestion_window_ = congestion_window * kDefaultTCPMSS;
+    congestion_window_ = congestion_window * kDefaultTCPMSS;
+    cwnd_to_calculate_min_pacing_rate_ = std::min(
+        initial_congestion_window_, cwnd_to_calculate_min_pacing_rate_);
+  }
+}
+
+bool BbrSender::InSlowStart() const {
+  return mode_ == STARTUP;
+}
+
+void BbrSender::OnPacketSent(QuicTime sent_time,
+                             QuicByteCount bytes_in_flight,
+                             QuicPacketNumber packet_number,
+                             QuicByteCount bytes,
+                             HasRetransmittableData is_retransmittable) {
+  if (stats_ && InSlowStart()) {
+    ++stats_->slowstart_packets_sent;
+    stats_->slowstart_bytes_sent += bytes;
+  }
+
+  last_sent_packet_ = packet_number;
+
+  if (bytes_in_flight == 0 && sampler_.is_app_limited()) {
+    exiting_quiescence_ = true;
+  }
+
+  sampler_.OnPacketSent(sent_time, packet_number, bytes, bytes_in_flight,
+                        is_retransmittable);
+}
+
+void BbrSender::OnPacketNeutered(QuicPacketNumber packet_number) {
+  sampler_.OnPacketNeutered(packet_number);
+}
+
+bool BbrSender::CanSend(QuicByteCount bytes_in_flight) {
+  return bytes_in_flight < GetCongestionWindow();
+}
+
+QuicBandwidth BbrSender::PacingRate(QuicByteCount /*bytes_in_flight*/) const {
+  if (pacing_rate_.IsZero()) {
+    return high_gain_ * QuicBandwidth::FromBytesAndTimeDelta(
+                            initial_congestion_window_, GetMinRtt());
+  }
+  return pacing_rate_;
+}
+
+QuicBandwidth BbrSender::BandwidthEstimate() const {
+  return max_bandwidth_.GetBest();
+}
+
+QuicByteCount BbrSender::GetCongestionWindow() const {
+  if (mode_ == PROBE_RTT) {
+    return ProbeRttCongestionWindow();
+  }
+
+  if (InRecovery()) {
+    return std::min(congestion_window_, recovery_window_);
+  }
+
+  return congestion_window_;
+}
+
+QuicByteCount BbrSender::GetSlowStartThreshold() const {
+  return 0;
+}
+
+bool BbrSender::InRecovery() const {
+  return recovery_state_ != NOT_IN_RECOVERY;
+}
+
+bool BbrSender::ShouldSendProbingPacket() const {
+  if (pacing_gain_ <= 1) {
+    return false;
+  }
+
+  // TODO(b/77975811): If the pipe is highly under-utilized, consider not
+  // sending a probing transmission, because the extra bandwidth is not needed.
+  return true;
+}
+
+void BbrSender::SetFromConfig(const QuicConfig& config,
+                              Perspective perspective) {
+  if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
+    num_startup_rtts_ = 1;
+  }
+  if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
+    num_startup_rtts_ = 2;
+  }
+  if (config.HasClientRequestedIndependentOption(kBBR3, perspective)) {
+    drain_to_target_ = true;
+  }
+  if (config.HasClientRequestedIndependentOption(kBWM3, perspective)) {
+    bytes_lost_multiplier_while_detecting_overshooting_ = 3;
+  }
+  if (config.HasClientRequestedIndependentOption(kBWM4, perspective)) {
+    bytes_lost_multiplier_while_detecting_overshooting_ = 4;
+  }
+  if (config.HasClientRequestedIndependentOption(kBBR4, perspective)) {
+    sampler_.SetMaxAckHeightTrackerWindowLength(2 * kBandwidthWindowSize);
+  }
+  if (config.HasClientRequestedIndependentOption(kBBR5, perspective)) {
+    sampler_.SetMaxAckHeightTrackerWindowLength(4 * kBandwidthWindowSize);
+  }
+  if (config.HasClientRequestedIndependentOption(kBBQ1, perspective)) {
+    set_high_gain(kDerivedHighGain);
+    set_high_cwnd_gain(kDerivedHighGain);
+    set_drain_gain(1.f / kDerivedHighGain);
+  }
+  if (config.HasClientRequestedIndependentOption(kBBQ3, perspective)) {
+    enable_ack_aggregation_during_startup_ = true;
+  }
+  if (config.HasClientRequestedIndependentOption(kBBQ5, perspective)) {
+    expire_ack_aggregation_in_startup_ = true;
+  }
+  if (config.HasClientRequestedIndependentOption(kMIN1, perspective)) {
+    min_congestion_window_ = kMaxSegmentSize;
+  }
+  if (config.HasClientRequestedIndependentOption(kICW1, perspective)) {
+    max_congestion_window_with_network_parameters_adjusted_ =
+        100 * kDefaultTCPMSS;
+  }
+  if (config.HasClientRequestedIndependentOption(kDTOS, perspective)) {
+    detect_overshooting_ = true;
+    // DTOS would allow pacing rate drop to IW 10 / min_rtt if overshooting is
+    // detected.
+    cwnd_to_calculate_min_pacing_rate_ =
+        std::min(initial_congestion_window_, 10 * kDefaultTCPMSS);
+  }
+
+  ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
+}
+
+void BbrSender::ApplyConnectionOptions(
+    const QuicTagVector& connection_options) {
+  if (ContainsQuicTag(connection_options, kBSAO)) {
+    sampler_.EnableOverestimateAvoidance();
+  }
+  if (ContainsQuicTag(connection_options, kBBRA)) {
+    sampler_.SetStartNewAggregationEpochAfterFullRound(true);
+  }
+  if (ContainsQuicTag(connection_options, kBBRB)) {
+    sampler_.SetLimitMaxAckHeightTrackerBySendRate(true);
+  }
+}
+
+void BbrSender::AdjustNetworkParameters(const NetworkParams& params) {
+  const QuicBandwidth& bandwidth = params.bandwidth;
+  const QuicTime::Delta& rtt = params.rtt;
+
+  if (!rtt.IsZero() && (min_rtt_ > rtt || min_rtt_.IsZero())) {
+    min_rtt_ = rtt;
+  }
+
+  if (mode_ == STARTUP) {
+    if (bandwidth.IsZero()) {
+      // Ignore bad bandwidth samples.
+      return;
+    }
+
+    auto cwnd_bootstrapping_rtt = GetMinRtt();
+    if (params.max_initial_congestion_window > 0) {
+      max_congestion_window_with_network_parameters_adjusted_ =
+          params.max_initial_congestion_window * kDefaultTCPMSS;
+    }
+    const QuicByteCount new_cwnd = std::max(
+        kMinInitialCongestionWindow * kDefaultTCPMSS,
+        std::min(max_congestion_window_with_network_parameters_adjusted_,
+                 bandwidth * cwnd_bootstrapping_rtt));
+
+    stats_->cwnd_bootstrapping_rtt_us = cwnd_bootstrapping_rtt.ToMicroseconds();
+    if (!rtt_stats_->smoothed_rtt().IsZero()) {
+      QUIC_CODE_COUNT(quic_smoothed_rtt_available);
+    } else if (rtt_stats_->initial_rtt() !=
+               QuicTime::Delta::FromMilliseconds(kInitialRttMs)) {
+      QUIC_CODE_COUNT(quic_client_initial_rtt_available);
+    } else {
+      QUIC_CODE_COUNT(quic_default_initial_rtt);
+    }
+    if (new_cwnd < congestion_window_ && !params.allow_cwnd_to_decrease) {
+      // Only decrease cwnd if allow_cwnd_to_decrease is true.
+      return;
+    }
+    if (GetQuicReloadableFlag(quic_conservative_cwnd_and_pacing_gains)) {
+      // Decreases cwnd gain and pacing gain. Please note, if pacing_rate_ has
+      // been calculated, it cannot decrease in STARTUP phase.
+      QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_cwnd_and_pacing_gains);
+      set_high_gain(kDerivedHighCWNDGain);
+      set_high_cwnd_gain(kDerivedHighCWNDGain);
+    }
+    congestion_window_ = new_cwnd;
+
+    // Pace at the rate of new_cwnd / RTT.
+    QuicBandwidth new_pacing_rate =
+        QuicBandwidth::FromBytesAndTimeDelta(congestion_window_, GetMinRtt());
+    pacing_rate_ = std::max(pacing_rate_, new_pacing_rate);
+    detect_overshooting_ = true;
+  }
+}
+
+void BbrSender::OnCongestionEvent(bool /*rtt_updated*/,
+                                  QuicByteCount prior_in_flight,
+                                  QuicTime event_time,
+                                  const AckedPacketVector& acked_packets,
+                                  const LostPacketVector& lost_packets) {
+  const QuicByteCount total_bytes_acked_before = sampler_.total_bytes_acked();
+  const QuicByteCount total_bytes_lost_before = sampler_.total_bytes_lost();
+
+  bool is_round_start = false;
+  bool min_rtt_expired = false;
+  QuicByteCount excess_acked = 0;
+  QuicByteCount bytes_lost = 0;
+
+  // The send state of the largest packet in acked_packets, unless it is
+  // empty. If acked_packets is empty, it's the send state of the largest
+  // packet in lost_packets.
+  SendTimeState last_packet_send_state;
+
+  if (!acked_packets.empty()) {
+    QuicPacketNumber last_acked_packet = acked_packets.rbegin()->packet_number;
+    is_round_start = UpdateRoundTripCounter(last_acked_packet);
+    UpdateRecoveryState(last_acked_packet, !lost_packets.empty(),
+                        is_round_start);
+  }
+
+  BandwidthSamplerInterface::CongestionEventSample sample =
+      sampler_.OnCongestionEvent(event_time, acked_packets, lost_packets,
+                                 max_bandwidth_.GetBest(),
+                                 QuicBandwidth::Infinite(), round_trip_count_);
+  if (sample.last_packet_send_state.is_valid) {
+    last_sample_is_app_limited_ = sample.last_packet_send_state.is_app_limited;
+    has_non_app_limited_sample_ |= !last_sample_is_app_limited_;
+    if (stats_) {
+      stats_->has_non_app_limited_sample = has_non_app_limited_sample_;
+    }
+  }
+  // Avoid updating |max_bandwidth_| if a) this is a loss-only event, or b) all
+  // packets in |acked_packets| did not generate valid samples. (e.g. ack of
+  // ack-only packets). In both cases, sampler_.total_bytes_acked() will not
+  // change.
+  if (total_bytes_acked_before != sampler_.total_bytes_acked()) {
+    QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
+        << sampler_.total_bytes_acked() - total_bytes_acked_before
+        << " bytes from " << acked_packets.size()
+        << " packets have been acked, but sample_max_bandwidth is zero.";
+    if (!sample.sample_is_app_limited ||
+        sample.sample_max_bandwidth > max_bandwidth_.GetBest()) {
+      max_bandwidth_.Update(sample.sample_max_bandwidth, round_trip_count_);
+    }
+  }
+
+  if (!sample.sample_rtt.IsInfinite()) {
+    min_rtt_expired = MaybeUpdateMinRtt(event_time, sample.sample_rtt);
+  }
+  bytes_lost = sampler_.total_bytes_lost() - total_bytes_lost_before;
+  if (mode_ == STARTUP) {
+    if (stats_) {
+      stats_->slowstart_packets_lost += lost_packets.size();
+      stats_->slowstart_bytes_lost += bytes_lost;
+    }
+  }
+  excess_acked = sample.extra_acked;
+  last_packet_send_state = sample.last_packet_send_state;
+
+  if (!lost_packets.empty()) {
+    ++num_loss_events_in_round_;
+    bytes_lost_in_round_ += bytes_lost;
+  }
+
+  // Handle logic specific to PROBE_BW mode.
+  if (mode_ == PROBE_BW) {
+    UpdateGainCyclePhase(event_time, prior_in_flight, !lost_packets.empty());
+  }
+
+  // Handle logic specific to STARTUP and DRAIN modes.
+  if (is_round_start && !is_at_full_bandwidth_) {
+    CheckIfFullBandwidthReached(last_packet_send_state);
+  }
+  MaybeExitStartupOrDrain(event_time);
+
+  // Handle logic specific to PROBE_RTT.
+  MaybeEnterOrExitProbeRtt(event_time, is_round_start, min_rtt_expired);
+
+  // Calculate number of packets acked and lost.
+  QuicByteCount bytes_acked =
+      sampler_.total_bytes_acked() - total_bytes_acked_before;
+
+  // After the model is updated, recalculate the pacing rate and congestion
+  // window.
+  CalculatePacingRate(bytes_lost);
+  CalculateCongestionWindow(bytes_acked, excess_acked);
+  CalculateRecoveryWindow(bytes_acked, bytes_lost);
+
+  // Cleanup internal state.
+  sampler_.RemoveObsoletePackets(unacked_packets_->GetLeastUnacked());
+  if (is_round_start) {
+    num_loss_events_in_round_ = 0;
+    bytes_lost_in_round_ = 0;
+  }
+}
+
+CongestionControlType BbrSender::GetCongestionControlType() const {
+  return kBBR;
+}
+
+QuicTime::Delta BbrSender::GetMinRtt() const {
+  if (!min_rtt_.IsZero()) {
+    return min_rtt_;
+  }
+  // min_rtt could be available if the handshake packet gets neutered then
+  // gets acknowledged. This could only happen for QUIC crypto where we do not
+  // drop keys.
+  return rtt_stats_->MinOrInitialRtt();
+}
+
+QuicByteCount BbrSender::GetTargetCongestionWindow(float gain) const {
+  QuicByteCount bdp = GetMinRtt() * BandwidthEstimate();
+  QuicByteCount congestion_window = gain * bdp;
+
+  // BDP estimate will be zero if no bandwidth samples are available yet.
+  if (congestion_window == 0) {
+    congestion_window = gain * initial_congestion_window_;
+  }
+
+  return std::max(congestion_window, min_congestion_window_);
+}
+
+QuicByteCount BbrSender::ProbeRttCongestionWindow() const {
+  return min_congestion_window_;
+}
+
+void BbrSender::EnterStartupMode(QuicTime now) {
+  if (stats_) {
+    ++stats_->slowstart_count;
+    stats_->slowstart_duration.Start(now);
+  }
+  mode_ = STARTUP;
+  pacing_gain_ = high_gain_;
+  congestion_window_gain_ = high_cwnd_gain_;
+}
+
+void BbrSender::EnterProbeBandwidthMode(QuicTime now) {
+  mode_ = PROBE_BW;
+  congestion_window_gain_ = congestion_window_gain_constant_;
+
+  // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is
+  // excluded because in that case increased gain and decreased gain would not
+  // follow each other.
+  cycle_current_offset_ = random_->RandUint64() % (kGainCycleLength - 1);
+  if (cycle_current_offset_ >= 1) {
+    cycle_current_offset_ += 1;
+  }
+
+  last_cycle_start_ = now;
+  pacing_gain_ = kPacingGain[cycle_current_offset_];
+}
+
+bool BbrSender::UpdateRoundTripCounter(QuicPacketNumber last_acked_packet) {
+  if (!current_round_trip_end_.IsInitialized() ||
+      last_acked_packet > current_round_trip_end_) {
+    round_trip_count_++;
+    current_round_trip_end_ = last_sent_packet_;
+    if (stats_ && InSlowStart()) {
+      ++stats_->slowstart_num_rtts;
+    }
+    return true;
+  }
+
+  return false;
+}
+
+bool BbrSender::MaybeUpdateMinRtt(QuicTime now,
+                                  QuicTime::Delta sample_min_rtt) {
+  // Do not expire min_rtt if none was ever available.
+  bool min_rtt_expired =
+      !min_rtt_.IsZero() && (now > (min_rtt_timestamp_ + kMinRttExpiry));
+
+  if (min_rtt_expired || sample_min_rtt < min_rtt_ || min_rtt_.IsZero()) {
+    QUIC_DVLOG(2) << "Min RTT updated, old value: " << min_rtt_
+                  << ", new value: " << sample_min_rtt
+                  << ", current time: " << now.ToDebuggingValue();
+
+    min_rtt_ = sample_min_rtt;
+    min_rtt_timestamp_ = now;
+  }
+  QUICHE_DCHECK(!min_rtt_.IsZero());
+
+  return min_rtt_expired;
+}
+
+void BbrSender::UpdateGainCyclePhase(QuicTime now,
+                                     QuicByteCount prior_in_flight,
+                                     bool has_losses) {
+  const QuicByteCount bytes_in_flight = unacked_packets_->bytes_in_flight();
+  // In most cases, the cycle is advanced after an RTT passes.
+  bool should_advance_gain_cycling = now - last_cycle_start_ > GetMinRtt();
+
+  // If the pacing gain is above 1.0, the connection is trying to probe the
+  // bandwidth by increasing the number of bytes in flight to at least
+  // pacing_gain * BDP.  Make sure that it actually reaches the target, as long
+  // as there are no losses suggesting that the buffers are not able to hold
+  // that much.
+  if (pacing_gain_ > 1.0 && !has_losses &&
+      prior_in_flight < GetTargetCongestionWindow(pacing_gain_)) {
+    should_advance_gain_cycling = false;
+  }
+
+  // If pacing gain is below 1.0, the connection is trying to drain the extra
+  // queue which could have been incurred by probing prior to it.  If the number
+  // of bytes in flight falls down to the estimated BDP value earlier, conclude
+  // that the queue has been successfully drained and exit this cycle early.
+  if (pacing_gain_ < 1.0 && bytes_in_flight <= GetTargetCongestionWindow(1)) {
+    should_advance_gain_cycling = true;
+  }
+
+  if (should_advance_gain_cycling) {
+    cycle_current_offset_ = (cycle_current_offset_ + 1) % kGainCycleLength;
+    if (cycle_current_offset_ == 0) {
+      ++stats_->bbr_num_cycles;
+    }
+    last_cycle_start_ = now;
+    // Stay in low gain mode until the target BDP is hit.
+    // Low gain mode will be exited immediately when the target BDP is achieved.
+    if (drain_to_target_ && pacing_gain_ < 1 &&
+        kPacingGain[cycle_current_offset_] == 1 &&
+        bytes_in_flight > GetTargetCongestionWindow(1)) {
+      return;
+    }
+    pacing_gain_ = kPacingGain[cycle_current_offset_];
+  }
+}
+
+void BbrSender::CheckIfFullBandwidthReached(
+    const SendTimeState& last_packet_send_state) {
+  if (last_sample_is_app_limited_) {
+    return;
+  }
+
+  QuicBandwidth target = bandwidth_at_last_round_ * kStartupGrowthTarget;
+  if (BandwidthEstimate() >= target) {
+    bandwidth_at_last_round_ = BandwidthEstimate();
+    rounds_without_bandwidth_gain_ = 0;
+    if (expire_ack_aggregation_in_startup_) {
+      // Expire old excess delivery measurements now that bandwidth increased.
+      sampler_.ResetMaxAckHeightTracker(0, round_trip_count_);
+    }
+    return;
+  }
+
+  rounds_without_bandwidth_gain_++;
+  if ((rounds_without_bandwidth_gain_ >= num_startup_rtts_) ||
+      ShouldExitStartupDueToLoss(last_packet_send_state)) {
+    QUICHE_DCHECK(has_non_app_limited_sample_);
+    is_at_full_bandwidth_ = true;
+  }
+}
+
+void BbrSender::MaybeExitStartupOrDrain(QuicTime now) {
+  if (mode_ == STARTUP && is_at_full_bandwidth_) {
+    OnExitStartup(now);
+    mode_ = DRAIN;
+    pacing_gain_ = drain_gain_;
+    congestion_window_gain_ = high_cwnd_gain_;
+  }
+  if (mode_ == DRAIN &&
+      unacked_packets_->bytes_in_flight() <= GetTargetCongestionWindow(1)) {
+    EnterProbeBandwidthMode(now);
+  }
+}
+
+void BbrSender::OnExitStartup(QuicTime now) {
+  QUICHE_DCHECK_EQ(mode_, STARTUP);
+  if (stats_) {
+    stats_->slowstart_duration.Stop(now);
+  }
+}
+
+bool BbrSender::ShouldExitStartupDueToLoss(
+    const SendTimeState& last_packet_send_state) const {
+  if (num_loss_events_in_round_ <
+          GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count) ||
+      !last_packet_send_state.is_valid) {
+    return false;
+  }
+
+  const QuicByteCount inflight_at_send = last_packet_send_state.bytes_in_flight;
+
+  if (inflight_at_send > 0 && bytes_lost_in_round_ > 0) {
+    if (bytes_lost_in_round_ >
+        inflight_at_send *
+            GetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold)) {
+      stats_->bbr_exit_startup_due_to_loss = true;
+      return true;
+    }
+    return false;
+  }
+
+  return false;
+}
+
+void BbrSender::MaybeEnterOrExitProbeRtt(QuicTime now,
+                                         bool is_round_start,
+                                         bool min_rtt_expired) {
+  if (min_rtt_expired && !exiting_quiescence_ && mode_ != PROBE_RTT) {
+    if (InSlowStart()) {
+      OnExitStartup(now);
+    }
+    mode_ = PROBE_RTT;
+    pacing_gain_ = 1;
+    // Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight|
+    // is at the target small value.
+    exit_probe_rtt_at_ = QuicTime::Zero();
+  }
+
+  if (mode_ == PROBE_RTT) {
+    sampler_.OnAppLimited();
+
+    if (exit_probe_rtt_at_ == QuicTime::Zero()) {
+      // If the window has reached the appropriate size, schedule exiting
+      // PROBE_RTT.  The CWND during PROBE_RTT is kMinimumCongestionWindow, but
+      // we allow an extra packet since QUIC checks CWND before sending a
+      // packet.
+      if (unacked_packets_->bytes_in_flight() <
+          ProbeRttCongestionWindow() + kMaxOutgoingPacketSize) {
+        exit_probe_rtt_at_ = now + kProbeRttTime;
+        probe_rtt_round_passed_ = false;
+      }
+    } else {
+      if (is_round_start) {
+        probe_rtt_round_passed_ = true;
+      }
+      if (now >= exit_probe_rtt_at_ && probe_rtt_round_passed_) {
+        min_rtt_timestamp_ = now;
+        if (!is_at_full_bandwidth_) {
+          EnterStartupMode(now);
+        } else {
+          EnterProbeBandwidthMode(now);
+        }
+      }
+    }
+  }
+
+  exiting_quiescence_ = false;
+}
+
+void BbrSender::UpdateRecoveryState(QuicPacketNumber last_acked_packet,
+                                    bool has_losses,
+                                    bool is_round_start) {
+  // Disable recovery in startup, if loss-based exit is enabled.
+  if (!is_at_full_bandwidth_) {
+    return;
+  }
+
+  // Exit recovery when there are no losses for a round.
+  if (has_losses) {
+    end_recovery_at_ = last_sent_packet_;
+  }
+
+  switch (recovery_state_) {
+    case NOT_IN_RECOVERY:
+      // Enter conservation on the first loss.
+      if (has_losses) {
+        recovery_state_ = CONSERVATION;
+        // This will cause the |recovery_window_| to be set to the correct
+        // value in CalculateRecoveryWindow().
+        recovery_window_ = 0;
+        // Since the conservation phase is meant to be lasting for a whole
+        // round, extend the current round as if it were started right now.
+        current_round_trip_end_ = last_sent_packet_;
+      }
+      break;
+
+    case CONSERVATION:
+      if (is_round_start) {
+        recovery_state_ = GROWTH;
+      }
+      ABSL_FALLTHROUGH_INTENDED;
+
+    case GROWTH:
+      // Exit recovery if appropriate.
+      if (!has_losses && last_acked_packet > end_recovery_at_) {
+        recovery_state_ = NOT_IN_RECOVERY;
+      }
+
+      break;
+  }
+}
+
+void BbrSender::CalculatePacingRate(QuicByteCount bytes_lost) {
+  if (BandwidthEstimate().IsZero()) {
+    return;
+  }
+
+  QuicBandwidth target_rate = pacing_gain_ * BandwidthEstimate();
+  if (is_at_full_bandwidth_) {
+    pacing_rate_ = target_rate;
+    return;
+  }
+
+  // Pace at the rate of initial_window / RTT as soon as RTT measurements are
+  // available.
+  if (pacing_rate_.IsZero() && !rtt_stats_->min_rtt().IsZero()) {
+    pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta(
+        initial_congestion_window_, rtt_stats_->min_rtt());
+    return;
+  }
+
+  if (detect_overshooting_) {
+    bytes_lost_while_detecting_overshooting_ += bytes_lost;
+    // Check for overshooting with network parameters adjusted when pacing rate
+    // > target_rate and loss has been detected.
+    if (pacing_rate_ > target_rate &&
+        bytes_lost_while_detecting_overshooting_ > 0) {
+      if (has_non_app_limited_sample_ ||
+          bytes_lost_while_detecting_overshooting_ *
+                  bytes_lost_multiplier_while_detecting_overshooting_ >
+              initial_congestion_window_) {
+        // We are fairly sure overshoot happens if 1) there is at least one
+        // non app-limited bw sample or 2) half of IW gets lost. Slow pacing
+        // rate.
+        pacing_rate_ = std::max(
+            target_rate, QuicBandwidth::FromBytesAndTimeDelta(
+                             cwnd_to_calculate_min_pacing_rate_, GetMinRtt()));
+        if (stats_) {
+          stats_->overshooting_detected_with_network_parameters_adjusted = true;
+        }
+        bytes_lost_while_detecting_overshooting_ = 0;
+        detect_overshooting_ = false;
+      }
+    }
+  }
+
+  // Do not decrease the pacing rate during startup.
+  pacing_rate_ = std::max(pacing_rate_, target_rate);
+}
+
+void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked,
+                                          QuicByteCount excess_acked) {
+  if (mode_ == PROBE_RTT) {
+    return;
+  }
+
+  QuicByteCount target_window =
+      GetTargetCongestionWindow(congestion_window_gain_);
+  if (is_at_full_bandwidth_) {
+    // Add the max recently measured ack aggregation to CWND.
+    target_window += sampler_.max_ack_height();
+  } else if (enable_ack_aggregation_during_startup_) {
+    // Add the most recent excess acked.  Because CWND never decreases in
+    // STARTUP, this will automatically create a very localized max filter.
+    target_window += excess_acked;
+  }
+
+  // Instead of immediately setting the target CWND as the new one, BBR grows
+  // the CWND towards |target_window| by only increasing it |bytes_acked| at a
+  // time.
+  if (is_at_full_bandwidth_) {
+    congestion_window_ =
+        std::min(target_window, congestion_window_ + bytes_acked);
+  } else if (congestion_window_ < target_window ||
+             sampler_.total_bytes_acked() < initial_congestion_window_) {
+    // If the connection is not yet out of startup phase, do not decrease the
+    // window.
+    congestion_window_ = congestion_window_ + bytes_acked;
+  }
+
+  // Enforce the limits on the congestion window.
+  congestion_window_ = std::max(congestion_window_, min_congestion_window_);
+  congestion_window_ = std::min(congestion_window_, max_congestion_window_);
+}
+
+void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked,
+                                        QuicByteCount bytes_lost) {
+  if (recovery_state_ == NOT_IN_RECOVERY) {
+    return;
+  }
+
+  // Set up the initial recovery window.
+  if (recovery_window_ == 0) {
+    recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked;
+    recovery_window_ = std::max(min_congestion_window_, recovery_window_);
+    return;
+  }
+
+  // Remove losses from the recovery window, while accounting for a potential
+  // integer underflow.
+  recovery_window_ = recovery_window_ >= bytes_lost
+                         ? recovery_window_ - bytes_lost
+                         : kMaxSegmentSize;
+
+  // In CONSERVATION mode, just subtracting losses is sufficient.  In GROWTH,
+  // release additional |bytes_acked| to achieve a slow-start-like behavior.
+  if (recovery_state_ == GROWTH) {
+    recovery_window_ += bytes_acked;
+  }
+
+  // Always allow sending at least |bytes_acked| in response.
+  recovery_window_ = std::max(
+      recovery_window_, unacked_packets_->bytes_in_flight() + bytes_acked);
+  recovery_window_ = std::max(min_congestion_window_, recovery_window_);
+}
+
+std::string BbrSender::GetDebugState() const {
+  std::ostringstream stream;
+  stream << ExportDebugState();
+  return stream.str();
+}
+
+void BbrSender::OnApplicationLimited(QuicByteCount bytes_in_flight) {
+  if (bytes_in_flight >= GetCongestionWindow()) {
+    return;
+  }
+
+  sampler_.OnAppLimited();
+  QUIC_DVLOG(2) << "Becoming application limited. Last sent packet: "
+                << last_sent_packet_ << ", CWND: " << GetCongestionWindow();
+}
+
+void BbrSender::PopulateConnectionStats(QuicConnectionStats* stats) const {
+  stats->num_ack_aggregation_epochs = sampler_.num_ack_aggregation_epochs();
+}
+
+BbrSender::DebugState BbrSender::ExportDebugState() const {
+  return DebugState(*this);
+}
+
+static std::string ModeToString(BbrSender::Mode mode) {
+  switch (mode) {
+    case BbrSender::STARTUP:
+      return "STARTUP";
+    case BbrSender::DRAIN:
+      return "DRAIN";
+    case BbrSender::PROBE_BW:
+      return "PROBE_BW";
+    case BbrSender::PROBE_RTT:
+      return "PROBE_RTT";
+  }
+  return "???";
+}
+
+std::ostream& operator<<(std::ostream& os, const BbrSender::Mode& mode) {
+  os << ModeToString(mode);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const BbrSender::DebugState& state) {
+  os << "Mode: " << ModeToString(state.mode) << std::endl;
+  os << "Maximum bandwidth: " << state.max_bandwidth << std::endl;
+  os << "Round trip counter: " << state.round_trip_count << std::endl;
+  os << "Gain cycle index: " << static_cast<int>(state.gain_cycle_index)
+     << std::endl;
+  os << "Congestion window: " << state.congestion_window << " bytes"
+     << std::endl;
+
+  if (state.mode == BbrSender::STARTUP) {
+    os << "(startup) Bandwidth at last round: " << state.bandwidth_at_last_round
+       << std::endl;
+    os << "(startup) Rounds without gain: "
+       << state.rounds_without_bandwidth_gain << std::endl;
+  }
+
+  os << "Minimum RTT: " << state.min_rtt << std::endl;
+  os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue()
+     << std::endl;
+
+  os << "Last sample is app-limited: "
+     << (state.last_sample_is_app_limited ? "yes" : "no");
+
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr_sender.h b/quiche/quic/core/congestion_control/bbr_sender.h
new file mode 100644
index 0000000..1b9afc3
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr_sender.h
@@ -0,0 +1,399 @@
+// Copyright 2016 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.
+
+// BBR (Bottleneck Bandwidth and RTT) congestion control algorithm.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
+
+#include <cstdint>
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/windowed_filter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class RttStats;
+
+// BbrSender implements BBR congestion control algorithm.  BBR aims to estimate
+// the current available Bottleneck Bandwidth and RTT (hence the name), and
+// regulates the pacing rate and the size of the congestion window based on
+// those signals.
+//
+// BBR relies on pacing in order to function properly.  Do not use BBR when
+// pacing is disabled.
+//
+// TODO(vasilvv): implement traffic policer (long-term sampling) mode.
+class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
+ public:
+  enum Mode {
+    // Startup phase of the connection.
+    STARTUP,
+    // After achieving the highest possible bandwidth during the startup, lower
+    // the pacing rate in order to drain the queue.
+    DRAIN,
+    // Cruising mode.
+    PROBE_BW,
+    // Temporarily slow down sending in order to empty the buffer and measure
+    // the real minimum RTT.
+    PROBE_RTT,
+  };
+
+  // Indicates how the congestion control limits the amount of bytes in flight.
+  enum RecoveryState {
+    // Do not limit.
+    NOT_IN_RECOVERY,
+    // Allow an extra outstanding byte for each byte acknowledged.
+    CONSERVATION,
+    // Allow two extra outstanding bytes for each byte acknowledged (slow
+    // start).
+    GROWTH
+  };
+
+  // Debug state can be exported in order to troubleshoot potential congestion
+  // control issues.
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    explicit DebugState(const BbrSender& sender);
+    DebugState(const DebugState& state);
+
+    Mode mode;
+    QuicBandwidth max_bandwidth;
+    QuicRoundTripCount round_trip_count;
+    int gain_cycle_index;
+    QuicByteCount congestion_window;
+
+    bool is_at_full_bandwidth;
+    QuicBandwidth bandwidth_at_last_round;
+    QuicRoundTripCount rounds_without_bandwidth_gain;
+
+    QuicTime::Delta min_rtt;
+    QuicTime min_rtt_timestamp;
+
+    RecoveryState recovery_state;
+    QuicByteCount recovery_window;
+
+    bool last_sample_is_app_limited;
+    QuicPacketNumber end_of_app_limited_phase;
+  };
+
+  BbrSender(QuicTime now,
+            const RttStats* rtt_stats,
+            const QuicUnackedPacketMap* unacked_packets,
+            QuicPacketCount initial_tcp_congestion_window,
+            QuicPacketCount max_tcp_congestion_window,
+            QuicRandom* random,
+            QuicConnectionStats* stats);
+  BbrSender(const BbrSender&) = delete;
+  BbrSender& operator=(const BbrSender&) = delete;
+  ~BbrSender() override;
+
+  // Start implementation of SendAlgorithmInterface.
+  bool InSlowStart() const override;
+  bool InRecovery() const override;
+  bool ShouldSendProbingPacket() const override;
+
+  void SetFromConfig(const QuicConfig& config,
+                     Perspective perspective) override;
+  void ApplyConnectionOptions(const QuicTagVector& connection_options) override;
+
+  void AdjustNetworkParameters(const NetworkParams& params) override;
+  void SetInitialCongestionWindowInPackets(
+      QuicPacketCount congestion_window) override;
+  void OnCongestionEvent(bool rtt_updated,
+                         QuicByteCount prior_in_flight,
+                         QuicTime event_time,
+                         const AckedPacketVector& acked_packets,
+                         const LostPacketVector& lost_packets) override;
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData is_retransmittable) override;
+  void OnPacketNeutered(QuicPacketNumber packet_number) override;
+  void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
+  void OnConnectionMigration() override {}
+  bool CanSend(QuicByteCount bytes_in_flight) override;
+  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
+  QuicBandwidth BandwidthEstimate() const override;
+  bool HasGoodBandwidthEstimateForResumption() const override {
+    return has_non_app_limited_sample();
+  }
+  QuicByteCount GetCongestionWindow() const override;
+  QuicByteCount GetSlowStartThreshold() const override;
+  CongestionControlType GetCongestionControlType() const override;
+  std::string GetDebugState() const override;
+  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
+  void PopulateConnectionStats(QuicConnectionStats* stats) const override;
+  // End implementation of SendAlgorithmInterface.
+
+  // Gets the number of RTTs BBR remains in STARTUP phase.
+  QuicRoundTripCount num_startup_rtts() const { return num_startup_rtts_; }
+  bool has_non_app_limited_sample() const {
+    return has_non_app_limited_sample_;
+  }
+
+  // Sets the pacing gain used in STARTUP.  Must be greater than 1.
+  void set_high_gain(float high_gain) {
+    QUICHE_DCHECK_LT(1.0f, high_gain);
+    high_gain_ = high_gain;
+    if (mode_ == STARTUP) {
+      pacing_gain_ = high_gain;
+    }
+  }
+
+  // Sets the CWND gain used in STARTUP.  Must be greater than 1.
+  void set_high_cwnd_gain(float high_cwnd_gain) {
+    QUICHE_DCHECK_LT(1.0f, high_cwnd_gain);
+    high_cwnd_gain_ = high_cwnd_gain;
+    if (mode_ == STARTUP) {
+      congestion_window_gain_ = high_cwnd_gain;
+    }
+  }
+
+  // Sets the gain used in DRAIN.  Must be less than 1.
+  void set_drain_gain(float drain_gain) {
+    QUICHE_DCHECK_GT(1.0f, drain_gain);
+    drain_gain_ = drain_gain;
+  }
+
+  // Returns the current estimate of the RTT of the connection.  Outside of the
+  // edge cases, this is minimum RTT.
+  QuicTime::Delta GetMinRtt() const;
+
+  DebugState ExportDebugState() const;
+
+ private:
+  // For switching send algorithm mid connection.
+  friend class Bbr2Sender;
+
+  using MaxBandwidthFilter = WindowedFilter<QuicBandwidth,
+                                            MaxFilter<QuicBandwidth>,
+                                            QuicRoundTripCount,
+                                            QuicRoundTripCount>;
+
+  using MaxAckHeightFilter = WindowedFilter<QuicByteCount,
+                                            MaxFilter<QuicByteCount>,
+                                            QuicRoundTripCount,
+                                            QuicRoundTripCount>;
+
+  // Computes the target congestion window using the specified gain.
+  QuicByteCount GetTargetCongestionWindow(float gain) const;
+  // The target congestion window during PROBE_RTT.
+  QuicByteCount ProbeRttCongestionWindow() const;
+  bool MaybeUpdateMinRtt(QuicTime now, QuicTime::Delta sample_min_rtt);
+
+  // Enters the STARTUP mode.
+  void EnterStartupMode(QuicTime now);
+  // Enters the PROBE_BW mode.
+  void EnterProbeBandwidthMode(QuicTime now);
+
+  // Updates the round-trip counter if a round-trip has passed.  Returns true if
+  // the counter has been advanced.
+  bool UpdateRoundTripCounter(QuicPacketNumber last_acked_packet);
+
+  // Updates the current gain used in PROBE_BW mode.
+  void UpdateGainCyclePhase(QuicTime now,
+                            QuicByteCount prior_in_flight,
+                            bool has_losses);
+  // Tracks for how many round-trips the bandwidth has not increased
+  // significantly.
+  void CheckIfFullBandwidthReached(const SendTimeState& last_packet_send_state);
+  // Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if
+  // appropriate.
+  void MaybeExitStartupOrDrain(QuicTime now);
+  // Decides whether to enter or exit PROBE_RTT.
+  void MaybeEnterOrExitProbeRtt(QuicTime now,
+                                bool is_round_start,
+                                bool min_rtt_expired);
+  // Determines whether BBR needs to enter, exit or advance state of the
+  // recovery.
+  void UpdateRecoveryState(QuicPacketNumber last_acked_packet,
+                           bool has_losses,
+                           bool is_round_start);
+
+  // Updates the ack aggregation max filter in bytes.
+  // Returns the most recent addition to the filter, or |newly_acked_bytes| if
+  // nothing was fed in to the filter.
+  QuicByteCount UpdateAckAggregationBytes(QuicTime ack_time,
+                                          QuicByteCount newly_acked_bytes);
+
+  // Determines the appropriate pacing rate for the connection.
+  void CalculatePacingRate(QuicByteCount bytes_lost);
+  // Determines the appropriate congestion window for the connection.
+  void CalculateCongestionWindow(QuicByteCount bytes_acked,
+                                 QuicByteCount excess_acked);
+  // Determines the appropriate window that constrains the in-flight during
+  // recovery.
+  void CalculateRecoveryWindow(QuicByteCount bytes_acked,
+                               QuicByteCount bytes_lost);
+
+  // Called right before exiting STARTUP.
+  void OnExitStartup(QuicTime now);
+
+  // Return whether we should exit STARTUP due to excessive loss.
+  bool ShouldExitStartupDueToLoss(
+      const SendTimeState& last_packet_send_state) const;
+
+  const RttStats* rtt_stats_;
+  const QuicUnackedPacketMap* unacked_packets_;
+  QuicRandom* random_;
+  QuicConnectionStats* stats_;
+
+  Mode mode_;
+
+  // Bandwidth sampler provides BBR with the bandwidth measurements at
+  // individual points.
+  BandwidthSampler sampler_;
+
+  // The number of the round trips that have occurred during the connection.
+  QuicRoundTripCount round_trip_count_;
+
+  // The packet number of the most recently sent packet.
+  QuicPacketNumber last_sent_packet_;
+  // Acknowledgement of any packet after |current_round_trip_end_| will cause
+  // the round trip counter to advance.
+  QuicPacketNumber current_round_trip_end_;
+
+  // Number of congestion events with some losses, in the current round.
+  int64_t num_loss_events_in_round_;
+
+  // Number of total bytes lost in the current round.
+  QuicByteCount bytes_lost_in_round_;
+
+  // The filter that tracks the maximum bandwidth over the multiple recent
+  // round-trips.
+  MaxBandwidthFilter max_bandwidth_;
+
+  // Minimum RTT estimate.  Automatically expires within 10 seconds (and
+  // triggers PROBE_RTT mode) if no new value is sampled during that period.
+  QuicTime::Delta min_rtt_;
+  // The time at which the current value of |min_rtt_| was assigned.
+  QuicTime min_rtt_timestamp_;
+
+  // The maximum allowed number of bytes in flight.
+  QuicByteCount congestion_window_;
+
+  // The initial value of the |congestion_window_|.
+  QuicByteCount initial_congestion_window_;
+
+  // The largest value the |congestion_window_| can achieve.
+  QuicByteCount max_congestion_window_;
+
+  // The smallest value the |congestion_window_| can achieve.
+  QuicByteCount min_congestion_window_;
+
+  // The pacing gain applied during the STARTUP phase.
+  float high_gain_;
+
+  // The CWND gain applied during the STARTUP phase.
+  float high_cwnd_gain_;
+
+  // The pacing gain applied during the DRAIN phase.
+  float drain_gain_;
+
+  // The current pacing rate of the connection.
+  QuicBandwidth pacing_rate_;
+
+  // The gain currently applied to the pacing rate.
+  float pacing_gain_;
+  // The gain currently applied to the congestion window.
+  float congestion_window_gain_;
+
+  // The gain used for the congestion window during PROBE_BW.  Latched from
+  // quic_bbr_cwnd_gain flag.
+  const float congestion_window_gain_constant_;
+  // The number of RTTs to stay in STARTUP mode.  Defaults to 3.
+  QuicRoundTripCount num_startup_rtts_;
+
+  // Number of round-trips in PROBE_BW mode, used for determining the current
+  // pacing gain cycle.
+  int cycle_current_offset_;
+  // The time at which the last pacing gain cycle was started.
+  QuicTime last_cycle_start_;
+
+  // Indicates whether the connection has reached the full bandwidth mode.
+  bool is_at_full_bandwidth_;
+  // Number of rounds during which there was no significant bandwidth increase.
+  QuicRoundTripCount rounds_without_bandwidth_gain_;
+  // The bandwidth compared to which the increase is measured.
+  QuicBandwidth bandwidth_at_last_round_;
+
+  // Set to true upon exiting quiescence.
+  bool exiting_quiescence_;
+
+  // Time at which PROBE_RTT has to be exited.  Setting it to zero indicates
+  // that the time is yet unknown as the number of packets in flight has not
+  // reached the required value.
+  QuicTime exit_probe_rtt_at_;
+  // Indicates whether a round-trip has passed since PROBE_RTT became active.
+  bool probe_rtt_round_passed_;
+
+  // Indicates whether the most recent bandwidth sample was marked as
+  // app-limited.
+  bool last_sample_is_app_limited_;
+  // Indicates whether any non app-limited samples have been recorded.
+  bool has_non_app_limited_sample_;
+
+  // Current state of recovery.
+  RecoveryState recovery_state_;
+  // Receiving acknowledgement of a packet after |end_recovery_at_| will cause
+  // BBR to exit the recovery mode.  A value above zero indicates at least one
+  // loss has been detected, so it must not be set back to zero.
+  QuicPacketNumber end_recovery_at_;
+  // A window used to limit the number of bytes in flight during loss recovery.
+  QuicByteCount recovery_window_;
+  // If true, consider all samples in recovery app-limited.
+  bool is_app_limited_recovery_;
+
+  // When true, pace at 1.5x and disable packet conservation in STARTUP.
+  bool slower_startup_;
+  // When true, disables packet conservation in STARTUP.
+  bool rate_based_startup_;
+
+  // When true, add the most recent ack aggregation measurement during STARTUP.
+  bool enable_ack_aggregation_during_startup_;
+  // When true, expire the windowed ack aggregation values in STARTUP when
+  // bandwidth increases more than 25%.
+  bool expire_ack_aggregation_in_startup_;
+
+  // If true, will not exit low gain mode until bytes_in_flight drops below BDP
+  // or it's time for high gain mode.
+  bool drain_to_target_;
+
+  // If true, slow down pacing rate in STARTUP when overshooting is detected.
+  bool detect_overshooting_;
+  // Bytes lost while detect_overshooting_ is true.
+  QuicByteCount bytes_lost_while_detecting_overshooting_;
+  // Slow down pacing rate if
+  // bytes_lost_while_detecting_overshooting_ *
+  // bytes_lost_multiplier_while_detecting_overshooting_ > IW.
+  uint8_t bytes_lost_multiplier_while_detecting_overshooting_;
+  // When overshooting is detected, do not drop pacing_rate_ below this value /
+  // min_rtt.
+  QuicByteCount cwnd_to_calculate_min_pacing_rate_;
+
+  // Max congestion window when adjusting network parameters.
+  QuicByteCount max_congestion_window_with_network_parameters_adjusted_;
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const BbrSender::Mode& mode);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const BbrSender::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
diff --git a/quiche/quic/core/congestion_control/bbr_sender_test.cc b/quiche/quic/core/congestion_control/bbr_sender_test.cc
new file mode 100644
index 0000000..62abb7a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr_sender_test.cc
@@ -0,0 +1,1334 @@
+// Copyright 2016 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 "quiche/quic/core/congestion_control/bbr_sender.h"
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/send_algorithm_test_result.pb.h"
+#include "quiche/quic/test_tools/send_algorithm_test_utils.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+using testing::AllOf;
+using testing::Ge;
+using testing::Le;
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, quic_bbr_test_regression_mode, "",
+    "One of a) 'record' to record test result (one file per test), or "
+    "b) 'regress' to regress against recorded results, or "
+    "c) <anything else> for non-regression mode.");
+
+namespace quic {
+namespace test {
+
+// Use the initial CWND of 10, as 32 is too much for the test network.
+const uint32_t kInitialCongestionWindowPackets = 10;
+const uint32_t kDefaultWindowTCP =
+    kInitialCongestionWindowPackets * kDefaultTCPMSS;
+
+// Test network parameters.  Here, the topology of the network is:
+//
+//          BBR sender
+//               |
+//               |  <-- local link (10 Mbps, 2 ms delay)
+//               |
+//        Network switch
+//               *  <-- the bottleneck queue in the direction
+//               |          of the receiver
+//               |
+//               |  <-- test link (4 Mbps, 30 ms delay)
+//               |
+//               |
+//           Receiver
+//
+// The reason the bandwidths chosen are relatively low is the fact that the
+// connection simulator uses QuicTime for its internal clock, and as such has
+// the granularity of 1us, meaning that at bandwidth higher than 20 Mbps the
+// packets can start to land on the same timestamp.
+const QuicBandwidth kTestLinkBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(4000);
+const QuicBandwidth kLocalLinkBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(10000);
+const QuicTime::Delta kTestPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(30);
+const QuicTime::Delta kLocalPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(2);
+const QuicTime::Delta kTestTransferTime =
+    kTestLinkBandwidth.TransferTime(kMaxOutgoingPacketSize) +
+    kLocalLinkBandwidth.TransferTime(kMaxOutgoingPacketSize);
+const QuicTime::Delta kTestRtt =
+    (kTestPropagationDelay + kLocalPropagationDelay + kTestTransferTime) * 2;
+const QuicByteCount kTestBdp = kTestRtt * kTestLinkBandwidth;
+
+class BbrSenderTest : public QuicTest {
+ protected:
+  BbrSenderTest()
+      : simulator_(&random_),
+        bbr_sender_(&simulator_,
+                    "BBR sender",
+                    "Receiver",
+                    Perspective::IS_CLIENT,
+                    /*connection_id=*/TestConnectionId(42)),
+        competing_sender_(&simulator_,
+                          "Competing sender",
+                          "Competing receiver",
+                          Perspective::IS_CLIENT,
+                          /*connection_id=*/TestConnectionId(43)),
+        receiver_(&simulator_,
+                  "Receiver",
+                  "BBR sender",
+                  Perspective::IS_SERVER,
+                  /*connection_id=*/TestConnectionId(42)),
+        competing_receiver_(&simulator_,
+                            "Competing receiver",
+                            "Competing sender",
+                            Perspective::IS_SERVER,
+                            /*connection_id=*/TestConnectionId(43)),
+        receiver_multiplexer_("Receiver multiplexer",
+                              {&receiver_, &competing_receiver_}) {
+    rtt_stats_ = bbr_sender_.connection()->sent_packet_manager().GetRttStats();
+    const int kTestMaxPacketSize = 1350;
+    bbr_sender_.connection()->SetMaxPacketLength(kTestMaxPacketSize);
+    sender_ = SetupBbrSender(&bbr_sender_);
+    SetConnectionOption(kBBRA);
+    clock_ = simulator_.GetClock();
+  }
+
+  void SetUp() override {
+    if (GetQuicFlag(FLAGS_quic_bbr_test_regression_mode) == "regress") {
+      SendAlgorithmTestResult expected;
+      ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
+      random_seed_ = expected.random_seed();
+    } else {
+      random_seed_ = QuicRandom::GetInstance()->RandUint64();
+    }
+    random_.set_seed(random_seed_);
+    QUIC_LOG(INFO) << "BbrSenderTest simulator set up.  Seed: " << random_seed_;
+  }
+
+  ~BbrSenderTest() {
+    const std::string regression_mode =
+        GetQuicFlag(FLAGS_quic_bbr_test_regression_mode);
+    const QuicTime::Delta simulated_duration = clock_->Now() - QuicTime::Zero();
+    if (regression_mode == "record") {
+      RecordSendAlgorithmTestResult(random_seed_,
+                                    simulated_duration.ToMicroseconds());
+    } else if (regression_mode == "regress") {
+      CompareSendAlgorithmTestResult(simulated_duration.ToMicroseconds());
+    }
+  }
+
+  uint64_t random_seed_;
+  SimpleRandom random_;
+  simulator::Simulator simulator_;
+  simulator::QuicEndpoint bbr_sender_;
+  simulator::QuicEndpoint competing_sender_;
+  simulator::QuicEndpoint receiver_;
+  simulator::QuicEndpoint competing_receiver_;
+  simulator::QuicEndpointMultiplexer receiver_multiplexer_;
+  std::unique_ptr<simulator::Switch> switch_;
+  std::unique_ptr<simulator::SymmetricLink> bbr_sender_link_;
+  std::unique_ptr<simulator::SymmetricLink> competing_sender_link_;
+  std::unique_ptr<simulator::SymmetricLink> receiver_link_;
+
+  // Owned by different components of the connection.
+  const QuicClock* clock_;
+  const RttStats* rtt_stats_;
+  BbrSender* sender_;
+
+  // Enables BBR on |endpoint| and returns the associated BBR congestion
+  // controller.
+  BbrSender* SetupBbrSender(simulator::QuicEndpoint* endpoint) {
+    const RttStats* rtt_stats =
+        endpoint->connection()->sent_packet_manager().GetRttStats();
+    // Ownership of the sender will be overtaken by the endpoint.
+    BbrSender* sender = new BbrSender(
+        endpoint->connection()->clock()->Now(), rtt_stats,
+        QuicSentPacketManagerPeer::GetUnackedPacketMap(
+            QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
+        kInitialCongestionWindowPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+        QuicConnectionPeer::GetStats(endpoint->connection()));
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  // Creates a default setup, which is a network with a bottleneck between the
+  // receiver and the switch.  The switch has the buffers four times larger than
+  // the bottleneck BDP, which should guarantee a lack of losses.
+  void CreateDefaultSetup() {
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
+                                                  2 * kTestBdp);
+    bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
+        kLocalPropagationDelay);
+    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
+        &receiver_, switch_->port(2), kTestLinkBandwidth,
+        kTestPropagationDelay);
+  }
+
+  // Same as the default setup, except the buffer now is half of the BDP.
+  void CreateSmallBufferSetup() {
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
+                                                  0.5 * kTestBdp);
+    bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
+        kLocalPropagationDelay);
+    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
+        &receiver_, switch_->port(2), kTestLinkBandwidth,
+        kTestPropagationDelay);
+  }
+
+  // Creates the variation of the default setup in which there is another sender
+  // that competes for the same bottleneck link.
+  void CreateCompetitionSetup() {
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
+                                                  2 * kTestBdp);
+
+    // Add a small offset to the competing link in order to avoid
+    // synchronization effects.
+    const QuicTime::Delta small_offset = QuicTime::Delta::FromMicroseconds(3);
+    bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
+        kLocalPropagationDelay);
+    competing_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &competing_sender_, switch_->port(3), kLocalLinkBandwidth,
+        kLocalPropagationDelay + small_offset);
+    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
+        &receiver_multiplexer_, switch_->port(2), kTestLinkBandwidth,
+        kTestPropagationDelay);
+  }
+
+  // Creates a BBR vs BBR competition setup.
+  void CreateBbrVsBbrSetup() {
+    SetupBbrSender(&competing_sender_);
+    CreateCompetitionSetup();
+  }
+
+  void EnableAggregation(QuicByteCount aggregation_bytes,
+                         QuicTime::Delta aggregation_timeout) {
+    // Enable aggregation on the path from the receiver to the sender.
+    switch_->port_queue(1)->EnableAggregation(aggregation_bytes,
+                                              aggregation_timeout);
+  }
+
+  void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta deadline) {
+    bbr_sender_.AddBytesToTransfer(transfer_size);
+    // TODO(vasilvv): consider rewriting this to run until the receiver actually
+    // receives the intended amount of bytes.
+    bool simulator_result = simulator_.RunUntilOrTimeout(
+        [this]() { return bbr_sender_.bytes_to_transfer() == 0; }, deadline);
+    EXPECT_TRUE(simulator_result)
+        << "Simple transfer failed.  Bytes remaining: "
+        << bbr_sender_.bytes_to_transfer();
+    QUIC_LOG(INFO) << "Simple transfer state: " << sender_->ExportDebugState();
+  }
+
+  // Drive the simulator by sending enough data to enter PROBE_BW.
+  void DriveOutOfStartup() {
+    ASSERT_FALSE(sender_->ExportDebugState().is_at_full_bandwidth);
+    DoSimpleTransfer(1024 * 1024, QuicTime::Delta::FromSeconds(15));
+    EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+    EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                     sender_->ExportDebugState().max_bandwidth, 0.02f);
+  }
+
+  // Send |bytes|-sized bursts of data |number_of_bursts| times, waiting for
+  // |wait_time| between each burst.
+  void SendBursts(size_t number_of_bursts,
+                  QuicByteCount bytes,
+                  QuicTime::Delta wait_time) {
+    ASSERT_EQ(0u, bbr_sender_.bytes_to_transfer());
+    for (size_t i = 0; i < number_of_bursts; i++) {
+      bbr_sender_.AddBytesToTransfer(bytes);
+
+      // Transfer data and wait for three seconds between each transfer.
+      simulator_.RunFor(wait_time);
+
+      // Ensure the connection did not time out.
+      ASSERT_TRUE(bbr_sender_.connection()->connected());
+      ASSERT_TRUE(receiver_.connection()->connected());
+    }
+
+    simulator_.RunFor(wait_time + kTestRtt);
+    ASSERT_EQ(0u, bbr_sender_.bytes_to_transfer());
+  }
+
+  void SetConnectionOption(QuicTag option) {
+    QuicConfig config;
+    QuicTagVector options;
+    options.push_back(option);
+    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+    sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  }
+};
+
+TEST_F(BbrSenderTest, SetInitialCongestionWindow) {
+  EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+  sender_->SetInitialCongestionWindowInPackets(3);
+  EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
+// Test a simple long data transfer in the default setup.
+TEST_F(BbrSenderTest, SimpleTransfer) {
+  CreateDefaultSetup();
+
+  // At startup make sure we are at the default.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // And that window is un-affected.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  ASSERT_GE(kTestBdp, kDefaultWindowTCP + kDefaultTCPMSS);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // The margin here is quite high, since there exists a possibility that the
+  // connection just exited high gain cycle.
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.2f);
+}
+
+TEST_F(BbrSenderTest, SimpleTransferBBRB) {
+  SetConnectionOption(kBBRB);
+  CreateDefaultSetup();
+
+  // At startup make sure we are at the default.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // And that window is un-affected.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  ASSERT_GE(kTestBdp, kDefaultWindowTCP + kDefaultTCPMSS);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // The margin here is quite high, since there exists a possibility that the
+  // connection just exited high gain cycle.
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.2f);
+}
+
+// Test a simple transfer in a situation when the buffer is less than BDP.
+TEST_F(BbrSenderTest, SimpleTransferSmallBuffer) {
+  CreateSmallBufferSetup();
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  EXPECT_GE(bbr_sender_.connection()->GetStats().packets_lost, 0u);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // The margin here is quite high, since there exists a possibility that the
+  // connection just exited high gain cycle.
+  EXPECT_APPROX_EQ(kTestRtt, sender_->GetMinRtt(), 0.2f);
+}
+
+TEST_F(BbrSenderTest, RemoveBytesLostInRecovery) {
+  CreateDefaultSetup();
+
+  DriveOutOfStartup();
+
+  // Drop a packet to enter recovery.
+  receiver_.DropNextIncomingPacket();
+  ASSERT_TRUE(
+      simulator_.RunUntilOrTimeout([this]() { return sender_->InRecovery(); },
+                                   QuicTime::Delta::FromSeconds(30)));
+
+  QuicUnackedPacketMap* unacked_packets =
+      QuicSentPacketManagerPeer::GetUnackedPacketMap(
+          QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection()));
+  QuicPacketNumber largest_sent =
+      bbr_sender_.connection()->sent_packet_manager().GetLargestSentPacket();
+  // least_inflight is the smallest inflight packet.
+  QuicPacketNumber least_inflight =
+      bbr_sender_.connection()->sent_packet_manager().GetLeastUnacked();
+  while (!unacked_packets->GetTransmissionInfo(least_inflight).in_flight) {
+    ASSERT_LE(least_inflight, largest_sent);
+    least_inflight++;
+  }
+  QuicPacketLength least_inflight_packet_size =
+      unacked_packets->GetTransmissionInfo(least_inflight).bytes_sent;
+  QuicByteCount prior_recovery_window =
+      sender_->ExportDebugState().recovery_window;
+  QuicByteCount prior_inflight = unacked_packets->bytes_in_flight();
+  QUIC_LOG(INFO) << "Recovery window:" << prior_recovery_window
+                 << ", least_inflight_packet_size:"
+                 << least_inflight_packet_size
+                 << ", bytes_in_flight:" << prior_inflight;
+  ASSERT_GT(prior_recovery_window, least_inflight_packet_size);
+
+  // Lose the least inflight packet and expect the recovery window to drop.
+  unacked_packets->RemoveFromInFlight(least_inflight);
+  LostPacketVector lost_packets;
+  lost_packets.emplace_back(least_inflight, least_inflight_packet_size);
+  sender_->OnCongestionEvent(false, prior_inflight, clock_->Now(), {},
+                             lost_packets);
+  EXPECT_EQ(sender_->ExportDebugState().recovery_window,
+            prior_inflight - least_inflight_packet_size);
+  EXPECT_LT(sender_->ExportDebugState().recovery_window, prior_recovery_window);
+}
+
+// Test a simple long data transfer with 2 rtts of aggregation.
+TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes) {
+  SetConnectionOption(kBSAO);
+  CreateDefaultSetup();
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * kTestRtt);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
+              sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
+
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.5f);
+}
+
+// Test a simple long data transfer with 2 rtts of aggregation.
+TEST_F(BbrSenderTest, SimpleTransferAckDecimation) {
+  SetConnectionOption(kBSAO);
+  // Decrease the CWND gain so extra CWND is required with stretch acks.
+  SetQuicFlag(FLAGS_quic_bbr_cwnd_gain, 1.0);
+  sender_ = new BbrSender(
+      bbr_sender_.connection()->clock()->Now(), rtt_stats_,
+      QuicSentPacketManagerPeer::GetUnackedPacketMap(
+          QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection())),
+      kInitialCongestionWindowPackets,
+      GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+      QuicConnectionPeer::GetStats(bbr_sender_.connection()));
+  QuicConnectionPeer::SetSendAlgorithm(bbr_sender_.connection(), sender_);
+  CreateDefaultSetup();
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+
+  // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
+  // bandwidth higher than the link rate.
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(kTestRtt * 2, rtt_stats_->smoothed_rtt());
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.1f);
+}
+
+// Test a simple long data transfer with 2 rtts of aggregation.
+// TODO(b/172302465) Re-enable this test.
+TEST_F(BbrSenderTest,
+       QUIC_TEST_DISABLED_IN_CHROME(
+           SimpleTransfer2RTTAggregationBytes20RTTWindow)) {
+  SetConnectionOption(kBSAO);
+  CreateDefaultSetup();
+  SetConnectionOption(kBBR4);
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * kTestRtt);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
+              sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
+
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+
+  // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
+  // bandwidth higher than the link rate.
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.25f);
+}
+
+// Test a simple long data transfer with 2 rtts of aggregation.
+TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes40RTTWindow) {
+  SetConnectionOption(kBSAO);
+  CreateDefaultSetup();
+  SetConnectionOption(kBBR5);
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * kTestRtt);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
+              sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
+
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+
+  // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
+  // bandwidth higher than the link rate.
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.25f);
+}
+
+// Test the number of losses incurred by the startup phase in a situation when
+// the buffer is less than BDP.
+TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartup) {
+  CreateSmallBufferSetup();
+
+  DriveOutOfStartup();
+  float loss_rate =
+      static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
+      bbr_sender_.connection()->GetStats().packets_sent;
+  EXPECT_LE(loss_rate, 0.31);
+}
+
+// Test the number of losses incurred by the startup phase in a situation when
+// the buffer is less than BDP, with a STARTUP CWND gain of 2.
+TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartupDerivedCWNDGain) {
+  CreateSmallBufferSetup();
+
+  SetConnectionOption(kBBQ2);
+  DriveOutOfStartup();
+  float loss_rate =
+      static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
+      bbr_sender_.connection()->GetStats().packets_sent;
+  EXPECT_LE(loss_rate, 0.1);
+}
+
+// Ensures the code transitions loss recovery states correctly (NOT_IN_RECOVERY
+// -> CONSERVATION -> GROWTH -> NOT_IN_RECOVERY).
+TEST_F(BbrSenderTest, RecoveryStates) {
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+  bool simulator_result;
+  CreateSmallBufferSetup();
+
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+  ASSERT_EQ(BbrSender::NOT_IN_RECOVERY,
+            sender_->ExportDebugState().recovery_state);
+
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().recovery_state !=
+               BbrSender::NOT_IN_RECOVERY;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::CONSERVATION,
+            sender_->ExportDebugState().recovery_state);
+
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().recovery_state !=
+               BbrSender::CONSERVATION;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::GROWTH, sender_->ExportDebugState().recovery_state);
+
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().recovery_state != BbrSender::GROWTH;
+      },
+      timeout);
+
+  ASSERT_EQ(BbrSender::NOT_IN_RECOVERY,
+            sender_->ExportDebugState().recovery_state);
+  ASSERT_TRUE(simulator_result);
+}
+
+// Verify the behavior of the algorithm in the case when the connection sends
+// small bursts of data after sending continuously for a while.
+TEST_F(BbrSenderTest, ApplicationLimitedBursts) {
+  CreateDefaultSetup();
+  EXPECT_FALSE(sender_->HasGoodBandwidthEstimateForResumption());
+
+  DriveOutOfStartup();
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
+
+  SendBursts(20, 512, QuicTime::Delta::FromSeconds(3));
+  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+}
+
+// Verify the behavior of the algorithm in the case when the connection sends
+// small bursts of data and then starts sending continuously.
+TEST_F(BbrSenderTest, ApplicationLimitedBurstsWithoutPrior) {
+  CreateDefaultSetup();
+
+  SendBursts(40, 512, QuicTime::Delta::FromSeconds(3));
+  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  DriveOutOfStartup();
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Verify that the DRAIN phase works correctly.
+TEST_F(BbrSenderTest, Drain) {
+  CreateDefaultSetup();
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+  // Get the queue at the bottleneck, which is the outgoing queue at the port to
+  // which the receiver is connected.
+  const simulator::Queue* queue = switch_->port_queue(2);
+  bool simulator_result;
+
+  // We have no intention of ever finishing this transfer.
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Run the startup, and verify that it fills up the queue.
+  ASSERT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode != BbrSender::STARTUP;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
+                   sender_->PacingRate(0), 0.01f);
+
+  // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer
+  // with approximately 1 BDP.  Here, we use 0.8 to give some margin for
+  // error.
+  EXPECT_GE(queue->bytes_queued(), 0.8 * kTestBdp);
+
+  // Observe increased RTT due to bufferbloat.
+  const QuicTime::Delta queueing_delay =
+      kTestLinkBandwidth.TransferTime(queue->bytes_queued());
+  EXPECT_APPROX_EQ(kTestRtt + queueing_delay, rtt_stats_->latest_rtt(), 0.1f);
+
+  // Transition to the drain phase and verify that it makes the queue
+  // have at most a BDP worth of packets.
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().mode != BbrSender::DRAIN; },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_LE(queue->bytes_queued(), kTestBdp);
+
+  // Wait for a few round trips and ensure we're in appropriate phase of gain
+  // cycling before taking an RTT measurement.
+  const QuicRoundTripCount start_round_trip =
+      sender_->ExportDebugState().round_trip_count;
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this, start_round_trip]() {
+        QuicRoundTripCount rounds_passed =
+            sender_->ExportDebugState().round_trip_count - start_round_trip;
+        return rounds_passed >= 4 &&
+               sender_->ExportDebugState().gain_cycle_index == 7;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Observe the bufferbloat go away.
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.1f);
+}
+
+// TODO(wub): Re-enable this test once default drain_gain changed to 0.75.
+// Verify that the DRAIN phase works correctly.
+TEST_F(BbrSenderTest, DISABLED_ShallowDrain) {
+  CreateDefaultSetup();
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+  // Get the queue at the bottleneck, which is the outgoing queue at the port to
+  // which the receiver is connected.
+  const simulator::Queue* queue = switch_->port_queue(2);
+  bool simulator_result;
+
+  // We have no intention of ever finishing this transfer.
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Run the startup, and verify that it fills up the queue.
+  ASSERT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode != BbrSender::STARTUP;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(0.75 * sender_->BandwidthEstimate(), sender_->PacingRate(0));
+  // BBR uses CWND gain of 2.88 during STARTUP, hence it will fill the buffer
+  // with approximately 1.88 BDPs.  Here, we use 1.5 to give some margin for
+  // error.
+  EXPECT_GE(queue->bytes_queued(), 1.5 * kTestBdp);
+
+  // Observe increased RTT due to bufferbloat.
+  const QuicTime::Delta queueing_delay =
+      kTestLinkBandwidth.TransferTime(queue->bytes_queued());
+  EXPECT_APPROX_EQ(kTestRtt + queueing_delay, rtt_stats_->latest_rtt(), 0.1f);
+
+  // Transition to the drain phase and verify that it makes the queue
+  // have at most a BDP worth of packets.
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().mode != BbrSender::DRAIN; },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_LE(queue->bytes_queued(), kTestBdp);
+
+  // Wait for a few round trips and ensure we're in appropriate phase of gain
+  // cycling before taking an RTT measurement.
+  const QuicRoundTripCount start_round_trip =
+      sender_->ExportDebugState().round_trip_count;
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this, start_round_trip]() {
+        QuicRoundTripCount rounds_passed =
+            sender_->ExportDebugState().round_trip_count - start_round_trip;
+        return rounds_passed >= 4 &&
+               sender_->ExportDebugState().gain_cycle_index == 7;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Observe the bufferbloat go away.
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.1f);
+}
+
+// Verify that the connection enters and exits PROBE_RTT correctly.
+TEST_F(BbrSenderTest, ProbeRtt) {
+  CreateDefaultSetup();
+  DriveOutOfStartup();
+
+  // We have no intention of ever finishing this transfer.
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Wait until the connection enters PROBE_RTT.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode);
+
+  // Exit PROBE_RTT.
+  const QuicTime probe_rtt_start = clock_->Now();
+  const QuicTime::Delta time_to_exit_probe_rtt =
+      kTestRtt + QuicTime::Delta::FromMilliseconds(200);
+  simulator_.RunFor(1.5 * time_to_exit_probe_rtt);
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start);
+}
+
+// Ensure that a connection that is app-limited and is at sufficiently low
+// bandwidth will not exit high gain phase, and similarly ensure that the
+// connection will exit low gain early if the number of bytes in flight is low.
+// TODO(crbug.com/1145095): Re-enable this test.
+TEST_F(BbrSenderTest, QUIC_TEST_DISABLED_IN_CHROME(InFlightAwareGainCycling)) {
+  CreateDefaultSetup();
+  DriveOutOfStartup();
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  while (!(sender_->ExportDebugState().gain_cycle_index >= 4 &&
+           bbr_sender_.bytes_to_transfer() == 0)) {
+    bbr_sender_.AddBytesToTransfer(kTestLinkBandwidth.ToBytesPerSecond());
+    ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+        [this]() { return bbr_sender_.bytes_to_transfer() == 0; }, timeout));
+  }
+
+  // Send at 10% of available rate.  Run for 3 seconds, checking in the middle
+  // and at the end.  The pacing gain should be high throughout.
+  QuicBandwidth target_bandwidth = 0.1f * kTestLinkBandwidth;
+  QuicTime::Delta burst_interval = QuicTime::Delta::FromMilliseconds(300);
+  for (int i = 0; i < 2; i++) {
+    SendBursts(5, target_bandwidth * burst_interval, burst_interval);
+    EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+    EXPECT_EQ(0, sender_->ExportDebugState().gain_cycle_index);
+    EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                     sender_->ExportDebugState().max_bandwidth, 0.02f);
+  }
+
+  // Now that in-flight is almost zero and the pacing gain is still above 1,
+  // send approximately 1.25 BDPs worth of data.  This should cause the
+  // PROBE_BW mode to enter low gain cycle, and exit it earlier than one min_rtt
+  // due to running out of data to send.
+  bbr_sender_.AddBytesToTransfer(1.3 * kTestBdp);
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().gain_cycle_index == 1; },
+      timeout));
+
+  simulator_.RunFor(0.75 * sender_->ExportDebugState().min_rtt);
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_EQ(2, sender_->ExportDebugState().gain_cycle_index);
+}
+
+// Ensure that the pacing rate does not drop at startup.
+TEST_F(BbrSenderTest, NoBandwidthDropOnStartup) {
+  CreateDefaultSetup();
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result;
+
+  QuicBandwidth initial_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      kInitialCongestionWindowPackets * kDefaultTCPMSS,
+      rtt_stats_->initial_rtt());
+  EXPECT_GE(sender_->PacingRate(0), initial_rate);
+
+  // Send a packet.
+  bbr_sender_.AddBytesToTransfer(1000);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return receiver_.bytes_received() == 1000; }, timeout);
+  ASSERT_TRUE(simulator_result);
+  EXPECT_GE(sender_->PacingRate(0), initial_rate);
+
+  // Wait for a while.
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(2));
+  EXPECT_GE(sender_->PacingRate(0), initial_rate);
+
+  // Send another packet.
+  bbr_sender_.AddBytesToTransfer(1000);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return receiver_.bytes_received() == 2000; }, timeout);
+  ASSERT_TRUE(simulator_result);
+  EXPECT_GE(sender_->PacingRate(0), initial_rate);
+}
+
+// Test exiting STARTUP earlier due to the 1RTT connection option.
+TEST_F(BbrSenderTest, SimpleTransfer1RTTStartup) {
+  CreateDefaultSetup();
+
+  SetConnectionOption(k1RTT);
+  EXPECT_EQ(1u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(1u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Test exiting STARTUP earlier due to the 2RTT connection option.
+TEST_F(BbrSenderTest, SimpleTransfer2RTTStartup) {
+  CreateDefaultSetup();
+
+  SetConnectionOption(k2RTT);
+  EXPECT_EQ(2u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(2u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Test exiting STARTUP earlier upon loss.
+TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLoss) {
+  CreateDefaultSetup();
+
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Test exiting STARTUP earlier upon loss with a small buffer.
+TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLossSmallBuffer) {
+  CreateSmallBufferSetup();
+
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(1u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_NE(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(BbrSenderTest, DerivedPacingGainStartup) {
+  CreateDefaultSetup();
+
+  SetConnectionOption(kBBQ1);
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.773 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(BbrSenderTest, DerivedCWNDGainStartup) {
+  CreateSmallBufferSetup();
+
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  if (!bbr_sender_.connection()->GetStats().bbr_exit_startup_due_to_loss) {
+    EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  }
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  float loss_rate =
+      static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
+      bbr_sender_.connection()->GetStats().packets_sent;
+  EXPECT_LT(loss_rate, 0.15f);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  // Expect an SRTT less than 2.7 * Min RTT on exit from STARTUP.
+  EXPECT_GT(kTestRtt * 2.7, rtt_stats_->smoothed_rtt());
+}
+
+TEST_F(BbrSenderTest, AckAggregationInStartup) {
+  CreateDefaultSetup();
+
+  SetConnectionOption(kBBQ3);
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Test that two BBR flows started slightly apart from each other terminate.
+TEST_F(BbrSenderTest, SimpleCompetition) {
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      kTestLinkBandwidth.TransferTime(transfer_size);
+  CreateBbrVsBbrSetup();
+
+  // Transfer 10% of data in first transfer.
+  bbr_sender_.AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return receiver_.bytes_received() >= 0.1 * transfer_size; },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  competing_sender_.AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_.bytes_received() == transfer_size &&
+               competing_receiver_.bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+// Test that BBR can resume bandwidth from cached network parameters.
+TEST_F(BbrSenderTest, ResumeConnectionState) {
+  CreateDefaultSetup();
+
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth, kTestRtt,
+                                            false));
+  EXPECT_EQ(kTestLinkBandwidth * kTestRtt,
+            sender_->ExportDebugState().congestion_window);
+
+  EXPECT_EQ(kTestLinkBandwidth, sender_->PacingRate(/*bytes_in_flight=*/0));
+
+  EXPECT_APPROX_EQ(kTestRtt, sender_->ExportDebugState().min_rtt, 0.01f);
+
+  DriveOutOfStartup();
+}
+
+// Test with a min CWND of 1 instead of 4 packets.
+TEST_F(BbrSenderTest, ProbeRTTMinCWND1) {
+  CreateDefaultSetup();
+  SetConnectionOption(kMIN1);
+  DriveOutOfStartup();
+
+  // We have no intention of ever finishing this transfer.
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Wait until the connection enters PROBE_RTT.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode);
+  // The PROBE_RTT CWND should be 1 if the min CWND is 1.
+  EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
+
+  // Exit PROBE_RTT.
+  const QuicTime probe_rtt_start = clock_->Now();
+  const QuicTime::Delta time_to_exit_probe_rtt =
+      kTestRtt + QuicTime::Delta::FromMilliseconds(200);
+  simulator_.RunFor(1.5 * time_to_exit_probe_rtt);
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start);
+}
+
+TEST_F(BbrSenderTest, StartupStats) {
+  CreateDefaultSetup();
+
+  DriveOutOfStartup();
+  ASSERT_FALSE(sender_->InSlowStart());
+
+  const QuicConnectionStats& stats = bbr_sender_.connection()->GetStats();
+  EXPECT_EQ(1u, stats.slowstart_count);
+  EXPECT_THAT(stats.slowstart_num_rtts, AllOf(Ge(5u), Le(15u)));
+  EXPECT_THAT(stats.slowstart_packets_sent, AllOf(Ge(100u), Le(1000u)));
+  EXPECT_THAT(stats.slowstart_bytes_sent, AllOf(Ge(100000u), Le(1000000u)));
+  EXPECT_LE(stats.slowstart_packets_lost, 10u);
+  EXPECT_LE(stats.slowstart_bytes_lost, 10000u);
+  EXPECT_FALSE(stats.slowstart_duration.IsRunning());
+  EXPECT_THAT(stats.slowstart_duration.GetTotalElapsedTime(),
+              AllOf(Ge(QuicTime::Delta::FromMilliseconds(500)),
+                    Le(QuicTime::Delta::FromMilliseconds(1500))));
+  EXPECT_EQ(stats.slowstart_duration.GetTotalElapsedTime(),
+            QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection())
+                ->GetSlowStartDuration());
+}
+
+// Regression test for b/143540157.
+TEST_F(BbrSenderTest, RecalculatePacingRateOnCwndChange1RTT) {
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  const QuicByteCount previous_cwnd =
+      sender_->ExportDebugState().congestion_window;
+
+  // Bootstrap cwnd.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  EXPECT_LT(previous_cwnd, sender_->ExportDebugState().congestion_window);
+
+  // Verify pacing rate is re-calculated based on the new cwnd and min_rtt.
+  EXPECT_APPROX_EQ(QuicBandwidth::FromBytesAndTimeDelta(
+                       sender_->ExportDebugState().congestion_window,
+                       sender_->ExportDebugState().min_rtt),
+                   sender_->PacingRate(/*bytes_in_flight=*/0), 0.01f);
+}
+
+TEST_F(BbrSenderTest, RecalculatePacingRateOnCwndChange0RTT) {
+  CreateDefaultSetup();
+  // Initial RTT is available.
+  const_cast<RttStats*>(rtt_stats_)->set_initial_rtt(kTestRtt);
+
+  // Bootstrap cwnd.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  EXPECT_LT(kInitialCongestionWindowPackets * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  // No Rtt sample is available.
+  EXPECT_TRUE(sender_->ExportDebugState().min_rtt.IsZero());
+
+  // Verify pacing rate is re-calculated based on the new cwnd and initial
+  // RTT.
+  EXPECT_APPROX_EQ(QuicBandwidth::FromBytesAndTimeDelta(
+                       sender_->ExportDebugState().congestion_window,
+                       rtt_stats_->initial_rtt()),
+                   sender_->PacingRate(/*bytes_in_flight=*/0), 0.01f);
+}
+
+TEST_F(BbrSenderTest, MitigateCwndBootstrappingOvershoot) {
+  CreateDefaultSetup();
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(8 * kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  QuicBandwidth pacing_rate = sender_->PacingRate(0);
+  EXPECT_EQ(8 * kTestLinkBandwidth, pacing_rate);
+
+  // Wait until pacing_rate decreases.
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this, pacing_rate]() { return sender_->PacingRate(0) < pacing_rate; },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
+  if (GetQuicReloadableFlag(quic_conservative_cwnd_and_pacing_gains)) {
+    EXPECT_APPROX_EQ(2.0f * sender_->BandwidthEstimate(),
+                     sender_->PacingRate(0), 0.01f);
+  } else {
+    EXPECT_APPROX_EQ(2.885f * sender_->BandwidthEstimate(),
+                     sender_->PacingRate(0), 0.01f);
+  }
+}
+
+TEST_F(BbrSenderTest, 200InitialCongestionWindowWithNetworkParameterAdjusted) {
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  // Verify cwnd is capped at 200.
+  EXPECT_EQ(200 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
+}
+
+TEST_F(BbrSenderTest, 100InitialCongestionWindowFromNetworkParameter) {
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  SendAlgorithmInterface::NetworkParams network_params(
+      1024 * kTestLinkBandwidth, QuicTime::Delta::Zero(), false);
+  network_params.max_initial_congestion_window = 100;
+  bbr_sender_.connection()->AdjustNetworkParameters(network_params);
+  // Verify cwnd is capped at 100.
+  EXPECT_EQ(100 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
+}
+
+TEST_F(BbrSenderTest, 100InitialCongestionWindowWithNetworkParameterAdjusted) {
+  SetConnectionOption(kICW1);
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  // Verify cwnd is capped at 100.
+  EXPECT_EQ(100 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
+}
+
+// Ensures bandwidth estimate does not change after a loss only event.
+// Regression test for b/151239871.
+TEST_F(BbrSenderTest, LossOnlyCongestionEvent) {
+  CreateDefaultSetup();
+
+  DriveOutOfStartup();
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // Send some bursts, each burst increments round count by 1, since it only
+  // generates small, app-limited samples, the max_bandwidth_ will not be
+  // updated. At the end of all bursts, all estimates in max_bandwidth_ will
+  // look very old such that any Update() will reset all estimates.
+  SendBursts(20, 512, QuicTime::Delta::FromSeconds(3));
+
+  QuicUnackedPacketMap* unacked_packets =
+      QuicSentPacketManagerPeer::GetUnackedPacketMap(
+          QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection()));
+  // Run until we have something in flight.
+  bbr_sender_.AddBytesToTransfer(50 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [&]() { return unacked_packets->bytes_in_flight() > 0; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+
+  const QuicBandwidth prior_bandwidth_estimate = sender_->BandwidthEstimate();
+  EXPECT_APPROX_EQ(kTestLinkBandwidth, prior_bandwidth_estimate, 0.01f);
+
+  // Lose the least unacked packet.
+  LostPacketVector lost_packets;
+  lost_packets.emplace_back(
+      bbr_sender_.connection()->sent_packet_manager().GetLeastUnacked(),
+      kDefaultMaxPacketSize);
+
+  QuicTime now = simulator_.GetClock()->Now() + kTestRtt * 0.25;
+  sender_->OnCongestionEvent(false, unacked_packets->bytes_in_flight(), now, {},
+                             lost_packets);
+
+  // Bandwidth estimate should not change for the loss only event.
+  EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
+}
+
+TEST_F(BbrSenderTest, EnableOvershootingDetection) {
+  SetConnectionOption(kDTOS);
+  CreateSmallBufferSetup();
+  // Set a overly large initial cwnd.
+  sender_->SetInitialCongestionWindowInPackets(200);
+  const QuicConnectionStats& stats = bbr_sender_.connection()->GetStats();
+  EXPECT_FALSE(stats.overshooting_detected_with_network_parameters_adjusted);
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+
+  // Verify overshooting is detected.
+  EXPECT_TRUE(stats.overshooting_detected_with_network_parameters_adjusted);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/cubic_bytes.cc b/quiche/quic/core/congestion_control/cubic_bytes.cc
new file mode 100644
index 0000000..f3f9d37
--- /dev/null
+++ b/quiche/quic/core/congestion_control/cubic_bytes.cc
@@ -0,0 +1,191 @@
+// Copyright (c) 2015 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 "quiche/quic/core/congestion_control/cubic_bytes.h"
+
+#include <algorithm>
+#include <cmath>
+#include <cstdint>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Constants based on TCP defaults.
+// The following constants are in 2^10 fractions of a second instead of ms to
+// allow a 10 shift right to divide.
+const int kCubeScale = 40;  // 1024*1024^3 (first 1024 is from 0.100^3)
+                            // where 0.100 is 100 ms which is the scaling
+                            // round trip time.
+const int kCubeCongestionWindowScale = 410;
+// The cube factor for packets in bytes.
+const uint64_t kCubeFactor =
+    (UINT64_C(1) << kCubeScale) / kCubeCongestionWindowScale / kDefaultTCPMSS;
+
+const float kDefaultCubicBackoffFactor = 0.7f;  // Default Cubic backoff factor.
+// Additional backoff factor when loss occurs in the concave part of the Cubic
+// curve. This additional backoff factor is expected to give up bandwidth to
+// new concurrent flows and speed up convergence.
+const float kBetaLastMax = 0.85f;
+
+}  // namespace
+
+CubicBytes::CubicBytes(const QuicClock* clock)
+    : clock_(clock),
+      num_connections_(kDefaultNumConnections),
+      epoch_(QuicTime::Zero()) {
+  ResetCubicState();
+}
+
+void CubicBytes::SetNumConnections(int num_connections) {
+  num_connections_ = num_connections;
+}
+
+float CubicBytes::Alpha() const {
+  // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
+  // beta here is a cwnd multiplier, and is equal to 1-beta from the paper.
+  // We derive the equivalent alpha for an N-connection emulation as:
+  const float beta = Beta();
+  return 3 * num_connections_ * num_connections_ * (1 - beta) / (1 + beta);
+}
+
+float CubicBytes::Beta() const {
+  // kNConnectionBeta is the backoff factor after loss for our N-connection
+  // emulation, which emulates the effective backoff of an ensemble of N
+  // TCP-Reno connections on a single loss event. The effective multiplier is
+  // computed as:
+  return (num_connections_ - 1 + kDefaultCubicBackoffFactor) / num_connections_;
+}
+
+float CubicBytes::BetaLastMax() const {
+  // BetaLastMax is the additional backoff factor after loss for our
+  // N-connection emulation, which emulates the additional backoff of
+  // an ensemble of N TCP-Reno connections on a single loss event. The
+  // effective multiplier is computed as:
+  return (num_connections_ - 1 + kBetaLastMax) / num_connections_;
+}
+
+void CubicBytes::ResetCubicState() {
+  epoch_ = QuicTime::Zero();             // Reset time.
+  last_max_congestion_window_ = 0;
+  acked_bytes_count_ = 0;
+  estimated_tcp_congestion_window_ = 0;
+  origin_point_congestion_window_ = 0;
+  time_to_origin_point_ = 0;
+  last_target_congestion_window_ = 0;
+}
+
+void CubicBytes::OnApplicationLimited() {
+  // When sender is not using the available congestion window, the window does
+  // not grow. But to be RTT-independent, Cubic assumes that the sender has been
+  // using the entire window during the time since the beginning of the current
+  // "epoch" (the end of the last loss recovery period). Since
+  // application-limited periods break this assumption, we reset the epoch when
+  // in such a period. This reset effectively freezes congestion window growth
+  // through application-limited periods and allows Cubic growth to continue
+  // when the entire window is being used.
+  epoch_ = QuicTime::Zero();
+}
+
+QuicByteCount CubicBytes::CongestionWindowAfterPacketLoss(
+    QuicByteCount current_congestion_window) {
+  // Since bytes-mode Reno mode slightly under-estimates the cwnd, we
+  // may never reach precisely the last cwnd over the course of an
+  // RTT.  Do not interpret a slight under-estimation as competing traffic.
+  if (current_congestion_window + kDefaultTCPMSS <
+      last_max_congestion_window_) {
+    // We never reached the old max, so assume we are competing with
+    // another flow. Use our extra back off factor to allow the other
+    // flow to go up.
+    last_max_congestion_window_ =
+        static_cast<int>(BetaLastMax() * current_congestion_window);
+  } else {
+    last_max_congestion_window_ = current_congestion_window;
+  }
+  epoch_ = QuicTime::Zero();  // Reset time.
+  return static_cast<int>(current_congestion_window * Beta());
+}
+
+QuicByteCount CubicBytes::CongestionWindowAfterAck(
+    QuicByteCount acked_bytes,
+    QuicByteCount current_congestion_window,
+    QuicTime::Delta delay_min,
+    QuicTime event_time) {
+  acked_bytes_count_ += acked_bytes;
+
+  if (!epoch_.IsInitialized()) {
+    // First ACK after a loss event.
+    QUIC_DVLOG(1) << "Start of epoch";
+    epoch_ = event_time;               // Start of epoch.
+    acked_bytes_count_ = acked_bytes;  // Reset count.
+    // Reset estimated_tcp_congestion_window_ to be in sync with cubic.
+    estimated_tcp_congestion_window_ = current_congestion_window;
+    if (last_max_congestion_window_ <= current_congestion_window) {
+      time_to_origin_point_ = 0;
+      origin_point_congestion_window_ = current_congestion_window;
+    } else {
+      time_to_origin_point_ = static_cast<uint32_t>(
+          cbrt(kCubeFactor *
+               (last_max_congestion_window_ - current_congestion_window)));
+      origin_point_congestion_window_ = last_max_congestion_window_;
+    }
+  }
+  // Change the time unit from microseconds to 2^10 fractions per second. Take
+  // the round trip time in account. This is done to allow us to use shift as a
+  // divide operator.
+  int64_t elapsed_time =
+      ((event_time + delay_min - epoch_).ToMicroseconds() << 10) /
+      kNumMicrosPerSecond;
+
+  // Right-shifts of negative, signed numbers have implementation-dependent
+  // behavior, so force the offset to be positive, as is done in the kernel.
+  uint64_t offset = std::abs(time_to_origin_point_ - elapsed_time);
+
+  QuicByteCount delta_congestion_window = (kCubeCongestionWindowScale * offset *
+                                           offset * offset * kDefaultTCPMSS) >>
+                                          kCubeScale;
+
+  const bool add_delta = elapsed_time > time_to_origin_point_;
+  QUICHE_DCHECK(add_delta ||
+                (origin_point_congestion_window_ > delta_congestion_window));
+  QuicByteCount target_congestion_window =
+      add_delta ? origin_point_congestion_window_ + delta_congestion_window
+                : origin_point_congestion_window_ - delta_congestion_window;
+  // Limit the CWND increase to half the acked bytes.
+  target_congestion_window =
+      std::min(target_congestion_window,
+               current_congestion_window + acked_bytes_count_ / 2);
+
+  QUICHE_DCHECK_LT(0u, estimated_tcp_congestion_window_);
+  // Increase the window by approximately Alpha * 1 MSS of bytes every
+  // time we ack an estimated tcp window of bytes.  For small
+  // congestion windows (less than 25), the formula below will
+  // increase slightly slower than linearly per estimated tcp window
+  // of bytes.
+  estimated_tcp_congestion_window_ += acked_bytes_count_ *
+                                      (Alpha() * kDefaultTCPMSS) /
+                                      estimated_tcp_congestion_window_;
+  acked_bytes_count_ = 0;
+
+  // We have a new cubic congestion window.
+  last_target_congestion_window_ = target_congestion_window;
+
+  // Compute target congestion_window based on cubic target and estimated TCP
+  // congestion_window, use highest (fastest).
+  if (target_congestion_window < estimated_tcp_congestion_window_) {
+    target_congestion_window = estimated_tcp_congestion_window_;
+  }
+
+  QUIC_DVLOG(1) << "Final target congestion_window: "
+                << target_congestion_window;
+  return target_congestion_window;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/cubic_bytes.h b/quiche/quic/core/congestion_control/cubic_bytes.h
new file mode 100644
index 0000000..6eb43ab
--- /dev/null
+++ b/quiche/quic/core/congestion_control/cubic_bytes.h
@@ -0,0 +1,102 @@
+// Copyright (c) 2015 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.
+
+// Cubic algorithm, helper class to TCP cubic.
+// For details see http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class CubicBytesTest;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE CubicBytes {
+ public:
+  explicit CubicBytes(const QuicClock* clock);
+  CubicBytes(const CubicBytes&) = delete;
+  CubicBytes& operator=(const CubicBytes&) = delete;
+
+  void SetNumConnections(int num_connections);
+
+  // Call after a timeout to reset the cubic state.
+  void ResetCubicState();
+
+  // Compute a new congestion window to use after a loss event.
+  // Returns the new congestion window in packets. The new congestion window is
+  // a multiplicative decrease of our current window.
+  QuicByteCount CongestionWindowAfterPacketLoss(QuicPacketCount current);
+
+  // Compute a new congestion window to use after a received ACK.
+  // Returns the new congestion window in bytes. The new congestion window
+  // follows a cubic function that depends on the time passed since last packet
+  // loss.
+  QuicByteCount CongestionWindowAfterAck(QuicByteCount acked_bytes,
+                                         QuicByteCount current,
+                                         QuicTime::Delta delay_min,
+                                         QuicTime event_time);
+
+  // Call on ack arrival when sender is unable to use the available congestion
+  // window. Resets Cubic state during quiescence.
+  void OnApplicationLimited();
+
+ private:
+  friend class test::CubicBytesTest;
+
+  static const QuicTime::Delta MaxCubicTimeInterval() {
+    return QuicTime::Delta::FromMilliseconds(30);
+  }
+
+  // Compute the TCP Cubic alpha, beta, and beta-last-max based on the
+  // current number of connections.
+  float Alpha() const;
+  float Beta() const;
+  float BetaLastMax() const;
+
+  QuicByteCount last_max_congestion_window() const {
+    return last_max_congestion_window_;
+  }
+
+  const QuicClock* clock_;
+
+  // Number of connections to simulate.
+  int num_connections_;
+
+  // Time when this cycle started, after last loss event.
+  QuicTime epoch_;
+
+  // Max congestion window used just before last loss event.
+  // Note: to improve fairness to other streams an additional back off is
+  // applied to this value if the new value is below our latest value.
+  QuicByteCount last_max_congestion_window_;
+
+  // Number of acked bytes since the cycle started (epoch).
+  QuicByteCount acked_bytes_count_;
+
+  // TCP Reno equivalent congestion window in packets.
+  QuicByteCount estimated_tcp_congestion_window_;
+
+  // Origin point of cubic function.
+  QuicByteCount origin_point_congestion_window_;
+
+  // Time to origin point of cubic function in 2^10 fractions of a second.
+  uint32_t time_to_origin_point_;
+
+  // Last congestion window in packets computed by cubic function.
+  QuicByteCount last_target_congestion_window_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
diff --git a/quiche/quic/core/congestion_control/cubic_bytes_test.cc b/quiche/quic/core/congestion_control/cubic_bytes_test.cc
new file mode 100644
index 0000000..4899d51
--- /dev/null
+++ b/quiche/quic/core/congestion_control/cubic_bytes_test.cc
@@ -0,0 +1,387 @@
+// Copyright (c) 2015 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 "quiche/quic/core/congestion_control/cubic_bytes.h"
+
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+const float kBeta = 0.7f;          // Default Cubic backoff factor.
+const float kBetaLastMax = 0.85f;  // Default Cubic backoff factor.
+const uint32_t kNumConnections = 2;
+const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
+const float kNConnectionBetaLastMax =
+    (kNumConnections - 1 + kBetaLastMax) / kNumConnections;
+const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
+                                (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
+
+}  // namespace
+
+class CubicBytesTest : public QuicTest {
+ protected:
+  CubicBytesTest()
+      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
+        hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
+        cubic_(&clock_) {}
+
+  QuicByteCount RenoCwndInBytes(QuicByteCount current_cwnd) {
+    QuicByteCount reno_estimated_cwnd =
+        current_cwnd +
+        kDefaultTCPMSS * (kNConnectionAlpha * kDefaultTCPMSS) / current_cwnd;
+    return reno_estimated_cwnd;
+  }
+
+  QuicByteCount ConservativeCwndInBytes(QuicByteCount current_cwnd) {
+    QuicByteCount conservative_cwnd = current_cwnd + kDefaultTCPMSS / 2;
+    return conservative_cwnd;
+  }
+
+  QuicByteCount CubicConvexCwndInBytes(QuicByteCount initial_cwnd,
+                                       QuicTime::Delta rtt,
+                                       QuicTime::Delta elapsed_time) {
+    const int64_t offset =
+        ((elapsed_time + rtt).ToMicroseconds() << 10) / 1000000;
+    const QuicByteCount delta_congestion_window =
+        ((410 * offset * offset * offset) * kDefaultTCPMSS >> 40);
+    const QuicByteCount cubic_cwnd = initial_cwnd + delta_congestion_window;
+    return cubic_cwnd;
+  }
+
+  QuicByteCount LastMaxCongestionWindow() {
+    return cubic_.last_max_congestion_window();
+  }
+
+  QuicTime::Delta MaxCubicTimeInterval() {
+    return cubic_.MaxCubicTimeInterval();
+  }
+
+  const QuicTime::Delta one_ms_;
+  const QuicTime::Delta hundred_ms_;
+  MockClock clock_;
+  CubicBytes cubic_;
+};
+
+// TODO(jokulik): The original "AboveOrigin" test, below, is very
+// loose.  It's nearly impossible to make the test tighter without
+// deploying the fix for convex mode.  Once cubic convex is deployed,
+// replace "AboveOrigin" with this test.
+TEST_F(CubicBytesTest, AboveOriginWithTighterBounds) {
+  // Convex growth.
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  int64_t rtt_min_ms = rtt_min.ToMilliseconds();
+  float rtt_min_s = rtt_min_ms / 1000.0;
+  QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
+  const QuicByteCount initial_cwnd = current_cwnd;
+
+  clock_.AdvanceTime(one_ms_);
+  const QuicTime initial_time = clock_.ApproximateNow();
+  const QuicByteCount expected_first_cwnd = RenoCwndInBytes(current_cwnd);
+  current_cwnd = cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                                 rtt_min, initial_time);
+  ASSERT_EQ(expected_first_cwnd, current_cwnd);
+
+  // Normal TCP phase.
+  // The maximum number of expected Reno RTTs is calculated by
+  // finding the point where the cubic curve and the reno curve meet.
+  const int max_reno_rtts =
+      std::sqrt(kNConnectionAlpha / (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) -
+      2;
+  for (int i = 0; i < max_reno_rtts; ++i) {
+    // Alternatively, we expect it to increase by one, every time we
+    // receive current_cwnd/Alpha acks back.  (This is another way of
+    // saying we expect cwnd to increase by approximately Alpha once
+    // we receive current_cwnd number ofacks back).
+    const uint64_t num_acks_this_epoch =
+        current_cwnd / kDefaultTCPMSS / kNConnectionAlpha;
+    const QuicByteCount initial_cwnd_this_epoch = current_cwnd;
+    for (QuicPacketCount n = 0; n < num_acks_this_epoch; ++n) {
+      // Call once per ACK.
+      const QuicByteCount expected_next_cwnd = RenoCwndInBytes(current_cwnd);
+      current_cwnd = cubic_.CongestionWindowAfterAck(
+          kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+      ASSERT_EQ(expected_next_cwnd, current_cwnd);
+    }
+    // Our byte-wise Reno implementation is an estimate.  We expect
+    // the cwnd to increase by approximately one MSS every
+    // cwnd/kDefaultTCPMSS/Alpha acks, but it may be off by as much as
+    // half a packet for smaller values of current_cwnd.
+    const QuicByteCount cwnd_change_this_epoch =
+        current_cwnd - initial_cwnd_this_epoch;
+    ASSERT_NEAR(kDefaultTCPMSS, cwnd_change_this_epoch, kDefaultTCPMSS / 2);
+    clock_.AdvanceTime(hundred_ms_);
+  }
+
+  for (int i = 0; i < 54; ++i) {
+    const uint64_t max_acks_this_epoch = current_cwnd / kDefaultTCPMSS;
+    const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
+        hundred_ms_.ToMicroseconds() / max_acks_this_epoch);
+    for (QuicPacketCount n = 0; n < max_acks_this_epoch; ++n) {
+      clock_.AdvanceTime(interval);
+      current_cwnd = cubic_.CongestionWindowAfterAck(
+          kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+      const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
+          initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
+      // If we allow per-ack updates, every update is a small cubic update.
+      ASSERT_EQ(expected_cwnd, current_cwnd);
+    }
+  }
+  const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
+      initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  ASSERT_EQ(expected_cwnd, current_cwnd);
+}
+
+// TODO(ianswett): This test was disabled when all fixes were enabled, but it
+// may be worth fixing.
+TEST_F(CubicBytesTest, DISABLED_AboveOrigin) {
+  // Convex growth.
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
+  // Without the signed-integer, cubic-convex fix, we start out in the
+  // wrong mode.
+  QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
+  // Initialize the state.
+  clock_.AdvanceTime(one_ms_);
+  ASSERT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                            rtt_min, clock_.ApproximateNow()));
+  current_cwnd = expected_cwnd;
+  const QuicPacketCount initial_cwnd = expected_cwnd;
+  // Normal TCP phase.
+  for (int i = 0; i < 48; ++i) {
+    for (QuicPacketCount n = 1;
+         n < current_cwnd / kDefaultTCPMSS / kNConnectionAlpha; ++n) {
+      // Call once per ACK.
+      ASSERT_NEAR(
+          current_cwnd,
+          cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min,
+                                          clock_.ApproximateNow()),
+          kDefaultTCPMSS);
+    }
+    clock_.AdvanceTime(hundred_ms_);
+    current_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+    // When we fix convex mode and the uint64 arithmetic, we
+    // increase the expected_cwnd only after after the first 100ms,
+    // rather than after the initial 1ms.
+    expected_cwnd += kDefaultTCPMSS;
+    ASSERT_NEAR(expected_cwnd, current_cwnd, kDefaultTCPMSS);
+  }
+  // Cubic phase.
+  for (int i = 0; i < 52; ++i) {
+    for (QuicPacketCount n = 1; n < current_cwnd / kDefaultTCPMSS; ++n) {
+      // Call once per ACK.
+      ASSERT_NEAR(
+          current_cwnd,
+          cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min,
+                                          clock_.ApproximateNow()),
+          kDefaultTCPMSS);
+    }
+    clock_.AdvanceTime(hundred_ms_);
+    current_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  }
+  // Total time elapsed so far; add min_rtt (0.1s) here as well.
+  float elapsed_time_s = 10.0f + 0.1f;
+  // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
+  expected_cwnd =
+      initial_cwnd / kDefaultTCPMSS +
+      (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024;
+  EXPECT_EQ(expected_cwnd, current_cwnd / kDefaultTCPMSS);
+}
+
+// Constructs an artificial scenario to ensure that cubic-convex
+// increases are truly fine-grained:
+//
+// - After starting the epoch, this test advances the elapsed time
+// sufficiently far that cubic will do small increases at less than
+// MaxCubicTimeInterval() intervals.
+//
+// - Sets an artificially large initial cwnd to prevent Reno from the
+// convex increases on every ack.
+TEST_F(CubicBytesTest, AboveOriginFineGrainedCubing) {
+  // Start the test with an artificially large cwnd to prevent Reno
+  // from over-taking cubic.
+  QuicByteCount current_cwnd = 1000 * kDefaultTCPMSS;
+  const QuicByteCount initial_cwnd = current_cwnd;
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  clock_.AdvanceTime(one_ms_);
+  QuicTime initial_time = clock_.ApproximateNow();
+
+  // Start the epoch and then artificially advance the time.
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(600));
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+
+  // We expect the algorithm to perform only non-zero, fine-grained cubic
+  // increases on every ack in this case.
+  for (int i = 0; i < 100; ++i) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+    const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
+        initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
+    const QuicByteCount next_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+    // Make sure we are performing cubic increases.
+    ASSERT_EQ(expected_cwnd, next_cwnd);
+    // Make sure that these are non-zero, less-than-packet sized
+    // increases.
+    ASSERT_GT(next_cwnd, current_cwnd);
+    const QuicByteCount cwnd_delta = next_cwnd - current_cwnd;
+    ASSERT_GT(kDefaultTCPMSS * .1, cwnd_delta);
+
+    current_cwnd = next_cwnd;
+  }
+}
+
+// Constructs an artificial scenario to show what happens when we
+// allow per-ack updates, rather than limititing update freqency.  In
+// this scenario, the first two acks of the epoch produce the same
+// cwnd.  When we limit per-ack updates, this would cause the
+// cessation of cubic updates for 30ms.  When we allow per-ack
+// updates, the window continues to grow on every ack.
+TEST_F(CubicBytesTest, PerAckUpdates) {
+  // Start the test with a large cwnd and RTT, to force the first
+  // increase to be a cubic increase.
+  QuicPacketCount initial_cwnd_packets = 150;
+  QuicByteCount current_cwnd = initial_cwnd_packets * kDefaultTCPMSS;
+  const QuicTime::Delta rtt_min = 350 * one_ms_;
+
+  // Initialize the epoch
+  clock_.AdvanceTime(one_ms_);
+  // Keep track of the growth of the reno-equivalent cwnd.
+  QuicByteCount reno_cwnd = RenoCwndInBytes(current_cwnd);
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  const QuicByteCount initial_cwnd = current_cwnd;
+
+  // Simulate the return of cwnd packets in less than
+  // MaxCubicInterval() time.
+  const QuicPacketCount max_acks = initial_cwnd_packets / kNConnectionAlpha;
+  const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
+      MaxCubicTimeInterval().ToMicroseconds() / (max_acks + 1));
+
+  // In this scenario, the first increase is dictated by the cubic
+  // equation, but it is less than one byte, so the cwnd doesn't
+  // change.  Normally, without per-ack increases, any cwnd plateau
+  // will cause the cwnd to be pinned for MaxCubicTimeInterval().  If
+  // we enable per-ack updates, the cwnd will continue to grow,
+  // regardless of the temporary plateau.
+  clock_.AdvanceTime(interval);
+  reno_cwnd = RenoCwndInBytes(reno_cwnd);
+  ASSERT_EQ(current_cwnd,
+            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                            rtt_min, clock_.ApproximateNow()));
+  for (QuicPacketCount i = 1; i < max_acks; ++i) {
+    clock_.AdvanceTime(interval);
+    const QuicByteCount next_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+    reno_cwnd = RenoCwndInBytes(reno_cwnd);
+    // The window shoud increase on every ack.
+    ASSERT_LT(current_cwnd, next_cwnd);
+    ASSERT_EQ(reno_cwnd, next_cwnd);
+    current_cwnd = next_cwnd;
+  }
+
+  // After all the acks are returned from the epoch, we expect the
+  // cwnd to have increased by nearly one packet.  (Not exactly one
+  // packet, because our byte-wise Reno algorithm is always a slight
+  // under-estimation).  Without per-ack updates, the current_cwnd
+  // would otherwise be unchanged.
+  const QuicByteCount minimum_expected_increase = kDefaultTCPMSS * .9;
+  EXPECT_LT(minimum_expected_increase + initial_cwnd, current_cwnd);
+}
+
+TEST_F(CubicBytesTest, LossEvents) {
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
+  // Without the signed-integer, cubic-convex fix, we mistakenly
+  // increment cwnd after only one_ms_ and a single ack.
+  QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
+  // Initialize the state.
+  clock_.AdvanceTime(one_ms_);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                            rtt_min, clock_.ApproximateNow()));
+
+  // On the first loss, the last max congestion window is set to the
+  // congestion window before the loss.
+  QuicByteCount pre_loss_cwnd = current_cwnd;
+  ASSERT_EQ(0u, LastMaxCongestionWindow());
+  expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
+  ASSERT_EQ(pre_loss_cwnd, LastMaxCongestionWindow());
+  current_cwnd = expected_cwnd;
+
+  // On the second loss, the current congestion window has not yet
+  // reached the last max congestion window.  The last max congestion
+  // window will be reduced by an additional backoff factor to allow
+  // for competition.
+  pre_loss_cwnd = current_cwnd;
+  expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
+  ASSERT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
+  current_cwnd = expected_cwnd;
+  EXPECT_GT(pre_loss_cwnd, LastMaxCongestionWindow());
+  QuicByteCount expected_last_max =
+      static_cast<QuicByteCount>(pre_loss_cwnd * kNConnectionBetaLastMax);
+  EXPECT_EQ(expected_last_max, LastMaxCongestionWindow());
+  EXPECT_LT(expected_cwnd, LastMaxCongestionWindow());
+  // Simulate an increase, and check that we are below the origin.
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  EXPECT_GT(LastMaxCongestionWindow(), current_cwnd);
+
+  // On the final loss, simulate the condition where the congestion
+  // window had a chance to grow nearly to the last congestion window.
+  current_cwnd = LastMaxCongestionWindow() - 1;
+  pre_loss_cwnd = current_cwnd;
+  expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
+  expected_last_max = pre_loss_cwnd;
+  ASSERT_EQ(expected_last_max, LastMaxCongestionWindow());
+}
+
+TEST_F(CubicBytesTest, BelowOrigin) {
+  // Concave growth.
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
+  // Without the signed-integer, cubic-convex fix, we mistakenly
+  // increment cwnd after only one_ms_ and a single ack.
+  QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
+  // Initialize the state.
+  clock_.AdvanceTime(one_ms_);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                            rtt_min, clock_.ApproximateNow()));
+  expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
+  current_cwnd = expected_cwnd;
+  // First update after loss to initialize the epoch.
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  // Cubic phase.
+  for (int i = 0; i < 40; ++i) {
+    clock_.AdvanceTime(hundred_ms_);
+    current_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  }
+  expected_cwnd = 553632;
+  EXPECT_EQ(expected_cwnd, current_cwnd);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/general_loss_algorithm.cc b/quiche/quic/core/congestion_control/general_loss_algorithm.cc
new file mode 100644
index 0000000..38557a1
--- /dev/null
+++ b/quiche/quic/core/congestion_control/general_loss_algorithm.cc
@@ -0,0 +1,196 @@
+// Copyright 2015 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 "quiche/quic/core/congestion_control/general_loss_algorithm.h"
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace {
+float DetectionResponseTime(QuicTime::Delta rtt,
+                            QuicTime send_time,
+                            QuicTime detection_time) {
+  if (detection_time <= send_time || rtt.IsZero()) {
+    // Time skewed, assume a very fast detection where |detection_time| is
+    // |send_time| + |rtt|.
+    return 1.0;
+  }
+  float send_to_detection_us = (detection_time - send_time).ToMicroseconds();
+  return send_to_detection_us / rtt.ToMicroseconds();
+}
+
+QuicTime::Delta GetMaxRtt(const RttStats& rtt_stats) {
+  return std::max(kAlarmGranularity,
+                  std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt()));
+}
+
+}  // namespace
+
+// Uses nack counts to decide when packets are lost.
+LossDetectionInterface::DetectionStats GeneralLossAlgorithm::DetectLosses(
+    const QuicUnackedPacketMap& unacked_packets,
+    QuicTime time,
+    const RttStats& rtt_stats,
+    QuicPacketNumber largest_newly_acked,
+    const AckedPacketVector& packets_acked,
+    LostPacketVector* packets_lost) {
+  DetectionStats detection_stats;
+
+  loss_detection_timeout_ = QuicTime::Zero();
+  if (!packets_acked.empty() && least_in_flight_.IsInitialized() &&
+      packets_acked.front().packet_number == least_in_flight_) {
+    if (packets_acked.back().packet_number == largest_newly_acked &&
+        least_in_flight_ + packets_acked.size() - 1 == largest_newly_acked) {
+      // Optimization for the case when no packet is missing. Please note,
+      // packets_acked can include packets of different packet number space, so
+      // do not use this optimization if largest_newly_acked is not the largest
+      // packet in packets_acked.
+      least_in_flight_ = largest_newly_acked + 1;
+      return detection_stats;
+    }
+    // There is hole in acked_packets, increment least_in_flight_ if possible.
+    for (const auto& acked : packets_acked) {
+      if (acked.packet_number != least_in_flight_) {
+        break;
+      }
+      ++least_in_flight_;
+    }
+  }
+
+  const QuicTime::Delta max_rtt = GetMaxRtt(rtt_stats);
+
+  QuicPacketNumber packet_number = unacked_packets.GetLeastUnacked();
+  auto it = unacked_packets.begin();
+  if (least_in_flight_.IsInitialized() && least_in_flight_ >= packet_number) {
+    if (least_in_flight_ > unacked_packets.largest_sent_packet() + 1) {
+      QUIC_BUG(quic_bug_10430_1) << "least_in_flight: " << least_in_flight_
+                                 << " is greater than largest_sent_packet + 1: "
+                                 << unacked_packets.largest_sent_packet() + 1;
+    } else {
+      it += (least_in_flight_ - packet_number);
+      packet_number = least_in_flight_;
+    }
+  }
+  // Clear least_in_flight_.
+  least_in_flight_.Clear();
+  QUICHE_DCHECK_EQ(packet_number_space_,
+                   unacked_packets.GetPacketNumberSpace(largest_newly_acked));
+  for (; it != unacked_packets.end() && packet_number <= largest_newly_acked;
+       ++it, ++packet_number) {
+    if (unacked_packets.GetPacketNumberSpace(it->encryption_level) !=
+        packet_number_space_) {
+      // Skip packets of different packet number space.
+      continue;
+    }
+
+    if (!it->in_flight) {
+      continue;
+    }
+
+    if (parent_ != nullptr && largest_newly_acked != packet_number) {
+      parent_->OnReorderingDetected();
+    }
+
+    if (largest_newly_acked - packet_number >
+        detection_stats.sent_packets_max_sequence_reordering) {
+      detection_stats.sent_packets_max_sequence_reordering =
+          largest_newly_acked - packet_number;
+    }
+
+    // Packet threshold loss detection.
+    // Skip packet threshold loss detection if largest_newly_acked is a runt.
+    const bool skip_packet_threshold_detection =
+        !use_packet_threshold_for_runt_packets_ &&
+        it->bytes_sent >
+            unacked_packets.GetTransmissionInfo(largest_newly_acked).bytes_sent;
+    if (!skip_packet_threshold_detection &&
+        largest_newly_acked - packet_number >= reordering_threshold_) {
+      packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
+      detection_stats.total_loss_detection_response_time +=
+          DetectionResponseTime(max_rtt, it->sent_time, time);
+      continue;
+    }
+
+    // Time threshold loss detection.
+    const QuicTime::Delta loss_delay = max_rtt + (max_rtt >> reordering_shift_);
+    QuicTime when_lost = it->sent_time + loss_delay;
+    if (time < when_lost) {
+      if (time >=
+          it->sent_time + max_rtt + (max_rtt >> (reordering_shift_ + 1))) {
+        ++detection_stats.sent_packets_num_borderline_time_reorderings;
+      }
+      loss_detection_timeout_ = when_lost;
+      if (!least_in_flight_.IsInitialized()) {
+        // At this point, packet_number is in flight and not detected as lost.
+        least_in_flight_ = packet_number;
+      }
+      break;
+    }
+    packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
+    detection_stats.total_loss_detection_response_time +=
+        DetectionResponseTime(max_rtt, it->sent_time, time);
+  }
+  if (!least_in_flight_.IsInitialized()) {
+    // There is no in flight packet.
+    least_in_flight_ = largest_newly_acked + 1;
+  }
+
+  return detection_stats;
+}
+
+QuicTime GeneralLossAlgorithm::GetLossTimeout() const {
+  return loss_detection_timeout_;
+}
+
+void GeneralLossAlgorithm::SpuriousLossDetected(
+    const QuicUnackedPacketMap& unacked_packets,
+    const RttStats& rtt_stats,
+    QuicTime ack_receive_time,
+    QuicPacketNumber packet_number,
+    QuicPacketNumber previous_largest_acked) {
+  if (use_adaptive_time_threshold_ && reordering_shift_ > 0) {
+    // Increase reordering fraction such that the packet would not have been
+    // declared lost.
+    QuicTime::Delta time_needed =
+        ack_receive_time -
+        unacked_packets.GetTransmissionInfo(packet_number).sent_time;
+    QuicTime::Delta max_rtt =
+        std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt());
+    while (max_rtt + (max_rtt >> reordering_shift_) < time_needed &&
+           reordering_shift_ > 0) {
+      --reordering_shift_;
+    }
+  }
+
+  if (use_adaptive_reordering_threshold_) {
+    QUICHE_DCHECK_LT(packet_number, previous_largest_acked);
+    // Increase reordering_threshold_ such that packet_number would not have
+    // been declared lost.
+    reordering_threshold_ = std::max(
+        reordering_threshold_, previous_largest_acked - packet_number + 1);
+  }
+}
+
+void GeneralLossAlgorithm::Initialize(PacketNumberSpace packet_number_space,
+                                      LossDetectionInterface* parent) {
+  parent_ = parent;
+  if (packet_number_space_ < NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10430_2) << "Cannot switch packet_number_space";
+    return;
+  }
+
+  packet_number_space_ = packet_number_space;
+}
+
+void GeneralLossAlgorithm::Reset() {
+  loss_detection_timeout_ = QuicTime::Zero();
+  least_in_flight_.Clear();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/general_loss_algorithm.h b/quiche/quic/core/congestion_control/general_loss_algorithm.h
new file mode 100644
index 0000000..701b2dc
--- /dev/null
+++ b/quiche/quic/core/congestion_control/general_loss_algorithm.h
@@ -0,0 +1,138 @@
+// Copyright 2015 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_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
+
+#include <algorithm>
+#include <map>
+
+#include "quiche/quic/core/congestion_control/loss_detection_interface.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Class which can be configured to implement's TCP's approach of detecting loss
+// when 3 nacks have been received for a packet or with a time threshold.
+// Also implements TCP's early retransmit(RFC5827).
+class QUIC_EXPORT_PRIVATE GeneralLossAlgorithm : public LossDetectionInterface {
+ public:
+  GeneralLossAlgorithm() = default;
+  GeneralLossAlgorithm(const GeneralLossAlgorithm&) = delete;
+  GeneralLossAlgorithm& operator=(const GeneralLossAlgorithm&) = delete;
+  ~GeneralLossAlgorithm() override {}
+
+  void SetFromConfig(const QuicConfig& /*config*/,
+                     Perspective /*perspective*/) override {}
+
+  // Uses |largest_acked| and time to decide when packets are lost.
+  DetectionStats DetectLosses(const QuicUnackedPacketMap& unacked_packets,
+                              QuicTime time,
+                              const RttStats& rtt_stats,
+                              QuicPacketNumber largest_newly_acked,
+                              const AckedPacketVector& packets_acked,
+                              LostPacketVector* packets_lost) override;
+
+  // Returns a non-zero value when the early retransmit timer is active.
+  QuicTime GetLossTimeout() const override;
+
+  // Called to increases time and/or packet threshold.
+  void SpuriousLossDetected(const QuicUnackedPacketMap& unacked_packets,
+                            const RttStats& rtt_stats,
+                            QuicTime ack_receive_time,
+                            QuicPacketNumber packet_number,
+                            QuicPacketNumber previous_largest_acked) override;
+
+  void OnConfigNegotiated() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnConfigNegotiated";
+  }
+
+  void OnMinRttAvailable() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnMinRttAvailable";
+  }
+
+  void OnUserAgentIdKnown() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnUserAgentIdKnown";
+  }
+
+  void OnConnectionClosed() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnConnectionClosed";
+  }
+
+  void OnReorderingDetected() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnReorderingDetected";
+  }
+
+  void Initialize(PacketNumberSpace packet_number_space,
+                  LossDetectionInterface* parent);
+
+  void Reset();
+
+  QuicPacketCount reordering_threshold() const { return reordering_threshold_; }
+
+  int reordering_shift() const { return reordering_shift_; }
+
+  void set_reordering_shift(int reordering_shift) {
+    reordering_shift_ = reordering_shift;
+  }
+
+  void set_reordering_threshold(QuicPacketCount reordering_threshold) {
+    reordering_threshold_ = reordering_threshold;
+  }
+
+  bool use_adaptive_reordering_threshold() const {
+    return use_adaptive_reordering_threshold_;
+  }
+
+  void set_use_adaptive_reordering_threshold(bool value) {
+    use_adaptive_reordering_threshold_ = value;
+  }
+
+  bool use_adaptive_time_threshold() const {
+    return use_adaptive_time_threshold_;
+  }
+
+  void enable_adaptive_time_threshold() { use_adaptive_time_threshold_ = true; }
+
+  bool use_packet_threshold_for_runt_packets() const {
+    return use_packet_threshold_for_runt_packets_;
+  }
+
+  void disable_packet_threshold_for_runt_packets() {
+    use_packet_threshold_for_runt_packets_ = false;
+  }
+
+ private:
+  LossDetectionInterface* parent_ = nullptr;
+  QuicTime loss_detection_timeout_ = QuicTime::Zero();
+  // Fraction of a max(SRTT, latest_rtt) to permit reordering before declaring
+  // loss.  Fraction calculated by shifting max(SRTT, latest_rtt) to the right
+  // by reordering_shift.
+  int reordering_shift_ = kDefaultLossDelayShift;
+  // Reordering threshold for loss detection.
+  QuicPacketCount reordering_threshold_ = kDefaultPacketReorderingThreshold;
+  // If true, uses adaptive reordering threshold for loss detection.
+  bool use_adaptive_reordering_threshold_ = true;
+  // If true, uses adaptive time threshold for time based loss detection.
+  bool use_adaptive_time_threshold_ = false;
+  // If true, uses packet threshold when largest acked is a runt packet.
+  bool use_packet_threshold_for_runt_packets_ = true;
+  // The least in flight packet. Loss detection should start from this. Please
+  // note, least_in_flight_ could be largest packet ever sent + 1.
+  QuicPacketNumber least_in_flight_{1};
+  PacketNumberSpace packet_number_space_ = NUM_PACKET_NUMBER_SPACES;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
diff --git a/quiche/quic/core/congestion_control/general_loss_algorithm_test.cc b/quiche/quic/core/congestion_control/general_loss_algorithm_test.cc
new file mode 100644
index 0000000..3b67c65
--- /dev/null
+++ b/quiche/quic/core/congestion_control/general_loss_algorithm_test.cc
@@ -0,0 +1,489 @@
+// Copyright 2015 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 "quiche/quic/core/congestion_control/general_loss_algorithm.h"
+
+#include <algorithm>
+#include <cstdint>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+class GeneralLossAlgorithmTest : public QuicTest {
+ protected:
+  GeneralLossAlgorithmTest() : unacked_packets_(Perspective::IS_CLIENT) {
+    rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                         QuicTime::Delta::Zero(), clock_.Now());
+    EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
+    loss_algorithm_.Initialize(HANDSHAKE_DATA, nullptr);
+  }
+
+  ~GeneralLossAlgorithmTest() override {}
+
+  void SendDataPacket(uint64_t packet_number,
+                      QuicPacketLength encrypted_length) {
+    QuicStreamFrame frame;
+    frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        CurrentSupportedVersions()[0].transport_version,
+        Perspective::IS_CLIENT);
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr,
+                            encrypted_length, false, false);
+    packet.retransmittable_frames.push_back(QuicFrame(frame));
+    unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
+                                   true, true);
+  }
+
+  void SendDataPacket(uint64_t packet_number) {
+    SendDataPacket(packet_number, kDefaultLength);
+  }
+
+  void SendAckPacket(uint64_t packet_number) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            true, false);
+    unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
+                                   false, true);
+  }
+
+  void VerifyLosses(uint64_t largest_newly_acked,
+                    const AckedPacketVector& packets_acked,
+                    const std::vector<uint64_t>& losses_expected) {
+    return VerifyLosses(largest_newly_acked, packets_acked, losses_expected,
+                        absl::nullopt, absl::nullopt);
+  }
+
+  void VerifyLosses(
+      uint64_t largest_newly_acked,
+      const AckedPacketVector& packets_acked,
+      const std::vector<uint64_t>& losses_expected,
+      absl::optional<QuicPacketCount> max_sequence_reordering_expected,
+      absl::optional<QuicPacketCount>
+          num_borderline_time_reorderings_expected) {
+    unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+        APPLICATION_DATA, QuicPacketNumber(largest_newly_acked));
+    LostPacketVector lost_packets;
+    LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses(
+        unacked_packets_, clock_.Now(), rtt_stats_,
+        QuicPacketNumber(largest_newly_acked), packets_acked, &lost_packets);
+    if (max_sequence_reordering_expected.has_value()) {
+      EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
+                max_sequence_reordering_expected.value());
+    }
+    if (num_borderline_time_reorderings_expected.has_value()) {
+      EXPECT_EQ(stats.sent_packets_num_borderline_time_reorderings,
+                num_borderline_time_reorderings_expected.value());
+    }
+    ASSERT_EQ(losses_expected.size(), lost_packets.size());
+    for (size_t i = 0; i < losses_expected.size(); ++i) {
+      EXPECT_EQ(lost_packets[i].packet_number,
+                QuicPacketNumber(losses_expected[i]));
+    }
+  }
+
+  QuicUnackedPacketMap unacked_packets_;
+  GeneralLossAlgorithm loss_algorithm_;
+  RttStats rtt_stats_;
+  MockClock clock_;
+};
+
+TEST_F(GeneralLossAlgorithmTest, NackRetransmit1Packet) {
+  const size_t kNumSentPackets = 5;
+  // Transmit 5 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // No loss on one ack.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{}, 1, 0);
+  packets_acked.clear();
+  // No loss on two acks.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(3, packets_acked, std::vector<uint64_t>{}, 2, 0);
+  packets_acked.clear();
+  // Loss on three acks.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, {1}, 3, 0);
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+// A stretch ack is an ack that covers more than 1 packet of previously
+// unacknowledged data.
+TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketWith1StretchAck) {
+  const size_t kNumSentPackets = 10;
+  // Transmit 10 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // Nack the first packet 3 times in a single StretchAck.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+// Ack a packet 3 packets ahead, causing a retransmit.
+TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketSingleAck) {
+  const size_t kNumSentPackets = 10;
+  // Transmit 10 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // Nack the first packet 3 times in an AckFrame with three missing packets.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, {1});
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, EarlyRetransmit1Packet) {
+  const size_t kNumSentPackets = 2;
+  // Transmit 2 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // Early retransmit when the final packet gets acked and the first is nacked.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+
+  clock_.AdvanceTime(1.13 * rtt_stats_.latest_rtt());
+  // If reordering_shift increases by one we should have detected a loss.
+  VerifyLosses(2, packets_acked, {}, /*max_sequence_reordering_expected=*/1,
+               /*num_borderline_time_reorderings_expected=*/1);
+
+  clock_.AdvanceTime(0.13 * rtt_stats_.latest_rtt());
+  VerifyLosses(2, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitAllPackets) {
+  const size_t kNumSentPackets = 5;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+    // Advance the time 1/4 RTT between 3 and 4.
+    if (i == 3) {
+      clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
+    }
+  }
+  AckedPacketVector packets_acked;
+  // Early retransmit when the final packet gets acked and 1.25 RTTs have
+  // elapsed since the packets were sent.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(kNumSentPackets));
+  packets_acked.push_back(AckedPacket(QuicPacketNumber(kNumSentPackets),
+                                      kMaxOutgoingPacketSize,
+                                      QuicTime::Zero()));
+  // This simulates a single ack following multiple missing packets with FACK.
+  VerifyLosses(kNumSentPackets, packets_acked, {1, 2});
+  packets_acked.clear();
+  // The time has already advanced 1/4 an RTT, so ensure the timeout is set
+  // 1.25 RTTs after the earliest pending packet(3), not the last(4).
+  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+  VerifyLosses(kNumSentPackets, packets_acked, {3});
+  EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+  clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
+  VerifyLosses(kNumSentPackets, packets_acked, {4});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, DontEarlyRetransmitNeuteredPacket) {
+  const size_t kNumSentPackets = 2;
+  // Transmit 2 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // Neuter packet 1.
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+
+  // Early retransmit when the final packet gets acked and the first is nacked.
+  unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitWithLargerUnackablePackets) {
+  // Transmit 2 data packets and one ack.
+  SendDataPacket(1);
+  SendDataPacket(2);
+  SendAckPacket(3);
+  AckedPacketVector packets_acked;
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+
+  // Early retransmit when the final packet gets acked and the first is nacked.
+  unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+
+  // The packet should be lost once the loss timeout is reached.
+  clock_.AdvanceTime(0.25 * rtt_stats_.latest_rtt());
+  VerifyLosses(2, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, AlwaysLosePacketSent1RTTEarlier) {
+  // Transmit 1 packet and then wait an rtt plus 1ms.
+  SendDataPacket(1);
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
+                     QuicTime::Delta::FromMilliseconds(1));
+
+  // Transmit 2 packets.
+  SendDataPacket(2);
+  SendDataPacket(3);
+  AckedPacketVector packets_acked;
+  // Wait another RTT and ack 2.
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+  unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, {1});
+}
+
+TEST_F(GeneralLossAlgorithmTest, IncreaseTimeThresholdUponSpuriousLoss) {
+  loss_algorithm_.enable_adaptive_time_threshold();
+  loss_algorithm_.set_reordering_shift(kDefaultLossDelayShift);
+  EXPECT_EQ(kDefaultLossDelayShift, loss_algorithm_.reordering_shift());
+  EXPECT_TRUE(loss_algorithm_.use_adaptive_time_threshold());
+  const size_t kNumSentPackets = 10;
+  // Transmit 2 packets at 1/10th an RTT interval.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+    clock_.AdvanceTime(0.1 * rtt_stats_.smoothed_rtt());
+  }
+  EXPECT_EQ(QuicTime::Zero() + rtt_stats_.smoothed_rtt(), clock_.Now());
+  AckedPacketVector packets_acked;
+  // Expect the timer to not be set.
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+  // Packet 1 should not be lost until 1/4 RTTs pass.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  // Expect the timer to be set to 1/4 RTT's in the future.
+  EXPECT_EQ(rtt_stats_.smoothed_rtt() * (1.0f / 4),
+            loss_algorithm_.GetLossTimeout() - clock_.Now());
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
+  VerifyLosses(2, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+  // Retransmit packet 1 as 11 and 2 as 12.
+  SendDataPacket(11);
+  SendDataPacket(12);
+
+  // Advance the time 1/4 RTT and indicate the loss was spurious.
+  // The new threshold should be 1/2 RTT.
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
+  loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
+                                       clock_.Now(), QuicPacketNumber(1),
+                                       QuicPacketNumber(2));
+  EXPECT_EQ(1, loss_algorithm_.reordering_shift());
+}
+
+TEST_F(GeneralLossAlgorithmTest, IncreaseReorderingThresholdUponSpuriousLoss) {
+  loss_algorithm_.set_use_adaptive_reordering_threshold(true);
+  for (size_t i = 1; i <= 4; ++i) {
+    SendDataPacket(i);
+  }
+  // Acking 4 causes 1 detected lost.
+  AckedPacketVector packets_acked;
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, std::vector<uint64_t>{1});
+  packets_acked.clear();
+
+  // Retransmit 1 as 5.
+  SendDataPacket(5);
+
+  // Acking 1 such that it was detected lost spuriously.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(1), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
+                                       clock_.Now(), QuicPacketNumber(1),
+                                       QuicPacketNumber(4));
+  VerifyLosses(4, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+
+  // Verify acking 5 does not cause 2 detected lost.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(5), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(5, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+
+  SendDataPacket(6);
+
+  // Acking 6 will causes 2 detected lost.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(6, packets_acked, std::vector<uint64_t>{2});
+  packets_acked.clear();
+
+  // Retransmit 2 as 7.
+  SendDataPacket(7);
+
+  // Acking 2 such that it was detected lost spuriously.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
+                                       clock_.Now(), QuicPacketNumber(2),
+                                       QuicPacketNumber(6));
+  VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+
+  // Acking 7 will not cause 3 as detected lost.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+}
+
+TEST_F(GeneralLossAlgorithmTest, DefaultIetfLossDetection) {
+  loss_algorithm_.set_reordering_shift(kDefaultIetfLossDelayShift);
+  for (size_t i = 1; i <= 6; ++i) {
+    SendDataPacket(i);
+  }
+  // Packet threshold loss detection.
+  AckedPacketVector packets_acked;
+  // No loss on one ack.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  // No loss on two acks.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(3, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  // Loss on three acks.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+  packets_acked.clear();
+
+  SendDataPacket(7);
+
+  // Time threshold loss detection.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
+                (rtt_stats_.smoothed_rtt() >> 3),
+            loss_algorithm_.GetLossTimeout());
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
+                     (rtt_stats_.smoothed_rtt() >> 3));
+  VerifyLosses(6, packets_acked, {5});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, IetfLossDetectionWithOneFourthRttDelay) {
+  loss_algorithm_.set_reordering_shift(2);
+  SendDataPacket(1);
+  SendDataPacket(2);
+
+  AckedPacketVector packets_acked;
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
+                (rtt_stats_.smoothed_rtt() >> 2),
+            loss_algorithm_.GetLossTimeout());
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
+                     (rtt_stats_.smoothed_rtt() >> 2));
+  VerifyLosses(2, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, NoPacketThresholdForRuntPackets) {
+  loss_algorithm_.disable_packet_threshold_for_runt_packets();
+  for (size_t i = 1; i <= 6; ++i) {
+    SendDataPacket(i);
+  }
+  // Send a small packet.
+  SendDataPacket(7, /*encrypted_length=*/kDefaultLength / 2);
+  // No packet threshold for runt packet.
+  AckedPacketVector packets_acked;
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  // Verify no packet is detected lost because packet 7 is a runt.
+  VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
+  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
+                (rtt_stats_.smoothed_rtt() >> 2),
+            loss_algorithm_.GetLossTimeout());
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
+                     (rtt_stats_.smoothed_rtt() >> 2));
+  // Verify packets are declared lost because time threshold has passed.
+  VerifyLosses(7, packets_acked, {1, 2, 3, 4, 5, 6});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/hybrid_slow_start.cc b/quiche/quic/core/congestion_control/hybrid_slow_start.cc
new file mode 100644
index 0000000..1eb9944
--- /dev/null
+++ b/quiche/quic/core/congestion_control/hybrid_slow_start.cc
@@ -0,0 +1,104 @@
+// 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 "quiche/quic/core/congestion_control/hybrid_slow_start.h"
+
+#include <algorithm>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// Note(pwestin): the magic clamping numbers come from the original code in
+// tcp_cubic.c.
+const int64_t kHybridStartLowWindow = 16;
+// Number of delay samples for detecting the increase of delay.
+const uint32_t kHybridStartMinSamples = 8;
+// Exit slow start if the min rtt has increased by more than 1/8th.
+const int kHybridStartDelayFactorExp = 3;  // 2^3 = 8
+// The original paper specifies 2 and 8ms, but those have changed over time.
+const int64_t kHybridStartDelayMinThresholdUs = 4000;
+const int64_t kHybridStartDelayMaxThresholdUs = 16000;
+
+HybridSlowStart::HybridSlowStart()
+    : started_(false),
+      hystart_found_(NOT_FOUND),
+      rtt_sample_count_(0),
+      current_min_rtt_(QuicTime::Delta::Zero()) {}
+
+void HybridSlowStart::OnPacketAcked(QuicPacketNumber acked_packet_number) {
+  // OnPacketAcked gets invoked after ShouldExitSlowStart, so it's best to end
+  // the round when the final packet of the burst is received and start it on
+  // the next incoming ack.
+  if (IsEndOfRound(acked_packet_number)) {
+    started_ = false;
+  }
+}
+
+void HybridSlowStart::OnPacketSent(QuicPacketNumber packet_number) {
+  last_sent_packet_number_ = packet_number;
+}
+
+void HybridSlowStart::Restart() {
+  started_ = false;
+  hystart_found_ = NOT_FOUND;
+}
+
+void HybridSlowStart::StartReceiveRound(QuicPacketNumber last_sent) {
+  QUIC_DVLOG(1) << "Reset hybrid slow start @" << last_sent;
+  end_packet_number_ = last_sent;
+  current_min_rtt_ = QuicTime::Delta::Zero();
+  rtt_sample_count_ = 0;
+  started_ = true;
+}
+
+bool HybridSlowStart::IsEndOfRound(QuicPacketNumber ack) const {
+  return !end_packet_number_.IsInitialized() || end_packet_number_ <= ack;
+}
+
+bool HybridSlowStart::ShouldExitSlowStart(QuicTime::Delta latest_rtt,
+                                          QuicTime::Delta min_rtt,
+                                          QuicPacketCount congestion_window) {
+  if (!started_) {
+    // Time to start the hybrid slow start.
+    StartReceiveRound(last_sent_packet_number_);
+  }
+  if (hystart_found_ != NOT_FOUND) {
+    return true;
+  }
+  // Second detection parameter - delay increase detection.
+  // Compare the minimum delay (current_min_rtt_) of the current
+  // burst of packets relative to the minimum delay during the session.
+  // Note: we only look at the first few(8) packets in each burst, since we
+  // only want to compare the lowest RTT of the burst relative to previous
+  // bursts.
+  rtt_sample_count_++;
+  if (rtt_sample_count_ <= kHybridStartMinSamples) {
+    if (current_min_rtt_.IsZero() || current_min_rtt_ > latest_rtt) {
+      current_min_rtt_ = latest_rtt;
+    }
+  }
+  // We only need to check this once per round.
+  if (rtt_sample_count_ == kHybridStartMinSamples) {
+    // Divide min_rtt by 8 to get a rtt increase threshold for exiting.
+    int64_t min_rtt_increase_threshold_us =
+        min_rtt.ToMicroseconds() >> kHybridStartDelayFactorExp;
+    // Ensure the rtt threshold is never less than 2ms or more than 16ms.
+    min_rtt_increase_threshold_us = std::min(min_rtt_increase_threshold_us,
+                                             kHybridStartDelayMaxThresholdUs);
+    QuicTime::Delta min_rtt_increase_threshold =
+        QuicTime::Delta::FromMicroseconds(std::max(
+            min_rtt_increase_threshold_us, kHybridStartDelayMinThresholdUs));
+
+    if (current_min_rtt_ > min_rtt + min_rtt_increase_threshold) {
+      hystart_found_ = DELAY;
+    }
+  }
+  // Exit from slow start if the cwnd is greater than 16 and
+  // increasing delay is found.
+  return congestion_window >= kHybridStartLowWindow &&
+         hystart_found_ != NOT_FOUND;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/hybrid_slow_start.h b/quiche/quic/core/congestion_control/hybrid_slow_start.h
new file mode 100644
index 0000000..9ea130c
--- /dev/null
+++ b/quiche/quic/core/congestion_control/hybrid_slow_start.h
@@ -0,0 +1,83 @@
+// 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.
+
+// This class is a helper class to TcpCubicSender.
+// Slow start is the initial startup phase of TCP, it lasts until first packet
+// loss. This class implements hybrid slow start of the TCP cubic send side
+// congestion algorithm. The key feaure of hybrid slow start is that it tries to
+// avoid running into the wall too hard during the slow start phase, which
+// the traditional TCP implementation does.
+// This does not implement ack train detection because it interacts poorly with
+// pacing.
+// http://netsrv.csc.ncsu.edu/export/hybridstart_pfldnet08.pdf
+// http://research.csc.ncsu.edu/netsrv/sites/default/files/hystart_techreport_2008.pdf
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE HybridSlowStart {
+ public:
+  HybridSlowStart();
+  HybridSlowStart(const HybridSlowStart&) = delete;
+  HybridSlowStart& operator=(const HybridSlowStart&) = delete;
+
+  void OnPacketAcked(QuicPacketNumber acked_packet_number);
+
+  void OnPacketSent(QuicPacketNumber packet_number);
+
+  // ShouldExitSlowStart should be called on every new ack frame, since a new
+  // RTT measurement can be made then.
+  // rtt: the RTT for this ack packet.
+  // min_rtt: is the lowest delay (RTT) we have seen during the session.
+  // congestion_window: the congestion window in packets.
+  bool ShouldExitSlowStart(QuicTime::Delta rtt,
+                           QuicTime::Delta min_rtt,
+                           QuicPacketCount congestion_window);
+
+  // Start a new slow start phase.
+  void Restart();
+
+  // TODO(ianswett): The following methods should be private, but that requires
+  // a follow up CL to update the unit test.
+  // Returns true if this ack the last packet number of our current slow start
+  // round.
+  // Call Reset if this returns true.
+  bool IsEndOfRound(QuicPacketNumber ack) const;
+
+  // Call for the start of each receive round (burst) in the slow start phase.
+  void StartReceiveRound(QuicPacketNumber last_sent);
+
+  // Whether slow start has started.
+  bool started() const { return started_; }
+
+ private:
+  // Whether a condition for exiting slow start has been found.
+  enum HystartState {
+    NOT_FOUND,
+    DELAY,  // Too much increase in the round's min_rtt was observed.
+  };
+
+  // Whether the hybrid slow start has been started.
+  bool started_;
+  HystartState hystart_found_;
+  // Last packet number sent which was CWND limited.
+  QuicPacketNumber last_sent_packet_number_;
+
+  // Variables for tracking acks received during a slow start round.
+  QuicPacketNumber end_packet_number_;  // End of the receive round.
+  uint32_t rtt_sample_count_;  // Number of rtt samples in the current round.
+  QuicTime::Delta current_min_rtt_;  // The minimum rtt of current round.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
diff --git a/quiche/quic/core/congestion_control/hybrid_slow_start_test.cc b/quiche/quic/core/congestion_control/hybrid_slow_start_test.cc
new file mode 100644
index 0000000..94654fc
--- /dev/null
+++ b/quiche/quic/core/congestion_control/hybrid_slow_start_test.cc
@@ -0,0 +1,76 @@
+// 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 "quiche/quic/core/congestion_control/hybrid_slow_start.h"
+
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class HybridSlowStartTest : public QuicTest {
+ protected:
+  HybridSlowStartTest()
+      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
+        rtt_(QuicTime::Delta::FromMilliseconds(60)) {}
+  void SetUp() override { slow_start_ = std::make_unique<HybridSlowStart>(); }
+  const QuicTime::Delta one_ms_;
+  const QuicTime::Delta rtt_;
+  std::unique_ptr<HybridSlowStart> slow_start_;
+};
+
+TEST_F(HybridSlowStartTest, Simple) {
+  QuicPacketNumber packet_number(1);
+  QuicPacketNumber end_packet_number(3);
+  slow_start_->StartReceiveRound(end_packet_number);
+
+  EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
+
+  // Test duplicates.
+  EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number));
+
+  EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
+  EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
+
+  // Test without a new registered end_packet_number;
+  EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
+
+  end_packet_number = QuicPacketNumber(20);
+  slow_start_->StartReceiveRound(end_packet_number);
+  while (packet_number < end_packet_number) {
+    EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
+  }
+  EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
+}
+
+TEST_F(HybridSlowStartTest, Delay) {
+  // We expect to detect the increase at +1/8 of the RTT; hence at a typical
+  // RTT of 60ms the detection will happen at 67.5 ms.
+  const int kHybridStartMinSamples = 8;  // Number of acks required to trigger.
+
+  QuicPacketNumber end_packet_number(1);
+  slow_start_->StartReceiveRound(end_packet_number++);
+
+  // Will not trigger since our lowest RTT in our burst is the same as the long
+  // term RTT provided.
+  for (int n = 0; n < kHybridStartMinSamples; ++n) {
+    EXPECT_FALSE(slow_start_->ShouldExitSlowStart(
+        rtt_ + QuicTime::Delta::FromMilliseconds(n), rtt_, 100));
+  }
+  slow_start_->StartReceiveRound(end_packet_number++);
+  for (int n = 1; n < kHybridStartMinSamples; ++n) {
+    EXPECT_FALSE(slow_start_->ShouldExitSlowStart(
+        rtt_ + QuicTime::Delta::FromMilliseconds(n + 10), rtt_, 100));
+  }
+  // Expect to trigger since all packets in this burst was above the long term
+  // RTT provided.
+  EXPECT_TRUE(slow_start_->ShouldExitSlowStart(
+      rtt_ + QuicTime::Delta::FromMilliseconds(10), rtt_, 100));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/loss_detection_interface.h b/quiche/quic/core/congestion_control/loss_detection_interface.h
new file mode 100644
index 0000000..76aa2df
--- /dev/null
+++ b/quiche/quic/core/congestion_control/loss_detection_interface.h
@@ -0,0 +1,75 @@
+// 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.
+
+// The pure virtual class for send side loss detection algorithm.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
+
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicUnackedPacketMap;
+class RttStats;
+
+class QUIC_EXPORT_PRIVATE LossDetectionInterface {
+ public:
+  virtual ~LossDetectionInterface() {}
+
+  virtual void SetFromConfig(const QuicConfig& config,
+                             Perspective perspective) = 0;
+
+  struct QUIC_NO_EXPORT DetectionStats {
+    // Maximum sequence reordering observed in newly acked packets.
+    QuicPacketCount sent_packets_max_sequence_reordering = 0;
+    QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
+    // Total detection response time for lost packets from this detection.
+    // See QuicConnectionStats for the definition of detection response time.
+    float total_loss_detection_response_time = 0.0;
+  };
+
+  // Called when a new ack arrives or the loss alarm fires.
+  virtual DetectionStats DetectLosses(
+      const QuicUnackedPacketMap& unacked_packets,
+      QuicTime time,
+      const RttStats& rtt_stats,
+      QuicPacketNumber largest_newly_acked,
+      const AckedPacketVector& packets_acked,
+      LostPacketVector* packets_lost) = 0;
+
+  // Get the time the LossDetectionAlgorithm wants to re-evaluate losses.
+  // Returns QuicTime::Zero if no alarm needs to be set.
+  virtual QuicTime GetLossTimeout() const = 0;
+
+  // Called when |packet_number| was detected lost but gets acked later.
+  virtual void SpuriousLossDetected(
+      const QuicUnackedPacketMap& unacked_packets,
+      const RttStats& rtt_stats,
+      QuicTime ack_receive_time,
+      QuicPacketNumber packet_number,
+      QuicPacketNumber previous_largest_acked) = 0;
+
+  virtual void OnConfigNegotiated() = 0;
+
+  virtual void OnMinRttAvailable() = 0;
+
+  virtual void OnUserAgentIdKnown() = 0;
+
+  virtual void OnConnectionClosed() = 0;
+
+  // Called when a reordering is detected by the loss algorithm, but _before_
+  // the reordering_shift and reordering_threshold are consulted to see whether
+  // it is a loss.
+  virtual void OnReorderingDetected() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
diff --git a/quiche/quic/core/congestion_control/pacing_sender.cc b/quiche/quic/core/congestion_control/pacing_sender.cc
new file mode 100644
index 0000000..9eede85
--- /dev/null
+++ b/quiche/quic/core/congestion_control/pacing_sender.cc
@@ -0,0 +1,177 @@
+// Copyright (c) 2013 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 "quiche/quic/core/congestion_control/pacing_sender.h"
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace {
+
+// Configured maximum size of the burst coming out of quiescence.  The burst
+// is never larger than the current CWND in packets.
+static const uint32_t kInitialUnpacedBurst = 10;
+
+}  // namespace
+
+PacingSender::PacingSender()
+    : sender_(nullptr),
+      max_pacing_rate_(QuicBandwidth::Zero()),
+      burst_tokens_(kInitialUnpacedBurst),
+      ideal_next_packet_send_time_(QuicTime::Zero()),
+      initial_burst_size_(kInitialUnpacedBurst),
+      lumpy_tokens_(0),
+      alarm_granularity_(kAlarmGranularity),
+      pacing_limited_(false) {
+  if (GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_donot_reset_ideal_next_packet_send_time);
+  }
+}
+
+PacingSender::~PacingSender() {}
+
+void PacingSender::set_sender(SendAlgorithmInterface* sender) {
+  QUICHE_DCHECK(sender != nullptr);
+  sender_ = sender;
+}
+
+void PacingSender::OnCongestionEvent(bool rtt_updated,
+                                     QuicByteCount bytes_in_flight,
+                                     QuicTime event_time,
+                                     const AckedPacketVector& acked_packets,
+                                     const LostPacketVector& lost_packets) {
+  QUICHE_DCHECK(sender_ != nullptr);
+  if (!lost_packets.empty()) {
+    // Clear any burst tokens when entering recovery.
+    burst_tokens_ = 0;
+  }
+  sender_->OnCongestionEvent(rtt_updated, bytes_in_flight, event_time,
+                             acked_packets, lost_packets);
+}
+
+void PacingSender::OnPacketSent(
+    QuicTime sent_time,
+    QuicByteCount bytes_in_flight,
+    QuicPacketNumber packet_number,
+    QuicByteCount bytes,
+    HasRetransmittableData has_retransmittable_data) {
+  QUICHE_DCHECK(sender_ != nullptr);
+  sender_->OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes,
+                        has_retransmittable_data);
+  if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
+    return;
+  }
+  // If in recovery, the connection is not coming out of quiescence.
+  if (bytes_in_flight == 0 && !sender_->InRecovery()) {
+    // Add more burst tokens anytime the connection is leaving quiescence, but
+    // limit it to the equivalent of a single bulk write, not exceeding the
+    // current CWND in packets.
+    burst_tokens_ = std::min(
+        initial_burst_size_,
+        static_cast<uint32_t>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
+  }
+  if (burst_tokens_ > 0) {
+    --burst_tokens_;
+    if (!GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) {
+      ideal_next_packet_send_time_ = QuicTime::Zero();
+    }
+    pacing_limited_ = false;
+    return;
+  }
+  // The next packet should be sent as soon as the current packet has been
+  // transferred.  PacingRate is based on bytes in flight including this packet.
+  QuicTime::Delta delay =
+      PacingRate(bytes_in_flight + bytes).TransferTime(bytes);
+  if (!pacing_limited_ || lumpy_tokens_ == 0) {
+    // Reset lumpy_tokens_ if either application or cwnd throttles sending or
+    // token runs out.
+    lumpy_tokens_ = std::max(
+        1u, std::min(static_cast<uint32_t>(
+                         GetQuicFlag(FLAGS_quic_lumpy_pacing_size)),
+                     static_cast<uint32_t>(
+                         (sender_->GetCongestionWindow() *
+                          GetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction)) /
+                         kDefaultTCPMSS)));
+    if (sender_->BandwidthEstimate() <
+        QuicBandwidth::FromKBitsPerSecond(
+            GetQuicFlag(FLAGS_quic_lumpy_pacing_min_bandwidth_kbps))) {
+      // Below 1.2Mbps, send 1 packet at once, because one full-sized packet
+      // is about 10ms of queueing.
+      lumpy_tokens_ = 1u;
+    }
+    if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts) &&
+        (bytes_in_flight + bytes) >= sender_->GetCongestionWindow()) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_fix_pacing_sender_bursts);
+      // Don't add lumpy_tokens if the congestion controller is CWND limited.
+      lumpy_tokens_ = 1u;
+    }
+  }
+  --lumpy_tokens_;
+  if (pacing_limited_) {
+    // Make up for lost time since pacing throttles the sending.
+    ideal_next_packet_send_time_ = ideal_next_packet_send_time_ + delay;
+  } else {
+    ideal_next_packet_send_time_ =
+        std::max(ideal_next_packet_send_time_ + delay, sent_time + delay);
+  }
+  // Stop making up for lost time if underlying sender prevents sending.
+  pacing_limited_ = sender_->CanSend(bytes_in_flight + bytes);
+}
+
+void PacingSender::OnApplicationLimited() {
+  // The send is application limited, stop making up for lost time.
+  pacing_limited_ = false;
+}
+
+void PacingSender::SetBurstTokens(uint32_t burst_tokens) {
+  initial_burst_size_ = burst_tokens;
+  burst_tokens_ = std::min(
+      initial_burst_size_,
+      static_cast<uint32_t>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
+}
+
+QuicTime::Delta PacingSender::TimeUntilSend(
+    QuicTime now,
+    QuicByteCount bytes_in_flight) const {
+  QUICHE_DCHECK(sender_ != nullptr);
+
+  if (!sender_->CanSend(bytes_in_flight)) {
+    // The underlying sender prevents sending.
+    return QuicTime::Delta::Infinite();
+  }
+
+  if (burst_tokens_ > 0 || bytes_in_flight == 0 || lumpy_tokens_ > 0) {
+    // Don't pace if we have burst tokens available or leaving quiescence.
+    QUIC_DVLOG(1) << "Sending packet now. burst_tokens:" << burst_tokens_
+                  << ", bytes_in_flight:" << bytes_in_flight
+                  << ", lumpy_tokens:" << lumpy_tokens_;
+    return QuicTime::Delta::Zero();
+  }
+
+  // If the next send time is within the alarm granularity, send immediately.
+  if (ideal_next_packet_send_time_ > now + alarm_granularity_) {
+    QUIC_DVLOG(1) << "Delaying packet: "
+                  << (ideal_next_packet_send_time_ - now).ToMicroseconds();
+    return ideal_next_packet_send_time_ - now;
+  }
+
+  QUIC_DVLOG(1) << "Sending packet now. ideal_next_packet_send_time: "
+                << ideal_next_packet_send_time_ << ", now: " << now;
+  return QuicTime::Delta::Zero();
+}
+
+QuicBandwidth PacingSender::PacingRate(QuicByteCount bytes_in_flight) const {
+  QUICHE_DCHECK(sender_ != nullptr);
+  if (!max_pacing_rate_.IsZero()) {
+    return QuicBandwidth::FromBitsPerSecond(
+        std::min(max_pacing_rate_.ToBitsPerSecond(),
+                 sender_->PacingRate(bytes_in_flight).ToBitsPerSecond()));
+  }
+  return sender_->PacingRate(bytes_in_flight);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/pacing_sender.h b/quiche/quic/core/congestion_control/pacing_sender.h
new file mode 100644
index 0000000..c7be125
--- /dev/null
+++ b/quiche/quic/core/congestion_control/pacing_sender.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2013 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.
+
+// A send algorithm that adds pacing on top of an another send algorithm.
+// It uses the underlying sender's pacing rate to schedule packets.
+// It also takes into consideration the expected granularity of the underlying
+// alarm to ensure that alarms are not set too aggressively, and err towards
+// sending packets too early instead of too late.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
+
+#include <cstdint>
+#include <map>
+#include <memory>
+
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicSentPacketManagerPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE PacingSender {
+ public:
+  PacingSender();
+  PacingSender(const PacingSender&) = delete;
+  PacingSender& operator=(const PacingSender&) = delete;
+  ~PacingSender();
+
+  // Sets the underlying sender. Does not take ownership of |sender|. |sender|
+  // must not be null. This must be called before any of the
+  // SendAlgorithmInterface wrapper methods are called.
+  void set_sender(SendAlgorithmInterface* sender);
+
+  void set_max_pacing_rate(QuicBandwidth max_pacing_rate) {
+    max_pacing_rate_ = max_pacing_rate;
+  }
+
+  void set_alarm_granularity(QuicTime::Delta alarm_granularity) {
+    alarm_granularity_ = alarm_granularity;
+  }
+
+  QuicBandwidth max_pacing_rate() const { return max_pacing_rate_; }
+
+  void OnCongestionEvent(bool rtt_updated,
+                         QuicByteCount bytes_in_flight,
+                         QuicTime event_time,
+                         const AckedPacketVector& acked_packets,
+                         const LostPacketVector& lost_packets);
+
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData has_retransmittable_data);
+
+  // Called when application throttles the sending, so that pacing sender stops
+  // making up for lost time.
+  void OnApplicationLimited();
+
+  // Set burst_tokens_ and initial_burst_size_.
+  void SetBurstTokens(uint32_t burst_tokens);
+
+  QuicTime::Delta TimeUntilSend(QuicTime now,
+                                QuicByteCount bytes_in_flight) const;
+
+  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const;
+
+  NextReleaseTimeResult GetNextReleaseTime() const {
+    bool allow_burst = (burst_tokens_ > 0 || lumpy_tokens_ > 0);
+    return {ideal_next_packet_send_time_, allow_burst};
+  }
+
+  uint32_t initial_burst_size() const { return initial_burst_size_; }
+
+ protected:
+  uint32_t lumpy_tokens() const { return lumpy_tokens_; }
+
+ private:
+  friend class test::QuicSentPacketManagerPeer;
+
+  // Underlying sender. Not owned.
+  SendAlgorithmInterface* sender_;
+  // If not QuicBandidth::Zero, the maximum rate the PacingSender will use.
+  QuicBandwidth max_pacing_rate_;
+
+  // Number of unpaced packets to be sent before packets are delayed.
+  uint32_t burst_tokens_;
+  QuicTime ideal_next_packet_send_time_;  // When can the next packet be sent.
+  uint32_t initial_burst_size_;
+
+  // Number of unpaced packets to be sent before packets are delayed. This token
+  // is consumed after burst_tokens_ ran out.
+  uint32_t lumpy_tokens_;
+
+  // If the next send time is within alarm_granularity_, send immediately.
+  // TODO(fayang): Remove alarm_granularity_ when deprecating
+  // quic_offload_pacing_to_usps2 flag.
+  QuicTime::Delta alarm_granularity_;
+
+  // Indicates whether pacing throttles the sending. If true, make up for lost
+  // time.
+  bool pacing_limited_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
diff --git a/quiche/quic/core/congestion_control/pacing_sender_test.cc b/quiche/quic/core/congestion_control/pacing_sender_test.cc
new file mode 100644
index 0000000..9e28c75
--- /dev/null
+++ b/quiche/quic/core/congestion_control/pacing_sender_test.cc
@@ -0,0 +1,597 @@
+// Copyright (c) 2013 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 "quiche/quic/core/congestion_control/pacing_sender.h"
+
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::AtMost;
+using testing::IsEmpty;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+
+const QuicByteCount kBytesInFlight = 1024;
+const int kInitialBurstPackets = 10;
+
+class TestPacingSender : public PacingSender {
+ public:
+  using PacingSender::lumpy_tokens;
+  using PacingSender::PacingSender;
+
+  QuicTime ideal_next_packet_send_time() const {
+    return GetNextReleaseTime().release_time;
+  }
+};
+
+class PacingSenderTest : public QuicTest {
+ protected:
+  PacingSenderTest()
+      : zero_time_(QuicTime::Delta::Zero()),
+        infinite_time_(QuicTime::Delta::Infinite()),
+        packet_number_(1),
+        mock_sender_(new StrictMock<MockSendAlgorithm>()),
+        pacing_sender_(new TestPacingSender) {
+    pacing_sender_->set_sender(mock_sender_.get());
+    // Pick arbitrary time.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(9));
+  }
+
+  ~PacingSenderTest() override {}
+
+  void InitPacingRate(QuicPacketCount burst_size, QuicBandwidth bandwidth) {
+    mock_sender_ = std::make_unique<StrictMock<MockSendAlgorithm>>();
+    pacing_sender_ = std::make_unique<TestPacingSender>();
+    pacing_sender_->set_sender(mock_sender_.get());
+    EXPECT_CALL(*mock_sender_, PacingRate(_)).WillRepeatedly(Return(bandwidth));
+    EXPECT_CALL(*mock_sender_, BandwidthEstimate())
+        .WillRepeatedly(Return(bandwidth));
+    if (burst_size == 0) {
+      EXPECT_CALL(*mock_sender_, OnCongestionEvent(_, _, _, _, _));
+      LostPacketVector lost_packets;
+      lost_packets.push_back(
+          LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+      AckedPacketVector empty;
+      pacing_sender_->OnCongestionEvent(true, 1234, clock_.Now(), empty,
+                                        lost_packets);
+    } else if (burst_size != kInitialBurstPackets) {
+      QUIC_LOG(FATAL) << "Unsupported burst_size " << burst_size
+                      << " specificied, only 0 and " << kInitialBurstPackets
+                      << " are supported.";
+    }
+  }
+
+  void CheckPacketIsSentImmediately(HasRetransmittableData retransmittable_data,
+                                    QuicByteCount prior_in_flight,
+                                    bool in_recovery,
+                                    QuicPacketCount cwnd) {
+    // In order for the packet to be sendable, the underlying sender must
+    // permit it to be sent immediately.
+    for (int i = 0; i < 2; ++i) {
+      EXPECT_CALL(*mock_sender_, CanSend(prior_in_flight))
+          .WillOnce(Return(true));
+      // Verify that the packet can be sent immediately.
+      EXPECT_EQ(zero_time_,
+                pacing_sender_->TimeUntilSend(clock_.Now(), prior_in_flight));
+    }
+
+    // Actually send the packet.
+    if (prior_in_flight == 0) {
+      EXPECT_CALL(*mock_sender_, InRecovery()).WillOnce(Return(in_recovery));
+    }
+    EXPECT_CALL(*mock_sender_,
+                OnPacketSent(clock_.Now(), prior_in_flight, packet_number_,
+                             kMaxOutgoingPacketSize, retransmittable_data));
+    EXPECT_CALL(*mock_sender_, GetCongestionWindow())
+        .WillRepeatedly(Return(cwnd * kDefaultTCPMSS));
+    EXPECT_CALL(*mock_sender_,
+                CanSend(prior_in_flight + kMaxOutgoingPacketSize))
+        .Times(AtMost(1))
+        .WillRepeatedly(Return((prior_in_flight + kMaxOutgoingPacketSize) <
+                               (cwnd * kDefaultTCPMSS)));
+    pacing_sender_->OnPacketSent(clock_.Now(), prior_in_flight,
+                                 packet_number_++, kMaxOutgoingPacketSize,
+                                 retransmittable_data);
+  }
+
+  void CheckPacketIsSentImmediately() {
+    CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, kBytesInFlight,
+                                 false, 10);
+  }
+
+  void CheckPacketIsDelayed(QuicTime::Delta delay) {
+    // In order for the packet to be sendable, the underlying sender must
+    // permit it to be sent immediately.
+    for (int i = 0; i < 2; ++i) {
+      EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight))
+          .WillOnce(Return(true));
+      // Verify that the packet is delayed.
+      EXPECT_EQ(delay.ToMicroseconds(),
+                pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight)
+                    .ToMicroseconds());
+    }
+  }
+
+  void UpdateRtt() {
+    EXPECT_CALL(*mock_sender_,
+                OnCongestionEvent(true, kBytesInFlight, _, _, _));
+    AckedPacketVector empty_acked;
+    LostPacketVector empty_lost;
+    pacing_sender_->OnCongestionEvent(true, kBytesInFlight, clock_.Now(),
+                                      empty_acked, empty_lost);
+  }
+
+  void OnApplicationLimited() { pacing_sender_->OnApplicationLimited(); }
+
+  const QuicTime::Delta zero_time_;
+  const QuicTime::Delta infinite_time_;
+  MockClock clock_;
+  QuicPacketNumber packet_number_;
+  std::unique_ptr<StrictMock<MockSendAlgorithm>> mock_sender_;
+  std::unique_ptr<TestPacingSender> pacing_sender_;
+};
+
+TEST_F(PacingSenderTest, NoSend) {
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight)).WillOnce(Return(false));
+    EXPECT_EQ(infinite_time_,
+              pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight));
+  }
+}
+
+TEST_F(PacingSenderTest, SendNow) {
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight)).WillOnce(Return(true));
+    EXPECT_EQ(zero_time_,
+              pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight));
+  }
+}
+
+TEST_F(PacingSenderTest, VariousSending) {
+  // Configure pacing rate of 1 packet per 1 ms, no initial burst.
+  InitPacingRate(
+      0, QuicBandwidth::FromBytesAndTimeDelta(
+             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  // Now update the RTT and verify that packets are actually paced.
+  UpdateRtt();
+
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up on time.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up late.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(4));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up really late.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up really late again, but application pause partway through.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  OnApplicationLimited();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+  // Wake up early, but after enough time has passed to permit a send.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  CheckPacketIsSentImmediately();
+}
+
+TEST_F(PacingSenderTest, InitialBurst) {
+  // Configure pacing rate of 1 packet per 1 ms.
+  InitPacingRate(
+      10, QuicBandwidth::FromBytesAndTimeDelta(
+              kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  // Update the RTT and verify that the first 10 packets aren't paced.
+  UpdateRtt();
+
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  CheckPacketIsSentImmediately();
+
+  // Next time TimeUntilSend is called with no bytes in flight, pacing should
+  // allow a packet to be sent, and when it's sent, the tokens are refilled.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
+  for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, InitialBurstNoRttMeasurement) {
+  // Configure pacing rate of 1 packet per 1 ms.
+  InitPacingRate(
+      10, QuicBandwidth::FromBytesAndTimeDelta(
+              kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  CheckPacketIsSentImmediately();
+
+  // Next time TimeUntilSend is called with no bytes in flight, the tokens
+  // should be refilled and there should be no delay.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, FastSending) {
+  // Ensure the pacing sender paces, even when the inter-packet spacing(0.5ms)
+  // is less than the pacing granularity(1ms).
+  InitPacingRate(10, QuicBandwidth::FromBytesAndTimeDelta(
+                         2 * kMaxOutgoingPacketSize,
+                         QuicTime::Delta::FromMilliseconds(1)));
+  // Update the RTT and verify that the first 10 packets aren't paced.
+  UpdateRtt();
+
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  CheckPacketIsSentImmediately();  // Make up
+  CheckPacketIsSentImmediately();  // Lumpy token
+  CheckPacketIsSentImmediately();  // "In the future" but within granularity.
+  CheckPacketIsSentImmediately();  // Lumpy token
+  CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(2000));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  CheckPacketIsSentImmediately();
+
+  // Next time TimeUntilSend is called with no bytes in flight, the tokens
+  // should be refilled and there should be no delay.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
+  for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 1.5ms.
+  CheckPacketIsSentImmediately();  // Make up
+  CheckPacketIsSentImmediately();  // Lumpy token
+  CheckPacketIsSentImmediately();  // "In the future" but within granularity.
+  CheckPacketIsSentImmediately();  // Lumpy token
+  CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(2000));
+}
+
+TEST_F(PacingSenderTest, NoBurstEnteringRecovery) {
+  // Configure pacing rate of 1 packet per 1 ms with no burst tokens.
+  InitPacingRate(
+      0, QuicBandwidth::FromBytesAndTimeDelta(
+             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+  // Sending a packet will set burst tokens.
+  CheckPacketIsSentImmediately();
+
+  // Losing a packet will set clear burst tokens.
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+  AckedPacketVector empty_acked;
+  EXPECT_CALL(*mock_sender_,
+              OnCongestionEvent(true, kMaxOutgoingPacketSize, _, IsEmpty(), _));
+  pacing_sender_->OnCongestionEvent(true, kMaxOutgoingPacketSize, clock_.Now(),
+                                    empty_acked, lost_packets);
+  // One packet is sent immediately, because of 1ms pacing granularity.
+  CheckPacketIsSentImmediately();
+  // Ensure packets are immediately paced.
+  EXPECT_CALL(*mock_sender_, CanSend(kMaxOutgoingPacketSize))
+      .WillOnce(Return(true));
+  // Verify the next packet is paced and delayed 2ms due to granularity.
+  EXPECT_EQ(
+      QuicTime::Delta::FromMilliseconds(2),
+      pacing_sender_->TimeUntilSend(clock_.Now(), kMaxOutgoingPacketSize));
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, NoBurstInRecovery) {
+  // Configure pacing rate of 1 packet per 1 ms with no burst tokens.
+  InitPacingRate(
+      0, QuicBandwidth::FromBytesAndTimeDelta(
+             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  UpdateRtt();
+
+  // Ensure only one packet is sent immediately and the rest are paced.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, true, 10);
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, CwndLimited) {
+  // Configure pacing rate of 1 packet per 1 ms, no initial burst.
+  InitPacingRate(
+      0, QuicBandwidth::FromBytesAndTimeDelta(
+             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  UpdateRtt();
+
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  // Packet 3 will be delayed 2ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up on time.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
+  // After sending packet 3, cwnd is limited.
+  // This test is slightly odd because bytes_in_flight is calculated using
+  // kMaxOutgoingPacketSize and CWND is calculated using kDefaultTCPMSS,
+  // which is 8 bytes larger, so 3 packets can be sent for a CWND of 2.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                               2 * kMaxOutgoingPacketSize, false, 2);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  // Verify pacing sender stops making up for lost time after sending packet 3.
+  // Packet 6 will be delayed 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, LumpyPacingWithInitialBurstToken) {
+  // Set lumpy size to be 3, and cwnd faction to 0.5
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
+  // Configure pacing rate of 1 packet per 1 ms.
+  InitPacingRate(
+      10, QuicBandwidth::FromBytesAndTimeDelta(
+              kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+  UpdateRtt();
+
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  // Packet 14 will be delayed 3ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
+
+  // Wake up on time.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  // Packet 17 will be delayed 3ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
+
+  // Application throttles sending.
+  OnApplicationLimited();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  // Packet 20 will be delayed 3ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
+
+  // Wake up on time.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3));
+  CheckPacketIsSentImmediately();
+  // After sending packet 21, cwnd is limited.
+  // This test is slightly odd because bytes_in_flight is calculated using
+  // kMaxOutgoingPacketSize and CWND is calculated using kDefaultTCPMSS,
+  // which is 8 bytes larger, so 21 packets can be sent for a CWND of 20.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                               20 * kMaxOutgoingPacketSize, false, 20);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  // Suppose cwnd size is 5, so that lumpy size becomes 2.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, kBytesInFlight, false,
+                               5);
+  CheckPacketIsSentImmediately();
+  // Packet 24 will be delayed 2ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, NoLumpyPacingForLowBandwidthFlows) {
+  // Set lumpy size to be 3, and cwnd fraction to 0.5
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
+
+  // Configure pacing rate of 1 packet per 100 ms.
+  QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(100);
+  InitPacingRate(kInitialBurstPackets,
+                 QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
+                                                      inter_packet_delay));
+  UpdateRtt();
+
+  // Send kInitialBurstPackets packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet after burst token exhausted is also sent immediately,
+  // because ideal_next_packet_send_time has not been set yet.
+  CheckPacketIsSentImmediately();
+
+  for (int i = 0; i < 200; ++i) {
+    CheckPacketIsDelayed(inter_packet_delay);
+  }
+}
+
+// Regression test for b/184471302 to ensure that ACKs received back-to-back
+// don't cause bursts in sending.
+TEST_F(PacingSenderTest, NoBurstsForLumpyPacingWithAckAggregation) {
+  // Configure pacing rate of 1 packet per millisecond.
+  QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(1);
+  InitPacingRate(kInitialBurstPackets,
+                 QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
+                                                      inter_packet_delay));
+  UpdateRtt();
+
+  // Send kInitialBurstPackets packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+  // The last packet of the burst causes the sender to be CWND limited.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                               10 * kMaxOutgoingPacketSize, false, 10);
+
+  if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
+    // The last sent packet made the connection CWND limited, so no lumpy tokens
+    // should be available.
+    EXPECT_EQ(0u, pacing_sender_->lumpy_tokens());
+    CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                                 10 * kMaxOutgoingPacketSize, false, 10);
+    EXPECT_EQ(0u, pacing_sender_->lumpy_tokens());
+    CheckPacketIsDelayed(2 * inter_packet_delay);
+  } else {
+    EXPECT_EQ(1u, pacing_sender_->lumpy_tokens());
+    // Repeatedly send single packets to make the sender CWND limited and
+    // observe that there's no pacing without the fix.
+    for (int i = 0; i < 10; ++i) {
+      CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                                   10 * kMaxOutgoingPacketSize, false, 10);
+    }
+  }
+}
+
+TEST_F(PacingSenderTest, IdealNextPacketSendTimeWithLumpyPacing) {
+  // Set lumpy size to be 3, and cwnd faction to 0.5
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
+
+  // Configure pacing rate of 1 packet per millisecond.
+  QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(1);
+  InitPacingRate(kInitialBurstPackets,
+                 QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
+                                                      inter_packet_delay));
+
+  // Send kInitialBurstPackets packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 2 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 3 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
+
+  CheckPacketIsDelayed(3 * inter_packet_delay);
+
+  // Wake up on time.
+  clock_.AdvanceTime(3 * inter_packet_delay);
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 2 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 3 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
+
+  CheckPacketIsDelayed(3 * inter_packet_delay);
+
+  // Wake up late.
+  clock_.AdvanceTime(4.5 * inter_packet_delay);
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() - 0.5 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 0.5 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 1.5 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
+
+  CheckPacketIsDelayed(1.5 * inter_packet_delay);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/prr_sender.cc b/quiche/quic/core/congestion_control/prr_sender.cc
new file mode 100644
index 0000000..951f0ba
--- /dev/null
+++ b/quiche/quic/core/congestion_control/prr_sender.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 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 "quiche/quic/core/congestion_control/prr_sender.h"
+
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+PrrSender::PrrSender()
+    : bytes_sent_since_loss_(0),
+      bytes_delivered_since_loss_(0),
+      ack_count_since_loss_(0),
+      bytes_in_flight_before_loss_(0) {}
+
+void PrrSender::OnPacketSent(QuicByteCount sent_bytes) {
+  bytes_sent_since_loss_ += sent_bytes;
+}
+
+void PrrSender::OnPacketLost(QuicByteCount prior_in_flight) {
+  bytes_sent_since_loss_ = 0;
+  bytes_in_flight_before_loss_ = prior_in_flight;
+  bytes_delivered_since_loss_ = 0;
+  ack_count_since_loss_ = 0;
+}
+
+void PrrSender::OnPacketAcked(QuicByteCount acked_bytes) {
+  bytes_delivered_since_loss_ += acked_bytes;
+  ++ack_count_since_loss_;
+}
+
+bool PrrSender::CanSend(QuicByteCount congestion_window,
+                        QuicByteCount bytes_in_flight,
+                        QuicByteCount slowstart_threshold) const {
+  // Return QuicTime::Zero in order to ensure limited transmit always works.
+  if (bytes_sent_since_loss_ == 0 || bytes_in_flight < kMaxSegmentSize) {
+    return true;
+  }
+  if (congestion_window > bytes_in_flight) {
+    // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead
+    // of sending the entire available window. This prevents burst retransmits
+    // when more packets are lost than the CWND reduction.
+    //   limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS
+    if (bytes_delivered_since_loss_ + ack_count_since_loss_ * kMaxSegmentSize <=
+        bytes_sent_since_loss_) {
+      return false;
+    }
+    return true;
+  }
+  // Implement Proportional Rate Reduction (RFC6937).
+  // Checks a simplified version of the PRR formula that doesn't use division:
+  // AvailableSendWindow =
+  //   CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent
+  if (bytes_delivered_since_loss_ * slowstart_threshold >
+      bytes_sent_since_loss_ * bytes_in_flight_before_loss_) {
+    return true;
+  }
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/prr_sender.h b/quiche/quic/core/congestion_control/prr_sender.h
new file mode 100644
index 0000000..f55069b
--- /dev/null
+++ b/quiche/quic/core/congestion_control/prr_sender.h
@@ -0,0 +1,43 @@
+// Copyright (c) 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.
+
+// Implements Proportional Rate Reduction (PRR) per RFC 6937.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE PrrSender {
+ public:
+  PrrSender();
+  // OnPacketLost should be called on the first loss that triggers a recovery
+  // period and all other methods in this class should only be called when in
+  // recovery.
+  void OnPacketLost(QuicByteCount prior_in_flight);
+  void OnPacketSent(QuicByteCount sent_bytes);
+  void OnPacketAcked(QuicByteCount acked_bytes);
+  bool CanSend(QuicByteCount congestion_window,
+               QuicByteCount bytes_in_flight,
+               QuicByteCount slowstart_threshold) const;
+
+ private:
+  // Bytes sent and acked since the last loss event.
+  // |bytes_sent_since_loss_| is the same as "prr_out_" in RFC 6937,
+  // and |bytes_delivered_since_loss_| is the same as "prr_delivered_".
+  QuicByteCount bytes_sent_since_loss_;
+  QuicByteCount bytes_delivered_since_loss_;
+  size_t ack_count_since_loss_;
+
+  // The congestion window before the last loss event.
+  QuicByteCount bytes_in_flight_before_loss_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
diff --git a/quiche/quic/core/congestion_control/prr_sender_test.cc b/quiche/quic/core/congestion_control/prr_sender_test.cc
new file mode 100644
index 0000000..60dd779
--- /dev/null
+++ b/quiche/quic/core/congestion_control/prr_sender_test.cc
@@ -0,0 +1,123 @@
+// Copyright (c) 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 "quiche/quic/core/congestion_control/prr_sender.h"
+
+#include <algorithm>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+// Constant based on TCP defaults.
+const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
+}  // namespace
+
+class PrrSenderTest : public QuicTest {};
+
+TEST_F(PrrSenderTest, SingleLossResultsInSendOnEveryOtherAck) {
+  PrrSender prr;
+  QuicPacketCount num_packets_in_flight = 50;
+  QuicByteCount bytes_in_flight = num_packets_in_flight * kMaxSegmentSize;
+  const QuicPacketCount ssthresh_after_loss = num_packets_in_flight / 2;
+  const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;
+
+  prr.OnPacketLost(bytes_in_flight);
+  // Ack a packet. PRR allows one packet to leave immediately.
+  prr.OnPacketAcked(kMaxSegmentSize);
+  bytes_in_flight -= kMaxSegmentSize;
+  EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                          ssthresh_after_loss * kMaxSegmentSize));
+  // Send retransmission.
+  prr.OnPacketSent(kMaxSegmentSize);
+  // PRR shouldn't allow sending any more packets.
+  EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
+                           ssthresh_after_loss * kMaxSegmentSize));
+
+  // One packet is lost, and one ack was consumed above. PRR now paces
+  // transmissions through the remaining 48 acks. PRR will alternatively
+  // disallow and allow a packet to be sent in response to an ack.
+  for (uint64_t i = 0; i < ssthresh_after_loss - 1; ++i) {
+    // Ack a packet. PRR shouldn't allow sending a packet in response.
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
+                             ssthresh_after_loss * kMaxSegmentSize));
+    // Ack another packet. PRR should now allow sending a packet in response.
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                            ssthresh_after_loss * kMaxSegmentSize));
+    // Send a packet in response.
+    prr.OnPacketSent(kMaxSegmentSize);
+    bytes_in_flight += kMaxSegmentSize;
+  }
+
+  // Since bytes_in_flight is now equal to congestion_window, PRR now maintains
+  // packet conservation, allowing one packet to be sent in response to an ack.
+  EXPECT_EQ(congestion_window, bytes_in_flight);
+  for (int i = 0; i < 10; ++i) {
+    // Ack a packet.
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                            ssthresh_after_loss * kMaxSegmentSize));
+    // Send a packet in response, since PRR allows it.
+    prr.OnPacketSent(kMaxSegmentSize);
+    bytes_in_flight += kMaxSegmentSize;
+
+    // Since bytes_in_flight is equal to the congestion_window,
+    // PRR disallows sending.
+    EXPECT_EQ(congestion_window, bytes_in_flight);
+    EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
+                             ssthresh_after_loss * kMaxSegmentSize));
+  }
+}
+
+TEST_F(PrrSenderTest, BurstLossResultsInSlowStart) {
+  PrrSender prr;
+  QuicByteCount bytes_in_flight = 20 * kMaxSegmentSize;
+  const QuicPacketCount num_packets_lost = 13;
+  const QuicPacketCount ssthresh_after_loss = 10;
+  const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;
+
+  // Lose 13 packets.
+  bytes_in_flight -= num_packets_lost * kMaxSegmentSize;
+  prr.OnPacketLost(bytes_in_flight);
+
+  // PRR-SSRB will allow the following 3 acks to send up to 2 packets.
+  for (int i = 0; i < 3; ++i) {
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    // PRR-SSRB should allow two packets to be sent.
+    for (int j = 0; j < 2; ++j) {
+      EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                              ssthresh_after_loss * kMaxSegmentSize));
+      // Send a packet in response.
+      prr.OnPacketSent(kMaxSegmentSize);
+      bytes_in_flight += kMaxSegmentSize;
+    }
+    // PRR should allow no more than 2 packets in response to an ack.
+    EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
+                             ssthresh_after_loss * kMaxSegmentSize));
+  }
+
+  // Out of SSRB mode, PRR allows one send in response to each ack.
+  for (int i = 0; i < 10; ++i) {
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                            ssthresh_after_loss * kMaxSegmentSize));
+    // Send a packet in response.
+    prr.OnPacketSent(kMaxSegmentSize);
+    bytes_in_flight += kMaxSegmentSize;
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/rtt_stats.cc b/quiche/quic/core/congestion_control/rtt_stats.cc
new file mode 100644
index 0000000..90a9efe
--- /dev/null
+++ b/quiche/quic/core/congestion_control/rtt_stats.cc
@@ -0,0 +1,144 @@
+// 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 "quiche/quic/core/congestion_control/rtt_stats.h"
+
+#include <cstdlib>  // std::abs
+
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+const float kAlpha = 0.125f;
+const float kOneMinusAlpha = (1 - kAlpha);
+const float kBeta = 0.25f;
+const float kOneMinusBeta = (1 - kBeta);
+
+}  // namespace
+
+RttStats::RttStats()
+    : latest_rtt_(QuicTime::Delta::Zero()),
+      min_rtt_(QuicTime::Delta::Zero()),
+      smoothed_rtt_(QuicTime::Delta::Zero()),
+      previous_srtt_(QuicTime::Delta::Zero()),
+      mean_deviation_(QuicTime::Delta::Zero()),
+      calculate_standard_deviation_(false),
+      initial_rtt_(QuicTime::Delta::FromMilliseconds(kInitialRttMs)),
+      last_update_time_(QuicTime::Zero()) {}
+
+void RttStats::ExpireSmoothedMetrics() {
+  mean_deviation_ = std::max(
+      mean_deviation_, QuicTime::Delta::FromMicroseconds(std::abs(
+                           (smoothed_rtt_ - latest_rtt_).ToMicroseconds())));
+  smoothed_rtt_ = std::max(smoothed_rtt_, latest_rtt_);
+}
+
+// Updates the RTT based on a new sample.
+void RttStats::UpdateRtt(QuicTime::Delta send_delta,
+                         QuicTime::Delta ack_delay,
+                         QuicTime now) {
+  if (send_delta.IsInfinite() || send_delta <= QuicTime::Delta::Zero()) {
+    QUIC_LOG_FIRST_N(WARNING, 3)
+        << "Ignoring measured send_delta, because it's is "
+        << "either infinite, zero, or negative.  send_delta = "
+        << send_delta.ToMicroseconds();
+    return;
+  }
+
+  last_update_time_ = now;
+
+  // Update min_rtt_ first. min_rtt_ does not use an rtt_sample corrected for
+  // ack_delay but the raw observed send_delta, since poor clock granularity at
+  // the client may cause a high ack_delay to result in underestimation of the
+  // min_rtt_.
+  if (min_rtt_.IsZero() || min_rtt_ > send_delta) {
+    min_rtt_ = send_delta;
+  }
+
+  QuicTime::Delta rtt_sample(send_delta);
+  previous_srtt_ = smoothed_rtt_;
+  // Correct for ack_delay if information received from the peer results in a
+  // an RTT sample at least as large as min_rtt. Otherwise, only use the
+  // send_delta.
+  // TODO(fayang): consider to ignore rtt_sample if rtt_sample < ack_delay and
+  // ack_delay is relatively large.
+  if (rtt_sample > ack_delay) {
+    if (rtt_sample - min_rtt_ >= ack_delay) {
+      rtt_sample = rtt_sample - ack_delay;
+    } else {
+      QUIC_CODE_COUNT(quic_ack_delay_makes_rtt_sample_smaller_than_min_rtt);
+    }
+  } else {
+    QUIC_CODE_COUNT(quic_ack_delay_greater_than_rtt_sample);
+  }
+  latest_rtt_ = rtt_sample;
+  if (calculate_standard_deviation_) {
+    standard_deviation_calculator_.OnNewRttSample(rtt_sample, smoothed_rtt_);
+  }
+  // First time call.
+  if (smoothed_rtt_.IsZero()) {
+    smoothed_rtt_ = rtt_sample;
+    mean_deviation_ =
+        QuicTime::Delta::FromMicroseconds(rtt_sample.ToMicroseconds() / 2);
+  } else {
+    mean_deviation_ = QuicTime::Delta::FromMicroseconds(static_cast<int64_t>(
+        kOneMinusBeta * mean_deviation_.ToMicroseconds() +
+        kBeta * std::abs((smoothed_rtt_ - rtt_sample).ToMicroseconds())));
+    smoothed_rtt_ = kOneMinusAlpha * smoothed_rtt_ + kAlpha * rtt_sample;
+    QUIC_DVLOG(1) << " smoothed_rtt(us):" << smoothed_rtt_.ToMicroseconds()
+                  << " mean_deviation(us):" << mean_deviation_.ToMicroseconds();
+  }
+}
+
+void RttStats::OnConnectionMigration() {
+  latest_rtt_ = QuicTime::Delta::Zero();
+  min_rtt_ = QuicTime::Delta::Zero();
+  smoothed_rtt_ = QuicTime::Delta::Zero();
+  mean_deviation_ = QuicTime::Delta::Zero();
+  initial_rtt_ = QuicTime::Delta::FromMilliseconds(kInitialRttMs);
+}
+
+QuicTime::Delta RttStats::GetStandardOrMeanDeviation() const {
+  QUICHE_DCHECK(calculate_standard_deviation_);
+  if (!standard_deviation_calculator_.has_valid_standard_deviation) {
+    return mean_deviation_;
+  }
+  return standard_deviation_calculator_.CalculateStandardDeviation();
+}
+
+void RttStats::StandardDeviationCaculator::OnNewRttSample(
+    QuicTime::Delta rtt_sample,
+    QuicTime::Delta smoothed_rtt) {
+  double new_value = rtt_sample.ToMicroseconds();
+  if (smoothed_rtt.IsZero()) {
+    return;
+  }
+  has_valid_standard_deviation = true;
+  const double delta = new_value - smoothed_rtt.ToMicroseconds();
+  m2 = kOneMinusBeta * m2 + kBeta * pow(delta, 2);
+}
+
+QuicTime::Delta
+RttStats::StandardDeviationCaculator::CalculateStandardDeviation() const {
+  QUICHE_DCHECK(has_valid_standard_deviation);
+  return QuicTime::Delta::FromMicroseconds(sqrt(m2));
+}
+
+void RttStats::CloneFrom(const RttStats& stats) {
+  latest_rtt_ = stats.latest_rtt_;
+  min_rtt_ = stats.min_rtt_;
+  smoothed_rtt_ = stats.smoothed_rtt_;
+  previous_srtt_ = stats.previous_srtt_;
+  mean_deviation_ = stats.mean_deviation_;
+  standard_deviation_calculator_ = stats.standard_deviation_calculator_;
+  calculate_standard_deviation_ = stats.calculate_standard_deviation_;
+  initial_rtt_ = stats.initial_rtt_;
+  last_update_time_ = stats.last_update_time_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/rtt_stats.h b/quiche/quic/core/congestion_control/rtt_stats.h
new file mode 100644
index 0000000..6b6569a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/rtt_stats.h
@@ -0,0 +1,131 @@
+// 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.
+
+// A convenience class to store rtt samples and calculate smoothed rtt.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
+
+#include <algorithm>
+#include <cstdint>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class RttStatsPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE RttStats {
+ public:
+  // Calculates running standard-deviation using Welford's algorithm:
+  // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#
+  // Welford's_Online_algorithm.
+  struct QUIC_EXPORT_PRIVATE StandardDeviationCaculator {
+    StandardDeviationCaculator() {}
+
+    // Called when a new RTT sample is available.
+    void OnNewRttSample(QuicTime::Delta rtt_sample,
+                        QuicTime::Delta smoothed_rtt);
+    // Calculates the standard deviation.
+    QuicTime::Delta CalculateStandardDeviation() const;
+
+    bool has_valid_standard_deviation = false;
+
+   private:
+    double m2 = 0;
+  };
+
+  RttStats();
+  RttStats(const RttStats&) = delete;
+  RttStats& operator=(const RttStats&) = delete;
+
+  // Updates the RTT from an incoming ack which is received |send_delta| after
+  // the packet is sent and the peer reports the ack being delayed |ack_delay|.
+  void UpdateRtt(QuicTime::Delta send_delta,
+                 QuicTime::Delta ack_delay,
+                 QuicTime now);
+
+  // Causes the smoothed_rtt to be increased to the latest_rtt if the latest_rtt
+  // is larger. The mean deviation is increased to the most recent deviation if
+  // it's larger.
+  void ExpireSmoothedMetrics();
+
+  // Called when connection migrates and rtt measurement needs to be reset.
+  void OnConnectionMigration();
+
+  // Returns the EWMA smoothed RTT for the connection.
+  // May return Zero if no valid updates have occurred.
+  QuicTime::Delta smoothed_rtt() const { return smoothed_rtt_; }
+
+  // Returns the EWMA smoothed RTT prior to the most recent RTT sample.
+  QuicTime::Delta previous_srtt() const { return previous_srtt_; }
+
+  QuicTime::Delta initial_rtt() const { return initial_rtt_; }
+
+  QuicTime::Delta SmoothedOrInitialRtt() const {
+    return smoothed_rtt_.IsZero() ? initial_rtt_ : smoothed_rtt_;
+  }
+
+  QuicTime::Delta MinOrInitialRtt() const {
+    return min_rtt_.IsZero() ? initial_rtt_ : min_rtt_;
+  }
+
+  // Sets an initial RTT to be used for SmoothedRtt before any RTT updates.
+  void set_initial_rtt(QuicTime::Delta initial_rtt) {
+    if (initial_rtt.ToMicroseconds() <= 0) {
+      QUIC_BUG(quic_bug_10453_1) << "Attempt to set initial rtt to <= 0.";
+      return;
+    }
+    initial_rtt_ = initial_rtt;
+  }
+
+  // The most recent rtt measurement.
+  // May return Zero if no valid updates have occurred.
+  QuicTime::Delta latest_rtt() const { return latest_rtt_; }
+
+  // Returns the min_rtt for the entire connection.
+  // May return Zero if no valid updates have occurred.
+  QuicTime::Delta min_rtt() const { return min_rtt_; }
+
+  QuicTime::Delta mean_deviation() const { return mean_deviation_; }
+
+  // Returns standard deviation if there is a valid one. Otherwise, returns
+  // mean_deviation_.
+  QuicTime::Delta GetStandardOrMeanDeviation() const;
+
+  QuicTime last_update_time() const { return last_update_time_; }
+
+  void EnableStandardDeviationCalculation() {
+    calculate_standard_deviation_ = true;
+  }
+
+  void CloneFrom(const RttStats& stats);
+
+ private:
+  friend class test::RttStatsPeer;
+
+  QuicTime::Delta latest_rtt_;
+  QuicTime::Delta min_rtt_;
+  QuicTime::Delta smoothed_rtt_;
+  QuicTime::Delta previous_srtt_;
+  // Mean RTT deviation during this session.
+  // Approximation of standard deviation, the error is roughly 1.25 times
+  // larger than the standard deviation, for a normally distributed signal.
+  QuicTime::Delta mean_deviation_;
+  // Standard deviation calculator. Only used calculate_standard_deviation_ is
+  // true.
+  StandardDeviationCaculator standard_deviation_calculator_;
+  bool calculate_standard_deviation_;
+  QuicTime::Delta initial_rtt_;
+  QuicTime last_update_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
diff --git a/quiche/quic/core/congestion_control/rtt_stats_test.cc b/quiche/quic/core/congestion_control/rtt_stats_test.cc
new file mode 100644
index 0000000..d1a7080
--- /dev/null
+++ b/quiche/quic/core/congestion_control/rtt_stats_test.cc
@@ -0,0 +1,242 @@
+// 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 "quiche/quic/core/congestion_control/rtt_stats.h"
+
+#include <cmath>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_mock_log.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/rtt_stats_peer.h"
+
+using testing::_;
+using testing::Message;
+
+namespace quic {
+namespace test {
+
+class RttStatsTest : public QuicTest {
+ protected:
+  RttStats rtt_stats_;
+};
+
+TEST_F(RttStatsTest, DefaultsBeforeUpdate) {
+  EXPECT_LT(QuicTime::Delta::Zero(), rtt_stats_.initial_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
+}
+
+TEST_F(RttStatsTest, SmoothedRtt) {
+  // Verify that ack_delay is ignored in the first measurement.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
+                       QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
+  // Verify that a plausible ack delay increases the max ack delay.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(400),
+                       QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
+  // Verify that Smoothed RTT includes max ack delay if it's reasonable.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(350),
+                       QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
+  // Verify that large erroneous ack_delay does not change Smoothed RTT.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
+                       QuicTime::Delta::FromMilliseconds(300),
+                       QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
+            rtt_stats_.smoothed_rtt());
+}
+
+// Ensure that the potential rounding artifacts in EWMA calculation do not cause
+// the SRTT to drift too far from the exact value.
+TEST_F(RttStatsTest, SmoothedRttStability) {
+  for (size_t time = 3; time < 20000; time++) {
+    RttStats stats;
+    for (size_t i = 0; i < 100; i++) {
+      stats.UpdateRtt(QuicTime::Delta::FromMicroseconds(time),
+                      QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
+      int64_t time_delta_us = stats.smoothed_rtt().ToMicroseconds() - time;
+      ASSERT_LE(std::abs(time_delta_us), 1);
+    }
+  }
+}
+
+TEST_F(RttStatsTest, PreviousSmoothedRtt) {
+  // Verify that ack_delay is corrected for in Smoothed RTT.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
+                       QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.previous_srtt());
+  // Ensure the previous SRTT is 200ms after a 100ms sample.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(187500).ToMicroseconds(),
+            rtt_stats_.smoothed_rtt().ToMicroseconds());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.previous_srtt());
+}
+
+TEST_F(RttStatsTest, MinRtt) {
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(10), QuicTime::Delta::Zero(),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(20));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(30));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(40));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
+  // Verify that ack_delay does not go into recording of min_rtt_.
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(7),
+      QuicTime::Delta::FromMilliseconds(2),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(50));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_.min_rtt());
+}
+
+TEST_F(RttStatsTest, ExpireSmoothedMetrics) {
+  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10);
+  rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
+  EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
+
+  EXPECT_EQ(0.5 * initial_rtt, rtt_stats_.mean_deviation());
+
+  // Update once with a 20ms RTT.
+  QuicTime::Delta doubled_rtt = 2 * initial_rtt;
+  rtt_stats_.UpdateRtt(doubled_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(1.125 * initial_rtt, rtt_stats_.smoothed_rtt());
+
+  // Expire the smoothed metrics, increasing smoothed rtt and mean deviation.
+  rtt_stats_.ExpireSmoothedMetrics();
+  EXPECT_EQ(doubled_rtt, rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(0.875 * initial_rtt, rtt_stats_.mean_deviation());
+
+  // Now go back down to 5ms and expire the smoothed metrics, and ensure the
+  // mean deviation increases to 15ms.
+  QuicTime::Delta half_rtt = 0.5 * initial_rtt;
+  rtt_stats_.UpdateRtt(half_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_GT(doubled_rtt, rtt_stats_.smoothed_rtt());
+  EXPECT_LT(initial_rtt, rtt_stats_.mean_deviation());
+}
+
+TEST_F(RttStatsTest, UpdateRttWithBadSendDeltas) {
+  // Make sure we ignore bad RTTs.
+  CREATE_QUIC_MOCK_LOG(log);
+
+  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10);
+  rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
+  EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
+
+  std::vector<QuicTime::Delta> bad_send_deltas;
+  bad_send_deltas.push_back(QuicTime::Delta::Zero());
+  bad_send_deltas.push_back(QuicTime::Delta::Infinite());
+  bad_send_deltas.push_back(QuicTime::Delta::FromMicroseconds(-1000));
+  log.StartCapturingLogs();
+
+  for (QuicTime::Delta bad_send_delta : bad_send_deltas) {
+    SCOPED_TRACE(Message() << "bad_send_delta = "
+                           << bad_send_delta.ToMicroseconds());
+    if (QUIC_LOG_WARNING_IS_ON()) {
+      EXPECT_QUIC_LOG_CALL_CONTAINS(log, WARNING, "Ignoring");
+    }
+    rtt_stats_.UpdateRtt(bad_send_delta, QuicTime::Delta::Zero(),
+                         QuicTime::Zero());
+    EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
+    EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
+  }
+}
+
+TEST_F(RttStatsTest, ResetAfterConnectionMigrations) {
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
+                       QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
+
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
+                       QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
+
+  // Reset rtt stats on connection migrations.
+  rtt_stats_.OnConnectionMigration();
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
+}
+
+TEST_F(RttStatsTest, StandardDeviationCaculatorTest1) {
+  // All samples are the same.
+  rtt_stats_.EnableStandardDeviationCalculation();
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(rtt_stats_.mean_deviation(),
+            rtt_stats_.GetStandardOrMeanDeviation());
+
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.GetStandardOrMeanDeviation());
+}
+
+TEST_F(RttStatsTest, StandardDeviationCaculatorTest2) {
+  // Small variance.
+  rtt_stats_.EnableStandardDeviationCalculation();
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(9),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(11),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_LT(QuicTime::Delta::FromMicroseconds(500),
+            rtt_stats_.GetStandardOrMeanDeviation());
+  EXPECT_GT(QuicTime::Delta::FromMilliseconds(1),
+            rtt_stats_.GetStandardOrMeanDeviation());
+}
+
+TEST_F(RttStatsTest, StandardDeviationCaculatorTest3) {
+  // Some variance.
+  rtt_stats_.EnableStandardDeviationCalculation();
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_APPROX_EQ(rtt_stats_.mean_deviation(),
+                   rtt_stats_.GetStandardOrMeanDeviation(), 0.25f);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/send_algorithm_interface.cc b/quiche/quic/core/congestion_control/send_algorithm_interface.cc
new file mode 100644
index 0000000..f8be8d9
--- /dev/null
+++ b/quiche/quic/core/congestion_control/send_algorithm_interface.cc
@@ -0,0 +1,61 @@
+// 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 "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+
+#include "absl/base/attributes.h"
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/congestion_control/bbr_sender.h"
+#include "quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class RttStats;
+
+// Factory for send side congestion control algorithm.
+SendAlgorithmInterface* SendAlgorithmInterface::Create(
+    const QuicClock* clock,
+    const RttStats* rtt_stats,
+    const QuicUnackedPacketMap* unacked_packets,
+    CongestionControlType congestion_control_type,
+    QuicRandom* random,
+    QuicConnectionStats* stats,
+    QuicPacketCount initial_congestion_window,
+    SendAlgorithmInterface* old_send_algorithm) {
+  QuicPacketCount max_congestion_window =
+      GetQuicFlag(FLAGS_quic_max_congestion_window);
+  switch (congestion_control_type) {
+    case kGoogCC:  // GoogCC is not supported by quic/core, fall back to BBR.
+    case kBBR:
+      return new BbrSender(clock->ApproximateNow(), rtt_stats, unacked_packets,
+                           initial_congestion_window, max_congestion_window,
+                           random, stats);
+    case kBBRv2:
+      return new Bbr2Sender(
+          clock->ApproximateNow(), rtt_stats, unacked_packets,
+          initial_congestion_window, max_congestion_window, random, stats,
+          old_send_algorithm &&
+                  old_send_algorithm->GetCongestionControlType() == kBBR
+              ? static_cast<BbrSender*>(old_send_algorithm)
+              : nullptr);
+    case kPCC:
+      // PCC is currently not supported, fall back to CUBIC instead.
+      ABSL_FALLTHROUGH_INTENDED;
+    case kCubicBytes:
+      return new TcpCubicSenderBytes(
+          clock, rtt_stats, false /* don't use Reno */,
+          initial_congestion_window, max_congestion_window, stats);
+    case kRenoBytes:
+      return new TcpCubicSenderBytes(clock, rtt_stats, true /* use Reno */,
+                                     initial_congestion_window,
+                                     max_congestion_window, stats);
+  }
+  return nullptr;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/send_algorithm_interface.h b/quiche/quic/core/congestion_control/send_algorithm_interface.h
new file mode 100644
index 0000000..ed85d2f
--- /dev/null
+++ b/quiche/quic/core/congestion_control/send_algorithm_interface.h
@@ -0,0 +1,181 @@
+// 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 pure virtual class for send side congestion control algorithm.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
+
+#include <algorithm>
+#include <map>
+#include <string>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+using QuicRoundTripCount = uint64_t;
+
+class CachedNetworkParameters;
+class RttStats;
+
+class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
+ public:
+  // Network Params for AdjustNetworkParameters.
+  struct QUIC_NO_EXPORT NetworkParams {
+    NetworkParams() = default;
+    NetworkParams(const QuicBandwidth& bandwidth, const QuicTime::Delta& rtt,
+                  bool allow_cwnd_to_decrease)
+        : bandwidth(bandwidth),
+          rtt(rtt),
+          allow_cwnd_to_decrease(allow_cwnd_to_decrease) {}
+    explicit NetworkParams(int burst_token) : burst_token(burst_token) {}
+
+    bool operator==(const NetworkParams& other) const {
+      return bandwidth == other.bandwidth && rtt == other.rtt &&
+             max_initial_congestion_window ==
+                 other.max_initial_congestion_window &&
+             burst_token == other.burst_token &&
+             allow_cwnd_to_decrease == other.allow_cwnd_to_decrease &&
+             is_rtt_trusted == other.is_rtt_trusted;
+    }
+
+    QuicBandwidth bandwidth = QuicBandwidth::Zero();
+    QuicTime::Delta rtt = QuicTime::Delta::Zero();
+    int max_initial_congestion_window = 0;
+    int burst_token = 0;
+    bool allow_cwnd_to_decrease = false;
+    bool is_rtt_trusted = false;
+  };
+
+  static SendAlgorithmInterface* Create(
+      const QuicClock* clock,
+      const RttStats* rtt_stats,
+      const QuicUnackedPacketMap* unacked_packets,
+      CongestionControlType type,
+      QuicRandom* random,
+      QuicConnectionStats* stats,
+      QuicPacketCount initial_congestion_window,
+      SendAlgorithmInterface* old_send_algorithm);
+
+  virtual ~SendAlgorithmInterface() {}
+
+  virtual void SetFromConfig(const QuicConfig& config,
+                             Perspective perspective) = 0;
+
+  virtual void ApplyConnectionOptions(
+      const QuicTagVector& connection_options) = 0;
+
+  // Sets the initial congestion window in number of packets.  May be ignored
+  // if called after the initial congestion window is no longer relevant.
+  virtual void SetInitialCongestionWindowInPackets(QuicPacketCount packets) = 0;
+
+  // Indicates an update to the congestion state, caused either by an incoming
+  // ack or loss event timeout.  |rtt_updated| indicates whether a new
+  // latest_rtt sample has been taken, |prior_in_flight| the bytes in flight
+  // prior to the congestion event.  |acked_packets| and |lost_packets| are any
+  // packets considered acked or lost as a result of the congestion event.
+  virtual void OnCongestionEvent(bool rtt_updated,
+                                 QuicByteCount prior_in_flight,
+                                 QuicTime event_time,
+                                 const AckedPacketVector& acked_packets,
+                                 const LostPacketVector& lost_packets) = 0;
+
+  // Inform that we sent |bytes| to the wire, and if the packet is
+  // retransmittable.  |bytes_in_flight| is the number of bytes in flight before
+  // the packet was sent.
+  // Note: this function must be called for every packet sent to the wire.
+  virtual void OnPacketSent(QuicTime sent_time,
+                            QuicByteCount bytes_in_flight,
+                            QuicPacketNumber packet_number,
+                            QuicByteCount bytes,
+                            HasRetransmittableData is_retransmittable) = 0;
+
+  // Inform that |packet_number| has been neutered.
+  virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
+
+  // Called when the retransmission timeout fires.  Neither OnPacketAbandoned
+  // nor OnPacketLost will be called for these packets.
+  virtual void OnRetransmissionTimeout(bool packets_retransmitted) = 0;
+
+  // Called when connection migrates and cwnd needs to be reset.
+  virtual void OnConnectionMigration() = 0;
+
+  // Make decision on whether the sender can send right now.  Note that even
+  // when this method returns true, the sending can be delayed due to pacing.
+  virtual bool CanSend(QuicByteCount bytes_in_flight) = 0;
+
+  // The pacing rate of the send algorithm.  May be zero if the rate is unknown.
+  virtual QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const = 0;
+
+  // What's the current estimated bandwidth in bytes per second.
+  // Returns 0 when it does not have an estimate.
+  virtual QuicBandwidth BandwidthEstimate() const = 0;
+
+  // Whether BandwidthEstimate returns a good measurement for resumption.
+  virtual bool HasGoodBandwidthEstimateForResumption() const = 0;
+
+  // Returns the size of the current congestion window in bytes.  Note, this is
+  // not the *available* window.  Some send algorithms may not use a congestion
+  // window and will return 0.
+  virtual QuicByteCount GetCongestionWindow() const = 0;
+
+  // Whether the send algorithm is currently in slow start.  When true, the
+  // BandwidthEstimate is expected to be too low.
+  virtual bool InSlowStart() const = 0;
+
+  // Whether the send algorithm is currently in recovery.
+  virtual bool InRecovery() const = 0;
+
+  // True when the congestion control is probing for more bandwidth and needs
+  // enough data to not be app-limited to do so.
+  // TODO(ianswett): In the future, this API may want to indicate the size of
+  // the probing packet.
+  virtual bool ShouldSendProbingPacket() const = 0;
+
+  // Returns the size of the slow start congestion window in bytes,
+  // aka ssthresh.  Only defined for Cubic and Reno, other algorithms return 0.
+  virtual QuicByteCount GetSlowStartThreshold() const = 0;
+
+  virtual CongestionControlType GetCongestionControlType() const = 0;
+
+  // Notifies the congestion control algorithm of an external network
+  // measurement or prediction.  Either |bandwidth| or |rtt| may be zero if no
+  // sample is available.
+  virtual void AdjustNetworkParameters(const NetworkParams& params) = 0;
+
+  // Retrieves debugging information about the current state of the
+  // send algorithm.
+  virtual std::string GetDebugState() const = 0;
+
+  // Called when the connection has no outstanding data to send. Specifically,
+  // this means that none of the data streams are write-blocked, there are no
+  // packets in the connection queue, and there are no pending retransmissins,
+  // i.e. the sender cannot send anything for reasons other than being blocked
+  // by congestion controller. This includes cases when the connection is
+  // blocked by the flow controller.
+  //
+  // The fact that this method is called does not necessarily imply that the
+  // connection would not be blocked by the congestion control if it actually
+  // tried to send data. If the congestion control algorithm needs to exclude
+  // such cases, it should use the internal state it uses for congestion control
+  // for that.
+  virtual void OnApplicationLimited(QuicByteCount bytes_in_flight) = 0;
+
+  // Called before connection close to collect stats.
+  virtual void PopulateConnectionStats(QuicConnectionStats* stats) const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
diff --git a/quiche/quic/core/congestion_control/send_algorithm_test.cc b/quiche/quic/core/congestion_control/send_algorithm_test.cc
new file mode 100644
index 0000000..f55d363
--- /dev/null
+++ b/quiche/quic/core/congestion_control/send_algorithm_test.cc
@@ -0,0 +1,373 @@
+// Copyright 2013 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 <algorithm>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Use the initial CWND of 10, as 32 is too much for the test network.
+const uint32_t kInitialCongestionWindowPackets = 10;
+
+// Test network parameters.  Here, the topology of the network is:
+//
+//           QUIC Sender
+//               |
+//               |  <-- local link
+//               |
+//        Network switch
+//               *  <-- the bottleneck queue in the direction
+//               |          of the receiver
+//               |
+//               |  <-- test link
+//               |
+//               |
+//           Receiver
+//
+// When setting the bandwidth of the local link and test link, choose
+// a bandwidth lower than 20Mbps, as the clock-granularity of the
+// simulator can only handle a granularity of 1us.
+
+// Default settings between the switch and the sender.
+const QuicBandwidth kLocalLinkBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(10000);
+const QuicTime::Delta kLocalPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(2);
+
+// Wired network settings.  A typical desktop network setup, a
+// high-bandwidth, 30ms test link to the receiver.
+const QuicBandwidth kTestLinkWiredBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(4000);
+const QuicTime::Delta kTestLinkWiredPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(50);
+const QuicTime::Delta kTestWiredTransferTime =
+    kTestLinkWiredBandwidth.TransferTime(kMaxOutgoingPacketSize) +
+    kLocalLinkBandwidth.TransferTime(kMaxOutgoingPacketSize);
+const QuicTime::Delta kTestWiredRtt =
+    (kTestLinkWiredPropagationDelay + kLocalPropagationDelay +
+     kTestWiredTransferTime) *
+    2;
+const QuicByteCount kTestWiredBdp = kTestWiredRtt * kTestLinkWiredBandwidth;
+
+// Small BDP, Bandwidth-policed network settings.  In this scenario,
+// the receiver has a low-bandwidth, short propagation-delay link,
+// resulting in a small BDP.  We model the policer by setting the
+// queue size to only one packet.
+const QuicBandwidth kTestLinkLowBdpBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(200);
+const QuicTime::Delta kTestLinkLowBdpPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(50);
+const QuicByteCount kTestPolicerQueue = kMaxOutgoingPacketSize;
+
+// Satellite network settings.  In a satellite network, the bottleneck
+// buffer is typically sized for non-satellite links , but the
+// propagation delay of the test link to the receiver is as much as a
+// quarter second.
+const QuicTime::Delta kTestSatellitePropagationDelay =
+    QuicTime::Delta::FromMilliseconds(250);
+
+// Cellular scenarios.  In a cellular network, the bottleneck queue at
+// the edge of the network can be as great as 3MB.
+const QuicBandwidth kTestLink2GBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(100);
+const QuicBandwidth kTestLink3GBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(1500);
+const QuicByteCount kCellularQueue = 3 * 1024 * 1024;
+const QuicTime::Delta kTestCellularPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(40);
+
+// Small RTT scenario, below the per-ack-update threshold of 30ms.
+const QuicTime::Delta kTestLinkSmallRTTDelay =
+    QuicTime::Delta::FromMilliseconds(10);
+
+const char* CongestionControlTypeToString(CongestionControlType cc_type) {
+  switch (cc_type) {
+    case kCubicBytes:
+      return "CUBIC_BYTES";
+    case kRenoBytes:
+      return "RENO_BYTES";
+    case kBBR:
+      return "BBR";
+    case kPCC:
+      return "PCC";
+    default:
+      QUIC_DLOG(FATAL) << "Unexpected CongestionControlType";
+      return nullptr;
+  }
+}
+
+struct TestParams {
+  explicit TestParams(CongestionControlType congestion_control_type)
+      : congestion_control_type(congestion_control_type) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
+    os << "{ congestion_control_type: "
+       << CongestionControlTypeToString(p.congestion_control_type);
+    os << " }";
+    return os;
+  }
+
+  const CongestionControlType congestion_control_type;
+};
+
+std::string TestParamToString(
+    const testing::TestParamInfo<TestParams>& params) {
+  return absl::StrCat(
+      CongestionControlTypeToString(params.param.congestion_control_type), "_");
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const CongestionControlType congestion_control_type :
+       {kBBR, kCubicBytes, kRenoBytes, kPCC}) {
+    params.push_back(TestParams(congestion_control_type));
+  }
+  return params;
+}
+
+}  // namespace
+
+class SendAlgorithmTest : public QuicTestWithParam<TestParams> {
+ protected:
+  SendAlgorithmTest()
+      : simulator_(),
+        quic_sender_(&simulator_,
+                     "QUIC sender",
+                     "Receiver",
+                     Perspective::IS_CLIENT,
+                     TestConnectionId()),
+        receiver_(&simulator_,
+                  "Receiver",
+                  "QUIC sender",
+                  Perspective::IS_SERVER,
+                  TestConnectionId()) {
+    rtt_stats_ = quic_sender_.connection()->sent_packet_manager().GetRttStats();
+    sender_ = SendAlgorithmInterface::Create(
+        simulator_.GetClock(), rtt_stats_,
+        QuicSentPacketManagerPeer::GetUnackedPacketMap(
+            QuicConnectionPeer::GetSentPacketManager(
+                quic_sender_.connection())),
+        GetParam().congestion_control_type, &random_, &stats_,
+        kInitialCongestionWindowPackets, nullptr);
+    quic_sender_.RecordTrace();
+
+    QuicConnectionPeer::SetSendAlgorithm(quic_sender_.connection(), sender_);
+    const int kTestMaxPacketSize = 1350;
+    quic_sender_.connection()->SetMaxPacketLength(kTestMaxPacketSize);
+    clock_ = simulator_.GetClock();
+    simulator_.set_random_generator(&random_);
+
+    uint64_t seed = QuicRandom::GetInstance()->RandUint64();
+    random_.set_seed(seed);
+    QUIC_LOG(INFO) << "SendAlgorithmTest simulator set up.  Seed: " << seed;
+  }
+
+  // Creates a simulated network, with default settings between the
+  // sender and the switch and the given settings from the switch to
+  // the receiver.
+  void CreateSetup(const QuicBandwidth& test_bandwidth,
+                   const QuicTime::Delta& test_link_delay,
+                   QuicByteCount bottleneck_queue_length) {
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
+                                                  bottleneck_queue_length);
+    quic_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &quic_sender_, switch_->port(1), kLocalLinkBandwidth,
+        kLocalPropagationDelay);
+    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
+        &receiver_, switch_->port(2), test_bandwidth, test_link_delay);
+  }
+
+  void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta deadline) {
+    quic_sender_.AddBytesToTransfer(transfer_size);
+    bool simulator_result = simulator_.RunUntilOrTimeout(
+        [this]() { return quic_sender_.bytes_to_transfer() == 0; }, deadline);
+    EXPECT_TRUE(simulator_result)
+        << "Simple transfer failed.  Bytes remaining: "
+        << quic_sender_.bytes_to_transfer();
+  }
+
+  void SendBursts(size_t number_of_bursts,
+                  QuicByteCount bytes,
+                  QuicTime::Delta rtt,
+                  QuicTime::Delta wait_time) {
+    ASSERT_EQ(0u, quic_sender_.bytes_to_transfer());
+    for (size_t i = 0; i < number_of_bursts; i++) {
+      quic_sender_.AddBytesToTransfer(bytes);
+
+      // Transfer data and wait for three seconds between each transfer.
+      simulator_.RunFor(wait_time);
+
+      // Ensure the connection did not time out.
+      ASSERT_TRUE(quic_sender_.connection()->connected());
+      ASSERT_TRUE(receiver_.connection()->connected());
+    }
+
+    simulator_.RunFor(wait_time + rtt);
+    EXPECT_EQ(0u, quic_sender_.bytes_to_transfer());
+  }
+
+  // Estimates the elapsed time for a given transfer size, given the
+  // bottleneck bandwidth and link propagation delay.
+  QuicTime::Delta EstimatedElapsedTime(
+      QuicByteCount transfer_size_bytes,
+      QuicBandwidth test_link_bandwidth,
+      const QuicTime::Delta& test_link_delay) const {
+    return test_link_bandwidth.TransferTime(transfer_size_bytes) +
+           2 * test_link_delay;
+  }
+
+  QuicTime QuicSenderStartTime() {
+    return quic_sender_.connection()->GetStats().connection_creation_time;
+  }
+
+  void PrintTransferStats() {
+    const QuicConnectionStats& stats = quic_sender_.connection()->GetStats();
+    QUIC_LOG(INFO) << "Summary for scenario " << GetParam();
+    QUIC_LOG(INFO) << "Sender stats is " << stats;
+    const double rtx_rate =
+        static_cast<double>(stats.bytes_retransmitted) / stats.bytes_sent;
+    QUIC_LOG(INFO) << "Retransmit rate (num_rtx/num_total_sent): " << rtx_rate;
+    QUIC_LOG(INFO) << "Connection elapsed time: "
+                   << (clock_->Now() - QuicSenderStartTime()).ToMilliseconds()
+                   << " (ms)";
+  }
+
+  simulator::Simulator simulator_;
+  simulator::QuicEndpoint quic_sender_;
+  simulator::QuicEndpoint receiver_;
+  std::unique_ptr<simulator::Switch> switch_;
+  std::unique_ptr<simulator::SymmetricLink> quic_sender_link_;
+  std::unique_ptr<simulator::SymmetricLink> receiver_link_;
+  QuicConnectionStats stats_;
+
+  SimpleRandom random_;
+
+  // Owned by different components of the connection.
+  const QuicClock* clock_;
+  const RttStats* rtt_stats_;
+  SendAlgorithmInterface* sender_;
+};
+
+INSTANTIATE_TEST_SUITE_P(SendAlgorithmTests,
+                         SendAlgorithmTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         TestParamToString);
+
+// Test a simple long data transfer in the default setup.
+TEST_P(SendAlgorithmTest, SimpleWiredNetworkTransfer) {
+  CreateSetup(kTestLinkWiredBandwidth, kTestLinkWiredPropagationDelay,
+              kTestWiredBdp);
+  const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
+                           kTestLinkWiredPropagationDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, LowBdpPolicedNetworkTransfer) {
+  CreateSetup(kTestLinkLowBdpBandwidth, kTestLinkLowBdpPropagationDelay,
+              kTestPolicerQueue);
+  const QuicByteCount kTransferSizeBytes = 5 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkLowBdpBandwidth,
+                           kTestLinkLowBdpPropagationDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, AppLimitedBurstsOverWiredNetwork) {
+  CreateSetup(kTestLinkWiredBandwidth, kTestLinkWiredPropagationDelay,
+              kTestWiredBdp);
+  const QuicByteCount kBurstSizeBytes = 512;
+  const int kNumBursts = 20;
+  const QuicTime::Delta kWaitTime = QuicTime::Delta::FromSeconds(3);
+  SendBursts(kNumBursts, kBurstSizeBytes, kTestWiredRtt, kWaitTime);
+  PrintTransferStats();
+
+  const QuicTime::Delta estimated_burst_time =
+      EstimatedElapsedTime(kBurstSizeBytes, kTestLinkWiredBandwidth,
+                           kTestLinkWiredPropagationDelay) +
+      kWaitTime;
+  const QuicTime::Delta max_elapsed_time =
+      kNumBursts * estimated_burst_time + kWaitTime;
+  const QuicTime::Delta actual_elapsed_time =
+      clock_->Now() - QuicSenderStartTime();
+  EXPECT_GE(max_elapsed_time, actual_elapsed_time);
+}
+
+TEST_P(SendAlgorithmTest, SatelliteNetworkTransfer) {
+  CreateSetup(kTestLinkWiredBandwidth, kTestSatellitePropagationDelay,
+              kTestWiredBdp);
+  const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
+                           kTestSatellitePropagationDelay) *
+      1.25;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, 2GNetworkTransfer) {
+  CreateSetup(kTestLink2GBandwidth, kTestCellularPropagationDelay,
+              kCellularQueue);
+  const QuicByteCount kTransferSizeBytes = 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLink2GBandwidth,
+                           kTestCellularPropagationDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, 3GNetworkTransfer) {
+  CreateSetup(kTestLink3GBandwidth, kTestCellularPropagationDelay,
+              kCellularQueue);
+  const QuicByteCount kTransferSizeBytes = 5 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLink3GBandwidth,
+                           kTestCellularPropagationDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, LowRTTTransfer) {
+  CreateSetup(kTestLinkWiredBandwidth, kTestLinkSmallRTTDelay, kCellularQueue);
+
+  const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
+                           kTestLinkSmallRTTDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
new file mode 100644
index 0000000..44afb90
--- /dev/null
+++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
@@ -0,0 +1,431 @@
+// Copyright (c) 2015 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 "quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <string>
+
+#include "quiche/quic/core/congestion_control/prr_sender.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+// Constants based on TCP defaults.
+const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
+const float kRenoBeta = 0.7f;  // Reno backoff factor.
+// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
+// fast retransmission.
+const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS;
+}  // namespace
+
+TcpCubicSenderBytes::TcpCubicSenderBytes(
+    const QuicClock* clock,
+    const RttStats* rtt_stats,
+    bool reno,
+    QuicPacketCount initial_tcp_congestion_window,
+    QuicPacketCount max_congestion_window,
+    QuicConnectionStats* stats)
+    : rtt_stats_(rtt_stats),
+      stats_(stats),
+      reno_(reno),
+      num_connections_(kDefaultNumConnections),
+      min4_mode_(false),
+      last_cutback_exited_slowstart_(false),
+      slow_start_large_reduction_(false),
+      no_prr_(false),
+      cubic_(clock),
+      num_acked_packets_(0),
+      congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
+      min_congestion_window_(kDefaultMinimumCongestionWindow),
+      max_congestion_window_(max_congestion_window * kDefaultTCPMSS),
+      slowstart_threshold_(max_congestion_window * kDefaultTCPMSS),
+      initial_tcp_congestion_window_(initial_tcp_congestion_window *
+                                     kDefaultTCPMSS),
+      initial_max_tcp_congestion_window_(max_congestion_window *
+                                         kDefaultTCPMSS),
+      min_slow_start_exit_window_(min_congestion_window_) {}
+
+TcpCubicSenderBytes::~TcpCubicSenderBytes() {}
+
+void TcpCubicSenderBytes::SetFromConfig(const QuicConfig& config,
+                                        Perspective perspective) {
+  if (perspective == Perspective::IS_SERVER) {
+    if (!GetQuicReloadableFlag(quic_unified_iw_options)) {
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
+        // Initial window experiment.
+        SetInitialCongestionWindowInPackets(3);
+      }
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
+        // Initial window experiment.
+        SetInitialCongestionWindowInPackets(10);
+      }
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
+        // Initial window experiment.
+        SetInitialCongestionWindowInPackets(20);
+      }
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
+        // Initial window experiment.
+        SetInitialCongestionWindowInPackets(50);
+      }
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
+        // Min CWND experiment.
+        SetMinCongestionWindowInPackets(1);
+      }
+    }
+    if (config.HasReceivedConnectionOptions() &&
+        ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
+      // Min CWND of 4 experiment.
+      min4_mode_ = true;
+      SetMinCongestionWindowInPackets(1);
+    }
+    if (config.HasReceivedConnectionOptions() &&
+        ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
+      // Slow Start Fast Exit experiment.
+      slow_start_large_reduction_ = true;
+    }
+    if (config.HasReceivedConnectionOptions() &&
+        ContainsQuicTag(config.ReceivedConnectionOptions(), kNPRR)) {
+      // Use unity pacing instead of PRR.
+      no_prr_ = true;
+    }
+  }
+}
+
+void TcpCubicSenderBytes::AdjustNetworkParameters(const NetworkParams& params) {
+  if (params.bandwidth.IsZero() || params.rtt.IsZero()) {
+    return;
+  }
+  SetCongestionWindowFromBandwidthAndRtt(params.bandwidth, params.rtt);
+}
+
+float TcpCubicSenderBytes::RenoBeta() const {
+  // kNConnectionBeta is the backoff factor after loss for our N-connection
+  // emulation, which emulates the effective backoff of an ensemble of N
+  // TCP-Reno connections on a single loss event. The effective multiplier is
+  // computed as:
+  return (num_connections_ - 1 + kRenoBeta) / num_connections_;
+}
+
+void TcpCubicSenderBytes::OnCongestionEvent(
+    bool rtt_updated,
+    QuicByteCount prior_in_flight,
+    QuicTime event_time,
+    const AckedPacketVector& acked_packets,
+    const LostPacketVector& lost_packets) {
+  if (rtt_updated && InSlowStart() &&
+      hybrid_slow_start_.ShouldExitSlowStart(
+          rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
+          GetCongestionWindow() / kDefaultTCPMSS)) {
+    ExitSlowstart();
+  }
+  for (const LostPacket& lost_packet : lost_packets) {
+    OnPacketLost(lost_packet.packet_number, lost_packet.bytes_lost,
+                 prior_in_flight);
+  }
+  for (const AckedPacket& acked_packet : acked_packets) {
+    OnPacketAcked(acked_packet.packet_number, acked_packet.bytes_acked,
+                  prior_in_flight, event_time);
+  }
+}
+
+void TcpCubicSenderBytes::OnPacketAcked(QuicPacketNumber acked_packet_number,
+                                        QuicByteCount acked_bytes,
+                                        QuicByteCount prior_in_flight,
+                                        QuicTime event_time) {
+  largest_acked_packet_number_.UpdateMax(acked_packet_number);
+  if (InRecovery()) {
+    if (!no_prr_) {
+      // PRR is used when in recovery.
+      prr_.OnPacketAcked(acked_bytes);
+    }
+    return;
+  }
+  MaybeIncreaseCwnd(acked_packet_number, acked_bytes, prior_in_flight,
+                    event_time);
+  if (InSlowStart()) {
+    hybrid_slow_start_.OnPacketAcked(acked_packet_number);
+  }
+}
+
+void TcpCubicSenderBytes::OnPacketSent(
+    QuicTime /*sent_time*/,
+    QuicByteCount /*bytes_in_flight*/,
+    QuicPacketNumber packet_number,
+    QuicByteCount bytes,
+    HasRetransmittableData is_retransmittable) {
+  if (InSlowStart()) {
+    ++(stats_->slowstart_packets_sent);
+  }
+
+  if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) {
+    return;
+  }
+  if (InRecovery()) {
+    // PRR is used when in recovery.
+    prr_.OnPacketSent(bytes);
+  }
+  QUICHE_DCHECK(!largest_sent_packet_number_.IsInitialized() ||
+                largest_sent_packet_number_ < packet_number);
+  largest_sent_packet_number_ = packet_number;
+  hybrid_slow_start_.OnPacketSent(packet_number);
+}
+
+bool TcpCubicSenderBytes::CanSend(QuicByteCount bytes_in_flight) {
+  if (!no_prr_ && InRecovery()) {
+    // PRR is used when in recovery.
+    return prr_.CanSend(GetCongestionWindow(), bytes_in_flight,
+                        GetSlowStartThreshold());
+  }
+  if (GetCongestionWindow() > bytes_in_flight) {
+    return true;
+  }
+  if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
+    return true;
+  }
+  return false;
+}
+
+QuicBandwidth TcpCubicSenderBytes::PacingRate(
+    QuicByteCount /* bytes_in_flight */) const {
+  // We pace at twice the rate of the underlying sender's bandwidth estimate
+  // during slow start and 1.25x during congestion avoidance to ensure pacing
+  // doesn't prevent us from filling the window.
+  QuicTime::Delta srtt = rtt_stats_->SmoothedOrInitialRtt();
+  const QuicBandwidth bandwidth =
+      QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
+  return bandwidth * (InSlowStart() ? 2 : (no_prr_ && InRecovery() ? 1 : 1.25));
+}
+
+QuicBandwidth TcpCubicSenderBytes::BandwidthEstimate() const {
+  QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
+  if (srtt.IsZero()) {
+    // If we haven't measured an rtt, the bandwidth estimate is unknown.
+    return QuicBandwidth::Zero();
+  }
+  return QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
+}
+
+bool TcpCubicSenderBytes::InSlowStart() const {
+  return GetCongestionWindow() < GetSlowStartThreshold();
+}
+
+bool TcpCubicSenderBytes::IsCwndLimited(QuicByteCount bytes_in_flight) const {
+  const QuicByteCount congestion_window = GetCongestionWindow();
+  if (bytes_in_flight >= congestion_window) {
+    return true;
+  }
+  const QuicByteCount available_bytes = congestion_window - bytes_in_flight;
+  const bool slow_start_limited =
+      InSlowStart() && bytes_in_flight > congestion_window / 2;
+  return slow_start_limited || available_bytes <= kMaxBurstBytes;
+}
+
+bool TcpCubicSenderBytes::InRecovery() const {
+  return largest_acked_packet_number_.IsInitialized() &&
+         largest_sent_at_last_cutback_.IsInitialized() &&
+         largest_acked_packet_number_ <= largest_sent_at_last_cutback_;
+}
+
+bool TcpCubicSenderBytes::ShouldSendProbingPacket() const {
+  return false;
+}
+
+void TcpCubicSenderBytes::OnRetransmissionTimeout(bool packets_retransmitted) {
+  largest_sent_at_last_cutback_.Clear();
+  if (!packets_retransmitted) {
+    return;
+  }
+  hybrid_slow_start_.Restart();
+  HandleRetransmissionTimeout();
+}
+
+std::string TcpCubicSenderBytes::GetDebugState() const {
+  return "";
+}
+
+void TcpCubicSenderBytes::OnApplicationLimited(
+    QuicByteCount /*bytes_in_flight*/) {}
+
+void TcpCubicSenderBytes::SetCongestionWindowFromBandwidthAndRtt(
+    QuicBandwidth bandwidth,
+    QuicTime::Delta rtt) {
+  QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt);
+  // Limit new CWND if needed.
+  congestion_window_ =
+      std::max(min_congestion_window_,
+               std::min(new_congestion_window,
+                        kMaxResumptionCongestionWindow * kDefaultTCPMSS));
+}
+
+void TcpCubicSenderBytes::SetInitialCongestionWindowInPackets(
+    QuicPacketCount congestion_window) {
+  congestion_window_ = congestion_window * kDefaultTCPMSS;
+}
+
+void TcpCubicSenderBytes::SetMinCongestionWindowInPackets(
+    QuicPacketCount congestion_window) {
+  min_congestion_window_ = congestion_window * kDefaultTCPMSS;
+}
+
+void TcpCubicSenderBytes::SetNumEmulatedConnections(int num_connections) {
+  num_connections_ = std::max(1, num_connections);
+  cubic_.SetNumConnections(num_connections_);
+}
+
+void TcpCubicSenderBytes::ExitSlowstart() {
+  slowstart_threshold_ = congestion_window_;
+}
+
+void TcpCubicSenderBytes::OnPacketLost(QuicPacketNumber packet_number,
+                                       QuicByteCount lost_bytes,
+                                       QuicByteCount prior_in_flight) {
+  // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
+  // already sent should be treated as a single loss event, since it's expected.
+  if (largest_sent_at_last_cutback_.IsInitialized() &&
+      packet_number <= largest_sent_at_last_cutback_) {
+    if (last_cutback_exited_slowstart_) {
+      ++stats_->slowstart_packets_lost;
+      stats_->slowstart_bytes_lost += lost_bytes;
+      if (slow_start_large_reduction_) {
+        // Reduce congestion window by lost_bytes for every loss.
+        congestion_window_ = std::max(congestion_window_ - lost_bytes,
+                                      min_slow_start_exit_window_);
+        slowstart_threshold_ = congestion_window_;
+      }
+    }
+    QUIC_DVLOG(1) << "Ignoring loss for largest_missing:" << packet_number
+                  << " because it was sent prior to the last CWND cutback.";
+    return;
+  }
+  ++stats_->tcp_loss_events;
+  last_cutback_exited_slowstart_ = InSlowStart();
+  if (InSlowStart()) {
+    ++stats_->slowstart_packets_lost;
+  }
+
+  if (!no_prr_) {
+    prr_.OnPacketLost(prior_in_flight);
+  }
+
+  // TODO(b/77268641): Separate out all of slow start into a separate class.
+  if (slow_start_large_reduction_ && InSlowStart()) {
+    QUICHE_DCHECK_LT(kDefaultTCPMSS, congestion_window_);
+    if (congestion_window_ >= 2 * initial_tcp_congestion_window_) {
+      min_slow_start_exit_window_ = congestion_window_ / 2;
+    }
+    congestion_window_ = congestion_window_ - kDefaultTCPMSS;
+  } else if (reno_) {
+    congestion_window_ = congestion_window_ * RenoBeta();
+  } else {
+    congestion_window_ =
+        cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
+  }
+  if (congestion_window_ < min_congestion_window_) {
+    congestion_window_ = min_congestion_window_;
+  }
+  slowstart_threshold_ = congestion_window_;
+  largest_sent_at_last_cutback_ = largest_sent_packet_number_;
+  // Reset packet count from congestion avoidance mode. We start counting again
+  // when we're out of recovery.
+  num_acked_packets_ = 0;
+  QUIC_DVLOG(1) << "Incoming loss; congestion window: " << congestion_window_
+                << " slowstart threshold: " << slowstart_threshold_;
+}
+
+QuicByteCount TcpCubicSenderBytes::GetCongestionWindow() const {
+  return congestion_window_;
+}
+
+QuicByteCount TcpCubicSenderBytes::GetSlowStartThreshold() const {
+  return slowstart_threshold_;
+}
+
+// Called when we receive an ack. Normal TCP tracks how many packets one ack
+// represents, but quic has a separate ack for each packet.
+void TcpCubicSenderBytes::MaybeIncreaseCwnd(
+    QuicPacketNumber /*acked_packet_number*/,
+    QuicByteCount acked_bytes,
+    QuicByteCount prior_in_flight,
+    QuicTime event_time) {
+  QUIC_BUG_IF(quic_bug_10439_1, InRecovery())
+      << "Never increase the CWND during recovery.";
+  // Do not increase the congestion window unless the sender is close to using
+  // the current window.
+  if (!IsCwndLimited(prior_in_flight)) {
+    cubic_.OnApplicationLimited();
+    return;
+  }
+  if (congestion_window_ >= max_congestion_window_) {
+    return;
+  }
+  if (InSlowStart()) {
+    // TCP slow start, exponential growth, increase by one for each ACK.
+    congestion_window_ += kDefaultTCPMSS;
+    QUIC_DVLOG(1) << "Slow start; congestion window: " << congestion_window_
+                  << " slowstart threshold: " << slowstart_threshold_;
+    return;
+  }
+  // Congestion avoidance.
+  if (reno_) {
+    // Classic Reno congestion avoidance.
+    ++num_acked_packets_;
+    // Divide by num_connections to smoothly increase the CWND at a faster rate
+    // than conventional Reno.
+    if (num_acked_packets_ * num_connections_ >=
+        congestion_window_ / kDefaultTCPMSS) {
+      congestion_window_ += kDefaultTCPMSS;
+      num_acked_packets_ = 0;
+    }
+
+    QUIC_DVLOG(1) << "Reno; congestion window: " << congestion_window_
+                  << " slowstart threshold: " << slowstart_threshold_
+                  << " congestion window count: " << num_acked_packets_;
+  } else {
+    congestion_window_ = std::min(
+        max_congestion_window_,
+        cubic_.CongestionWindowAfterAck(acked_bytes, congestion_window_,
+                                        rtt_stats_->min_rtt(), event_time));
+    QUIC_DVLOG(1) << "Cubic; congestion window: " << congestion_window_
+                  << " slowstart threshold: " << slowstart_threshold_;
+  }
+}
+
+void TcpCubicSenderBytes::HandleRetransmissionTimeout() {
+  cubic_.ResetCubicState();
+  slowstart_threshold_ = congestion_window_ / 2;
+  congestion_window_ = min_congestion_window_;
+}
+
+void TcpCubicSenderBytes::OnConnectionMigration() {
+  hybrid_slow_start_.Restart();
+  prr_ = PrrSender();
+  largest_sent_packet_number_.Clear();
+  largest_acked_packet_number_.Clear();
+  largest_sent_at_last_cutback_.Clear();
+  last_cutback_exited_slowstart_ = false;
+  cubic_.ResetCubicState();
+  num_acked_packets_ = 0;
+  congestion_window_ = initial_tcp_congestion_window_;
+  max_congestion_window_ = initial_max_tcp_congestion_window_;
+  slowstart_threshold_ = initial_max_tcp_congestion_window_;
+}
+
+CongestionControlType TcpCubicSenderBytes::GetCongestionControlType() const {
+  return reno_ ? kRenoBytes : kCubicBytes;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
new file mode 100644
index 0000000..aac0c0a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -0,0 +1,175 @@
+// Copyright (c) 2015 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.
+
+// TCP cubic send side congestion algorithm, emulates the behavior of TCP cubic.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
+
+#include <cstdint>
+#include <string>
+
+#include "quiche/quic/core/congestion_control/cubic_bytes.h"
+#include "quiche/quic/core/congestion_control/hybrid_slow_start.h"
+#include "quiche/quic/core/congestion_control/prr_sender.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class RttStats;
+
+// Maximum window to allow when doing bandwidth resumption.
+const QuicPacketCount kMaxResumptionCongestionWindow = 200;
+
+namespace test {
+class TcpCubicSenderBytesPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public SendAlgorithmInterface {
+ public:
+  TcpCubicSenderBytes(const QuicClock* clock,
+                      const RttStats* rtt_stats,
+                      bool reno,
+                      QuicPacketCount initial_tcp_congestion_window,
+                      QuicPacketCount max_congestion_window,
+                      QuicConnectionStats* stats);
+  TcpCubicSenderBytes(const TcpCubicSenderBytes&) = delete;
+  TcpCubicSenderBytes& operator=(const TcpCubicSenderBytes&) = delete;
+  ~TcpCubicSenderBytes() override;
+
+  // Start implementation of SendAlgorithmInterface.
+  void SetFromConfig(const QuicConfig& config,
+                     Perspective perspective) override;
+  void ApplyConnectionOptions(
+      const QuicTagVector& /*connection_options*/) override {}
+  void AdjustNetworkParameters(const NetworkParams& params) override;
+  void SetNumEmulatedConnections(int num_connections);
+  void SetInitialCongestionWindowInPackets(
+      QuicPacketCount congestion_window) override;
+  void OnConnectionMigration() override;
+  void OnCongestionEvent(bool rtt_updated,
+                         QuicByteCount prior_in_flight,
+                         QuicTime event_time,
+                         const AckedPacketVector& acked_packets,
+                         const LostPacketVector& lost_packets) override;
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData is_retransmittable) override;
+  void OnPacketNeutered(QuicPacketNumber /*packet_number*/) override {}
+  void OnRetransmissionTimeout(bool packets_retransmitted) override;
+  bool CanSend(QuicByteCount bytes_in_flight) override;
+  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
+  QuicBandwidth BandwidthEstimate() const override;
+  bool HasGoodBandwidthEstimateForResumption() const override { return false; }
+  QuicByteCount GetCongestionWindow() const override;
+  QuicByteCount GetSlowStartThreshold() const override;
+  CongestionControlType GetCongestionControlType() const override;
+  bool InSlowStart() const override;
+  bool InRecovery() const override;
+  bool ShouldSendProbingPacket() const override;
+  std::string GetDebugState() const override;
+  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
+  void PopulateConnectionStats(QuicConnectionStats* /*stats*/) const override {}
+  // End implementation of SendAlgorithmInterface.
+
+  QuicByteCount min_congestion_window() const { return min_congestion_window_; }
+
+ protected:
+  // Compute the TCP Reno beta based on the current number of connections.
+  float RenoBeta() const;
+
+  bool IsCwndLimited(QuicByteCount bytes_in_flight) const;
+
+  // TODO(ianswett): Remove these and migrate to OnCongestionEvent.
+  void OnPacketAcked(QuicPacketNumber acked_packet_number,
+                     QuicByteCount acked_bytes,
+                     QuicByteCount prior_in_flight,
+                     QuicTime event_time);
+  void SetCongestionWindowFromBandwidthAndRtt(QuicBandwidth bandwidth,
+                                              QuicTime::Delta rtt);
+  void SetMinCongestionWindowInPackets(QuicPacketCount congestion_window);
+  void ExitSlowstart();
+  void OnPacketLost(QuicPacketNumber packet_number, QuicByteCount lost_bytes,
+                    QuicByteCount prior_in_flight);
+  void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
+                         QuicByteCount acked_bytes,
+                         QuicByteCount prior_in_flight,
+                         QuicTime event_time);
+  void HandleRetransmissionTimeout();
+
+ private:
+  friend class test::TcpCubicSenderBytesPeer;
+
+  HybridSlowStart hybrid_slow_start_;
+  PrrSender prr_;
+  const RttStats* rtt_stats_;
+  QuicConnectionStats* stats_;
+
+  // If true, Reno congestion control is used instead of Cubic.
+  const bool reno_;
+
+  // Number of connections to simulate.
+  uint32_t num_connections_;
+
+  // Track the largest packet that has been sent.
+  QuicPacketNumber largest_sent_packet_number_;
+
+  // Track the largest packet that has been acked.
+  QuicPacketNumber largest_acked_packet_number_;
+
+  // Track the largest packet number outstanding when a CWND cutback occurs.
+  QuicPacketNumber largest_sent_at_last_cutback_;
+
+  // Whether to use 4 packets as the actual min, but pace lower.
+  bool min4_mode_;
+
+  // Whether the last loss event caused us to exit slowstart.
+  // Used for stats collection of slowstart_packets_lost
+  bool last_cutback_exited_slowstart_;
+
+  // When true, exit slow start with large cutback of congestion window.
+  bool slow_start_large_reduction_;
+
+  // When true, use unity pacing instead of PRR.
+  bool no_prr_;
+
+  CubicBytes cubic_;
+
+  // ACK counter for the Reno implementation.
+  uint64_t num_acked_packets_;
+
+  // Congestion window in bytes.
+  QuicByteCount congestion_window_;
+
+  // Minimum congestion window in bytes.
+  QuicByteCount min_congestion_window_;
+
+  // Maximum congestion window in bytes.
+  QuicByteCount max_congestion_window_;
+
+  // Slow start congestion window in bytes, aka ssthresh.
+  QuicByteCount slowstart_threshold_;
+
+  // Initial TCP congestion window in bytes. This variable can only be set when
+  // this algorithm is created.
+  const QuicByteCount initial_tcp_congestion_window_;
+
+  // Initial maximum TCP congestion window in bytes. This variable can only be
+  // set when this algorithm is created.
+  const QuicByteCount initial_max_tcp_congestion_window_;
+
+  // The minimum window when exiting slow start with large reduction.
+  QuicByteCount min_slow_start_exit_window_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
new file mode 100644
index 0000000..bac568a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
@@ -0,0 +1,845 @@
+// Copyright (c) 2015 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 "quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+
+namespace quic {
+namespace test {
+
+// TODO(ianswett): A number of theses tests were written with the assumption of
+// an initial CWND of 10. They have carefully calculated values which should be
+// updated to be based on kInitialCongestionWindow.
+const uint32_t kInitialCongestionWindowPackets = 10;
+const uint32_t kMaxCongestionWindowPackets = 200;
+const uint32_t kDefaultWindowTCP =
+    kInitialCongestionWindowPackets * kDefaultTCPMSS;
+const float kRenoBeta = 0.7f;  // Reno backoff factor.
+
+class TcpCubicSenderBytesPeer : public TcpCubicSenderBytes {
+ public:
+  TcpCubicSenderBytesPeer(const QuicClock* clock, bool reno)
+      : TcpCubicSenderBytes(clock,
+                            &rtt_stats_,
+                            reno,
+                            kInitialCongestionWindowPackets,
+                            kMaxCongestionWindowPackets,
+                            &stats_) {}
+
+  const HybridSlowStart& hybrid_slow_start() const {
+    return hybrid_slow_start_;
+  }
+
+  float GetRenoBeta() const { return RenoBeta(); }
+
+  RttStats rtt_stats_;
+  QuicConnectionStats stats_;
+};
+
+class TcpCubicSenderBytesTest : public QuicTest {
+ protected:
+  TcpCubicSenderBytesTest()
+      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
+        sender_(new TcpCubicSenderBytesPeer(&clock_, true)),
+        packet_number_(1),
+        acked_packet_number_(0),
+        bytes_in_flight_(0) {}
+
+  int SendAvailableSendWindow() {
+    return SendAvailableSendWindow(kDefaultTCPMSS);
+  }
+
+  int SendAvailableSendWindow(QuicPacketLength /*packet_length*/) {
+    // Send as long as TimeUntilSend returns Zero.
+    int packets_sent = 0;
+    bool can_send = sender_->CanSend(bytes_in_flight_);
+    while (can_send) {
+      sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
+                            QuicPacketNumber(packet_number_++), kDefaultTCPMSS,
+                            HAS_RETRANSMITTABLE_DATA);
+      ++packets_sent;
+      bytes_in_flight_ += kDefaultTCPMSS;
+      can_send = sender_->CanSend(bytes_in_flight_);
+    }
+    return packets_sent;
+  }
+
+  // Normal is that TCP acks every other segment.
+  void AckNPackets(int n) {
+    sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
+                                  QuicTime::Delta::Zero(), clock_.Now());
+    AckedPacketVector acked_packets;
+    LostPacketVector lost_packets;
+    for (int i = 0; i < n; ++i) {
+      ++acked_packet_number_;
+      acked_packets.push_back(
+          AckedPacket(QuicPacketNumber(acked_packet_number_), kDefaultTCPMSS,
+                      QuicTime::Zero()));
+    }
+    sender_->OnCongestionEvent(true, bytes_in_flight_, clock_.Now(),
+                               acked_packets, lost_packets);
+    bytes_in_flight_ -= n * kDefaultTCPMSS;
+    clock_.AdvanceTime(one_ms_);
+  }
+
+  void LoseNPackets(int n) { LoseNPackets(n, kDefaultTCPMSS); }
+
+  void LoseNPackets(int n, QuicPacketLength packet_length) {
+    AckedPacketVector acked_packets;
+    LostPacketVector lost_packets;
+    for (int i = 0; i < n; ++i) {
+      ++acked_packet_number_;
+      lost_packets.push_back(
+          LostPacket(QuicPacketNumber(acked_packet_number_), packet_length));
+    }
+    sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
+                               acked_packets, lost_packets);
+    bytes_in_flight_ -= n * packet_length;
+  }
+
+  // Does not increment acked_packet_number_.
+  void LosePacket(uint64_t packet_number) {
+    AckedPacketVector acked_packets;
+    LostPacketVector lost_packets;
+    lost_packets.push_back(
+        LostPacket(QuicPacketNumber(packet_number), kDefaultTCPMSS));
+    sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
+                               acked_packets, lost_packets);
+    bytes_in_flight_ -= kDefaultTCPMSS;
+  }
+
+  const QuicTime::Delta one_ms_;
+  MockClock clock_;
+  std::unique_ptr<TcpCubicSenderBytesPeer> sender_;
+  uint64_t packet_number_;
+  uint64_t acked_packet_number_;
+  QuicByteCount bytes_in_flight_;
+};
+
+TEST_F(TcpCubicSenderBytesTest, SimpleSender) {
+  // At startup make sure we are at the default.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // Make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // And that window is un-affected.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+
+  // Fill the send window with data, then verify that we can't send.
+  SendAvailableSendWindow();
+  EXPECT_FALSE(sender_->CanSend(sender_->GetCongestionWindow()));
+}
+
+TEST_F(TcpCubicSenderBytesTest, ApplicationLimitedSlowStart) {
+  // Send exactly 10 packets and ensure the CWND ends at 14 packets.
+  const int kNumberOfAcks = 5;
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // Make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+
+  SendAvailableSendWindow();
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    AckNPackets(2);
+  }
+  QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
+  // It's expected 2 acks will arrive when the bytes_in_flight are greater than
+  // half the CWND.
+  EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, bytes_to_send);
+}
+
+TEST_F(TcpCubicSenderBytesTest, ExponentialSlowStart) {
+  const int kNumberOfAcks = 20;
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
+  // Make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  const QuicByteCount cwnd = sender_->GetCongestionWindow();
+  EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
+  EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
+                cwnd, sender_->rtt_stats_.smoothed_rtt()),
+            sender_->BandwidthEstimate());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLoss) {
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = 10;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose a packet to exit slow start.
+  LoseNPackets(1);
+  size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
+
+  // We should now have fallen out of slow start with a reduced window.
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Recovery phase. We need to ack every packet in the recovery window before
+  // we exit recovery.
+  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
+  QUIC_DLOG(INFO) << "number_packets: " << number_of_packets_in_window;
+  AckNPackets(packets_in_recovery_window);
+  SendAvailableSendWindow();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // We need to ack an entire window before we increase CWND by 1.
+  AckNPackets(number_of_packets_in_window - 2);
+  SendAvailableSendWindow();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Next ack should increase cwnd by 1.
+  AckNPackets(1);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Now RTO and ensure slow start gets reset.
+  EXPECT_TRUE(sender_->hybrid_slow_start().started());
+  sender_->OnRetransmissionTimeout(true);
+  EXPECT_FALSE(sender_->hybrid_slow_start().started());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossWithLargeReduction) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kSSLR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = (kDefaultWindowTCP / (2 * kDefaultTCPMSS)) - 1;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose a packet to exit slow start. We should now have fallen out of
+  // slow start with a window reduced by 1.
+  LoseNPackets(1);
+  expected_send_window -= kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose 5 packets in recovery and verify that congestion window is reduced
+  // further.
+  LoseNPackets(5);
+  expected_send_window -= 5 * kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  // Lose another 10 packets and ensure it reduces below half the peak CWND,
+  // because we never acked the full IW.
+  LoseNPackets(10);
+  expected_send_window -= 10 * kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
+
+  // Recovery phase. We need to ack every packet in the recovery window before
+  // we exit recovery.
+  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
+  QUIC_DLOG(INFO) << "number_packets: " << number_of_packets_in_window;
+  AckNPackets(packets_in_recovery_window);
+  SendAvailableSendWindow();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // We need to ack an entire window before we increase CWND by 1.
+  AckNPackets(number_of_packets_in_window - 1);
+  SendAvailableSendWindow();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Next ack should increase cwnd by 1.
+  AckNPackets(1);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Now RTO and ensure slow start gets reset.
+  EXPECT_TRUE(sender_->hybrid_slow_start().started());
+  sender_->OnRetransmissionTimeout(true);
+  EXPECT_FALSE(sender_->hybrid_slow_start().started());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartHalfPacketLossWithLargeReduction) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kSSLR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = 10;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window in half sized packets.
+    SendAvailableSendWindow(kDefaultTCPMSS / 2);
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow(kDefaultTCPMSS / 2);
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose a packet to exit slow start. We should now have fallen out of
+  // slow start with a window reduced by 1.
+  LoseNPackets(1);
+  expected_send_window -= kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose 10 packets in recovery and verify that congestion window is reduced
+  // by 5 packets.
+  LoseNPackets(10, kDefaultTCPMSS / 2);
+  expected_send_window -= 5 * kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossWithMaxHalfReduction) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kSSLR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = kInitialCongestionWindowPackets / 2;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose a packet to exit slow start. We should now have fallen out of
+  // slow start with a window reduced by 1.
+  LoseNPackets(1);
+  expected_send_window -= kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose half the outstanding packets in recovery and verify the congestion
+  // window is only reduced by a max of half.
+  LoseNPackets(kNumberOfAcks * 2);
+  expected_send_window -= (kNumberOfAcks * 2 - 1) * kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  LoseNPackets(5);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, NoPRRWhenLessThanOnePacketInFlight) {
+  SendAvailableSendWindow();
+  LoseNPackets(kInitialCongestionWindowPackets - 1);
+  AckNPackets(1);
+  // PRR will allow 2 packets for every ack during recovery.
+  EXPECT_EQ(2, SendAvailableSendWindow());
+  // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
+  // PRR should now allow a packet to be sent, even though prr's state variables
+  // believe it has sent enough packets.
+  EXPECT_TRUE(sender_->CanSend(0));
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossPRR) {
+  sender_->SetNumEmulatedConnections(1);
+  // Test based on the first example in RFC6937.
+  // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
+  const int kNumberOfAcks = 5;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  LoseNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  size_t send_window_before_loss = expected_send_window;
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Testing TCP proportional rate reduction.
+  // We should send packets paced over the received acks for the remaining
+  // outstanding packets. The number of packets before we exit recovery is the
+  // original CWND minus the packet that has been lost and the one which
+  // triggered the loss.
+  size_t remaining_packets_in_recovery =
+      send_window_before_loss / kDefaultTCPMSS - 2;
+
+  for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
+    AckNPackets(1);
+    SendAvailableSendWindow();
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+
+  // We need to ack another window before we increase CWND by 1.
+  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
+  for (size_t i = 0; i < number_of_packets_in_window; ++i) {
+    AckNPackets(1);
+    EXPECT_EQ(1, SendAvailableSendWindow());
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+
+  AckNPackets(1);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartBurstPacketLossPRR) {
+  sender_->SetNumEmulatedConnections(1);
+  // Test based on the second example in RFC6937, though we also implement
+  // forward acknowledgements, so the first two incoming acks will trigger
+  // PRR immediately.
+  // Ack 20 packets in 10 acks to raise the CWND to 30.
+  const int kNumberOfAcks = 10;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose one more than the congestion window reduction, so that after loss,
+  // bytes_in_flight is lesser than the congestion window.
+  size_t send_window_after_loss = kRenoBeta * expected_send_window;
+  size_t num_packets_to_lose =
+      (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
+  LoseNPackets(num_packets_to_lose);
+  // Immediately after the loss, ensure at least one packet can be sent.
+  // Losses without subsequent acks can occur with timer based loss detection.
+  EXPECT_TRUE(sender_->CanSend(bytes_in_flight_));
+  AckNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Only 2 packets should be allowed to be sent, per PRR-SSRB.
+  EXPECT_EQ(2, SendAvailableSendWindow());
+
+  // Ack the next packet, which triggers another loss.
+  LoseNPackets(1);
+  AckNPackets(1);
+
+  // Send 2 packets to simulate PRR-SSRB.
+  EXPECT_EQ(2, SendAvailableSendWindow());
+
+  // Ack the next packet, which triggers another loss.
+  LoseNPackets(1);
+  AckNPackets(1);
+
+  // Send 2 packets to simulate PRR-SSRB.
+  EXPECT_EQ(2, SendAvailableSendWindow());
+
+  // Exit recovery and return to sending at the new rate.
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    AckNPackets(1);
+    EXPECT_EQ(1, SendAvailableSendWindow());
+  }
+}
+
+TEST_F(TcpCubicSenderBytesTest, RTOCongestionWindow) {
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  // Expect the window to decrease to the minimum once the RTO fires and slow
+  // start threshold to be set to 1/2 of the CWND.
+  sender_->OnRetransmissionTimeout(true);
+  EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
+  EXPECT_EQ(5u * kDefaultTCPMSS, sender_->GetSlowStartThreshold());
+}
+
+TEST_F(TcpCubicSenderBytesTest, RTOCongestionWindowNoRetransmission) {
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+
+  // Expect the window to remain unchanged if the RTO fires but no packets are
+  // retransmitted.
+  sender_->OnRetransmissionTimeout(false);
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, TcpCubicResetEpochOnQuiescence) {
+  const int kMaxCongestionWindow = 50;
+  const QuicByteCount kMaxCongestionWindowBytes =
+      kMaxCongestionWindow * kDefaultTCPMSS;
+  int num_sent = SendAvailableSendWindow();
+
+  // Make sure we fall out of slow start.
+  QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
+  LoseNPackets(1);
+  EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
+
+  // Ack the rest of the outstanding packets to get out of recovery.
+  for (int i = 1; i < num_sent; ++i) {
+    AckNPackets(1);
+  }
+  EXPECT_EQ(0u, bytes_in_flight_);
+
+  // Send a new window of data and ack all; cubic growth should occur.
+  saved_cwnd = sender_->GetCongestionWindow();
+  num_sent = SendAvailableSendWindow();
+  for (int i = 0; i < num_sent; ++i) {
+    AckNPackets(1);
+  }
+  EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
+  EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
+  EXPECT_EQ(0u, bytes_in_flight_);
+
+  // Quiescent time of 100 seconds
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100000));
+
+  // Send new window of data and ack one packet. Cubic epoch should have
+  // been reset; ensure cwnd increase is not dramatic.
+  saved_cwnd = sender_->GetCongestionWindow();
+  SendAvailableSendWindow();
+  AckNPackets(1);
+  EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
+  EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, MultipleLossesInOneWindow) {
+  SendAvailableSendWindow();
+  const QuicByteCount initial_window = sender_->GetCongestionWindow();
+  LosePacket(acked_packet_number_ + 1);
+  const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
+  EXPECT_GT(initial_window, post_loss_window);
+  LosePacket(acked_packet_number_ + 3);
+  EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
+  LosePacket(packet_number_ - 1);
+  EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
+
+  // Lose a later packet and ensure the window decreases.
+  LosePacket(packet_number_);
+  EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, ConfigureMaxInitialWindow) {
+  SetQuicReloadableFlag(quic_unified_iw_options, false);
+  QuicConfig config;
+
+  // Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
+  QuicTagVector options;
+  options.push_back(kIW10);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  EXPECT_EQ(10u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SetInitialCongestionWindow) {
+  EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+  sender_->SetInitialCongestionWindowInPackets(3);
+  EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
+  sender_->SetNumEmulatedConnections(2);
+  // Ack 10 packets in 5 acks to raise the CWND to 20.
+  const int kNumberOfAcks = 5;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  LoseNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  expected_send_window = expected_send_window * sender_->GetRenoBeta();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // No congestion window growth should occur in recovery phase, i.e., until the
+  // currently outstanding 20 packets are acked.
+  for (int i = 0; i < 10; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    EXPECT_TRUE(sender_->InRecovery());
+    AckNPackets(2);
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+  EXPECT_FALSE(sender_->InRecovery());
+
+  // Out of recovery now. Congestion window should not grow for half an RTT.
+  size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
+  SendAvailableSendWindow();
+  AckNPackets(packets_in_send_window / 2 - 2);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Next ack should increase congestion window by 1MSS.
+  SendAvailableSendWindow();
+  AckNPackets(2);
+  expected_send_window += kDefaultTCPMSS;
+  packets_in_send_window += 1;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Congestion window should remain steady again for half an RTT.
+  SendAvailableSendWindow();
+  AckNPackets(packets_in_send_window / 2 - 1);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Next ack should cause congestion window to grow by 1MSS.
+  SendAvailableSendWindow();
+  AckNPackets(2);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
+  sender_->SetNumEmulatedConnections(1);
+  // Ack 10 packets in 5 acks to raise the CWND to 20.
+  const int kNumberOfAcks = 5;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  LoseNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // No congestion window growth should occur in recovery phase, i.e., until the
+  // currently outstanding 20 packets are acked.
+  for (int i = 0; i < 10; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    EXPECT_TRUE(sender_->InRecovery());
+    AckNPackets(2);
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+  EXPECT_FALSE(sender_->InRecovery());
+
+  // Out of recovery now. Congestion window should not grow during RTT.
+  for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+
+  // Next ack should cause congestion window to grow by 1MSS.
+  SendAvailableSendWindow();
+  AckNPackets(2);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, BandwidthResumption) {
+  // Test that when provided with CachedNetworkParameters and opted in to the
+  // bandwidth resumption experiment, that the TcpCubicSenderPackets sets
+  // initial CWND appropriately.
+
+  // Set some common values.
+  const QuicPacketCount kNumberOfPackets = 123;
+  const QuicBandwidth kBandwidthEstimate =
+      QuicBandwidth::FromBytesPerSecond(kNumberOfPackets * kDefaultTCPMSS);
+  const QuicTime::Delta kRttEstimate = QuicTime::Delta::FromSeconds(1);
+
+  SendAlgorithmInterface::NetworkParams network_param;
+  network_param.bandwidth = kBandwidthEstimate;
+  network_param.rtt = kRttEstimate;
+  sender_->AdjustNetworkParameters(network_param);
+  EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
+
+  // Resume with an illegal value of 0 and verify the server ignores it.
+  SendAlgorithmInterface::NetworkParams network_param_no_bandwidth;
+  network_param_no_bandwidth.bandwidth = QuicBandwidth::Zero();
+  network_param_no_bandwidth.rtt = kRttEstimate;
+  sender_->AdjustNetworkParameters(network_param_no_bandwidth);
+  EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
+
+  // Resumed CWND is limited to be in a sensible range.
+  const QuicBandwidth kUnreasonableBandwidth =
+      QuicBandwidth::FromBytesPerSecond((kMaxResumptionCongestionWindow + 1) *
+                                        kDefaultTCPMSS);
+  SendAlgorithmInterface::NetworkParams network_param_large_bandwidth;
+  network_param_large_bandwidth.bandwidth = kUnreasonableBandwidth;
+  network_param_large_bandwidth.rtt = QuicTime::Delta::FromSeconds(1);
+  sender_->AdjustNetworkParameters(network_param_large_bandwidth);
+  EXPECT_EQ(kMaxResumptionCongestionWindow * kDefaultTCPMSS,
+            sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, PaceBelowCWND) {
+  QuicConfig config;
+
+  // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up
+  // to 4 to be sent.
+  QuicTagVector options;
+  options.push_back(kMIN4);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  sender_->OnRetransmissionTimeout(true);
+  EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
+  EXPECT_TRUE(sender_->CanSend(kDefaultTCPMSS));
+  EXPECT_TRUE(sender_->CanSend(2 * kDefaultTCPMSS));
+  EXPECT_TRUE(sender_->CanSend(3 * kDefaultTCPMSS));
+  EXPECT_FALSE(sender_->CanSend(4 * kDefaultTCPMSS));
+}
+
+TEST_F(TcpCubicSenderBytesTest, NoPRR) {
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(100);
+  sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  sender_->SetNumEmulatedConnections(1);
+  // Verify that kCOPT: kNPRR allows all packets to be sent, even if only one
+  // ack has been received.
+  QuicTagVector options;
+  options.push_back(kNPRR);
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  SendAvailableSendWindow();
+  LoseNPackets(9);
+  AckNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  EXPECT_EQ(kRenoBeta * kDefaultWindowTCP, sender_->GetCongestionWindow());
+  const QuicPacketCount window_in_packets =
+      kRenoBeta * kDefaultWindowTCP / kDefaultTCPMSS;
+  const QuicBandwidth expected_pacing_rate =
+      QuicBandwidth::FromBytesAndTimeDelta(kRenoBeta * kDefaultWindowTCP,
+                                           sender_->rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(expected_pacing_rate, sender_->PacingRate(0));
+  EXPECT_EQ(window_in_packets,
+            static_cast<uint64_t>(SendAvailableSendWindow()));
+  EXPECT_EQ(expected_pacing_rate,
+            sender_->PacingRate(kRenoBeta * kDefaultWindowTCP));
+}
+
+TEST_F(TcpCubicSenderBytesTest, ResetAfterConnectionMigration) {
+  // Starts from slow start.
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = 10;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Loses a packet to exit slow start.
+  LoseNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window. Slow
+  // start threshold is also updated.
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  EXPECT_EQ(expected_send_window, sender_->GetSlowStartThreshold());
+
+  // Resets cwnd and slow start threshold on connection migrations.
+  sender_->OnConnectionMigration();
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  EXPECT_EQ(kMaxCongestionWindowPackets * kDefaultTCPMSS,
+            sender_->GetSlowStartThreshold());
+  EXPECT_FALSE(sender_->hybrid_slow_start().started());
+}
+
+TEST_F(TcpCubicSenderBytesTest, DefaultMaxCwnd) {
+  RttStats rtt_stats;
+  QuicConnectionStats stats;
+  std::unique_ptr<SendAlgorithmInterface> sender(SendAlgorithmInterface::Create(
+      &clock_, &rtt_stats, /*unacked_packets=*/nullptr, kCubicBytes,
+      QuicRandom::GetInstance(), &stats, kInitialCongestionWindow, nullptr));
+
+  AckedPacketVector acked_packets;
+  LostPacketVector missing_packets;
+  QuicPacketCount max_congestion_window =
+      GetQuicFlag(FLAGS_quic_max_congestion_window);
+  for (uint64_t i = 1; i < max_congestion_window; ++i) {
+    acked_packets.clear();
+    acked_packets.push_back(
+        AckedPacket(QuicPacketNumber(i), 1350, QuicTime::Zero()));
+    sender->OnCongestionEvent(true, sender->GetCongestionWindow(), clock_.Now(),
+                              acked_packets, missing_packets);
+  }
+  EXPECT_EQ(max_congestion_window,
+            sender->GetCongestionWindow() / kDefaultTCPMSS);
+}
+
+TEST_F(TcpCubicSenderBytesTest, LimitCwndIncreaseInCongestionAvoidance) {
+  // Enable Cubic.
+  sender_ = std::make_unique<TcpCubicSenderBytesPeer>(&clock_, false);
+
+  int num_sent = SendAvailableSendWindow();
+
+  // Make sure we fall out of slow start.
+  QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
+  LoseNPackets(1);
+  EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
+
+  // Ack the rest of the outstanding packets to get out of recovery.
+  for (int i = 1; i < num_sent; ++i) {
+    AckNPackets(1);
+  }
+  EXPECT_EQ(0u, bytes_in_flight_);
+  // Send a new window of data and ack all; cubic growth should occur.
+  saved_cwnd = sender_->GetCongestionWindow();
+  num_sent = SendAvailableSendWindow();
+
+  // Ack packets until the CWND increases.
+  while (sender_->GetCongestionWindow() == saved_cwnd) {
+    AckNPackets(1);
+    SendAvailableSendWindow();
+  }
+  // Bytes in flight may be larger than the CWND if the CWND isn't an exact
+  // multiple of the packet sizes being sent.
+  EXPECT_GE(bytes_in_flight_, sender_->GetCongestionWindow());
+  saved_cwnd = sender_->GetCongestionWindow();
+
+  // Advance time 2 seconds waiting for an ack.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2000));
+
+  // Ack two packets.  The CWND should increase by only one packet.
+  AckNPackets(2);
+  EXPECT_EQ(saved_cwnd + kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/uber_loss_algorithm.cc b/quiche/quic/core/congestion_control/uber_loss_algorithm.cc
new file mode 100644
index 0000000..9fd4b8c
--- /dev/null
+++ b/quiche/quic/core/congestion_control/uber_loss_algorithm.cc
@@ -0,0 +1,215 @@
+// Copyright 2019 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 "quiche/quic/core/congestion_control/uber_loss_algorithm.h"
+
+#include <algorithm>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+UberLossAlgorithm::UberLossAlgorithm() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].Initialize(static_cast<PacketNumberSpace>(i),
+                                           this);
+  }
+}
+
+void UberLossAlgorithm::SetFromConfig(const QuicConfig& config,
+                                      Perspective perspective) {
+  if (config.HasClientRequestedIndependentOption(kELDT, perspective) &&
+      tuner_ != nullptr) {
+    tuning_configured_ = true;
+    MaybeStartTuning();
+  }
+}
+
+LossDetectionInterface::DetectionStats UberLossAlgorithm::DetectLosses(
+    const QuicUnackedPacketMap& unacked_packets,
+    QuicTime time,
+    const RttStats& rtt_stats,
+    QuicPacketNumber /*largest_newly_acked*/,
+    const AckedPacketVector& packets_acked,
+    LostPacketVector* packets_lost) {
+  DetectionStats overall_stats;
+
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    const QuicPacketNumber largest_acked =
+        unacked_packets.GetLargestAckedOfPacketNumberSpace(
+            static_cast<PacketNumberSpace>(i));
+    if (!largest_acked.IsInitialized() ||
+        unacked_packets.GetLeastUnacked() > largest_acked) {
+      // Skip detecting losses if no packet has been received for this packet
+      // number space or the least_unacked is greater than largest_acked.
+      continue;
+    }
+
+    DetectionStats stats = general_loss_algorithms_[i].DetectLosses(
+        unacked_packets, time, rtt_stats, largest_acked, packets_acked,
+        packets_lost);
+
+    overall_stats.sent_packets_max_sequence_reordering =
+        std::max(overall_stats.sent_packets_max_sequence_reordering,
+                 stats.sent_packets_max_sequence_reordering);
+    overall_stats.sent_packets_num_borderline_time_reorderings +=
+        stats.sent_packets_num_borderline_time_reorderings;
+    overall_stats.total_loss_detection_response_time +=
+        stats.total_loss_detection_response_time;
+  }
+
+  return overall_stats;
+}
+
+QuicTime UberLossAlgorithm::GetLossTimeout() const {
+  QuicTime loss_timeout = QuicTime::Zero();
+  // Returns the earliest non-zero loss timeout.
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    const QuicTime timeout = general_loss_algorithms_[i].GetLossTimeout();
+    if (!loss_timeout.IsInitialized()) {
+      loss_timeout = timeout;
+      continue;
+    }
+    if (timeout.IsInitialized()) {
+      loss_timeout = std::min(loss_timeout, timeout);
+    }
+  }
+  return loss_timeout;
+}
+
+void UberLossAlgorithm::SpuriousLossDetected(
+    const QuicUnackedPacketMap& unacked_packets,
+    const RttStats& rtt_stats,
+    QuicTime ack_receive_time,
+    QuicPacketNumber packet_number,
+    QuicPacketNumber previous_largest_acked) {
+  general_loss_algorithms_[unacked_packets.GetPacketNumberSpace(packet_number)]
+      .SpuriousLossDetected(unacked_packets, rtt_stats, ack_receive_time,
+                            packet_number, previous_largest_acked);
+}
+
+void UberLossAlgorithm::SetLossDetectionTuner(
+    std::unique_ptr<LossDetectionTunerInterface> tuner) {
+  if (tuner_ != nullptr) {
+    QUIC_BUG(quic_bug_10469_1)
+        << "LossDetectionTuner can only be set once when session begins.";
+    return;
+  }
+  tuner_ = std::move(tuner);
+}
+
+void UberLossAlgorithm::MaybeStartTuning() {
+  if (tuner_started_ || !tuning_configured_ || !min_rtt_available_ ||
+      !user_agent_known_ || !reorder_happened_) {
+    return;
+  }
+
+  tuner_started_ = tuner_->Start(&tuned_parameters_);
+  if (!tuner_started_) {
+    return;
+  }
+
+  if (tuned_parameters_.reordering_shift.has_value() &&
+      tuned_parameters_.reordering_threshold.has_value()) {
+    QUIC_DLOG(INFO) << "Setting reordering shift to "
+                    << *tuned_parameters_.reordering_shift
+                    << ", and reordering threshold to "
+                    << *tuned_parameters_.reordering_threshold;
+    SetReorderingShift(*tuned_parameters_.reordering_shift);
+    SetReorderingThreshold(*tuned_parameters_.reordering_threshold);
+  } else {
+    QUIC_BUG(quic_bug_10469_2)
+        << "Tuner started but some parameters are missing";
+  }
+}
+
+void UberLossAlgorithm::OnConfigNegotiated() {}
+
+void UberLossAlgorithm::OnMinRttAvailable() {
+  min_rtt_available_ = true;
+  MaybeStartTuning();
+}
+
+void UberLossAlgorithm::OnUserAgentIdKnown() {
+  user_agent_known_ = true;
+  MaybeStartTuning();
+}
+
+void UberLossAlgorithm::OnConnectionClosed() {
+  if (tuner_ != nullptr && tuner_started_) {
+    tuner_->Finish(tuned_parameters_);
+  }
+}
+
+void UberLossAlgorithm::OnReorderingDetected() {
+  const bool tuner_started_before = tuner_started_;
+  const bool reorder_happened_before = reorder_happened_;
+
+  reorder_happened_ = true;
+  MaybeStartTuning();
+
+  if (!tuner_started_before && tuner_started_) {
+    if (reorder_happened_before) {
+      QUIC_CODE_COUNT(quic_loss_tuner_started_after_first_reorder);
+    } else {
+      QUIC_CODE_COUNT(quic_loss_tuner_started_on_first_reorder);
+    }
+  }
+}
+
+void UberLossAlgorithm::SetReorderingShift(int reordering_shift) {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].set_reordering_shift(reordering_shift);
+  }
+}
+
+void UberLossAlgorithm::SetReorderingThreshold(
+    QuicPacketCount reordering_threshold) {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].set_reordering_threshold(reordering_threshold);
+  }
+}
+
+void UberLossAlgorithm::EnableAdaptiveReorderingThreshold() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].set_use_adaptive_reordering_threshold(true);
+  }
+}
+
+void UberLossAlgorithm::DisableAdaptiveReorderingThreshold() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].set_use_adaptive_reordering_threshold(false);
+  }
+}
+
+void UberLossAlgorithm::EnableAdaptiveTimeThreshold() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].enable_adaptive_time_threshold();
+  }
+}
+
+QuicPacketCount UberLossAlgorithm::GetPacketReorderingThreshold() const {
+  return general_loss_algorithms_[APPLICATION_DATA].reordering_threshold();
+}
+
+int UberLossAlgorithm::GetPacketReorderingShift() const {
+  return general_loss_algorithms_[APPLICATION_DATA].reordering_shift();
+}
+
+void UberLossAlgorithm::DisablePacketThresholdForRuntPackets() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].disable_packet_threshold_for_runt_packets();
+  }
+}
+
+void UberLossAlgorithm::ResetLossDetection(PacketNumberSpace space) {
+  if (space >= NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10469_3) << "Invalid packet number space: " << space;
+    return;
+  }
+  general_loss_algorithms_[space].Reset();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/uber_loss_algorithm.h b/quiche/quic/core/congestion_control/uber_loss_algorithm.h
new file mode 100644
index 0000000..ff79536
--- /dev/null
+++ b/quiche/quic/core/congestion_control/uber_loss_algorithm.h
@@ -0,0 +1,140 @@
+// Copyright 2019 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_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/congestion_control/general_loss_algorithm.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace test {
+
+class QuicSentPacketManagerPeer;
+
+}  // namespace test
+
+struct QUIC_EXPORT_PRIVATE LossDetectionParameters {
+  // See GeneralLossAlgorithm for the meaning of reordering_(shift|threshold).
+  absl::optional<int> reordering_shift;
+  absl::optional<QuicPacketCount> reordering_threshold;
+};
+
+class QUIC_EXPORT_PRIVATE LossDetectionTunerInterface {
+ public:
+  virtual ~LossDetectionTunerInterface() {}
+
+  // Start the tuning by choosing parameters and saving them into |*params|.
+  // Called near the start of a QUIC session, see the .cc file for exactly
+  // where.
+  virtual bool Start(LossDetectionParameters* params) = 0;
+
+  // Finish tuning. The tuner is expected to use the actual loss detection
+  // performance(for its definition of performance) to improve the parameter
+  // selection for future QUIC sessions.
+  // Called when a QUIC session closes.
+  virtual void Finish(const LossDetectionParameters& params) = 0;
+};
+
+// This class comprises multiple loss algorithms, each per packet number space.
+class QUIC_EXPORT_PRIVATE UberLossAlgorithm : public LossDetectionInterface {
+ public:
+  UberLossAlgorithm();
+  UberLossAlgorithm(const UberLossAlgorithm&) = delete;
+  UberLossAlgorithm& operator=(const UberLossAlgorithm&) = delete;
+  ~UberLossAlgorithm() override {}
+
+  void SetFromConfig(const QuicConfig& config,
+                     Perspective perspective) override;
+
+  // Detects lost packets.
+  DetectionStats DetectLosses(const QuicUnackedPacketMap& unacked_packets,
+                              QuicTime time,
+                              const RttStats& rtt_stats,
+                              QuicPacketNumber largest_newly_acked,
+                              const AckedPacketVector& packets_acked,
+                              LostPacketVector* packets_lost) override;
+
+  // Returns the earliest time the early retransmit timer should be active.
+  QuicTime GetLossTimeout() const override;
+
+  // Called to increases time or packet threshold.
+  void SpuriousLossDetected(const QuicUnackedPacketMap& unacked_packets,
+                            const RttStats& rtt_stats,
+                            QuicTime ack_receive_time,
+                            QuicPacketNumber packet_number,
+                            QuicPacketNumber previous_largest_acked) override;
+
+  void SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface> tuner);
+  void OnConfigNegotiated() override;
+  void OnMinRttAvailable() override;
+  void OnUserAgentIdKnown() override;
+  void OnConnectionClosed() override;
+  void OnReorderingDetected() override;
+
+  // Sets reordering_shift for all packet number spaces.
+  void SetReorderingShift(int reordering_shift);
+
+  // Sets reordering_threshold for all packet number spaces.
+  void SetReorderingThreshold(QuicPacketCount reordering_threshold);
+
+  // Enable adaptive reordering threshold of all packet number spaces.
+  void EnableAdaptiveReorderingThreshold();
+
+  // Disable adaptive reordering threshold of all packet number spaces.
+  void DisableAdaptiveReorderingThreshold();
+
+  // Enable adaptive time threshold of all packet number spaces.
+  void EnableAdaptiveTimeThreshold();
+
+  // Get the packet reordering threshold from the APPLICATION_DATA PN space.
+  // Always 3 when adaptive reordering is not enabled.
+  QuicPacketCount GetPacketReorderingThreshold() const;
+
+  // Get the packet reordering shift from the APPLICATION_DATA PN space.
+  int GetPacketReorderingShift() const;
+
+  // Disable packet threshold loss detection for *runt* packets.
+  void DisablePacketThresholdForRuntPackets();
+
+  // Called to reset loss detection of |space|.
+  void ResetLossDetection(PacketNumberSpace space);
+
+  bool use_adaptive_reordering_threshold() const {
+    return general_loss_algorithms_[APPLICATION_DATA]
+        .use_adaptive_reordering_threshold();
+  }
+
+  bool use_adaptive_time_threshold() const {
+    return general_loss_algorithms_[APPLICATION_DATA]
+        .use_adaptive_time_threshold();
+  }
+
+ private:
+  friend class test::QuicSentPacketManagerPeer;
+
+  void MaybeStartTuning();
+
+  // One loss algorithm per packet number space.
+  GeneralLossAlgorithm general_loss_algorithms_[NUM_PACKET_NUMBER_SPACES];
+
+  // Used to tune reordering_shift and reordering_threshold.
+  std::unique_ptr<LossDetectionTunerInterface> tuner_;
+  LossDetectionParameters tuned_parameters_;
+  bool tuner_started_ = false;
+  bool min_rtt_available_ = false;
+  // Whether user agent is known to the session.
+  bool user_agent_known_ = false;
+  // Whether tuning is configured in QuicConfig.
+  bool tuning_configured_ = false;
+  bool reorder_happened_ = false;  // Whether any reordered packet is observed.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
diff --git a/quiche/quic/core/congestion_control/uber_loss_algorithm_test.cc b/quiche/quic/core/congestion_control/uber_loss_algorithm_test.cc
new file mode 100644
index 0000000..1a1bbe5
--- /dev/null
+++ b/quiche/quic/core/congestion_control/uber_loss_algorithm_test.cc
@@ -0,0 +1,361 @@
+// Copyright 2019 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 "quiche/quic/core/congestion_control/uber_loss_algorithm.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_unacked_packet_map_peer.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+class UberLossAlgorithmTest : public QuicTest {
+ protected:
+  UberLossAlgorithmTest() {
+    unacked_packets_ =
+        std::make_unique<QuicUnackedPacketMap>(Perspective::IS_CLIENT);
+    rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                         QuicTime::Delta::Zero(), clock_.Now());
+    EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
+  }
+
+  void SendPacket(uint64_t packet_number, EncryptionLevel encryption_level) {
+    QuicStreamFrame frame;
+    QuicTransportVersion version =
+        CurrentSupportedVersions()[0].transport_version;
+    frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        version, Perspective::IS_CLIENT);
+    if (encryption_level == ENCRYPTION_INITIAL) {
+      if (QuicVersionUsesCryptoFrames(version)) {
+        frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+            version, Perspective::IS_CLIENT);
+      } else {
+        frame.stream_id = QuicUtils::GetCryptoStreamId(version);
+      }
+    }
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+    packet.encryption_level = encryption_level;
+    packet.retransmittable_frames.push_back(QuicFrame(frame));
+    unacked_packets_->AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
+                                    true, true);
+  }
+
+  void AckPackets(const std::vector<uint64_t>& packets_acked) {
+    packets_acked_.clear();
+    for (uint64_t acked : packets_acked) {
+      unacked_packets_->RemoveFromInFlight(QuicPacketNumber(acked));
+      packets_acked_.push_back(AckedPacket(
+          QuicPacketNumber(acked), kMaxOutgoingPacketSize, QuicTime::Zero()));
+    }
+  }
+
+  void VerifyLosses(uint64_t largest_newly_acked,
+                    const AckedPacketVector& packets_acked,
+                    const std::vector<uint64_t>& losses_expected) {
+    return VerifyLosses(largest_newly_acked, packets_acked, losses_expected,
+                        absl::nullopt);
+  }
+
+  void VerifyLosses(
+      uint64_t largest_newly_acked,
+      const AckedPacketVector& packets_acked,
+      const std::vector<uint64_t>& losses_expected,
+      absl::optional<QuicPacketCount> max_sequence_reordering_expected) {
+    LostPacketVector lost_packets;
+    LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses(
+        *unacked_packets_, clock_.Now(), rtt_stats_,
+        QuicPacketNumber(largest_newly_acked), packets_acked, &lost_packets);
+    if (max_sequence_reordering_expected.has_value()) {
+      EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
+                max_sequence_reordering_expected.value());
+    }
+    ASSERT_EQ(losses_expected.size(), lost_packets.size());
+    for (size_t i = 0; i < losses_expected.size(); ++i) {
+      EXPECT_EQ(lost_packets[i].packet_number,
+                QuicPacketNumber(losses_expected[i]));
+    }
+  }
+
+  MockClock clock_;
+  std::unique_ptr<QuicUnackedPacketMap> unacked_packets_;
+  RttStats rtt_stats_;
+  UberLossAlgorithm loss_algorithm_;
+  AckedPacketVector packets_acked_;
+};
+
+TEST_F(UberLossAlgorithmTest, ScenarioA) {
+  // This test mimics a scenario: client sends 1-CHLO, 2-0RTT, 3-0RTT,
+  // timeout and retransmits 4-CHLO. Server acks packet 1 (ack gets lost).
+  // Server receives and buffers packets 2 and 3. Server receives packet 4 and
+  // processes handshake asynchronously, so server acks 4 and cannot process
+  // packets 2 and 3.
+  SendPacket(1, ENCRYPTION_INITIAL);
+  SendPacket(2, ENCRYPTION_ZERO_RTT);
+  SendPacket(3, ENCRYPTION_ZERO_RTT);
+  unacked_packets_->RemoveFromInFlight(QuicPacketNumber(1));
+  SendPacket(4, ENCRYPTION_INITIAL);
+
+  AckPackets({1, 4});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      HANDSHAKE_DATA, QuicPacketNumber(4));
+  // Verify no packet is detected lost.
+  VerifyLosses(4, packets_acked_, std::vector<uint64_t>{}, 0);
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(UberLossAlgorithmTest, ScenarioB) {
+  // This test mimics a scenario: client sends 3-0RTT, 4-0RTT, receives SHLO,
+  // sends 5-1RTT, 6-1RTT.
+  SendPacket(3, ENCRYPTION_ZERO_RTT);
+  SendPacket(4, ENCRYPTION_ZERO_RTT);
+  SendPacket(5, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(6, ENCRYPTION_FORWARD_SECURE);
+
+  AckPackets({4});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(4));
+  // No packet loss by acking 4.
+  VerifyLosses(4, packets_acked_, std::vector<uint64_t>{}, 1);
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+
+  // Acking 6 causes 3 to be detected loss.
+  AckPackets({6});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(6));
+  VerifyLosses(6, packets_acked_, std::vector<uint64_t>{3}, 3);
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+  packets_acked_.clear();
+
+  clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
+  // Verify 5 will be early retransmitted.
+  VerifyLosses(6, packets_acked_, {5}, 1);
+}
+
+TEST_F(UberLossAlgorithmTest, ScenarioC) {
+  // This test mimics a scenario: server sends 1-SHLO, 2-1RTT, 3-1RTT, 4-1RTT
+  // and retransmit 4-SHLO. Client receives and buffers packet 4. Client
+  // receives packet 5 and processes 4.
+  QuicUnackedPacketMapPeer::SetPerspective(unacked_packets_.get(),
+                                           Perspective::IS_SERVER);
+  SendPacket(1, ENCRYPTION_ZERO_RTT);
+  SendPacket(2, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(3, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(4, ENCRYPTION_FORWARD_SECURE);
+  unacked_packets_->RemoveFromInFlight(QuicPacketNumber(1));
+  SendPacket(5, ENCRYPTION_ZERO_RTT);
+
+  AckPackets({4, 5});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(4));
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      HANDSHAKE_DATA, QuicPacketNumber(5));
+  // No packet loss by acking 5.
+  VerifyLosses(5, packets_acked_, std::vector<uint64_t>{}, 2);
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+  packets_acked_.clear();
+
+  clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
+  // Verify 2 and 3 will be early retransmitted.
+  VerifyLosses(5, packets_acked_, std::vector<uint64_t>{2, 3}, 2);
+}
+
+// Regression test for b/133771183.
+TEST_F(UberLossAlgorithmTest, PacketInLimbo) {
+  // This test mimics a scenario: server sends 1-SHLO, 2-1RTT, 3-1RTT,
+  // 4-retransmit SHLO. Client receives and ACKs packets 1, 3 and 4.
+  QuicUnackedPacketMapPeer::SetPerspective(unacked_packets_.get(),
+                                           Perspective::IS_SERVER);
+
+  SendPacket(1, ENCRYPTION_ZERO_RTT);
+  SendPacket(2, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(3, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(4, ENCRYPTION_ZERO_RTT);
+
+  SendPacket(5, ENCRYPTION_FORWARD_SECURE);
+  AckPackets({1, 3, 4});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(3));
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      HANDSHAKE_DATA, QuicPacketNumber(4));
+  // No packet loss detected.
+  VerifyLosses(4, packets_acked_, std::vector<uint64_t>{});
+
+  SendPacket(6, ENCRYPTION_FORWARD_SECURE);
+  AckPackets({5, 6});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(6));
+  // Verify packet 2 is detected lost.
+  VerifyLosses(6, packets_acked_, std::vector<uint64_t>{2});
+}
+
+class TestLossTuner : public LossDetectionTunerInterface {
+ public:
+  TestLossTuner(bool forced_start_result,
+                LossDetectionParameters forced_parameters)
+      : forced_start_result_(forced_start_result),
+        forced_parameters_(std::move(forced_parameters)) {}
+
+  ~TestLossTuner() override = default;
+
+  bool Start(LossDetectionParameters* params) override {
+    start_called_ = true;
+    *params = forced_parameters_;
+    return forced_start_result_;
+  }
+
+  void Finish(const LossDetectionParameters& /*params*/) override {}
+
+  bool start_called() const { return start_called_; }
+
+ private:
+  bool forced_start_result_;
+  LossDetectionParameters forced_parameters_;
+  bool start_called_ = false;
+};
+
+// Verify the parameters are changed if first call SetFromConfig(), then call
+// OnMinRttAvailable().
+TEST_F(UberLossAlgorithmTest, LossDetectionTuning_SetFromConfigFirst) {
+  const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
+  const QuicPacketCount old_reordering_threshold =
+      loss_algorithm_.GetPacketReorderingThreshold();
+
+  loss_algorithm_.OnUserAgentIdKnown();
+
+  // Not owned.
+  TestLossTuner* test_tuner = new TestLossTuner(
+      /*forced_start_result=*/true,
+      LossDetectionParameters{
+          /*reordering_shift=*/old_reordering_shift + 1,
+          /*reordering_threshold=*/old_reordering_threshold * 2});
+  loss_algorithm_.SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
+
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kELDT);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
+
+  // MinRtt was not available when SetFromConfig was called.
+  EXPECT_FALSE(test_tuner->start_called());
+  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_EQ(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+
+  // MinRtt available. Tuner should not start yet because no reordering yet.
+  loss_algorithm_.OnMinRttAvailable();
+  EXPECT_FALSE(test_tuner->start_called());
+
+  // Reordering happened. Tuner should start now.
+  loss_algorithm_.OnReorderingDetected();
+  EXPECT_TRUE(test_tuner->start_called());
+  EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_NE(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+}
+
+// Verify the parameters are changed if first call OnMinRttAvailable(), then
+// call SetFromConfig().
+TEST_F(UberLossAlgorithmTest, LossDetectionTuning_OnMinRttAvailableFirst) {
+  const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
+  const QuicPacketCount old_reordering_threshold =
+      loss_algorithm_.GetPacketReorderingThreshold();
+
+  loss_algorithm_.OnUserAgentIdKnown();
+
+  // Not owned.
+  TestLossTuner* test_tuner = new TestLossTuner(
+      /*forced_start_result=*/true,
+      LossDetectionParameters{
+          /*reordering_shift=*/old_reordering_shift + 1,
+          /*reordering_threshold=*/old_reordering_threshold * 2});
+  loss_algorithm_.SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
+
+  loss_algorithm_.OnMinRttAvailable();
+  EXPECT_FALSE(test_tuner->start_called());
+  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_EQ(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+
+  // Pretend a reodering has happened.
+  loss_algorithm_.OnReorderingDetected();
+  EXPECT_FALSE(test_tuner->start_called());
+
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kELDT);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  // Should start tuning since MinRtt is available.
+  loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
+
+  EXPECT_TRUE(test_tuner->start_called());
+  EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_NE(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+}
+
+// Verify the parameters are not changed if Tuner.Start() returns false.
+TEST_F(UberLossAlgorithmTest, LossDetectionTuning_StartFailed) {
+  const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
+  const QuicPacketCount old_reordering_threshold =
+      loss_algorithm_.GetPacketReorderingThreshold();
+
+  loss_algorithm_.OnUserAgentIdKnown();
+
+  // Not owned.
+  TestLossTuner* test_tuner = new TestLossTuner(
+      /*forced_start_result=*/false,
+      LossDetectionParameters{
+          /*reordering_shift=*/old_reordering_shift + 1,
+          /*reordering_threshold=*/old_reordering_threshold * 2});
+  loss_algorithm_.SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
+
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kELDT);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
+
+  // MinRtt was not available when SetFromConfig was called.
+  EXPECT_FALSE(test_tuner->start_called());
+  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_EQ(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+
+  // Pretend a reodering has happened.
+  loss_algorithm_.OnReorderingDetected();
+  EXPECT_FALSE(test_tuner->start_called());
+
+  // Parameters should not change since test_tuner->Start() returns false.
+  loss_algorithm_.OnMinRttAvailable();
+  EXPECT_TRUE(test_tuner->start_called());
+  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_EQ(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/windowed_filter.h b/quiche/quic/core/congestion_control/windowed_filter.h
new file mode 100644
index 0000000..9326a08
--- /dev/null
+++ b/quiche/quic/core/congestion_control/windowed_filter.h
@@ -0,0 +1,164 @@
+// Copyright (c) 2016 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_CONGESTION_CONTROL_WINDOWED_FILTER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
+
+// Implements Kathleen Nichols' algorithm for tracking the minimum (or maximum)
+// estimate of a stream of samples over some fixed time interval. (E.g.,
+// the minimum RTT over the past five minutes.) The algorithm keeps track of
+// the best, second best, and third best min (or max) estimates, maintaining an
+// invariant that the measurement time of the n'th best >= n-1'th best.
+
+// The algorithm works as follows. On a reset, all three estimates are set to
+// the same sample. The second best estimate is then recorded in the second
+// quarter of the window, and a third best estimate is recorded in the second
+// half of the window, bounding the worst case error when the true min is
+// monotonically increasing (or true max is monotonically decreasing) over the
+// window.
+//
+// A new best sample replaces all three estimates, since the new best is lower
+// (or higher) than everything else in the window and it is the most recent.
+// The window thus effectively gets reset on every new min. The same property
+// holds true for second best and third best estimates. Specifically, when a
+// sample arrives that is better than the second best but not better than the
+// best, it replaces the second and third best estimates but not the best
+// estimate. Similarly, a sample that is better than the third best estimate
+// but not the other estimates replaces only the third best estimate.
+//
+// Finally, when the best expires, it is replaced by the second best, which in
+// turn is replaced by the third best. The newest sample replaces the third
+// best.
+
+#include "quiche/quic/core/quic_time.h"
+
+namespace quic {
+
+// Compares two values and returns true if the first is less than or equal
+// to the second.
+template <class T>
+struct QUIC_EXPORT_PRIVATE MinFilter {
+  bool operator()(const T& lhs, const T& rhs) const { return lhs <= rhs; }
+};
+
+// Compares two values and returns true if the first is greater than or equal
+// to the second.
+template <class T>
+struct QUIC_EXPORT_PRIVATE MaxFilter {
+  bool operator()(const T& lhs, const T& rhs) const { return lhs >= rhs; }
+};
+
+// Use the following to construct a windowed filter object of type T.
+// For example, a min filter using QuicTime as the time type:
+//   WindowedFilter<T, MinFilter<T>, QuicTime, QuicTime::Delta> ObjectName;
+// A max filter using 64-bit integers as the time type:
+//   WindowedFilter<T, MaxFilter<T>, uint64_t, int64_t> ObjectName;
+// Specifically, this template takes four arguments:
+// 1. T -- type of the measurement that is being filtered.
+// 2. Compare -- MinFilter<T> or MaxFilter<T>, depending on the type of filter
+//    desired.
+// 3. TimeT -- the type used to represent timestamps.
+// 4. TimeDeltaT -- the type used to represent continuous time intervals between
+//    two timestamps.  Has to be the type of (a - b) if both |a| and |b| are
+//    of type TimeT.
+template <class T, class Compare, typename TimeT, typename TimeDeltaT>
+class QUIC_EXPORT_PRIVATE WindowedFilter {
+ public:
+  // |window_length| is the period after which a best estimate expires.
+  // |zero_value| is used as the uninitialized value for objects of T.
+  // Importantly, |zero_value| should be an invalid value for a true sample.
+  WindowedFilter(TimeDeltaT window_length, T zero_value, TimeT zero_time)
+      : window_length_(window_length),
+        zero_value_(zero_value),
+        zero_time_(zero_time),
+        estimates_{Sample(zero_value_, zero_time),
+                   Sample(zero_value_, zero_time),
+                   Sample(zero_value_, zero_time)} {}
+
+  // Changes the window length.  Does not update any current samples.
+  void SetWindowLength(TimeDeltaT window_length) {
+    window_length_ = window_length;
+  }
+
+  // Updates best estimates with |sample|, and expires and updates best
+  // estimates as necessary.
+  void Update(T new_sample, TimeT new_time) {
+    // Reset all estimates if they have not yet been initialized, if new sample
+    // is a new best, or if the newest recorded estimate is too old.
+    if (estimates_[0].sample == zero_value_ ||
+        Compare()(new_sample, estimates_[0].sample) ||
+        new_time - estimates_[2].time > window_length_) {
+      Reset(new_sample, new_time);
+      return;
+    }
+
+    if (Compare()(new_sample, estimates_[1].sample)) {
+      estimates_[1] = Sample(new_sample, new_time);
+      estimates_[2] = estimates_[1];
+    } else if (Compare()(new_sample, estimates_[2].sample)) {
+      estimates_[2] = Sample(new_sample, new_time);
+    }
+
+    // Expire and update estimates as necessary.
+    if (new_time - estimates_[0].time > window_length_) {
+      // The best estimate hasn't been updated for an entire window, so promote
+      // second and third best estimates.
+      estimates_[0] = estimates_[1];
+      estimates_[1] = estimates_[2];
+      estimates_[2] = Sample(new_sample, new_time);
+      // Need to iterate one more time. Check if the new best estimate is
+      // outside the window as well, since it may also have been recorded a
+      // long time ago. Don't need to iterate once more since we cover that
+      // case at the beginning of the method.
+      if (new_time - estimates_[0].time > window_length_) {
+        estimates_[0] = estimates_[1];
+        estimates_[1] = estimates_[2];
+      }
+      return;
+    }
+    if (estimates_[1].sample == estimates_[0].sample &&
+        new_time - estimates_[1].time > window_length_ >> 2) {
+      // A quarter of the window has passed without a better sample, so the
+      // second-best estimate is taken from the second quarter of the window.
+      estimates_[2] = estimates_[1] = Sample(new_sample, new_time);
+      return;
+    }
+
+    if (estimates_[2].sample == estimates_[1].sample &&
+        new_time - estimates_[2].time > window_length_ >> 1) {
+      // We've passed a half of the window without a better estimate, so take
+      // a third-best estimate from the second half of the window.
+      estimates_[2] = Sample(new_sample, new_time);
+    }
+  }
+
+  // Resets all estimates to new sample.
+  void Reset(T new_sample, TimeT new_time) {
+    estimates_[0] = estimates_[1] = estimates_[2] =
+        Sample(new_sample, new_time);
+  }
+
+  void Clear() { Reset(zero_value_, zero_time_); }
+
+  T GetBest() const { return estimates_[0].sample; }
+  T GetSecondBest() const { return estimates_[1].sample; }
+  T GetThirdBest() const { return estimates_[2].sample; }
+
+ private:
+  struct QUIC_EXPORT_PRIVATE Sample {
+    T sample;
+    TimeT time;
+    Sample(T init_sample, TimeT init_time)
+        : sample(init_sample), time(init_time) {}
+  };
+
+  TimeDeltaT window_length_;  // Time length of window.
+  T zero_value_;              // Uninitialized value of T.
+  TimeT zero_time_;           // Uninitialized value of TimeT.
+  Sample estimates_[3];       // Best estimate is element 0.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
diff --git a/quiche/quic/core/congestion_control/windowed_filter_test.cc b/quiche/quic/core/congestion_control/windowed_filter_test.cc
new file mode 100644
index 0000000..f2edad0
--- /dev/null
+++ b/quiche/quic/core/congestion_control/windowed_filter_test.cc
@@ -0,0 +1,388 @@
+// Copyright (c) 2016 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 "quiche/quic/core/congestion_control/windowed_filter.h"
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class WindowedFilterTest : public QuicTest {
+ public:
+  // Set the window to 99ms, so 25ms is more than a quarter rtt.
+  WindowedFilterTest()
+      : windowed_min_rtt_(QuicTime::Delta::FromMilliseconds(99),
+                          QuicTime::Delta::Zero(),
+                          QuicTime::Zero()),
+        windowed_max_bw_(QuicTime::Delta::FromMilliseconds(99),
+                         QuicBandwidth::Zero(),
+                         QuicTime::Zero()) {}
+
+  // Sets up windowed_min_rtt_ to have the following values:
+  // Best = 20ms, recorded at 25ms
+  // Second best = 40ms, recorded at 75ms
+  // Third best = 50ms, recorded at 100ms
+  void InitializeMinFilter() {
+    QuicTime now = QuicTime::Zero();
+    QuicTime::Delta rtt_sample = QuicTime::Delta::FromMilliseconds(10);
+    for (int i = 0; i < 5; ++i) {
+      windowed_min_rtt_.Update(rtt_sample, now);
+      QUIC_VLOG(1) << "i: " << i << " sample: " << rtt_sample.ToMilliseconds()
+                   << " mins: "
+                   << " " << windowed_min_rtt_.GetBest().ToMilliseconds() << " "
+                   << windowed_min_rtt_.GetSecondBest().ToMilliseconds() << " "
+                   << windowed_min_rtt_.GetThirdBest().ToMilliseconds();
+      now = now + QuicTime::Delta::FromMilliseconds(25);
+      rtt_sample = rtt_sample + QuicTime::Delta::FromMilliseconds(10);
+    }
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
+              windowed_min_rtt_.GetBest());
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
+              windowed_min_rtt_.GetSecondBest());
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
+              windowed_min_rtt_.GetThirdBest());
+  }
+
+  // Sets up windowed_max_bw_ to have the following values:
+  // Best = 900 bps, recorded at 25ms
+  // Second best = 700 bps, recorded at 75ms
+  // Third best = 600 bps, recorded at 100ms
+  void InitializeMaxFilter() {
+    QuicTime now = QuicTime::Zero();
+    QuicBandwidth bw_sample = QuicBandwidth::FromBitsPerSecond(1000);
+    for (int i = 0; i < 5; ++i) {
+      windowed_max_bw_.Update(bw_sample, now);
+      QUIC_VLOG(1) << "i: " << i << " sample: " << bw_sample.ToBitsPerSecond()
+                   << " maxs: "
+                   << " " << windowed_max_bw_.GetBest().ToBitsPerSecond() << " "
+                   << windowed_max_bw_.GetSecondBest().ToBitsPerSecond() << " "
+                   << windowed_max_bw_.GetThirdBest().ToBitsPerSecond();
+      now = now + QuicTime::Delta::FromMilliseconds(25);
+      bw_sample = bw_sample - QuicBandwidth::FromBitsPerSecond(100);
+    }
+    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900),
+              windowed_max_bw_.GetBest());
+    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
+              windowed_max_bw_.GetSecondBest());
+    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(600),
+              windowed_max_bw_.GetThirdBest());
+  }
+
+ protected:
+  WindowedFilter<QuicTime::Delta,
+                 MinFilter<QuicTime::Delta>,
+                 QuicTime,
+                 QuicTime::Delta>
+      windowed_min_rtt_;
+  WindowedFilter<QuicBandwidth,
+                 MaxFilter<QuicBandwidth>,
+                 QuicTime,
+                 QuicTime::Delta>
+      windowed_max_bw_;
+};
+
+namespace {
+// Test helper function: updates the filter with a lot of small values in order
+// to ensure that it is not susceptible to noise.
+void UpdateWithIrrelevantSamples(
+    WindowedFilter<uint64_t, MaxFilter<uint64_t>, uint64_t, uint64_t>* filter,
+    uint64_t max_value,
+    uint64_t time) {
+  for (uint64_t i = 0; i < 1000; i++) {
+    filter->Update(i % max_value, time);
+  }
+}
+}  // namespace
+
+TEST_F(WindowedFilterTest, UninitializedEstimates) {
+  EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetBest());
+  EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetBest());
+  EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetThirdBest());
+}
+
+TEST_F(WindowedFilterTest, MonotonicallyIncreasingMin) {
+  QuicTime now = QuicTime::Zero();
+  QuicTime::Delta rtt_sample = QuicTime::Delta::FromMilliseconds(10);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), windowed_min_rtt_.GetBest());
+
+  // Gradually increase the rtt samples and ensure the windowed min rtt starts
+  // rising.
+  for (int i = 0; i < 6; ++i) {
+    now = now + QuicTime::Delta::FromMilliseconds(25);
+    rtt_sample = rtt_sample + QuicTime::Delta::FromMilliseconds(10);
+    windowed_min_rtt_.Update(rtt_sample, now);
+    QUIC_VLOG(1) << "i: " << i << " sample: " << rtt_sample.ToMilliseconds()
+                 << " mins: "
+                 << " " << windowed_min_rtt_.GetBest().ToMilliseconds() << " "
+                 << windowed_min_rtt_.GetSecondBest().ToMilliseconds() << " "
+                 << windowed_min_rtt_.GetThirdBest().ToMilliseconds();
+    if (i < 3) {
+      EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+                windowed_min_rtt_.GetBest());
+    } else if (i == 3) {
+      EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
+                windowed_min_rtt_.GetBest());
+    } else if (i < 6) {
+      EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
+                windowed_min_rtt_.GetBest());
+    }
+  }
+}
+
+TEST_F(WindowedFilterTest, MonotonicallyDecreasingMax) {
+  QuicTime now = QuicTime::Zero();
+  QuicBandwidth bw_sample = QuicBandwidth::FromBitsPerSecond(1000);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1000), windowed_max_bw_.GetBest());
+
+  // Gradually decrease the bw samples and ensure the windowed max bw starts
+  // decreasing.
+  for (int i = 0; i < 6; ++i) {
+    now = now + QuicTime::Delta::FromMilliseconds(25);
+    bw_sample = bw_sample - QuicBandwidth::FromBitsPerSecond(100);
+    windowed_max_bw_.Update(bw_sample, now);
+    QUIC_VLOG(1) << "i: " << i << " sample: " << bw_sample.ToBitsPerSecond()
+                 << " maxs: "
+                 << " " << windowed_max_bw_.GetBest().ToBitsPerSecond() << " "
+                 << windowed_max_bw_.GetSecondBest().ToBitsPerSecond() << " "
+                 << windowed_max_bw_.GetThirdBest().ToBitsPerSecond();
+    if (i < 3) {
+      EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1000),
+                windowed_max_bw_.GetBest());
+    } else if (i == 3) {
+      EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900),
+                windowed_max_bw_.GetBest());
+    } else if (i < 6) {
+      EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
+                windowed_max_bw_.GetBest());
+    }
+  }
+}
+
+TEST_F(WindowedFilterTest, SampleChangesThirdBestMin) {
+  InitializeMinFilter();
+  // RTT sample lower than the third-choice min-rtt sets that, but nothing else.
+  QuicTime::Delta rtt_sample =
+      windowed_min_rtt_.GetThirdBest() - QuicTime::Delta::FromMilliseconds(5);
+  // This assert is necessary to avoid triggering -Wstrict-overflow
+  // See crbug/616957
+  ASSERT_GT(windowed_min_rtt_.GetThirdBest(),
+            QuicTime::Delta::FromMilliseconds(5));
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
+            windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesThirdBestMax) {
+  InitializeMaxFilter();
+  // BW sample higher than the third-choice max sets that, but nothing else.
+  QuicBandwidth bw_sample =
+      windowed_max_bw_.GetThirdBest() + QuicBandwidth::FromBitsPerSecond(50);
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
+            windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900), windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesSecondBestMin) {
+  InitializeMinFilter();
+  // RTT sample lower than the second-choice min sets that and also
+  // the third-choice min.
+  QuicTime::Delta rtt_sample =
+      windowed_min_rtt_.GetSecondBest() - QuicTime::Delta::FromMilliseconds(5);
+  // This assert is necessary to avoid triggering -Wstrict-overflow
+  // See crbug/616957
+  ASSERT_GT(windowed_min_rtt_.GetSecondBest(),
+            QuicTime::Delta::FromMilliseconds(5));
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesSecondBestMax) {
+  InitializeMaxFilter();
+  // BW sample higher than the second-choice max sets that and also
+  // the third-choice max.
+  QuicBandwidth bw_sample =
+      windowed_max_bw_.GetSecondBest() + QuicBandwidth::FromBitsPerSecond(50);
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900), windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesAllMins) {
+  InitializeMinFilter();
+  // RTT sample lower than the first-choice min-rtt sets that and also
+  // the second and third-choice mins.
+  QuicTime::Delta rtt_sample =
+      windowed_min_rtt_.GetBest() - QuicTime::Delta::FromMilliseconds(5);
+  // This assert is necessary to avoid triggering -Wstrict-overflow
+  // See crbug/616957
+  ASSERT_GT(windowed_min_rtt_.GetBest(), QuicTime::Delta::FromMilliseconds(5));
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesAllMaxs) {
+  InitializeMaxFilter();
+  // BW sample higher than the first-choice max sets that and also
+  // the second and third-choice maxs.
+  QuicBandwidth bw_sample =
+      windowed_max_bw_.GetBest() + QuicBandwidth::FromBitsPerSecond(50);
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireBestMin) {
+  InitializeMinFilter();
+  QuicTime::Delta old_third_best = windowed_min_rtt_.GetThirdBest();
+  QuicTime::Delta old_second_best = windowed_min_rtt_.GetSecondBest();
+  QuicTime::Delta rtt_sample =
+      old_third_best + QuicTime::Delta::FromMilliseconds(5);
+  // Best min sample was recorded at 25ms, so expiry time is 124ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(125);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(old_third_best, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(old_second_best, windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireBestMax) {
+  InitializeMaxFilter();
+  QuicBandwidth old_third_best = windowed_max_bw_.GetThirdBest();
+  QuicBandwidth old_second_best = windowed_max_bw_.GetSecondBest();
+  QuicBandwidth bw_sample =
+      old_third_best - QuicBandwidth::FromBitsPerSecond(50);
+  // Best max sample was recorded at 25ms, so expiry time is 124ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(125);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(old_third_best, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(old_second_best, windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireSecondBestMin) {
+  InitializeMinFilter();
+  QuicTime::Delta old_third_best = windowed_min_rtt_.GetThirdBest();
+  QuicTime::Delta rtt_sample =
+      old_third_best + QuicTime::Delta::FromMilliseconds(5);
+  // Second best min sample was recorded at 75ms, so expiry time is 174ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(175);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(old_third_best, windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireSecondBestMax) {
+  InitializeMaxFilter();
+  QuicBandwidth old_third_best = windowed_max_bw_.GetThirdBest();
+  QuicBandwidth bw_sample =
+      old_third_best - QuicBandwidth::FromBitsPerSecond(50);
+  // Second best max sample was recorded at 75ms, so expiry time is 174ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(175);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(old_third_best, windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireAllMins) {
+  InitializeMinFilter();
+  QuicTime::Delta rtt_sample =
+      windowed_min_rtt_.GetThirdBest() + QuicTime::Delta::FromMilliseconds(5);
+  // This assert is necessary to avoid triggering -Wstrict-overflow
+  // See crbug/616957
+  ASSERT_LT(windowed_min_rtt_.GetThirdBest(),
+            QuicTime::Delta::Infinite() - QuicTime::Delta::FromMilliseconds(5));
+  // Third best min sample was recorded at 100ms, so expiry time is 199ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(200);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireAllMaxs) {
+  InitializeMaxFilter();
+  QuicBandwidth bw_sample =
+      windowed_max_bw_.GetThirdBest() - QuicBandwidth::FromBitsPerSecond(50);
+  // Third best max sample was recorded at 100ms, so expiry time is 199ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(200);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetBest());
+}
+
+// Test the windowed filter where the time used is an exact counter instead of a
+// timestamp.  This is useful if, for example, the time is measured in round
+// trips.
+TEST_F(WindowedFilterTest, ExpireCounterBasedMax) {
+  // Create a window which starts at t = 0 and expires after two cycles.
+  WindowedFilter<uint64_t, MaxFilter<uint64_t>, uint64_t, uint64_t> max_filter(
+      2, 0, 0);
+
+  const uint64_t kBest = 50000;
+  // Insert 50000 at t = 1.
+  max_filter.Update(50000, 1);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+  UpdateWithIrrelevantSamples(&max_filter, 20, 1);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+
+  // Insert 40000 at t = 2.  Nothing is expected to expire.
+  max_filter.Update(40000, 2);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+  UpdateWithIrrelevantSamples(&max_filter, 20, 2);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+
+  // Insert 30000 at t = 3.  Nothing is expected to expire yet.
+  max_filter.Update(30000, 3);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+  UpdateWithIrrelevantSamples(&max_filter, 20, 3);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+  QUIC_VLOG(0) << max_filter.GetSecondBest();
+  QUIC_VLOG(0) << max_filter.GetThirdBest();
+
+  // Insert 20000 at t = 4.  50000 at t = 1 expires, so 40000 becomes the new
+  // maximum.
+  const uint64_t kNewBest = 40000;
+  max_filter.Update(20000, 4);
+  EXPECT_EQ(kNewBest, max_filter.GetBest());
+  UpdateWithIrrelevantSamples(&max_filter, 20, 4);
+  EXPECT_EQ(kNewBest, max_filter.GetBest());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aead_base_decrypter.cc b/quiche/quic/core/crypto/aead_base_decrypter.cc
new file mode 100644
index 0000000..fecf67e
--- /dev/null
+++ b/quiche/quic/core/crypto/aead_base_decrypter.cc
@@ -0,0 +1,214 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/aead_base_decrypter.h"
+
+#include <cstdint>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/crypto.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Clear OpenSSL error stack.
+void ClearOpenSslErrors() {
+  while (ERR_get_error()) {
+  }
+}
+
+// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
+// stack.
+void DLogOpenSslErrors() {
+#ifdef NDEBUG
+  ClearOpenSslErrors();
+#else
+  while (uint32_t error = ERR_get_error()) {
+    char buf[120];
+    ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf));
+    QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
+  }
+#endif
+}
+
+const EVP_AEAD* InitAndCall(const EVP_AEAD* (*aead_getter)()) {
+  // Ensure BoringSSL is initialized before calling |aead_getter|. In Chromium,
+  // the static initializer is disabled.
+  CRYPTO_library_init();
+  return aead_getter();
+}
+
+}  // namespace
+
+AeadBaseDecrypter::AeadBaseDecrypter(const EVP_AEAD* (*aead_getter)(),
+                                     size_t key_size,
+                                     size_t auth_tag_size,
+                                     size_t nonce_size,
+                                     bool use_ietf_nonce_construction)
+    : aead_alg_(InitAndCall(aead_getter)),
+      key_size_(key_size),
+      auth_tag_size_(auth_tag_size),
+      nonce_size_(nonce_size),
+      use_ietf_nonce_construction_(use_ietf_nonce_construction),
+      have_preliminary_key_(false) {
+  QUICHE_DCHECK_GT(256u, key_size);
+  QUICHE_DCHECK_GT(256u, auth_tag_size);
+  QUICHE_DCHECK_GT(256u, nonce_size);
+  QUICHE_DCHECK_LE(key_size_, sizeof(key_));
+  QUICHE_DCHECK_LE(nonce_size_, sizeof(iv_));
+}
+
+AeadBaseDecrypter::~AeadBaseDecrypter() {}
+
+bool AeadBaseDecrypter::SetKey(absl::string_view key) {
+  QUICHE_DCHECK_EQ(key.size(), key_size_);
+  if (key.size() != key_size_) {
+    return false;
+  }
+  memcpy(key_, key.data(), key.size());
+
+  EVP_AEAD_CTX_cleanup(ctx_.get());
+  if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
+                         nullptr)) {
+    DLogOpenSslErrors();
+    return false;
+  }
+
+  return true;
+}
+
+bool AeadBaseDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
+  if (use_ietf_nonce_construction_) {
+    QUIC_BUG(quic_bug_10709_1)
+        << "Attempted to set nonce prefix on IETF QUIC crypter";
+    return false;
+  }
+  QUICHE_DCHECK_EQ(nonce_prefix.size(), nonce_size_ - sizeof(QuicPacketNumber));
+  if (nonce_prefix.size() != nonce_size_ - sizeof(QuicPacketNumber)) {
+    return false;
+  }
+  memcpy(iv_, nonce_prefix.data(), nonce_prefix.size());
+  return true;
+}
+
+bool AeadBaseDecrypter::SetIV(absl::string_view iv) {
+  if (!use_ietf_nonce_construction_) {
+    QUIC_BUG(quic_bug_10709_2) << "Attempted to set IV on Google QUIC crypter";
+    return false;
+  }
+  QUICHE_DCHECK_EQ(iv.size(), nonce_size_);
+  if (iv.size() != nonce_size_) {
+    return false;
+  }
+  memcpy(iv_, iv.data(), iv.size());
+  return true;
+}
+
+bool AeadBaseDecrypter::SetPreliminaryKey(absl::string_view key) {
+  QUICHE_DCHECK(!have_preliminary_key_);
+  SetKey(key);
+  have_preliminary_key_ = true;
+
+  return true;
+}
+
+bool AeadBaseDecrypter::SetDiversificationNonce(
+    const DiversificationNonce& nonce) {
+  if (!have_preliminary_key_) {
+    return true;
+  }
+
+  std::string key, nonce_prefix;
+  size_t prefix_size = nonce_size_;
+  if (!use_ietf_nonce_construction_) {
+    prefix_size -= sizeof(QuicPacketNumber);
+  }
+  DiversifyPreliminaryKey(
+      absl::string_view(reinterpret_cast<const char*>(key_), key_size_),
+      absl::string_view(reinterpret_cast<const char*>(iv_), prefix_size), nonce,
+      key_size_, prefix_size, &key, &nonce_prefix);
+
+  if (!SetKey(key) ||
+      (!use_ietf_nonce_construction_ && !SetNoncePrefix(nonce_prefix)) ||
+      (use_ietf_nonce_construction_ && !SetIV(nonce_prefix))) {
+    QUICHE_DCHECK(false);
+    return false;
+  }
+
+  have_preliminary_key_ = false;
+  return true;
+}
+
+bool AeadBaseDecrypter::DecryptPacket(uint64_t packet_number,
+                                      absl::string_view associated_data,
+                                      absl::string_view ciphertext,
+                                      char* output,
+                                      size_t* output_length,
+                                      size_t max_output_length) {
+  if (ciphertext.length() < auth_tag_size_) {
+    return false;
+  }
+
+  if (have_preliminary_key_) {
+    QUIC_BUG(quic_bug_10709_3)
+        << "Unable to decrypt while key diversification is pending";
+    return false;
+  }
+
+  uint8_t nonce[kMaxNonceSize];
+  memcpy(nonce, iv_, nonce_size_);
+  size_t prefix_len = nonce_size_ - sizeof(packet_number);
+  if (use_ietf_nonce_construction_) {
+    for (size_t i = 0; i < sizeof(packet_number); ++i) {
+      nonce[prefix_len + i] ^=
+          (packet_number >> ((sizeof(packet_number) - i - 1) * 8)) & 0xff;
+    }
+  } else {
+    memcpy(nonce + prefix_len, &packet_number, sizeof(packet_number));
+  }
+  if (!EVP_AEAD_CTX_open(
+          ctx_.get(), reinterpret_cast<uint8_t*>(output), output_length,
+          max_output_length, reinterpret_cast<const uint8_t*>(nonce),
+          nonce_size_, reinterpret_cast<const uint8_t*>(ciphertext.data()),
+          ciphertext.size(),
+          reinterpret_cast<const uint8_t*>(associated_data.data()),
+          associated_data.size())) {
+    // Because QuicFramer does trial decryption, decryption errors are expected
+    // when encryption level changes. So we don't log decryption errors.
+    ClearOpenSslErrors();
+    return false;
+  }
+  return true;
+}
+
+size_t AeadBaseDecrypter::GetKeySize() const {
+  return key_size_;
+}
+
+size_t AeadBaseDecrypter::GetNoncePrefixSize() const {
+  return nonce_size_ - sizeof(QuicPacketNumber);
+}
+
+size_t AeadBaseDecrypter::GetIVSize() const {
+  return nonce_size_;
+}
+
+absl::string_view AeadBaseDecrypter::GetKey() const {
+  return absl::string_view(reinterpret_cast<const char*>(key_), key_size_);
+}
+
+absl::string_view AeadBaseDecrypter::GetNoncePrefix() const {
+  return absl::string_view(reinterpret_cast<const char*>(iv_),
+                           nonce_size_ - sizeof(QuicPacketNumber));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aead_base_decrypter.h b/quiche/quic/core/crypto/aead_base_decrypter.h
new file mode 100644
index 0000000..82a3e1c
--- /dev/null
+++ b/quiche/quic/core/crypto/aead_base_decrypter.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2013 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_CRYPTO_AEAD_BASE_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// AeadBaseDecrypter is the base class of AEAD QuicDecrypter subclasses.
+class QUIC_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
+ public:
+  // This takes the function pointer rather than the EVP_AEAD itself so
+  // subclasses do not need to call CRYPTO_library_init.
+  AeadBaseDecrypter(const EVP_AEAD* (*aead_getter)(),
+                    size_t key_size,
+                    size_t auth_tag_size,
+                    size_t nonce_size,
+                    bool use_ietf_nonce_construction);
+  AeadBaseDecrypter(const AeadBaseDecrypter&) = delete;
+  AeadBaseDecrypter& operator=(const AeadBaseDecrypter&) = delete;
+  ~AeadBaseDecrypter() override;
+
+  // QuicDecrypter implementation
+  bool SetKey(absl::string_view key) override;
+  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
+  bool SetIV(absl::string_view iv) override;
+  bool SetPreliminaryKey(absl::string_view key) override;
+  bool SetDiversificationNonce(const DiversificationNonce& nonce) override;
+  bool DecryptPacket(uint64_t packet_number,
+                     absl::string_view associated_data,
+                     absl::string_view ciphertext,
+                     char* output,
+                     size_t* output_length,
+                     size_t max_output_length) override;
+  size_t GetKeySize() const override;
+  size_t GetNoncePrefixSize() const override;
+  size_t GetIVSize() const override;
+  absl::string_view GetKey() const override;
+  absl::string_view GetNoncePrefix() const override;
+
+ protected:
+  // Make these constants available to the subclasses so that the subclasses
+  // can assert at compile time their key_size_ and nonce_size_ do not
+  // exceed the maximum.
+  static const size_t kMaxKeySize = 32;
+  static const size_t kMaxNonceSize = 12;
+
+ private:
+  const EVP_AEAD* const aead_alg_;
+  const size_t key_size_;
+  const size_t auth_tag_size_;
+  const size_t nonce_size_;
+  const bool use_ietf_nonce_construction_;
+  bool have_preliminary_key_;
+
+  // The key.
+  unsigned char key_[kMaxKeySize];
+  // The IV used to construct the nonce.
+  unsigned char iv_[kMaxNonceSize];
+
+  bssl::ScopedEVP_AEAD_CTX ctx_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aead_base_encrypter.cc b/quiche/quic/core/crypto/aead_base_encrypter.cc
new file mode 100644
index 0000000..e93f270
--- /dev/null
+++ b/quiche/quic/core/crypto/aead_base_encrypter.cc
@@ -0,0 +1,188 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/aead_base_encrypter.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/crypto.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
+// stack.
+void DLogOpenSslErrors() {
+#ifdef NDEBUG
+  while (ERR_get_error()) {
+  }
+#else
+  while (unsigned long error = ERR_get_error()) {
+    char buf[120];
+    ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf));
+    QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
+  }
+#endif
+}
+
+const EVP_AEAD* InitAndCall(const EVP_AEAD* (*aead_getter)()) {
+  // Ensure BoringSSL is initialized before calling |aead_getter|. In Chromium,
+  // the static initializer is disabled.
+  CRYPTO_library_init();
+  return aead_getter();
+}
+
+}  // namespace
+
+AeadBaseEncrypter::AeadBaseEncrypter(const EVP_AEAD* (*aead_getter)(),
+                                     size_t key_size,
+                                     size_t auth_tag_size,
+                                     size_t nonce_size,
+                                     bool use_ietf_nonce_construction)
+    : aead_alg_(InitAndCall(aead_getter)),
+      key_size_(key_size),
+      auth_tag_size_(auth_tag_size),
+      nonce_size_(nonce_size),
+      use_ietf_nonce_construction_(use_ietf_nonce_construction) {
+  QUICHE_DCHECK_LE(key_size_, sizeof(key_));
+  QUICHE_DCHECK_LE(nonce_size_, sizeof(iv_));
+  QUICHE_DCHECK_GE(kMaxNonceSize, nonce_size_);
+}
+
+AeadBaseEncrypter::~AeadBaseEncrypter() {}
+
+bool AeadBaseEncrypter::SetKey(absl::string_view key) {
+  QUICHE_DCHECK_EQ(key.size(), key_size_);
+  if (key.size() != key_size_) {
+    return false;
+  }
+  memcpy(key_, key.data(), key.size());
+
+  EVP_AEAD_CTX_cleanup(ctx_.get());
+
+  if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
+                         nullptr)) {
+    DLogOpenSslErrors();
+    return false;
+  }
+
+  return true;
+}
+
+bool AeadBaseEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
+  if (use_ietf_nonce_construction_) {
+    QUIC_BUG(quic_bug_10634_1)
+        << "Attempted to set nonce prefix on IETF QUIC crypter";
+    return false;
+  }
+  QUICHE_DCHECK_EQ(nonce_prefix.size(), nonce_size_ - sizeof(QuicPacketNumber));
+  if (nonce_prefix.size() != nonce_size_ - sizeof(QuicPacketNumber)) {
+    return false;
+  }
+  memcpy(iv_, nonce_prefix.data(), nonce_prefix.size());
+  return true;
+}
+
+bool AeadBaseEncrypter::SetIV(absl::string_view iv) {
+  if (!use_ietf_nonce_construction_) {
+    QUIC_BUG(quic_bug_10634_2) << "Attempted to set IV on Google QUIC crypter";
+    return false;
+  }
+  QUICHE_DCHECK_EQ(iv.size(), nonce_size_);
+  if (iv.size() != nonce_size_) {
+    return false;
+  }
+  memcpy(iv_, iv.data(), iv.size());
+  return true;
+}
+
+bool AeadBaseEncrypter::Encrypt(absl::string_view nonce,
+                                absl::string_view associated_data,
+                                absl::string_view plaintext,
+                                unsigned char* output) {
+  QUICHE_DCHECK_EQ(nonce.size(), nonce_size_);
+
+  size_t ciphertext_len;
+  if (!EVP_AEAD_CTX_seal(
+          ctx_.get(), output, &ciphertext_len,
+          plaintext.size() + auth_tag_size_,
+          reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
+          reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(),
+          reinterpret_cast<const uint8_t*>(associated_data.data()),
+          associated_data.size())) {
+    DLogOpenSslErrors();
+    return false;
+  }
+
+  return true;
+}
+
+bool AeadBaseEncrypter::EncryptPacket(uint64_t packet_number,
+                                      absl::string_view associated_data,
+                                      absl::string_view plaintext,
+                                      char* output,
+                                      size_t* output_length,
+                                      size_t max_output_length) {
+  size_t ciphertext_size = GetCiphertextSize(plaintext.length());
+  if (max_output_length < ciphertext_size) {
+    return false;
+  }
+  // TODO(ianswett): Introduce a check to ensure that we don't encrypt with the
+  // same packet number twice.
+  alignas(4) char nonce_buffer[kMaxNonceSize];
+  memcpy(nonce_buffer, iv_, nonce_size_);
+  size_t prefix_len = nonce_size_ - sizeof(packet_number);
+  if (use_ietf_nonce_construction_) {
+    for (size_t i = 0; i < sizeof(packet_number); ++i) {
+      nonce_buffer[prefix_len + i] ^=
+          (packet_number >> ((sizeof(packet_number) - i - 1) * 8)) & 0xff;
+    }
+  } else {
+    memcpy(nonce_buffer + prefix_len, &packet_number, sizeof(packet_number));
+  }
+
+  if (!Encrypt(absl::string_view(nonce_buffer, nonce_size_), associated_data,
+               plaintext, reinterpret_cast<unsigned char*>(output))) {
+    return false;
+  }
+  *output_length = ciphertext_size;
+  return true;
+}
+
+size_t AeadBaseEncrypter::GetKeySize() const {
+  return key_size_;
+}
+
+size_t AeadBaseEncrypter::GetNoncePrefixSize() const {
+  return nonce_size_ - sizeof(QuicPacketNumber);
+}
+
+size_t AeadBaseEncrypter::GetIVSize() const {
+  return nonce_size_;
+}
+
+size_t AeadBaseEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
+  return ciphertext_size - std::min(ciphertext_size, auth_tag_size_);
+}
+
+size_t AeadBaseEncrypter::GetCiphertextSize(size_t plaintext_size) const {
+  return plaintext_size + auth_tag_size_;
+}
+
+absl::string_view AeadBaseEncrypter::GetKey() const {
+  return absl::string_view(reinterpret_cast<const char*>(key_), key_size_);
+}
+
+absl::string_view AeadBaseEncrypter::GetNoncePrefix() const {
+  return absl::string_view(reinterpret_cast<const char*>(iv_),
+                           GetNoncePrefixSize());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aead_base_encrypter.h b/quiche/quic/core/crypto/aead_base_encrypter.h
new file mode 100644
index 0000000..c170a87
--- /dev/null
+++ b/quiche/quic/core/crypto/aead_base_encrypter.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2013 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_CRYPTO_AEAD_BASE_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// AeadBaseEncrypter is the base class of AEAD QuicEncrypter subclasses.
+class QUIC_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter {
+ public:
+  // This takes the function pointer rather than the EVP_AEAD itself so
+  // subclasses do not need to call CRYPTO_library_init.
+  AeadBaseEncrypter(const EVP_AEAD* (*aead_getter)(),
+                    size_t key_size,
+                    size_t auth_tag_size,
+                    size_t nonce_size,
+                    bool use_ietf_nonce_construction);
+  AeadBaseEncrypter(const AeadBaseEncrypter&) = delete;
+  AeadBaseEncrypter& operator=(const AeadBaseEncrypter&) = delete;
+  ~AeadBaseEncrypter() override;
+
+  // QuicEncrypter implementation
+  bool SetKey(absl::string_view key) override;
+  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
+  bool SetIV(absl::string_view iv) override;
+  bool EncryptPacket(uint64_t packet_number,
+                     absl::string_view associated_data,
+                     absl::string_view plaintext,
+                     char* output,
+                     size_t* output_length,
+                     size_t max_output_length) override;
+  size_t GetKeySize() const override;
+  size_t GetNoncePrefixSize() const override;
+  size_t GetIVSize() const override;
+  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
+  size_t GetCiphertextSize(size_t plaintext_size) const override;
+  absl::string_view GetKey() const override;
+  absl::string_view GetNoncePrefix() const override;
+
+  // Necessary so unit tests can explicitly specify a nonce, instead of an IV
+  // (or nonce prefix) and packet number.
+  bool Encrypt(absl::string_view nonce,
+               absl::string_view associated_data,
+               absl::string_view plaintext,
+               unsigned char* output);
+
+ protected:
+  // Make these constants available to the subclasses so that the subclasses
+  // can assert at compile time their key_size_ and nonce_size_ do not
+  // exceed the maximum.
+  static const size_t kMaxKeySize = 32;
+  enum : size_t { kMaxNonceSize = 12 };
+
+ private:
+  const EVP_AEAD* const aead_alg_;
+  const size_t key_size_;
+  const size_t auth_tag_size_;
+  const size_t nonce_size_;
+  const bool use_ietf_nonce_construction_;
+
+  // The key.
+  unsigned char key_[kMaxKeySize];
+  // The IV used to construct the nonce.
+  unsigned char iv_[kMaxNonceSize];
+
+  bssl::ScopedEVP_AEAD_CTX ctx_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.cc b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.cc
new file mode 100644
index 0000000..8c6fd1d
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 16;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes128Gcm12Decrypter::Aes128Gcm12Decrypter()
+    : AesBaseDecrypter(EVP_aead_aes_128_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ false) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes128Gcm12Decrypter::~Aes128Gcm12Decrypter() {}
+
+uint32_t Aes128Gcm12Decrypter::cipher_id() const {
+  return TLS1_CK_AES_128_GCM_SHA256;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h
new file mode 100644
index 0000000..38a9419
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2017 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_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/aes_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes128Gcm12Decrypter is a QuicDecrypter that implements the
+// AEAD_AES_128_GCM_12 algorithm specified in RFC 5282. Create an instance by
+// calling QuicDecrypter::Create(kAESG).
+//
+// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
+// of the nonce is four bytes.
+class QUIC_EXPORT_PRIVATE Aes128Gcm12Decrypter : public AesBaseDecrypter {
+ public:
+  enum {
+    // Authentication tags are truncated to 96 bits.
+    kAuthTagSize = 12,
+  };
+
+  Aes128Gcm12Decrypter();
+  Aes128Gcm12Decrypter(const Aes128Gcm12Decrypter&) = delete;
+  Aes128Gcm12Decrypter& operator=(const Aes128Gcm12Decrypter&) = delete;
+  ~Aes128Gcm12Decrypter() override;
+
+  uint32_t cipher_id() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
new file mode 100644
index 0000000..64e11eb
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
@@ -0,0 +1,288 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmDecrypt128.rsp
+// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
+// 2013-02-01. The test vectors in that file look like this:
+//
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = cf063a34d4a9a76c2c86787d3f96db71
+// IV = 113b9785971864c83b01c787
+// CT =
+// AAD =
+// Tag = 72ac8493e3a5228b5d130a69d2510e42
+// PT =
+//
+// Count = 1
+// Key = a49a5e26a2f8cb63d05546c2a62f5343
+// IV = 907763b19b9b4ab6bd4f0281
+// CT =
+// AAD =
+// Tag = a2be08210d8c470a8df6e8fbd79ec5cf
+// FAIL
+//
+// ...
+//
+// The gcmDecrypt128.rsp file is huge (2.6 MB), so I selected just a
+// few test vectors for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* ct;
+  const char* aad;
+  const char* tag;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestGroupInfo test_group_info[] = {
+    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
+    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
+     "72ac8493e3a5228b5d130a69d2510e42", ""},
+    {
+        "a49a5e26a2f8cb63d05546c2a62f5343", "907763b19b9b4ab6bd4f0281", "", "",
+        "a2be08210d8c470a8df6e8fbd79ec5cf",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {
+        "d1f6af919cde85661208bdce0c27cb22", "898c6929b435017bf031c3c5", "",
+        "7c5faa40e636bbc91107e68010c92b9f", "ae45f11777540a2caeb128be8092468a",
+        nullptr  // FAIL
+    },
+    {"2370e320d4344208e0ff5683f243b213", "04dbb82f044d30831c441228", "",
+     "d43a8e5089eea0d026c03a85178b27da", "2a049c049d25aa95969b451d93c31c6e",
+     ""},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"e98b72a9881a84ca6b76e0f43e68647a", "8b23299fde174053f3d652ba",
+     "5a3c1cf1985dbb8bed818036fdd5ab42", "", "23c7ab0f952b7091cd324835043b5eb5",
+     "28286a321293253c3e0aa2704a278032"},
+    {"33240636cd3236165f1a553b773e728e", "17c4d61493ecdc8f31700b12",
+     "47bb7e23f7bdfe05a8091ac90e4f8b2e", "", "b723c70e931d9785f40fd4ab1d612dc9",
+     "95695a5b12f2870b9cc5fdc8f218a97d"},
+    {
+        "5164df856f1e9cac04a79b808dc5be39", "e76925d5355e0584ce871b2b",
+        "0216c899c88d6e32c958c7e553daa5bc", "",
+        "a145319896329c96df291f64efbe0e3a",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"af57f42c60c0fc5a09adb81ab86ca1c3", "a2dc01871f37025dc0fc9a79",
+     "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
+     "338b22f9bad09093276a331e9c79c7f4",
+     "41dc38988945fcb44faf2ef72d0061289ef8efd8",
+     "4f71e72bde0018f555c5adcce062e005",
+     "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
+     "5b2f69b041596e8817d0a3c16f8fadeb"},
+    {"ebc753e5422b377d3cb64b58ffa41b61", "2e1821efaced9acf1f241c9b",
+     "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
+     "f401823e04b05817243d2142a3589878",
+     "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
+     "534d9234d2351cf30e565de47baece0b",
+     "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
+     "353a18017f5b36bfc00b1f6dcb7ed485"},
+    {
+        "52bdbbf9cf477f187ec010589cb39d58", "d3be36d3393134951d324b31",
+        "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
+        "32b992760b3a5f99e9a47838867000a9",
+        "93c4fc6a4135f54d640b0c976bf755a06a292c33",
+        "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"da2bb7d581493d692380c77105590201", "44aa3e7856ca279d2eb020c6",
+     "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
+     "f4ee16c761b3c9aeac3da03aa9889c88",
+     "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
+     "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
+     "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
+     "9e3ac938d3eb0cadd6f5c9e35d22ba38",
+     "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
+     "d65dbd1378b196ac270588dd0621f642"},
+    {"d74e4958717a9d5c0e235b76a926cae8", "0b7471141e0c70b1995fd7b1",
+     "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
+     "b0f1420be29ea547d42c713bc6af66aa",
+     "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
+     "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
+     "34a6039312774cedebf4961f3978b14a26509f96",
+     "e192c23cb036f0b31592989119eed55d",
+     "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
+     "f0a34bc305b88b804c60b90add594a17"},
+    {
+        "1986310c725ac94ecfe6422e75fc3ee7", "93ec4214fa8e6dc4e3afc775",
+        "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
+        "43edfd365b90d5b325950df0ada058f9",
+        "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
+        "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
+        "72c2cb136c8fd091cc4539877a5d1e72d607f960",
+        "8b347853f11d75e81e8a95010be81f17",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"387218b246c1a8257748b56980e50c94", "dd7e014198672be39f95b69d",
+     "cdba9e73eaf3d38eceb2b04a8d", "", "ecf90f4a47c9c626d6fb2c765d201556",
+     "48f5b426baca03064554cc2b30"},
+    {"294de463721e359863887c820524b3d4", "3338b35c9d57a5d28190e8c9",
+     "2f46634e74b8e4c89812ac83b9", "", "dabd506764e68b82a7e720aa18da0abe",
+     "46a2e55c8e264df211bd112685"},
+    {"28ead7fd2179e0d12aa6d5d88c58c2dc", "5055347f18b4d5add0ae5c41",
+     "142d8210c3fb84774cdbd0447a", "", "5fd321d9cdb01952dc85f034736c2a7d",
+     "3b95b981086ee73cc4d0cc1422"},
+    {
+        "7d7b6c988137b8d470c57bf674a09c87", "9edf2aa970d016ac962e1fd8",
+        "a85b66c3cb5eab91d5bdc8bc0e", "", "dc054efc01f3afd21d9c2484819f569a",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(Aes128Gcm12Decrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  uint64_t packet_number;
+  absl::string_view nonce_prefix(nonce.data(),
+                                 nonce.size() - sizeof(packet_number));
+  decrypter->SetNoncePrefix(nonce_prefix);
+  memcpy(&packet_number, nonce.data() + nonce_prefix.size(),
+         sizeof(packet_number));
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success = decrypter->DecryptPacket(
+      packet_number, associated_data, ciphertext, output.get(), &output_length,
+      ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class Aes128Gcm12DecrypterTest : public QuicTest {};
+
+TEST_F(Aes128Gcm12DecrypterTest, Decrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // If not present then decryption is expected to fail.
+      bool has_pt = test_vectors[j].pt;
+
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+      std::string pt;
+      if (has_pt) {
+        pt = absl::HexStringToBytes(test_vectors[j].pt);
+      }
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+      if (has_pt) {
+        EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      }
+
+      // The test vectors have 16 byte authenticators but this code only uses
+      // the first 12.
+      ASSERT_LE(static_cast<size_t>(Aes128Gcm12Decrypter::kAuthTagSize),
+                tag.length());
+      tag.resize(Aes128Gcm12Decrypter::kAuthTagSize);
+      std::string ciphertext = ct + tag;
+
+      Aes128Gcm12Decrypter decrypter;
+      ASSERT_TRUE(decrypter.SetKey(key));
+
+      std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+          &decrypter, iv,
+          // This deliberately tests that the decrypter can
+          // handle an AAD that is set to nullptr, as opposed
+          // to a zero-length, non-nullptr pointer.
+          aad.length() ? aad : absl::string_view(), ciphertext));
+      if (!decrypted) {
+        EXPECT_FALSE(has_pt);
+        continue;
+      }
+      EXPECT_TRUE(has_pt);
+
+      ASSERT_EQ(pt.length(), decrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+    }
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.cc b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.cc
new file mode 100644
index 0000000..1018c41
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 16;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes128Gcm12Encrypter::Aes128Gcm12Encrypter()
+    : AesBaseEncrypter(EVP_aead_aes_128_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ false) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h
new file mode 100644
index 0000000..64f0292
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2013 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_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/aes_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes128Gcm12Encrypter is a QuicEncrypter that implements the
+// AEAD_AES_128_GCM_12 algorithm specified in RFC 5282. Create an instance by
+// calling QuicEncrypter::Create(kAESG).
+//
+// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
+// of the nonce is four bytes.
+class QUIC_EXPORT_PRIVATE Aes128Gcm12Encrypter : public AesBaseEncrypter {
+ public:
+  enum {
+    // Authentication tags are truncated to 96 bits.
+    kAuthTagSize = 12,
+  };
+
+  Aes128Gcm12Encrypter();
+  Aes128Gcm12Encrypter(const Aes128Gcm12Encrypter&) = delete;
+  Aes128Gcm12Encrypter& operator=(const Aes128Gcm12Encrypter&) = delete;
+  ~Aes128Gcm12Encrypter() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
new file mode 100644
index 0000000..47dbd67
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
@@ -0,0 +1,244 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmEncryptExtIV128.rsp
+// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
+// 2013-02-01. The test vectors in that file look like this:
+//
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = 11754cd72aec309bf52f7687212e8957
+// IV = 3c819d9a9bed087615030b65
+// PT =
+// AAD =
+// CT =
+// Tag = 250327c674aaf477aef2675748cf6971
+//
+// Count = 1
+// Key = ca47248ac0b6f8372a97ac43508308ed
+// IV = ffd2b598feabc9019262d2be
+// PT =
+// AAD =
+// CT =
+// Tag = 60d20404af527d248d893ae495707d1a
+//
+// ...
+//
+// The gcmEncryptExtIV128.rsp file is huge (2.8 MB), so I selected just a
+// few test vectors for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* iv;
+  const char* pt;
+  const char* aad;
+  const char* ct;
+  const char* tag;
+};
+
+const TestGroupInfo test_group_info[] = {
+    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
+    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "", "",
+     "250327c674aaf477aef2675748cf6971"},
+    {"ca47248ac0b6f8372a97ac43508308ed", "ffd2b598feabc9019262d2be", "", "", "",
+     "60d20404af527d248d893ae495707d1a"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {"77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "",
+     "7a43ec1d9c0a5a78a0b16533a6213cab", "",
+     "209fcc8d3675ed938e9c7166709dd946"},
+    {"7680c5d3ca6154758e510f4d25b98820", "f8f105f9c3df4965780321f8", "",
+     "c94c410194c765e3dcc7964379758ed3", "",
+     "94dca8edfcf90bb74b153c8d48a17930"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"7fddb57453c241d03efbed3ac44e371c", "ee283a3fc75575e33efd4887",
+     "d5de42b461646c255c87bd2962d3b9a2", "", "2ccda4a5415cb91e135c2a0f78c9b2fd",
+     "b36d1df9b9d5e596f83e8b7f52971cb3"},
+    {"ab72c77b97cb5fe9a382d9fe81ffdbed", "54cc7dc2c37ec006bcc6d1da",
+     "007c5e5b3e59df24a7c355584fc1518d", "", "0e1bde206a07a9c2c1b65300f8c64997",
+     "2b4401346697138c7a4891ee59867d0c"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"fe47fcce5fc32665d2ae399e4eec72ba", "5adb9609dbaeb58cbd6e7275",
+     "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
+     "b840382c4bccaf3bafb4ca8429bea063",
+     "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
+     "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
+     "3ddbc5db8778371495da76d269e5db3e",
+     "291ef1982e4defedaa2249f898556b47"},
+    {"ec0c2ba17aa95cd6afffe949da9cc3a8", "296bce5b50b7d66096d627ef",
+     "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
+     "b764b9611f6c0f8641843d5d58f3a242",
+     "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
+     "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
+     "5506fde6309ffc19e716eddf1a828c5a",
+     "890147971946b627c40016da1ecf3e77"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"2c1f21cf0f6fb3661943155c3e3d8492", "23cb5ff362e22426984d1907",
+     "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
+     "8b5615ba7c1220ff6510e259f06655d8",
+     "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
+     "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
+     "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
+     "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
+     "b6ad57af43e1895df9dca2a5344a62cc",
+     "57a3ee28136e94c74838997ae9823f3a"},
+    {"d9f7d2411091f947b4d6f1e2d1f0fb2e", "e1934f5db57cc983e6b180e7",
+     "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
+     "c2c6f6166f4a59431e182663fcaea05a",
+     "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
+     "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
+     "15d2e51398344b16bee1ed7c499b353d6c597af8",
+     "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
+     "3c7891c2a91fbc48db29967ec9542b23",
+     "21b51ca862cb637cdd03b99a0f93b134"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"fe9bb47deb3a61e423c2231841cfd1fb", "4d328eb776f500a2f7fb47aa",
+     "f1cc3818e421876bb6b8bbd6c9", "", "b88c5c1977b35b517b0aeae967",
+     "43fd4727fe5cdb4b5b42818dea7ef8c9"},
+    {"6703df3701a7f54911ca72e24dca046a", "12823ab601c350ea4bc2488c",
+     "793cd125b0b84a043e3ac67717", "", "b2051c80014f42f08735a7b0cd",
+     "38e6bcd29962e5f2c13626b85a877101"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class Aes128Gcm12EncrypterTest : public QuicTest {};
+
+TEST_F(Aes128Gcm12EncrypterTest, Encrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+
+      Aes128Gcm12Encrypter encrypter;
+      ASSERT_TRUE(encrypter.SetKey(key));
+      std::unique_ptr<QuicData> encrypted(
+          EncryptWithNonce(&encrypter, iv,
+                           // This deliberately tests that the encrypter can
+                           // handle an AAD that is set to nullptr, as opposed
+                           // to a zero-length, non-nullptr pointer.
+                           aad.length() ? aad : absl::string_view(), pt));
+      ASSERT_TRUE(encrypted.get());
+
+      // The test vectors have 16 byte authenticators but this code only uses
+      // the first 12.
+      ASSERT_LE(static_cast<size_t>(Aes128Gcm12Encrypter::kAuthTagSize),
+                tag.length());
+      tag.resize(Aes128Gcm12Encrypter::kAuthTagSize);
+
+      ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
+      quiche::test::CompareCharArraysWithHexError(
+          "authentication tag", encrypted->data() + ct.length(), tag.length(),
+          tag.data(), tag.length());
+    }
+  }
+}
+
+TEST_F(Aes128Gcm12EncrypterTest, GetMaxPlaintextSize) {
+  Aes128Gcm12Encrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
+  EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11));
+}
+
+TEST_F(Aes128Gcm12EncrypterTest, GetCiphertextSize) {
+  Aes128Gcm12Encrypter encrypter;
+  EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_decrypter.cc b/quiche/quic/core/crypto/aes_128_gcm_decrypter.cc
new file mode 100644
index 0000000..d714ca0
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_decrypter.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_128_gcm_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 16;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes128GcmDecrypter::Aes128GcmDecrypter()
+    : AesBaseDecrypter(EVP_aead_aes_128_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes128GcmDecrypter::~Aes128GcmDecrypter() {}
+
+uint32_t Aes128GcmDecrypter::cipher_id() const {
+  return TLS1_CK_AES_128_GCM_SHA256;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_decrypter.h b/quiche/quic/core/crypto/aes_128_gcm_decrypter.h
new file mode 100644
index 0000000..c5f4d17
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_decrypter.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2017 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_CRYPTO_AES_128_GCM_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/aes_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes128GcmDecrypter is a QuicDecrypter that implements the
+// AEAD_AES_128_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE Aes128GcmDecrypter : public AesBaseDecrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  Aes128GcmDecrypter();
+  Aes128GcmDecrypter(const Aes128GcmDecrypter&) = delete;
+  Aes128GcmDecrypter& operator=(const Aes128GcmDecrypter&) = delete;
+  ~Aes128GcmDecrypter() override;
+
+  uint32_t cipher_id() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_decrypter_test.cc b/quiche/quic/core/crypto/aes_128_gcm_decrypter_test.cc
new file mode 100644
index 0000000..e02b433
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_decrypter_test.cc
@@ -0,0 +1,291 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_128_gcm_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmDecrypt128.rsp
+// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
+// 2013-02-01. The test vectors in that file look like this:
+//
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = cf063a34d4a9a76c2c86787d3f96db71
+// IV = 113b9785971864c83b01c787
+// CT =
+// AAD =
+// Tag = 72ac8493e3a5228b5d130a69d2510e42
+// PT =
+//
+// Count = 1
+// Key = a49a5e26a2f8cb63d05546c2a62f5343
+// IV = 907763b19b9b4ab6bd4f0281
+// CT =
+// AAD =
+// Tag = a2be08210d8c470a8df6e8fbd79ec5cf
+// FAIL
+//
+// ...
+//
+// The gcmDecrypt128.rsp file is huge (2.6 MB), so I selected just a
+// few test vectors for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* ct;
+  const char* aad;
+  const char* tag;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestGroupInfo test_group_info[] = {
+    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
+    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
+     "72ac8493e3a5228b5d130a69d2510e42", ""},
+    {
+        "a49a5e26a2f8cb63d05546c2a62f5343", "907763b19b9b4ab6bd4f0281", "", "",
+        "a2be08210d8c470a8df6e8fbd79ec5cf",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {
+        "d1f6af919cde85661208bdce0c27cb22", "898c6929b435017bf031c3c5", "",
+        "7c5faa40e636bbc91107e68010c92b9f", "ae45f11777540a2caeb128be8092468a",
+        nullptr  // FAIL
+    },
+    {"2370e320d4344208e0ff5683f243b213", "04dbb82f044d30831c441228", "",
+     "d43a8e5089eea0d026c03a85178b27da", "2a049c049d25aa95969b451d93c31c6e",
+     ""},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"e98b72a9881a84ca6b76e0f43e68647a", "8b23299fde174053f3d652ba",
+     "5a3c1cf1985dbb8bed818036fdd5ab42", "", "23c7ab0f952b7091cd324835043b5eb5",
+     "28286a321293253c3e0aa2704a278032"},
+    {"33240636cd3236165f1a553b773e728e", "17c4d61493ecdc8f31700b12",
+     "47bb7e23f7bdfe05a8091ac90e4f8b2e", "", "b723c70e931d9785f40fd4ab1d612dc9",
+     "95695a5b12f2870b9cc5fdc8f218a97d"},
+    {
+        "5164df856f1e9cac04a79b808dc5be39", "e76925d5355e0584ce871b2b",
+        "0216c899c88d6e32c958c7e553daa5bc", "",
+        "a145319896329c96df291f64efbe0e3a",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"af57f42c60c0fc5a09adb81ab86ca1c3", "a2dc01871f37025dc0fc9a79",
+     "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
+     "338b22f9bad09093276a331e9c79c7f4",
+     "41dc38988945fcb44faf2ef72d0061289ef8efd8",
+     "4f71e72bde0018f555c5adcce062e005",
+     "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
+     "5b2f69b041596e8817d0a3c16f8fadeb"},
+    {"ebc753e5422b377d3cb64b58ffa41b61", "2e1821efaced9acf1f241c9b",
+     "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
+     "f401823e04b05817243d2142a3589878",
+     "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
+     "534d9234d2351cf30e565de47baece0b",
+     "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
+     "353a18017f5b36bfc00b1f6dcb7ed485"},
+    {
+        "52bdbbf9cf477f187ec010589cb39d58", "d3be36d3393134951d324b31",
+        "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
+        "32b992760b3a5f99e9a47838867000a9",
+        "93c4fc6a4135f54d640b0c976bf755a06a292c33",
+        "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"da2bb7d581493d692380c77105590201", "44aa3e7856ca279d2eb020c6",
+     "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
+     "f4ee16c761b3c9aeac3da03aa9889c88",
+     "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
+     "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
+     "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
+     "9e3ac938d3eb0cadd6f5c9e35d22ba38",
+     "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
+     "d65dbd1378b196ac270588dd0621f642"},
+    {"d74e4958717a9d5c0e235b76a926cae8", "0b7471141e0c70b1995fd7b1",
+     "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
+     "b0f1420be29ea547d42c713bc6af66aa",
+     "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
+     "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
+     "34a6039312774cedebf4961f3978b14a26509f96",
+     "e192c23cb036f0b31592989119eed55d",
+     "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
+     "f0a34bc305b88b804c60b90add594a17"},
+    {
+        "1986310c725ac94ecfe6422e75fc3ee7", "93ec4214fa8e6dc4e3afc775",
+        "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
+        "43edfd365b90d5b325950df0ada058f9",
+        "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
+        "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
+        "72c2cb136c8fd091cc4539877a5d1e72d607f960",
+        "8b347853f11d75e81e8a95010be81f17",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"387218b246c1a8257748b56980e50c94", "dd7e014198672be39f95b69d",
+     "cdba9e73eaf3d38eceb2b04a8d", "", "ecf90f4a47c9c626d6fb2c765d201556",
+     "48f5b426baca03064554cc2b30"},
+    {"294de463721e359863887c820524b3d4", "3338b35c9d57a5d28190e8c9",
+     "2f46634e74b8e4c89812ac83b9", "", "dabd506764e68b82a7e720aa18da0abe",
+     "46a2e55c8e264df211bd112685"},
+    {"28ead7fd2179e0d12aa6d5d88c58c2dc", "5055347f18b4d5add0ae5c41",
+     "142d8210c3fb84774cdbd0447a", "", "5fd321d9cdb01952dc85f034736c2a7d",
+     "3b95b981086ee73cc4d0cc1422"},
+    {
+        "7d7b6c988137b8d470c57bf674a09c87", "9edf2aa970d016ac962e1fd8",
+        "a85b66c3cb5eab91d5bdc8bc0e", "", "dc054efc01f3afd21d9c2484819f569a",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(Aes128GcmDecrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  decrypter->SetIV(nonce);
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success =
+      decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
+                               &output_length, ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class Aes128GcmDecrypterTest : public QuicTest {};
+
+TEST_F(Aes128GcmDecrypterTest, Decrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // If not present then decryption is expected to fail.
+      bool has_pt = test_vectors[j].pt;
+
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+      std::string pt;
+      if (has_pt) {
+        pt = absl::HexStringToBytes(test_vectors[j].pt);
+      }
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+      if (has_pt) {
+        EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      }
+      std::string ciphertext = ct + tag;
+
+      Aes128GcmDecrypter decrypter;
+      ASSERT_TRUE(decrypter.SetKey(key));
+
+      std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+          &decrypter, iv,
+          // This deliberately tests that the decrypter can
+          // handle an AAD that is set to nullptr, as opposed
+          // to a zero-length, non-nullptr pointer.
+          aad.length() ? aad : absl::string_view(), ciphertext));
+      if (!decrypted) {
+        EXPECT_FALSE(has_pt);
+        continue;
+      }
+      EXPECT_TRUE(has_pt);
+
+      ASSERT_EQ(pt.length(), decrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+    }
+  }
+}
+
+TEST_F(Aes128GcmDecrypterTest, GenerateHeaderProtectionMask) {
+  Aes128GcmDecrypter decrypter;
+  std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
+  std::string sample =
+      absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
+  QuicDataReader sample_reader(sample.data(), sample.size());
+  ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
+  std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
+  std::string expected_mask =
+      absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_encrypter.cc b/quiche/quic/core/crypto/aes_128_gcm_encrypter.cc
new file mode 100644
index 0000000..56f698f
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_encrypter.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_128_gcm_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 16;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes128GcmEncrypter::Aes128GcmEncrypter()
+    : AesBaseEncrypter(EVP_aead_aes_128_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes128GcmEncrypter::~Aes128GcmEncrypter() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_encrypter.h b/quiche/quic/core/crypto/aes_128_gcm_encrypter.h
new file mode 100644
index 0000000..a40735c
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_encrypter.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2017 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_CRYPTO_AES_128_GCM_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/aes_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes128GcmEncrypter is a QuicEncrypter that implements the
+// AEAD_AES_128_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE Aes128GcmEncrypter : public AesBaseEncrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  Aes128GcmEncrypter();
+  Aes128GcmEncrypter(const Aes128GcmEncrypter&) = delete;
+  Aes128GcmEncrypter& operator=(const Aes128GcmEncrypter&) = delete;
+  ~Aes128GcmEncrypter() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_encrypter_test.cc b/quiche/quic/core/crypto/aes_128_gcm_encrypter_test.cc
new file mode 100644
index 0000000..7086094
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_encrypter_test.cc
@@ -0,0 +1,273 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_128_gcm_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmEncryptExtIV128.rsp
+// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
+// 2013-02-01. The test vectors in that file look like this:
+//
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = 11754cd72aec309bf52f7687212e8957
+// IV = 3c819d9a9bed087615030b65
+// PT =
+// AAD =
+// CT =
+// Tag = 250327c674aaf477aef2675748cf6971
+//
+// Count = 1
+// Key = ca47248ac0b6f8372a97ac43508308ed
+// IV = ffd2b598feabc9019262d2be
+// PT =
+// AAD =
+// CT =
+// Tag = 60d20404af527d248d893ae495707d1a
+//
+// ...
+//
+// The gcmEncryptExtIV128.rsp file is huge (2.8 MB), so I selected just a
+// few test vectors for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* iv;
+  const char* pt;
+  const char* aad;
+  const char* ct;
+  const char* tag;
+};
+
+const TestGroupInfo test_group_info[] = {
+    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
+    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "", "",
+     "250327c674aaf477aef2675748cf6971"},
+    {"ca47248ac0b6f8372a97ac43508308ed", "ffd2b598feabc9019262d2be", "", "", "",
+     "60d20404af527d248d893ae495707d1a"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {"77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "",
+     "7a43ec1d9c0a5a78a0b16533a6213cab", "",
+     "209fcc8d3675ed938e9c7166709dd946"},
+    {"7680c5d3ca6154758e510f4d25b98820", "f8f105f9c3df4965780321f8", "",
+     "c94c410194c765e3dcc7964379758ed3", "",
+     "94dca8edfcf90bb74b153c8d48a17930"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"7fddb57453c241d03efbed3ac44e371c", "ee283a3fc75575e33efd4887",
+     "d5de42b461646c255c87bd2962d3b9a2", "", "2ccda4a5415cb91e135c2a0f78c9b2fd",
+     "b36d1df9b9d5e596f83e8b7f52971cb3"},
+    {"ab72c77b97cb5fe9a382d9fe81ffdbed", "54cc7dc2c37ec006bcc6d1da",
+     "007c5e5b3e59df24a7c355584fc1518d", "", "0e1bde206a07a9c2c1b65300f8c64997",
+     "2b4401346697138c7a4891ee59867d0c"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"fe47fcce5fc32665d2ae399e4eec72ba", "5adb9609dbaeb58cbd6e7275",
+     "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
+     "b840382c4bccaf3bafb4ca8429bea063",
+     "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
+     "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
+     "3ddbc5db8778371495da76d269e5db3e",
+     "291ef1982e4defedaa2249f898556b47"},
+    {"ec0c2ba17aa95cd6afffe949da9cc3a8", "296bce5b50b7d66096d627ef",
+     "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
+     "b764b9611f6c0f8641843d5d58f3a242",
+     "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
+     "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
+     "5506fde6309ffc19e716eddf1a828c5a",
+     "890147971946b627c40016da1ecf3e77"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"2c1f21cf0f6fb3661943155c3e3d8492", "23cb5ff362e22426984d1907",
+     "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
+     "8b5615ba7c1220ff6510e259f06655d8",
+     "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
+     "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
+     "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
+     "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
+     "b6ad57af43e1895df9dca2a5344a62cc",
+     "57a3ee28136e94c74838997ae9823f3a"},
+    {"d9f7d2411091f947b4d6f1e2d1f0fb2e", "e1934f5db57cc983e6b180e7",
+     "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
+     "c2c6f6166f4a59431e182663fcaea05a",
+     "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
+     "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
+     "15d2e51398344b16bee1ed7c499b353d6c597af8",
+     "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
+     "3c7891c2a91fbc48db29967ec9542b23",
+     "21b51ca862cb637cdd03b99a0f93b134"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"fe9bb47deb3a61e423c2231841cfd1fb", "4d328eb776f500a2f7fb47aa",
+     "f1cc3818e421876bb6b8bbd6c9", "", "b88c5c1977b35b517b0aeae967",
+     "43fd4727fe5cdb4b5b42818dea7ef8c9"},
+    {"6703df3701a7f54911ca72e24dca046a", "12823ab601c350ea4bc2488c",
+     "793cd125b0b84a043e3ac67717", "", "b2051c80014f42f08735a7b0cd",
+     "38e6bcd29962e5f2c13626b85a877101"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(Aes128GcmEncrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class Aes128GcmEncrypterTest : public QuicTest {};
+
+TEST_F(Aes128GcmEncrypterTest, Encrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+
+      Aes128GcmEncrypter encrypter;
+      ASSERT_TRUE(encrypter.SetKey(key));
+      std::unique_ptr<QuicData> encrypted(
+          EncryptWithNonce(&encrypter, iv,
+                           // This deliberately tests that the encrypter can
+                           // handle an AAD that is set to nullptr, as opposed
+                           // to a zero-length, non-nullptr pointer.
+                           aad.length() ? aad : absl::string_view(), pt));
+      ASSERT_TRUE(encrypted.get());
+
+      ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
+      quiche::test::CompareCharArraysWithHexError(
+          "authentication tag", encrypted->data() + ct.length(), tag.length(),
+          tag.data(), tag.length());
+    }
+  }
+}
+
+TEST_F(Aes128GcmEncrypterTest, EncryptPacket) {
+  std::string key = absl::HexStringToBytes("d95a145250826c25a77b6a84fd4d34fc");
+  std::string iv = absl::HexStringToBytes("50c4431ebb18283448e276e2");
+  uint64_t packet_num = 0x13278f44;
+  std::string aad =
+      absl::HexStringToBytes("875d49f64a70c9cbe713278f44ff000005");
+  std::string pt = absl::HexStringToBytes("aa0003a250bd000000000001");
+  std::string ct = absl::HexStringToBytes(
+      "7dd4708b989ee7d38a013e3656e9b37beefd05808fe1ab41e3b4f2c0");
+
+  std::vector<char> out(ct.size());
+  size_t out_size;
+
+  Aes128GcmEncrypter encrypter;
+  ASSERT_TRUE(encrypter.SetKey(key));
+  ASSERT_TRUE(encrypter.SetIV(iv));
+  ASSERT_TRUE(encrypter.EncryptPacket(packet_num, aad, pt, out.data(),
+                                      &out_size, out.size()));
+  EXPECT_EQ(out_size, out.size());
+  quiche::test::CompareCharArraysWithHexError("ciphertext", out.data(),
+                                              out.size(), ct.data(), ct.size());
+}
+
+TEST_F(Aes128GcmEncrypterTest, GetMaxPlaintextSize) {
+  Aes128GcmEncrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
+}
+
+TEST_F(Aes128GcmEncrypterTest, GetCiphertextSize) {
+  Aes128GcmEncrypter encrypter;
+  EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
+}
+
+TEST_F(Aes128GcmEncrypterTest, GenerateHeaderProtectionMask) {
+  Aes128GcmEncrypter encrypter;
+  std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
+  std::string sample =
+      absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
+  ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
+  std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
+  std::string expected_mask =
+      absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_256_gcm_decrypter.cc b/quiche/quic/core/crypto/aes_256_gcm_decrypter.cc
new file mode 100644
index 0000000..f0cdc37
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_decrypter.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_256_gcm_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes256GcmDecrypter::Aes256GcmDecrypter()
+    : AesBaseDecrypter(EVP_aead_aes_256_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes256GcmDecrypter::~Aes256GcmDecrypter() {}
+
+uint32_t Aes256GcmDecrypter::cipher_id() const {
+  return TLS1_CK_AES_256_GCM_SHA384;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_256_gcm_decrypter.h b/quiche/quic/core/crypto/aes_256_gcm_decrypter.h
new file mode 100644
index 0000000..dc4f8c0
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_decrypter.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2017 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_CRYPTO_AES_256_GCM_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/aes_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes256GcmDecrypter is a QuicDecrypter that implements the
+// AEAD_AES_256_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE Aes256GcmDecrypter : public AesBaseDecrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  Aes256GcmDecrypter();
+  Aes256GcmDecrypter(const Aes256GcmDecrypter&) = delete;
+  Aes256GcmDecrypter& operator=(const Aes256GcmDecrypter&) = delete;
+  ~Aes256GcmDecrypter() override;
+
+  uint32_t cipher_id() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_256_gcm_decrypter_test.cc b/quiche/quic/core/crypto/aes_256_gcm_decrypter_test.cc
new file mode 100644
index 0000000..7c48c8c
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_decrypter_test.cc
@@ -0,0 +1,297 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_256_gcm_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmDecrypt256.rsp
+// downloaded from
+// https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#GCMVS
+// on 2017-09-27. The test vectors in that file look like this:
+//
+// [Keylen = 256]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010
+// IV = 58d2240f580a31c1d24948e9
+// CT =
+// AAD =
+// Tag = 15e051a5e4a5f5da6cea92e2ebee5bac
+// PT =
+//
+// Count = 1
+// Key = e5a8123f2e2e007d4e379ba114a2fb66e6613f57c72d4e4f024964053028a831
+// IV = 51e43385bf533e168427e1ad
+// CT =
+// AAD =
+// Tag = 38fe845c66e66bdd884c2aecafd280e6
+// FAIL
+//
+// ...
+//
+// The gcmDecrypt256.rsp file is huge (3.0 MB), so a few test vectors were
+// selected for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* ct;
+  const char* aad;
+  const char* tag;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestGroupInfo test_group_info[] = {
+    {256, 96, 0, 0, 128},     {256, 96, 0, 128, 128},   {256, 96, 128, 0, 128},
+    {256, 96, 408, 160, 128}, {256, 96, 408, 720, 128}, {256, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010",
+     "58d2240f580a31c1d24948e9", "", "", "15e051a5e4a5f5da6cea92e2ebee5bac",
+     ""},
+    {
+        "e5a8123f2e2e007d4e379ba114a2fb66e6613f57c72d4e4f024964053028a831",
+        "51e43385bf533e168427e1ad", "", "", "38fe845c66e66bdd884c2aecafd280e6",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {"6dfdafd6703c285c01f14fd10a6012862b2af950d4733abb403b2e745b26945d",
+     "3749d0b3d5bacb71be06ade6", "", "c0d249871992e70302ae008193d1e89f",
+     "4aa4cc69f84ee6ac16d9bfb4e05de500", ""},
+    {
+        "2c392a5eb1a9c705371beda3a901c7c61dca4d93b4291de1dd0dd15ec11ffc45",
+        "0723fb84a08f4ea09841f32a", "", "140be561b6171eab942c486a94d33d43",
+        "aa0e1c9b57975bfc91aa137231977d2c", nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"4c8ebfe1444ec1b2d503c6986659af2c94fafe945f72c1e8486a5acfedb8a0f8",
+     "473360e0ad24889959858995", "d2c78110ac7e8f107c0df0570bd7c90c", "",
+     "c26a379b6d98ef2852ead8ce83a833a7", "7789b41cb3ee548814ca0b388c10b343"},
+    {"3934f363fd9f771352c4c7a060682ed03c2864223a1573b3af997e2ababd60ab",
+     "efe2656d878c586e41c539c4", "e0de64302ac2d04048d65a87d2ad09fe", "",
+     "33cbd8d2fb8a3a03e30c1eb1b53c1d99", "697aff2d6b77e5ed6232770e400c1ead"},
+    {
+        "c997768e2d14e3d38259667a6649079de77beb4543589771e5068e6cd7cd0b14",
+        "835090aed9552dbdd45277e2", "9f6607d68e22ccf21928db0986be126e", "",
+        "f32617f67c574fd9f44ef76ff880ab9f", nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {
+        "e9d381a9c413bee66175d5586a189836e5c20f5583535ab4d3f3e612dc21700e",
+        "23e81571da1c7821c681c7ca",
+        "a25f3f580306cd5065d22a6b7e9660110af7204bb77d370f7f34bee547feeff7b32a59"
+        "6fce29c9040e68b1589aad48da881990",
+        "6f39c9ae7b8e8a58a95f0dd8ea6a9087cbccdfd6",
+        "5b6dcd70eefb0892fab1539298b92a4b",
+        nullptr  // FAIL
+    },
+    {"6450d4501b1e6cfbe172c4c8570363e96b496591b842661c28c2f6c908379cad",
+     "7e4262035e0bf3d60e91668a",
+     "5a99b336fd3cfd82f10fb08f7045012415f0d9a06bb92dcf59c6f0dbe62d433671aacb8a1"
+     "c52ce7bbf6aea372bf51e2ba79406",
+     "f1c522f026e4c5d43851da516a1b78768ab18171",
+     "fe93b01636f7bb0458041f213e98de65",
+     "17449e236ef5858f6d891412495ead4607bfae2a2d735182a2a0242f9d52fc5345ef912db"
+     "e16f3bb4576fe3bcafe336dee6085"},
+    {"90f2e71ccb1148979cb742efc8f921de95457d898c84ce28edeed701650d3a26",
+     "aba58ad60047ba553f6e4c98",
+     "3fc77a5fe9203d091c7916587c9763cf2e4d0d53ca20b078b851716f1dab4873fe342b7b3"
+     "01402f015d00263bf3f77c58a99d6",
+     "2abe465df6e5be47f05b92c9a93d76ae3611fac5",
+     "9cb3d04637048bc0bddef803ffbb56cf",
+     "1d21639640e11638a2769e3fab78778f84be3f4a8ce28dfd99cb2e75171e05ea8e94e30aa"
+     "78b54bb402b39d613616a8ed951dc"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {
+        "e36aca93414b13f5313e76a7244588ee116551d1f34c32859166f2eb0ac1a9b7",
+        "e9e701b1ccef6bddd03391d8",
+        "5b059ac6733b6de0e8cf5b88b7301c02c993426f71bb12abf692e9deeacfac1ff1644c"
+        "87d4df130028f515f0feda636309a24d",
+        "6a08fe6e55a08f283cec4c4b37676e770f402af6102f548ad473ec6236da764f7076ff"
+        "d41bbd9611b439362d899682b7b0f839fc5a68d9df54afd1e2b3c4e7d072454ee27111"
+        "d52193d28b9c4f925d2a8b451675af39191a2cba",
+        "43c7c9c93cc265fc8e192000e0417b5b",
+        nullptr  // FAIL
+    },
+    {"5f72046245d3f4a0877e50a86554bfd57d1c5e073d1ed3b5451f6d0fc2a8507a",
+     "ea6f5b391e44b751b26bce6f",
+     "0e6e0b2114c40769c15958d965a14dcf50b680e0185a4409d77d894ca15b1e698dd83b353"
+     "6b18c05d8cd0873d1edce8150ecb5",
+     "9b3a68c941d42744673fb60fea49075eae77322e7e70e34502c115b6495ebfc796d629080"
+     "7653c6b53cd84281bd0311656d0013f44619d2748177e99e8f8347c989a7b59f9d8dcf00f"
+     "31db0684a4a83e037e8777bae55f799b0d",
+     "fdaaff86ceb937502cd9012d03585800",
+     "b0a881b751cc1eb0c912a4cf9bd971983707dbd2411725664503455c55db25cdb19bc669c"
+     "2654a3a8011de6bf7eff3f9f07834"},
+    {"ab639bae205547607506522bd3cdca7861369e2b42ef175ff135f6ba435d5a8e",
+     "5fbb63eb44bd59fee458d8f6",
+     "9a34c62bed0972285503a32812877187a54dedbd55d2317fed89282bf1af4ba0b6bb9f9e1"
+     "6dd86da3b441deb7841262bc6bd63",
+     "1ef2b1768b805587935ffaf754a11bd2a305076d6374f1f5098b1284444b78f55408a786d"
+     "a37e1b7f1401c330d3585ef56f3e4d35eaaac92e1381d636477dc4f4beaf559735e902d6b"
+     "e58723257d4ac1ed9bd213de387f35f3c4",
+     "e0299e079bff46fd12e36d1c60e41434",
+     "e5a3ce804a8516cdd12122c091256b789076576040dbf3c55e8be3c016025896b8a72532b"
+     "fd51196cc82efca47aa0fd8e2e0dc"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {
+        "8b37c4b8cf634704920059866ad96c49e9da502c63fca4a3a7a4dcec74cb0610",
+        "cb59344d2b06c4ae57cd0ea4", "66ab935c93555e786b775637a3", "",
+        "d8733acbb564d8afaa99d7ca2e2f92a9", nullptr  // FAIL
+    },
+    {"a71dac1377a3bf5d7fb1b5e36bee70d2e01de2a84a1c1009ba7448f7f26131dc",
+     "c5b60dda3f333b1146e9da7c", "43af49ec1ae3738a20755034d6", "",
+     "6f80b6ef2d8830a55eb63680a8dff9e0", "5b87141335f2becac1a559e05f"},
+    {"dc1f64681014be221b00793bbcf5a5bc675b968eb7a3a3d5aa5978ef4fa45ecc",
+     "056ae9a1a69e38af603924fe", "33013a48d9ea0df2911d583271", "",
+     "5b8f9cc22303e979cd1524187e9f70fe", "2a7e05612191c8bce2f529dca9"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(Aes256GcmDecrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  decrypter->SetIV(nonce);
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success =
+      decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
+                               &output_length, ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class Aes256GcmDecrypterTest : public QuicTest {};
+
+TEST_F(Aes256GcmDecrypterTest, Decrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // If not present then decryption is expected to fail.
+      bool has_pt = test_vectors[j].pt;
+
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+      std::string pt;
+      if (has_pt) {
+        pt = absl::HexStringToBytes(test_vectors[j].pt);
+      }
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+      if (has_pt) {
+        EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      }
+      std::string ciphertext = ct + tag;
+
+      Aes256GcmDecrypter decrypter;
+      ASSERT_TRUE(decrypter.SetKey(key));
+
+      std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+          &decrypter, iv,
+          // This deliberately tests that the decrypter can
+          // handle an AAD that is set to nullptr, as opposed
+          // to a zero-length, non-nullptr pointer.
+          aad.length() ? aad : absl::string_view(), ciphertext));
+      if (!decrypted) {
+        EXPECT_FALSE(has_pt);
+        continue;
+      }
+      EXPECT_TRUE(has_pt);
+
+      ASSERT_EQ(pt.length(), decrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+    }
+  }
+}
+
+TEST_F(Aes256GcmDecrypterTest, GenerateHeaderProtectionMask) {
+  Aes256GcmDecrypter decrypter;
+  std::string key = absl::HexStringToBytes(
+      "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
+  std::string sample =
+      absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
+  QuicDataReader sample_reader(sample.data(), sample.size());
+  ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
+  std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
+  std::string expected_mask =
+      absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_256_gcm_encrypter.cc b/quiche/quic/core/crypto/aes_256_gcm_encrypter.cc
new file mode 100644
index 0000000..fce2207
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_encrypter.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_256_gcm_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes256GcmEncrypter::Aes256GcmEncrypter()
+    : AesBaseEncrypter(EVP_aead_aes_256_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes256GcmEncrypter::~Aes256GcmEncrypter() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_256_gcm_encrypter.h b/quiche/quic/core/crypto/aes_256_gcm_encrypter.h
new file mode 100644
index 0000000..9ba47f1
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_encrypter.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2017 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_CRYPTO_AES_256_GCM_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/aes_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes256GcmEncrypter is a QuicEncrypter that implements the
+// AEAD_AES_256_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE Aes256GcmEncrypter : public AesBaseEncrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  Aes256GcmEncrypter();
+  Aes256GcmEncrypter(const Aes256GcmEncrypter&) = delete;
+  Aes256GcmEncrypter& operator=(const Aes256GcmEncrypter&) = delete;
+  ~Aes256GcmEncrypter() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_256_gcm_encrypter_test.cc b/quiche/quic/core/crypto/aes_256_gcm_encrypter_test.cc
new file mode 100644
index 0000000..6389fdb
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_encrypter_test.cc
@@ -0,0 +1,259 @@
+// Copyright (c) 2017 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 "quiche/quic/core/crypto/aes_256_gcm_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmEncryptExtIV256.rsp
+// downloaded from
+// https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#GCMVS
+// on 2017-09-27. The test vectors in that file look like this:
+//
+// [Keylen = 256]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4
+// IV = 516c33929df5a3284ff463d7
+// PT =
+// AAD =
+// CT =
+// Tag = bdc1ac884d332457a1d2664f168c76f0
+//
+// Count = 1
+// Key = 5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f
+// IV = 770ac1a5a3d476d5d96944a1
+// PT =
+// AAD =
+// CT =
+// Tag = 196d691e1047093ca4b3d2ef4baba216
+//
+// ...
+//
+// The gcmEncryptExtIV256.rsp file is huge (3.2 MB), so a few test vectors were
+// selected for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* iv;
+  const char* pt;
+  const char* aad;
+  const char* ct;
+  const char* tag;
+};
+
+const TestGroupInfo test_group_info[] = {
+    {256, 96, 0, 0, 128},     {256, 96, 0, 128, 128},   {256, 96, 128, 0, 128},
+    {256, 96, 408, 160, 128}, {256, 96, 408, 720, 128}, {256, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4",
+     "516c33929df5a3284ff463d7", "", "", "",
+     "bdc1ac884d332457a1d2664f168c76f0"},
+    {"5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f",
+     "770ac1a5a3d476d5d96944a1", "", "", "",
+     "196d691e1047093ca4b3d2ef4baba216"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {"78dc4e0aaf52d935c3c01eea57428f00ca1fd475f5da86a49c8dd73d68c8e223",
+     "d79cf22d504cc793c3fb6c8a", "", "b96baa8c1c75a671bfb2d08d06be5f36", "",
+     "3e5d486aa2e30b22e040b85723a06e76"},
+    {"4457ff33683cca6ca493878bdc00373893a9763412eef8cddb54f91318e0da88",
+     "699d1f29d7b8c55300bb1fd2", "", "6749daeea367d0e9809e2dc2f309e6e3", "",
+     "d60c74d2517fde4a74e0cd4709ed43a9"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"31bdadd96698c204aa9ce1448ea94ae1fb4a9a0b3c9d773b51bb1822666b8f22",
+     "0d18e06c7c725ac9e362e1ce", "2db5168e932556f8089a0622981d017d", "",
+     "fa4362189661d163fcd6a56d8bf0405a", "d636ac1bbedd5cc3ee727dc2ab4a9489"},
+    {"460fc864972261c2560e1eb88761ff1c992b982497bd2ac36c04071cbb8e5d99",
+     "8a4a16b9e210eb68bcb6f58d", "99e4e926ffe927f691893fb79a96b067", "",
+     "133fc15751621b5f325c7ff71ce08324", "ec4e87e0cf74a13618d0b68636ba9fa7"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"24501ad384e473963d476edcfe08205237acfd49b5b8f33857f8114e863fec7f",
+     "9ff18563b978ec281b3f2794",
+     "27f348f9cdc0c5bd5e66b1ccb63ad920ff2219d14e8d631b3872265cf117ee86757accb15"
+     "8bd9abb3868fdc0d0b074b5f01b2c",
+     "adb5ec720ccf9898500028bf34afccbcaca126ef",
+     "eb7cb754c824e8d96f7c6d9b76c7d26fb874ffbf1d65c6f64a698d839b0b06145dae82057"
+     "ad55994cf59ad7f67c0fa5e85fab8",
+     "bc95c532fecc594c36d1550286a7a3f0"},
+    {"fb43f5ab4a1738a30c1e053d484a94254125d55dccee1ad67c368bc1a985d235",
+     "9fbb5f8252db0bca21f1c230",
+     "34b797bb82250e23c5e796db2c37e488b3b99d1b981cea5e5b0c61a0b39adb6bd6ef1f507"
+     "22e2e4f81115cfcf53f842e2a6c08",
+     "98f8ae1735c39f732e2cbee1156dabeb854ec7a2",
+     "871cd53d95a8b806bd4821e6c4456204d27fd704ba3d07ce25872dc604ea5c5ea13322186"
+     "b7489db4fa060c1fd4159692612c8",
+     "07b48e4a32fac47e115d7ac7445d8330"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"148579a3cbca86d5520d66c0ec71ca5f7e41ba78e56dc6eebd566fed547fe691",
+     "b08a5ea1927499c6ecbfd4e0",
+     "9d0b15fdf1bd595f91f8b3abc0f7dec927dfd4799935a1795d9ce00c9b879434420fe42c2"
+     "75a7cd7b39d638fb81ca52b49dc41",
+     "e4f963f015ffbb99ee3349bbaf7e8e8e6c2a71c230a48f9d59860a29091d2747e01a5ca57"
+     "2347e247d25f56ba7ae8e05cde2be3c97931292c02370208ecd097ef692687fecf2f419d3"
+     "200162a6480a57dad408a0dfeb492e2c5d",
+     "2097e372950a5e9383c675e89eea1c314f999159f5611344b298cda45e62843716f215f82"
+     "ee663919c64002a5c198d7878fd3f",
+     "adbecdb0d5c2224d804d2886ff9a5760"},
+    {"e49af19182faef0ebeeba9f2d3be044e77b1212358366e4ef59e008aebcd9788",
+     "e7f37d79a6a487a5a703edbb",
+     "461cd0caf7427a3d44408d825ed719237272ecd503b9094d1f62c97d63ed83a0b50bdc804"
+     "ffdd7991da7a5b6dcf48d4bcd2cbc",
+     "19a9a1cfc647346781bef51ed9070d05f99a0e0192a223c5cd2522dbdf97d9739dd39fb17"
+     "8ade3339e68774b058aa03e9a20a9a205bc05f32381df4d63396ef691fefd5a71b49a2ad8"
+     "2d5ea428778ca47ee1398792762413cff4",
+     "32ca3588e3e56eb4c8301b009d8b84b8a900b2b88ca3c21944205e9dd7311757b51394ae9"
+     "0d8bb3807b471677614f4198af909",
+     "3e403d035c71d88f1be1a256c89ba6ad"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"82c4f12eeec3b2d3d157b0f992d292b237478d2cecc1d5f161389b97f999057a",
+     "7b40b20f5f397177990ef2d1", "982a296ee1cd7086afad976945", "",
+     "ec8e05a0471d6b43a59ca5335f", "113ddeafc62373cac2f5951bb9165249"},
+    {"db4340af2f835a6c6d7ea0ca9d83ca81ba02c29b7410f221cb6071114e393240",
+     "40e438357dd80a85cac3349e", "8ddb3397bd42853193cb0f80c9", "",
+     "b694118c85c41abf69e229cb0f", "c07f1b8aafbd152f697eb67f2a85fe45"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(Aes256GcmEncrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class Aes256GcmEncrypterTest : public QuicTest {};
+
+TEST_F(Aes256GcmEncrypterTest, Encrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+
+      Aes256GcmEncrypter encrypter;
+      ASSERT_TRUE(encrypter.SetKey(key));
+      std::unique_ptr<QuicData> encrypted(
+          EncryptWithNonce(&encrypter, iv,
+                           // This deliberately tests that the encrypter can
+                           // handle an AAD that is set to nullptr, as opposed
+                           // to a zero-length, non-nullptr pointer.
+                           aad.length() ? aad : absl::string_view(), pt));
+      ASSERT_TRUE(encrypted.get());
+
+      ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
+      quiche::test::CompareCharArraysWithHexError(
+          "authentication tag", encrypted->data() + ct.length(), tag.length(),
+          tag.data(), tag.length());
+    }
+  }
+}
+
+TEST_F(Aes256GcmEncrypterTest, GetMaxPlaintextSize) {
+  Aes256GcmEncrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
+}
+
+TEST_F(Aes256GcmEncrypterTest, GetCiphertextSize) {
+  Aes256GcmEncrypter encrypter;
+  EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
+}
+
+TEST_F(Aes256GcmEncrypterTest, GenerateHeaderProtectionMask) {
+  Aes256GcmEncrypter encrypter;
+  std::string key = absl::HexStringToBytes(
+      "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
+  std::string sample =
+      absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
+  ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
+  std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
+  std::string expected_mask =
+      absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_base_decrypter.cc b/quiche/quic/core/crypto/aes_base_decrypter.cc
new file mode 100644
index 0000000..fb21ffe
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_base_decrypter.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/aes_base_decrypter.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+bool AesBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) {
+  if (key.size() != GetKeySize()) {
+    QUIC_BUG(quic_bug_10649_1) << "Invalid key size for header protection";
+    return false;
+  }
+  if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key.data()),
+                          key.size() * 8, &pne_key_) != 0) {
+    QUIC_BUG(quic_bug_10649_2) << "Unexpected failure of AES_set_encrypt_key";
+    return false;
+  }
+  return true;
+}
+
+std::string AesBaseDecrypter::GenerateHeaderProtectionMask(
+    QuicDataReader* sample_reader) {
+  absl::string_view sample;
+  if (!sample_reader->ReadStringPiece(&sample, AES_BLOCK_SIZE)) {
+    return std::string();
+  }
+  std::string out(AES_BLOCK_SIZE, 0);
+  AES_encrypt(reinterpret_cast<const uint8_t*>(sample.data()),
+              reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
+              &pne_key_);
+  return out;
+}
+
+QuicPacketCount AesBaseDecrypter::GetIntegrityLimit() const {
+  // For AEAD_AES_128_GCM ... endpoints that do not attempt to remove
+  // protection from packets larger than 2^11 bytes can attempt to remove
+  // protection from at most 2^57 packets.
+  // For AEAD_AES_256_GCM [the limit] is substantially larger than the limit for
+  // AEAD_AES_128_GCM. However, this document recommends that the same limit be
+  // applied to both functions as either limit is acceptably large.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-integrity-limit
+  static_assert(kMaxIncomingPacketSize <= 2048,
+                "This key limit requires limits on decryption payload sizes");
+  return 144115188075855872U;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_base_decrypter.h b/quiche/quic/core/crypto/aes_base_decrypter.h
new file mode 100644
index 0000000..1be0f7e
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_base_decrypter.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2013 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_CRYPTO_AES_BASE_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/core/crypto/aead_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE AesBaseDecrypter : public AeadBaseDecrypter {
+ public:
+  using AeadBaseDecrypter::AeadBaseDecrypter;
+
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  std::string GenerateHeaderProtectionMask(
+      QuicDataReader* sample_reader) override;
+  QuicPacketCount GetIntegrityLimit() const override;
+
+ private:
+  // The key used for packet number encryption.
+  AES_KEY pne_key_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_base_encrypter.cc b/quiche/quic/core/crypto/aes_base_encrypter.cc
new file mode 100644
index 0000000..74298ed
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_base_encrypter.cc
@@ -0,0 +1,48 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/aes_base_encrypter.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+bool AesBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) {
+  if (key.size() != GetKeySize()) {
+    QUIC_BUG(quic_bug_10726_1)
+        << "Invalid key size for header protection: " << key.size();
+    return false;
+  }
+  if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key.data()),
+                          key.size() * 8, &pne_key_) != 0) {
+    QUIC_BUG(quic_bug_10726_2) << "Unexpected failure of AES_set_encrypt_key";
+    return false;
+  }
+  return true;
+}
+
+std::string AesBaseEncrypter::GenerateHeaderProtectionMask(
+    absl::string_view sample) {
+  if (sample.size() != AES_BLOCK_SIZE) {
+    return std::string();
+  }
+  std::string out(AES_BLOCK_SIZE, 0);
+  AES_encrypt(reinterpret_cast<const uint8_t*>(sample.data()),
+              reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
+              &pne_key_);
+  return out;
+}
+
+QuicPacketCount AesBaseEncrypter::GetConfidentialityLimit() const {
+  // For AEAD_AES_128_GCM and AEAD_AES_256_GCM ... endpoints that do not send
+  // packets larger than 2^11 bytes cannot protect more than 2^28 packets.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-confidentiality-limit
+  static_assert(kMaxOutgoingPacketSize <= 2048,
+                "This key limit requires limits on encryption payload sizes");
+  return 268435456U;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_base_encrypter.h b/quiche/quic/core/crypto/aes_base_encrypter.h
new file mode 100644
index 0000000..b929cdd
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_base_encrypter.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2013 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_CRYPTO_AES_BASE_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/core/crypto/aead_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE AesBaseEncrypter : public AeadBaseEncrypter {
+ public:
+  using AeadBaseEncrypter::AeadBaseEncrypter;
+
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
+  QuicPacketCount GetConfidentialityLimit() const override;
+
+ private:
+  // The key used for packet number encryption.
+  AES_KEY pne_key_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/boring_utils.h b/quiche/quic/core/crypto/boring_utils.h
new file mode 100644
index 0000000..4a45cf4
--- /dev/null
+++ b/quiche/quic/core/crypto/boring_utils.h
@@ -0,0 +1,34 @@
+// Copyright 2020 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_CRYPTO_BORING_UTILS_H_
+#define QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+inline QUIC_EXPORT_PRIVATE absl::string_view CbsToStringPiece(CBS cbs) {
+  return absl::string_view(reinterpret_cast<const char*>(CBS_data(&cbs)),
+                           CBS_len(&cbs));
+}
+
+inline QUIC_EXPORT_PRIVATE CBS StringPieceToCbs(absl::string_view piece) {
+  CBS result;
+  CBS_init(&result, reinterpret_cast<const uint8_t*>(piece.data()),
+           piece.size());
+  return result;
+}
+
+inline QUIC_EXPORT_PRIVATE bool AddStringToCbb(CBB* cbb,
+                                               absl::string_view piece) {
+  return 1 == CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(piece.data()),
+                            piece.size());
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
diff --git a/quiche/quic/core/crypto/cert_compressor.cc b/quiche/quic/core/crypto/cert_compressor.cc
new file mode 100644
index 0000000..4765643
--- /dev/null
+++ b/quiche/quic/core/crypto/cert_compressor.cc
@@ -0,0 +1,599 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/cert_compressor.h"
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "third_party/zlib/zlib.h"
+
+namespace quic {
+
+namespace {
+
+// kCommonCertSubstrings contains ~1500 bytes of common certificate substrings
+// in order to help zlib. This was generated via a fairly dumb algorithm from
+// the Alexa Top 5000 set - we could probably do better.
+static const unsigned char kCommonCertSubstrings[] = {
+    0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
+    0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+    0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30,
+    0x5f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01,
+    0x06, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, 0x01, 0x07,
+    0x17, 0x01, 0x30, 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65,
+    0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x53, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x34,
+    0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+    0x32, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72,
+    0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x2d, 0x61, 0x69, 0x61, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x45, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+    0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x45, 0x2e, 0x63, 0x65,
+    0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+    0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a, 0x2e, 0x63,
+    0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
+    0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x30, 0x09, 0x06,
+    0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+    0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x0e, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+    0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd2,
+    0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x2e,
+    0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+    0x04, 0x14, 0xb4, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69,
+    0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x30, 0x0b, 0x06, 0x03,
+    0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08,
+    0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30,
+    0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74,
+    0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33,
+    0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74,
+    0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
+    0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53,
+    0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55,
+    0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37,
+    0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+    0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c,
+    0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
+    0x30, 0x1d, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+    0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+    0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x03, 0x02, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+    0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
+    0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
+    0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
+    0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+    0x67, 0x64, 0x73, 0x31, 0x2d, 0x32, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
+    0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65,
+    0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
+    0x70, 0x73, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17,
+    0x0d, 0x31, 0x33, 0x30, 0x35, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a,
+    0x2f, 0x2f, 0x73, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x02, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+    0x3d, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86,
+    0xf8, 0x45, 0x01, 0x07, 0x17, 0x06, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+    0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x53, 0x31, 0x17,
+    0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+    0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, 0x65,
+    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, 0x39,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, 0x73,
+    0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, 0x68,
+    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+    0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x31, 0x10, 0x30, 0x0e,
+    0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x31, 0x13, 0x30, 0x11,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x47, 0x31, 0x13, 0x30, 0x11,
+    0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01,
+    0x03, 0x13, 0x02, 0x55, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+    0x03, 0x14, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+    0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0f, 0x13, 0x14, 0x50,
+    0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e,
+    0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x12, 0x31, 0x21, 0x30,
+    0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, 0x61,
+    0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x56,
+    0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x14, 0x31, 0x31,
+    0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x53, 0x65, 0x65,
+    0x20, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63,
+    0x75, 0x72, 0x65, 0x2e, 0x67, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53,
+    0x69, 0x67, 0x6e, 0x31, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41,
+    0x2e, 0x63, 0x72, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x63, 0x72,
+    0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
+    0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x64, 0x31, 0x1a,
+    0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a,
+    0x2f, 0x2f, 0x45, 0x56, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63, 0x63, 0x72,
+    0x74, 0x2e, 0x67, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x69, 0x63, 0x65, 0x72,
+    0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x31, 0x6f, 0x63, 0x73, 0x70, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x30, 0x39, 0x72, 0x61, 0x70, 0x69, 0x64, 0x73, 0x73, 0x6c, 0x2e, 0x63,
+    0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63,
+    0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72,
+    0x79, 0x2f, 0x30, 0x81, 0x80, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+    0x07, 0x01, 0x01, 0x04, 0x74, 0x30, 0x72, 0x30, 0x24, 0x06, 0x08, 0x2b,
+    0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+    0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
+    0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x4a, 0x06,
+    0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68,
+    0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64,
+    0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
+    0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74,
+    0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72,
+    0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+    0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee,
+    0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x27,
+    0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x86, 0x30,
+    0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
+};
+
+// CertEntry represents a certificate in compressed form. Each entry is one of
+// the three types enumerated in |Type|.
+struct CertEntry {
+ public:
+  enum Type {
+    // Type 0 is reserved to mean "end of list" in the wire format.
+
+    // COMPRESSED means that the certificate is included in the trailing zlib
+    // data.
+    COMPRESSED = 1,
+    // CACHED means that the certificate is already known to the peer and will
+    // be replaced by its 64-bit hash (in |hash|).
+    CACHED = 2,
+  };
+
+  Type type;
+  uint64_t hash;
+  uint64_t set_hash;
+  uint32_t index;
+};
+
+// MatchCerts returns a vector of CertEntries describing how to most
+// efficiently represent |certs| to a peer who has cached the certificates
+// with the 64-bit, FNV-1a hashes in |client_cached_cert_hashes|.
+std::vector<CertEntry> MatchCerts(const std::vector<std::string>& certs,
+                                  absl::string_view client_cached_cert_hashes) {
+  std::vector<CertEntry> entries;
+  entries.reserve(certs.size());
+
+  const bool cached_valid =
+      client_cached_cert_hashes.size() % sizeof(uint64_t) == 0 &&
+      !client_cached_cert_hashes.empty();
+
+  for (auto i = certs.begin(); i != certs.end(); ++i) {
+    CertEntry entry;
+
+    if (cached_valid) {
+      bool cached = false;
+
+      uint64_t hash = QuicUtils::FNV1a_64_Hash(*i);
+      // This assumes that the machine is little-endian.
+      for (size_t j = 0; j < client_cached_cert_hashes.size();
+           j += sizeof(uint64_t)) {
+        uint64_t cached_hash;
+        memcpy(&cached_hash, client_cached_cert_hashes.data() + j,
+               sizeof(uint64_t));
+        if (hash != cached_hash) {
+          continue;
+        }
+
+        entry.type = CertEntry::CACHED;
+        entry.hash = hash;
+        entries.push_back(entry);
+        cached = true;
+        break;
+      }
+
+      if (cached) {
+        continue;
+      }
+    }
+
+    entry.type = CertEntry::COMPRESSED;
+    entries.push_back(entry);
+  }
+
+  return entries;
+}
+
+// CertEntriesSize returns the size, in bytes, of the serialised form of
+// |entries|.
+size_t CertEntriesSize(const std::vector<CertEntry>& entries) {
+  size_t entries_size = 0;
+
+  for (auto i = entries.begin(); i != entries.end(); ++i) {
+    entries_size++;
+    switch (i->type) {
+      case CertEntry::COMPRESSED:
+        break;
+      case CertEntry::CACHED:
+        entries_size += sizeof(uint64_t);
+        break;
+    }
+  }
+
+  entries_size++;  // for end marker
+
+  return entries_size;
+}
+
+// SerializeCertEntries serialises |entries| to |out|, which must have enough
+// space to contain them.
+void SerializeCertEntries(uint8_t* out, const std::vector<CertEntry>& entries) {
+  for (auto i = entries.begin(); i != entries.end(); ++i) {
+    *out++ = static_cast<uint8_t>(i->type);
+    switch (i->type) {
+      case CertEntry::COMPRESSED:
+        break;
+      case CertEntry::CACHED:
+        memcpy(out, &i->hash, sizeof(i->hash));
+        out += sizeof(uint64_t);
+        break;
+    }
+  }
+
+  *out++ = 0;  // end marker
+}
+
+// ZlibDictForEntries returns a string that contains the zlib pre-shared
+// dictionary to use in order to decompress a zlib block following |entries|.
+// |certs| is one-to-one with |entries| and contains the certificates for those
+// entries that are CACHED.
+std::string ZlibDictForEntries(const std::vector<CertEntry>& entries,
+                               const std::vector<std::string>& certs) {
+  std::string zlib_dict;
+
+  // The dictionary starts with the cached certs in reverse order.
+  size_t zlib_dict_size = 0;
+  for (size_t i = certs.size() - 1; i < certs.size(); i--) {
+    if (entries[i].type != CertEntry::COMPRESSED) {
+      zlib_dict_size += certs[i].size();
+    }
+  }
+
+  // At the end of the dictionary is a block of common certificate substrings.
+  zlib_dict_size += sizeof(kCommonCertSubstrings);
+
+  zlib_dict.reserve(zlib_dict_size);
+
+  for (size_t i = certs.size() - 1; i < certs.size(); i--) {
+    if (entries[i].type != CertEntry::COMPRESSED) {
+      zlib_dict += certs[i];
+    }
+  }
+
+  zlib_dict += std::string(reinterpret_cast<const char*>(kCommonCertSubstrings),
+                           sizeof(kCommonCertSubstrings));
+
+  QUICHE_DCHECK_EQ(zlib_dict.size(), zlib_dict_size);
+
+  return zlib_dict;
+}
+
+// HashCerts returns the FNV-1a hashes of |certs|.
+std::vector<uint64_t> HashCerts(const std::vector<std::string>& certs) {
+  std::vector<uint64_t> ret;
+  ret.reserve(certs.size());
+
+  for (auto i = certs.begin(); i != certs.end(); ++i) {
+    ret.push_back(QuicUtils::FNV1a_64_Hash(*i));
+  }
+
+  return ret;
+}
+
+// ParseEntries parses the serialised form of a vector of CertEntries from
+// |in_out| and writes them to |out_entries|. CACHED entries are resolved using
+// |cached_certs| and written to |out_certs|. |in_out| is updated to contain
+// the trailing data.
+bool ParseEntries(absl::string_view* in_out,
+                  const std::vector<std::string>& cached_certs,
+                  std::vector<CertEntry>* out_entries,
+                  std::vector<std::string>* out_certs) {
+  absl::string_view in = *in_out;
+  std::vector<uint64_t> cached_hashes;
+
+  out_entries->clear();
+  out_certs->clear();
+
+  for (;;) {
+    if (in.empty()) {
+      return false;
+    }
+    CertEntry entry;
+    const uint8_t type_byte = in[0];
+    in.remove_prefix(1);
+
+    if (type_byte == 0) {
+      break;
+    }
+
+    entry.type = static_cast<CertEntry::Type>(type_byte);
+
+    switch (entry.type) {
+      case CertEntry::COMPRESSED:
+        out_certs->push_back(std::string());
+        break;
+      case CertEntry::CACHED: {
+        if (in.size() < sizeof(uint64_t)) {
+          return false;
+        }
+        memcpy(&entry.hash, in.data(), sizeof(uint64_t));
+        in.remove_prefix(sizeof(uint64_t));
+
+        if (cached_hashes.size() != cached_certs.size()) {
+          cached_hashes = HashCerts(cached_certs);
+        }
+        bool found = false;
+        for (size_t i = 0; i < cached_hashes.size(); i++) {
+          if (cached_hashes[i] == entry.hash) {
+            out_certs->push_back(cached_certs[i]);
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          return false;
+        }
+        break;
+      }
+
+      default:
+        return false;
+    }
+    out_entries->push_back(entry);
+  }
+
+  *in_out = in;
+  return true;
+}
+
+// ScopedZLib deals with the automatic destruction of a zlib context.
+class ScopedZLib {
+ public:
+  enum Type {
+    INFLATE,
+    DEFLATE,
+  };
+
+  explicit ScopedZLib(Type type) : z_(nullptr), type_(type) {}
+
+  void reset(z_stream* z) {
+    Clear();
+    z_ = z;
+  }
+
+  ~ScopedZLib() { Clear(); }
+
+ private:
+  void Clear() {
+    if (!z_) {
+      return;
+    }
+
+    if (type_ == DEFLATE) {
+      deflateEnd(z_);
+    } else {
+      inflateEnd(z_);
+    }
+    z_ = nullptr;
+  }
+
+  z_stream* z_;
+  const Type type_;
+};
+
+}  // anonymous namespace
+
+// static
+std::string CertCompressor::CompressChain(
+    const std::vector<std::string>& certs,
+    absl::string_view client_cached_cert_hashes) {
+  const std::vector<CertEntry> entries =
+      MatchCerts(certs, client_cached_cert_hashes);
+  QUICHE_DCHECK_EQ(entries.size(), certs.size());
+
+  size_t uncompressed_size = 0;
+  for (size_t i = 0; i < entries.size(); i++) {
+    if (entries[i].type == CertEntry::COMPRESSED) {
+      uncompressed_size += 4 /* uint32_t length */ + certs[i].size();
+    }
+  }
+
+  size_t compressed_size = 0;
+  z_stream z;
+  ScopedZLib scoped_z(ScopedZLib::DEFLATE);
+
+  if (uncompressed_size > 0) {
+    memset(&z, 0, sizeof(z));
+    int rv = deflateInit(&z, Z_DEFAULT_COMPRESSION);
+    QUICHE_DCHECK_EQ(Z_OK, rv);
+    if (rv != Z_OK) {
+      return "";
+    }
+    scoped_z.reset(&z);
+
+    std::string zlib_dict = ZlibDictForEntries(entries, certs);
+
+    rv = deflateSetDictionary(
+        &z, reinterpret_cast<const uint8_t*>(&zlib_dict[0]), zlib_dict.size());
+    QUICHE_DCHECK_EQ(Z_OK, rv);
+    if (rv != Z_OK) {
+      return "";
+    }
+
+    compressed_size = deflateBound(&z, uncompressed_size);
+  }
+
+  const size_t entries_size = CertEntriesSize(entries);
+
+  std::string result;
+  result.resize(entries_size + (uncompressed_size > 0 ? 4 : 0) +
+                compressed_size);
+
+  uint8_t* j = reinterpret_cast<uint8_t*>(&result[0]);
+  SerializeCertEntries(j, entries);
+  j += entries_size;
+
+  if (uncompressed_size == 0) {
+    return result;
+  }
+
+  uint32_t uncompressed_size_32 = uncompressed_size;
+  memcpy(j, &uncompressed_size_32, sizeof(uint32_t));
+  j += sizeof(uint32_t);
+
+  int rv;
+
+  z.next_out = j;
+  z.avail_out = compressed_size;
+
+  for (size_t i = 0; i < certs.size(); i++) {
+    if (entries[i].type != CertEntry::COMPRESSED) {
+      continue;
+    }
+
+    uint32_t length32 = certs[i].size();
+    z.next_in = reinterpret_cast<uint8_t*>(&length32);
+    z.avail_in = sizeof(length32);
+    rv = deflate(&z, Z_NO_FLUSH);
+    QUICHE_DCHECK_EQ(Z_OK, rv);
+    QUICHE_DCHECK_EQ(0u, z.avail_in);
+    if (rv != Z_OK || z.avail_in) {
+      return "";
+    }
+
+    z.next_in =
+        const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(certs[i].data()));
+    z.avail_in = certs[i].size();
+    rv = deflate(&z, Z_NO_FLUSH);
+    QUICHE_DCHECK_EQ(Z_OK, rv);
+    QUICHE_DCHECK_EQ(0u, z.avail_in);
+    if (rv != Z_OK || z.avail_in) {
+      return "";
+    }
+  }
+
+  z.avail_in = 0;
+  rv = deflate(&z, Z_FINISH);
+  QUICHE_DCHECK_EQ(Z_STREAM_END, rv);
+  if (rv != Z_STREAM_END) {
+    return "";
+  }
+
+  result.resize(result.size() - z.avail_out);
+  return result;
+}
+
+// static
+bool CertCompressor::DecompressChain(
+    absl::string_view in,
+    const std::vector<std::string>& cached_certs,
+    std::vector<std::string>* out_certs) {
+  std::vector<CertEntry> entries;
+  if (!ParseEntries(&in, cached_certs, &entries, out_certs)) {
+    return false;
+  }
+  QUICHE_DCHECK_EQ(entries.size(), out_certs->size());
+
+  std::unique_ptr<uint8_t[]> uncompressed_data;
+  absl::string_view uncompressed;
+
+  if (!in.empty()) {
+    if (in.size() < sizeof(uint32_t)) {
+      return false;
+    }
+
+    uint32_t uncompressed_size;
+    memcpy(&uncompressed_size, in.data(), sizeof(uncompressed_size));
+    in.remove_prefix(sizeof(uint32_t));
+
+    if (uncompressed_size > 128 * 1024) {
+      return false;
+    }
+
+    uncompressed_data = std::make_unique<uint8_t[]>(uncompressed_size);
+    z_stream z;
+    ScopedZLib scoped_z(ScopedZLib::INFLATE);
+
+    memset(&z, 0, sizeof(z));
+    z.next_out = uncompressed_data.get();
+    z.avail_out = uncompressed_size;
+    z.next_in =
+        const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(in.data()));
+    z.avail_in = in.size();
+
+    if (Z_OK != inflateInit(&z)) {
+      return false;
+    }
+    scoped_z.reset(&z);
+
+    int rv = inflate(&z, Z_FINISH);
+    if (rv == Z_NEED_DICT) {
+      std::string zlib_dict = ZlibDictForEntries(entries, *out_certs);
+      const uint8_t* dict = reinterpret_cast<const uint8_t*>(zlib_dict.data());
+      if (Z_OK != inflateSetDictionary(&z, dict, zlib_dict.size())) {
+        return false;
+      }
+      rv = inflate(&z, Z_FINISH);
+    }
+
+    if (Z_STREAM_END != rv || z.avail_out > 0 || z.avail_in > 0) {
+      return false;
+    }
+
+    uncompressed = absl::string_view(
+        reinterpret_cast<char*>(uncompressed_data.get()), uncompressed_size);
+  }
+
+  for (size_t i = 0; i < entries.size(); i++) {
+    switch (entries[i].type) {
+      case CertEntry::COMPRESSED:
+        if (uncompressed.size() < sizeof(uint32_t)) {
+          return false;
+        }
+        uint32_t cert_len;
+        memcpy(&cert_len, uncompressed.data(), sizeof(cert_len));
+        uncompressed.remove_prefix(sizeof(uint32_t));
+        if (uncompressed.size() < cert_len) {
+          return false;
+        }
+        (*out_certs)[i] = std::string(uncompressed.substr(0, cert_len));
+        uncompressed.remove_prefix(cert_len);
+        break;
+      case CertEntry::CACHED:
+        break;
+    }
+  }
+
+  if (!uncompressed.empty()) {
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/cert_compressor.h b/quiche/quic/core/crypto/cert_compressor.h
new file mode 100644
index 0000000..9509ccd
--- /dev/null
+++ b/quiche/quic/core/crypto/cert_compressor.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2013 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_CRYPTO_CERT_COMPRESSOR_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// CertCompressor provides functions for compressing and decompressing
+// certificate chains using two techniquies:
+//   1) The peer may provide a list of a 64-bit, FNV-1a hashes of certificates
+//      that they already have. In the event that one of them is to be
+//      compressed, it can be replaced with just the hash.
+//   2) Otherwise the certificates are compressed with zlib using a pre-shared
+//      dictionary that consists of the certificates handled with the above
+//      methods and a small chunk of common substrings.
+class QUIC_EXPORT_PRIVATE CertCompressor {
+ public:
+  CertCompressor() = delete;
+
+  // CompressChain compresses the certificates in |certs| and returns a
+  // compressed representation. client_cached_cert_hashes| contains
+  // 64-bit, FNV-1a hashes of certificates that the peer already possesses.
+  static std::string CompressChain(const std::vector<std::string>& certs,
+                                   absl::string_view client_cached_cert_hashes);
+
+  // DecompressChain decompresses the result of |CompressChain|, given in |in|,
+  // into a series of certificates that are written to |out_certs|.
+  // |cached_certs| contains certificates that the peer may have omitted.
+  static bool DecompressChain(absl::string_view in,
+                              const std::vector<std::string>& cached_certs,
+                              std::vector<std::string>* out_certs);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
diff --git a/quiche/quic/core/crypto/cert_compressor_test.cc b/quiche/quic/core/crypto/cert_compressor_test.cc
new file mode 100644
index 0000000..d98f4c7
--- /dev/null
+++ b/quiche/quic/core/crypto/cert_compressor_test.cc
@@ -0,0 +1,119 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/cert_compressor.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class CertCompressorTest : public QuicTest {};
+
+TEST_F(CertCompressorTest, EmptyChain) {
+  std::vector<std::string> chain;
+  const std::string compressed =
+      CertCompressor::CompressChain(chain, absl::string_view());
+  EXPECT_EQ("00", absl::BytesToHexString(compressed));
+
+  std::vector<std::string> chain2, cached_certs;
+  ASSERT_TRUE(
+      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
+  EXPECT_EQ(chain.size(), chain2.size());
+}
+
+TEST_F(CertCompressorTest, Compressed) {
+  std::vector<std::string> chain;
+  chain.push_back("testcert");
+  const std::string compressed =
+      CertCompressor::CompressChain(chain, absl::string_view());
+  ASSERT_GE(compressed.size(), 2u);
+  EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2)));
+
+  std::vector<std::string> chain2, cached_certs;
+  ASSERT_TRUE(
+      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
+  EXPECT_EQ(chain.size(), chain2.size());
+  EXPECT_EQ(chain[0], chain2[0]);
+}
+
+TEST_F(CertCompressorTest, Common) {
+  std::vector<std::string> chain;
+  chain.push_back("testcert");
+  static const uint64_t set_hash = 42;
+  const std::string compressed = CertCompressor::CompressChain(
+      chain, absl::string_view(reinterpret_cast<const char*>(&set_hash),
+                               sizeof(set_hash)));
+  ASSERT_GE(compressed.size(), 2u);
+  // 01 is the prefix for a zlib "compressed" cert not common or cached.
+  EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2)));
+
+  std::vector<std::string> chain2, cached_certs;
+  ASSERT_TRUE(
+      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
+  EXPECT_EQ(chain.size(), chain2.size());
+  EXPECT_EQ(chain[0], chain2[0]);
+}
+
+TEST_F(CertCompressorTest, Cached) {
+  std::vector<std::string> chain;
+  chain.push_back("testcert");
+  uint64_t hash = QuicUtils::FNV1a_64_Hash(chain[0]);
+  absl::string_view hash_bytes(reinterpret_cast<char*>(&hash), sizeof(hash));
+  const std::string compressed =
+      CertCompressor::CompressChain(chain, hash_bytes);
+
+  EXPECT_EQ("02" /* cached */ + absl::BytesToHexString(hash_bytes) +
+                "00" /* end of list */,
+            absl::BytesToHexString(compressed));
+
+  std::vector<std::string> cached_certs, chain2;
+  cached_certs.push_back(chain[0]);
+  ASSERT_TRUE(
+      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
+  EXPECT_EQ(chain.size(), chain2.size());
+  EXPECT_EQ(chain[0], chain2[0]);
+}
+
+TEST_F(CertCompressorTest, BadInputs) {
+  std::vector<std::string> cached_certs, chain;
+
+  EXPECT_FALSE(CertCompressor::DecompressChain(
+      absl::BytesToHexString("04") /* bad entry type */, cached_certs, &chain));
+
+  EXPECT_FALSE(CertCompressor::DecompressChain(
+      absl::BytesToHexString("01") /* no terminator */, cached_certs, &chain));
+
+  EXPECT_FALSE(CertCompressor::DecompressChain(
+      absl::BytesToHexString("0200") /* hash truncated */, cached_certs,
+      &chain));
+
+  EXPECT_FALSE(CertCompressor::DecompressChain(
+      absl::BytesToHexString("0300") /* hash and index truncated */,
+      cached_certs, &chain));
+
+  /* without a CommonCertSets */
+  EXPECT_FALSE(
+      CertCompressor::DecompressChain(absl::BytesToHexString("03"
+                                                             "0000000000000000"
+                                                             "00000000"),
+                                      cached_certs, &chain));
+
+  /* incorrect hash and index */
+  EXPECT_FALSE(
+      CertCompressor::DecompressChain(absl::BytesToHexString("03"
+                                                             "a200000000000000"
+                                                             "00000000"),
+                                      cached_certs, &chain));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/certificate_util.cc b/quiche/quic/core/crypto/certificate_util.cc
new file mode 100644
index 0000000..e56d9cf
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_util.cc
@@ -0,0 +1,280 @@
+// Copyright 2021 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 "quiche/quic/core/crypto/certificate_util.h"
+
+#include "absl/strings/str_format.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/ec_key.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
+#include "third_party/boringssl/src/include/openssl/pkcs7.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
+#include "third_party/boringssl/src/include/openssl/rsa.h"
+#include "third_party/boringssl/src/include/openssl/stack.h"
+#include "quiche/quic/core/crypto/boring_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace {
+bool AddEcdsa256SignatureAlgorithm(CBB* cbb) {
+  // See RFC 5758. This is the encoding of OID 1.2.840.10045.4.3.2.
+  static const uint8_t kEcdsaWithSha256[] = {0x2a, 0x86, 0x48, 0xce,
+                                             0x3d, 0x04, 0x03, 0x02};
+
+  // An AlgorithmIdentifier is described in RFC 5280, 4.1.1.2.
+  CBB sequence, oid;
+  if (!CBB_add_asn1(cbb, &sequence, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&sequence, &oid, CBS_ASN1_OBJECT)) {
+    return false;
+  }
+
+  if (!CBB_add_bytes(&oid, kEcdsaWithSha256, sizeof(kEcdsaWithSha256))) {
+    return false;
+  }
+
+  // RFC 5758, section 3.2: ecdsa-with-sha256 MUST omit the parameters field.
+  return CBB_flush(cbb);
+}
+
+// Adds an X.509 Name with the specified distinguished name to |cbb|.
+bool AddName(CBB* cbb, absl::string_view name) {
+  // See RFC 4519.
+  static const uint8_t kCommonName[] = {0x55, 0x04, 0x03};
+  static const uint8_t kCountryName[] = {0x55, 0x04, 0x06};
+  static const uint8_t kOrganizationName[] = {0x55, 0x04, 0x0a};
+  static const uint8_t kOrganizationalUnitName[] = {0x55, 0x04, 0x0b};
+
+  std::vector<std::string> attributes =
+      absl::StrSplit(name, ',', absl::SkipEmpty());
+
+  if (attributes.empty()) {
+    QUIC_LOG(ERROR) << "Missing DN or wrong format";
+    return false;
+  }
+
+  // See RFC 5280, section 4.1.2.4.
+  CBB rdns;
+  if (!CBB_add_asn1(cbb, &rdns, CBS_ASN1_SEQUENCE)) {
+    return false;
+  }
+
+  for (const std::string& attribute : attributes) {
+    std::vector<std::string> parts =
+        absl::StrSplit(absl::StripAsciiWhitespace(attribute), '=');
+    if (parts.size() != 2) {
+      QUIC_LOG(ERROR) << "Wrong DN format at " + attribute;
+      return false;
+    }
+
+    const std::string& type_string = parts[0];
+    const std::string& value_string = parts[1];
+    absl::Span<const uint8_t> type_bytes;
+    if (type_string == "CN") {
+      type_bytes = kCommonName;
+    } else if (type_string == "C") {
+      type_bytes = kCountryName;
+    } else if (type_string == "O") {
+      type_bytes = kOrganizationName;
+    } else if (type_string == "OU") {
+      type_bytes = kOrganizationalUnitName;
+    } else {
+      QUIC_LOG(ERROR) << "Unrecognized type " + type_string;
+      return false;
+    }
+
+    CBB rdn, attr, type, value;
+    if (!CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) ||
+        !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) ||
+        !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) ||
+        !CBB_add_bytes(&type, type_bytes.data(), type_bytes.size()) ||
+        !CBB_add_asn1(&attr, &value,
+                      type_string == "C" ? CBS_ASN1_PRINTABLESTRING
+                                         : CBS_ASN1_UTF8STRING) ||
+        !AddStringToCbb(&value, value_string) || !CBB_flush(&rdns)) {
+      return false;
+    }
+  }
+  if (!CBB_flush(cbb)) {
+    return false;
+  }
+  return true;
+}
+
+bool CBBAddTime(CBB* cbb, const CertificateTimestamp& timestamp) {
+  CBB child;
+  std::string formatted_time;
+
+  // Per RFC 5280, 4.1.2.5, times which fit in UTCTime must be encoded as
+  // UTCTime rather than GeneralizedTime.
+  const bool is_utc_time = (1950 <= timestamp.year && timestamp.year < 2050);
+  if (is_utc_time) {
+    uint16_t year = timestamp.year - 1900;
+    if (year >= 100) {
+      year -= 100;
+    }
+    formatted_time = absl::StrFormat("%02d", year);
+    if (!CBB_add_asn1(cbb, &child, CBS_ASN1_UTCTIME)) {
+      return false;
+    }
+  } else {
+    formatted_time = absl::StrFormat("%04d", timestamp.year);
+    if (!CBB_add_asn1(cbb, &child, CBS_ASN1_GENERALIZEDTIME)) {
+      return false;
+    }
+  }
+
+  absl::StrAppendFormat(&formatted_time, "%02d%02d%02d%02d%02dZ",
+                        timestamp.month, timestamp.day, timestamp.hour,
+                        timestamp.minute, timestamp.second);
+
+  static const size_t kGeneralizedTimeLength = 15;
+  static const size_t kUTCTimeLength = 13;
+  QUICHE_DCHECK_EQ(formatted_time.size(),
+                   is_utc_time ? kUTCTimeLength : kGeneralizedTimeLength);
+
+  return AddStringToCbb(&child, formatted_time) && CBB_flush(cbb);
+}
+
+bool CBBAddExtension(CBB* extensions, absl::Span<const uint8_t> oid,
+                     bool critical, absl::Span<const uint8_t> contents) {
+  CBB extension, cbb_oid, cbb_contents;
+  if (!CBB_add_asn1(extensions, &extension, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&extension, &cbb_oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&cbb_oid, oid.data(), oid.size()) ||
+      (critical && !CBB_add_asn1_bool(&extension, 1)) ||
+      !CBB_add_asn1(&extension, &cbb_contents, CBS_ASN1_OCTETSTRING) ||
+      !CBB_add_bytes(&cbb_contents, contents.data(), contents.size()) ||
+      !CBB_flush(extensions)) {
+    return false;
+  }
+
+  return true;
+}
+
+bool IsEcdsa256Key(const EVP_PKEY& evp_key) {
+  if (EVP_PKEY_id(&evp_key) != EVP_PKEY_EC) {
+    return false;
+  }
+  const EC_KEY* key = EVP_PKEY_get0_EC_KEY(&evp_key);
+  if (key == nullptr) {
+    return false;
+  }
+  const EC_GROUP* group = EC_KEY_get0_group(key);
+  if (group == nullptr) {
+    return false;
+  }
+  return EC_GROUP_get_curve_name(group) == NID_X9_62_prime256v1;
+}
+
+}  // namespace
+
+bssl::UniquePtr<EVP_PKEY> MakeKeyPairForSelfSignedCertificate() {
+  bssl::UniquePtr<EVP_PKEY_CTX> context(
+      EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
+  if (!context) {
+    return nullptr;
+  }
+  if (EVP_PKEY_keygen_init(context.get()) != 1) {
+    return nullptr;
+  }
+  if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(context.get(),
+                                             NID_X9_62_prime256v1) != 1) {
+    return nullptr;
+  }
+  EVP_PKEY* raw_key = nullptr;
+  if (EVP_PKEY_keygen(context.get(), &raw_key) != 1) {
+    return nullptr;
+  }
+  return bssl::UniquePtr<EVP_PKEY>(raw_key);
+}
+
+std::string CreateSelfSignedCertificate(EVP_PKEY& key,
+                                        const CertificateOptions& options) {
+  std::string error;
+  if (!IsEcdsa256Key(key)) {
+    QUIC_LOG(ERROR) << "CreateSelfSignedCert only accepts ECDSA P-256 keys";
+    return error;
+  }
+
+  // See RFC 5280, section 4.1. First, construct the TBSCertificate.
+  bssl::ScopedCBB cbb;
+  CBB tbs_cert, version, validity;
+  uint8_t* tbs_cert_bytes;
+  size_t tbs_cert_len;
+
+  if (!CBB_init(cbb.get(), 64) ||
+      !CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&tbs_cert, &version,
+                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
+      !CBB_add_asn1_uint64(&version, 2) ||  // X.509 version 3
+      !CBB_add_asn1_uint64(&tbs_cert, options.serial_number) ||
+      !AddEcdsa256SignatureAlgorithm(&tbs_cert) ||  // signature algorithm
+      !AddName(&tbs_cert, options.subject) ||       // issuer
+      !CBB_add_asn1(&tbs_cert, &validity, CBS_ASN1_SEQUENCE) ||
+      !CBBAddTime(&validity, options.validity_start) ||
+      !CBBAddTime(&validity, options.validity_end) ||
+      !AddName(&tbs_cert, options.subject) ||      // subject
+      !EVP_marshal_public_key(&tbs_cert, &key)) {  // subjectPublicKeyInfo
+    return error;
+  }
+
+  CBB outer_extensions, extensions;
+  if (!CBB_add_asn1(&tbs_cert, &outer_extensions,
+                    3 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED) ||
+      !CBB_add_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
+    return error;
+  }
+
+  // Key Usage
+  constexpr uint8_t kKeyUsageOid[] = {0x55, 0x1d, 0x0f};
+  constexpr uint8_t kKeyUsageContent[] = {
+      0x3,   // BIT STRING
+      0x2,   // Length
+      0x0,   // Unused bits
+      0x80,  // bit(0): digitalSignature
+  };
+  CBBAddExtension(&extensions, kKeyUsageOid, true, kKeyUsageContent);
+
+  // TODO(wub): Add more extensions here if needed.
+
+  if (!CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len)) {
+    return error;
+  }
+
+  bssl::UniquePtr<uint8_t> delete_tbs_cert_bytes(tbs_cert_bytes);
+
+  // Sign the TBSCertificate and write the entire certificate.
+  CBB cert, signature;
+  bssl::ScopedEVP_MD_CTX ctx;
+  uint8_t* sig_out;
+  size_t sig_len;
+  uint8_t* cert_bytes;
+  size_t cert_len;
+  if (!CBB_init(cbb.get(), tbs_cert_len) ||
+      !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_bytes(&cert, tbs_cert_bytes, tbs_cert_len) ||
+      !AddEcdsa256SignatureAlgorithm(&cert) ||
+      !CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) ||
+      !CBB_add_u8(&signature, 0 /* no unused bits */) ||
+      !EVP_DigestSignInit(ctx.get(), nullptr, EVP_sha256(), nullptr, &key) ||
+      // Compute the maximum signature length.
+      !EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes,
+                      tbs_cert_len) ||
+      !CBB_reserve(&signature, &sig_out, sig_len) ||
+      // Actually sign the TBSCertificate.
+      !EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_cert_bytes,
+                      tbs_cert_len) ||
+      !CBB_did_write(&signature, sig_len) ||
+      !CBB_finish(cbb.get(), &cert_bytes, &cert_len)) {
+    return error;
+  }
+  bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes);
+  return std::string(reinterpret_cast<char*>(cert_bytes), cert_len);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/certificate_util.h b/quiche/quic/core/crypto/certificate_util.h
new file mode 100644
index 0000000..40c9f87
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_util.h
@@ -0,0 +1,46 @@
+// Copyright 2021 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_CRYPTO_CERTIFICATE_UTIL_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_NO_EXPORT CertificateTimestamp {
+  uint16_t year;
+  uint8_t month;
+  uint8_t day;
+  uint8_t hour;
+  uint8_t minute;
+  uint8_t second;
+};
+
+struct QUIC_NO_EXPORT CertificateOptions {
+  absl::string_view subject;
+  uint64_t serial_number;
+  CertificateTimestamp validity_start;  // a.k.a not_valid_before
+  CertificateTimestamp validity_end;    // a.k.a not_valid_after
+};
+
+// Creates a ECDSA P-256 key pair.
+QUIC_EXPORT_PRIVATE bssl::UniquePtr<EVP_PKEY>
+MakeKeyPairForSelfSignedCertificate();
+
+// Creates a self-signed, DER-encoded X.509 certificate.
+// |key| must be a ECDSA P-256 key.
+// This is mostly stolen from Chromium's net/cert/x509_util.h, with
+// modifications to make it work in QUICHE.
+QUIC_EXPORT_PRIVATE std::string CreateSelfSignedCertificate(
+    EVP_PKEY& key, const CertificateOptions& options);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
diff --git a/quiche/quic/core/crypto/certificate_util_test.cc b/quiche/quic/core/crypto/certificate_util_test.cc
new file mode 100644
index 0000000..1c67a4a
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_util_test.cc
@@ -0,0 +1,49 @@
+// Copyright 2021 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 "quiche/quic/core/crypto/certificate_util.h"
+
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_output.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(CertificateUtilTest, CreateSelfSignedCertificate) {
+  bssl::UniquePtr<EVP_PKEY> key = MakeKeyPairForSelfSignedCertificate();
+  ASSERT_NE(key, nullptr);
+
+  CertificatePrivateKey cert_key(std::move(key));
+
+  CertificateOptions options;
+  options.subject = "CN=subject";
+  options.serial_number = 0x12345678;
+  options.validity_start = {2020, 1, 1, 0, 0, 0};
+  options.validity_end = {2049, 12, 31, 0, 0, 0};
+  std::string der_cert =
+      CreateSelfSignedCertificate(*cert_key.private_key(), options);
+  ASSERT_FALSE(der_cert.empty());
+
+  QuicSaveTestOutput("CertificateUtilTest_CreateSelfSignedCert.crt", der_cert);
+
+  std::unique_ptr<CertificateView> cert_view =
+      CertificateView::ParseSingleCertificate(der_cert);
+  ASSERT_NE(cert_view, nullptr);
+  EXPECT_EQ(cert_view->public_key_type(), PublicKeyType::kP256);
+
+  absl::optional<std::string> subject = cert_view->GetHumanReadableSubject();
+  ASSERT_TRUE(subject.has_value());
+  EXPECT_EQ(*subject, options.subject);
+
+  EXPECT_TRUE(
+      cert_key.ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256));
+  EXPECT_TRUE(cert_key.MatchesPublicKey(*cert_view));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/certificate_view.cc b/quiche/quic/core/crypto/certificate_view.cc
new file mode 100644
index 0000000..aa2440b
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view.cc
@@ -0,0 +1,650 @@
+// Copyright 2020 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 "quiche/quic/core/crypto/certificate_view.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/match.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/ec_key.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/nid.h"
+#include "third_party/boringssl/src/include/openssl/rsa.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/boring_utils.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_time_utils.h"
+#include "quiche/common/quiche_data_reader.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace {
+
+using ::quiche::QuicheTextUtils;
+
+// The literals below were encoded using `ascii2der | xxd -i`.  The comments
+// above the literals are the contents in the der2ascii syntax.
+
+// X.509 version 3 (version numbering starts with zero).
+// INTEGER { 2 }
+constexpr uint8_t kX509Version[] = {0x02, 0x01, 0x02};
+
+// 2.5.29.17
+constexpr uint8_t kSubjectAltNameOid[] = {0x55, 0x1d, 0x11};
+
+PublicKeyType PublicKeyTypeFromKey(EVP_PKEY* public_key) {
+  switch (EVP_PKEY_id(public_key)) {
+    case EVP_PKEY_RSA:
+      return PublicKeyType::kRsa;
+    case EVP_PKEY_EC: {
+      const EC_KEY* key = EVP_PKEY_get0_EC_KEY(public_key);
+      if (key == nullptr) {
+        return PublicKeyType::kUnknown;
+      }
+      const EC_GROUP* group = EC_KEY_get0_group(key);
+      if (group == nullptr) {
+        return PublicKeyType::kUnknown;
+      }
+      const int curve_nid = EC_GROUP_get_curve_name(group);
+      switch (curve_nid) {
+        case NID_X9_62_prime256v1:
+          return PublicKeyType::kP256;
+        case NID_secp384r1:
+          return PublicKeyType::kP384;
+        default:
+          return PublicKeyType::kUnknown;
+      }
+    }
+    case EVP_PKEY_ED25519:
+      return PublicKeyType::kEd25519;
+    default:
+      return PublicKeyType::kUnknown;
+  }
+}
+
+PublicKeyType PublicKeyTypeFromSignatureAlgorithm(
+    uint16_t signature_algorithm) {
+  switch (signature_algorithm) {
+    case SSL_SIGN_RSA_PSS_RSAE_SHA256:
+      return PublicKeyType::kRsa;
+    case SSL_SIGN_ECDSA_SECP256R1_SHA256:
+      return PublicKeyType::kP256;
+    case SSL_SIGN_ECDSA_SECP384R1_SHA384:
+      return PublicKeyType::kP384;
+    case SSL_SIGN_ED25519:
+      return PublicKeyType::kEd25519;
+    default:
+      return PublicKeyType::kUnknown;
+  }
+}
+
+std::string AttributeNameToString(const CBS& oid_cbs) {
+  absl::string_view oid = CbsToStringPiece(oid_cbs);
+
+  // We only handle OIDs of form 2.5.4.N, which have binary encoding of
+  // "55 04 0N".
+  if (oid.length() == 3 && absl::StartsWith(oid, "\x55\x04")) {
+    // clang-format off
+    switch (oid[2]) {
+      case '\x3': return "CN";
+      case '\x7': return "L";
+      case '\x8': return "ST";
+      case '\xa': return "O";
+      case '\xb': return "OU";
+      case '\x6': return "C";
+    }
+    // clang-format on
+  }
+
+  bssl::UniquePtr<char> oid_representation(CBS_asn1_oid_to_text(&oid_cbs));
+  if (oid_representation == nullptr) {
+    return absl::StrCat("(", absl::BytesToHexString(oid), ")");
+  }
+  return std::string(oid_representation.get());
+}
+
+}  // namespace
+
+absl::optional<std::string> X509NameAttributeToString(CBS input) {
+  CBS name, value;
+  unsigned value_tag;
+  if (!CBS_get_asn1(&input, &name, CBS_ASN1_OBJECT) ||
+      !CBS_get_any_asn1(&input, &value, &value_tag) || CBS_len(&input) != 0) {
+    return absl::nullopt;
+  }
+  // Note that this does not process encoding of |input| in any way.  This works
+  // fine for the most cases.
+  return absl::StrCat(AttributeNameToString(name), "=",
+                      absl::CHexEscape(CbsToStringPiece(value)));
+}
+
+namespace {
+
+template <unsigned inner_tag,
+          char separator,
+          absl::optional<std::string> (*parser)(CBS)>
+absl::optional<std::string> ParseAndJoin(CBS input) {
+  std::vector<std::string> pieces;
+  while (CBS_len(&input) != 0) {
+    CBS attribute;
+    if (!CBS_get_asn1(&input, &attribute, inner_tag)) {
+      return absl::nullopt;
+    }
+    absl::optional<std::string> formatted = parser(attribute);
+    if (!formatted.has_value()) {
+      return absl::nullopt;
+    }
+    pieces.push_back(*formatted);
+  }
+
+  return absl::StrJoin(pieces, std::string({separator}));
+}
+
+absl::optional<std::string> RelativeDistinguishedNameToString(CBS input) {
+  return ParseAndJoin<CBS_ASN1_SEQUENCE, '+', X509NameAttributeToString>(input);
+}
+
+absl::optional<std::string> DistinguishedNameToString(CBS input) {
+  return ParseAndJoin<CBS_ASN1_SET, ',', RelativeDistinguishedNameToString>(
+      input);
+}
+
+}  // namespace
+
+std::string PublicKeyTypeToString(PublicKeyType type) {
+  switch (type) {
+    case PublicKeyType::kRsa:
+      return "RSA";
+    case PublicKeyType::kP256:
+      return "ECDSA P-256";
+    case PublicKeyType::kP384:
+      return "ECDSA P-384";
+    case PublicKeyType::kEd25519:
+      return "Ed25519";
+    case PublicKeyType::kUnknown:
+      return "unknown";
+  }
+  return "";
+}
+
+absl::optional<quic::QuicWallTime> ParseDerTime(unsigned tag,
+                                                absl::string_view payload) {
+  if (tag != CBS_ASN1_GENERALIZEDTIME && tag != CBS_ASN1_UTCTIME) {
+    QUIC_DLOG(WARNING) << "Invalid tag supplied for a DER timestamp";
+    return absl::nullopt;
+  }
+
+  const size_t year_length = tag == CBS_ASN1_GENERALIZEDTIME ? 4 : 2;
+  uint64_t year, month, day, hour, minute, second;
+  quiche::QuicheDataReader reader(payload);
+  if (!reader.ReadDecimal64(year_length, &year) ||
+      !reader.ReadDecimal64(2, &month) || !reader.ReadDecimal64(2, &day) ||
+      !reader.ReadDecimal64(2, &hour) || !reader.ReadDecimal64(2, &minute) ||
+      !reader.ReadDecimal64(2, &second) ||
+      reader.ReadRemainingPayload() != "Z") {
+    QUIC_DLOG(WARNING) << "Failed to parse the DER timestamp";
+    return absl::nullopt;
+  }
+
+  if (tag == CBS_ASN1_UTCTIME) {
+    QUICHE_DCHECK_LE(year, 100u);
+    year += (year >= 50) ? 1900 : 2000;
+  }
+
+  const absl::optional<int64_t> unix_time =
+      quiche::QuicheUtcDateTimeToUnixSeconds(year, month, day, hour, minute,
+                                             second);
+  if (!unix_time.has_value() || *unix_time < 0) {
+    return absl::nullopt;
+  }
+  return QuicWallTime::FromUNIXSeconds(*unix_time);
+}
+
+PemReadResult ReadNextPemMessage(std::istream* input) {
+  constexpr absl::string_view kPemBegin = "-----BEGIN ";
+  constexpr absl::string_view kPemEnd = "-----END ";
+  constexpr absl::string_view kPemDashes = "-----";
+
+  std::string line_buffer, encoded_message_contents, expected_end;
+  bool pending_message = false;
+  PemReadResult result;
+  while (std::getline(*input, line_buffer)) {
+    absl::string_view line(line_buffer);
+    QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&line);
+
+    // Handle BEGIN lines.
+    if (!pending_message && absl::StartsWith(line, kPemBegin) &&
+        absl::EndsWith(line, kPemDashes)) {
+      result.type = std::string(
+          line.substr(kPemBegin.size(),
+                      line.size() - kPemDashes.size() - kPemBegin.size()));
+      expected_end = absl::StrCat(kPemEnd, result.type, kPemDashes);
+      pending_message = true;
+      continue;
+    }
+
+    // Handle END lines.
+    if (pending_message && line == expected_end) {
+      absl::optional<std::string> data =
+          QuicheTextUtils::Base64Decode(encoded_message_contents);
+      if (data.has_value()) {
+        result.status = PemReadResult::kOk;
+        result.contents = data.value();
+      } else {
+        result.status = PemReadResult::kError;
+      }
+      return result;
+    }
+
+    if (pending_message) {
+      encoded_message_contents.append(std::string(line));
+    }
+  }
+  bool eof_reached = input->eof() && !pending_message;
+  return PemReadResult{
+      (eof_reached ? PemReadResult::kEof : PemReadResult::kError), "", ""};
+}
+
+std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate(
+    absl::string_view certificate) {
+  std::unique_ptr<CertificateView> result(new CertificateView());
+  CBS top = StringPieceToCbs(certificate);
+
+  CBS top_certificate, tbs_certificate, signature_algorithm, signature;
+  if (!CBS_get_asn1(&top, &top_certificate, CBS_ASN1_SEQUENCE) ||
+      CBS_len(&top) != 0) {
+    return nullptr;
+  }
+
+  // Certificate  ::=  SEQUENCE  {
+  if (
+      //   tbsCertificate       TBSCertificate,
+      !CBS_get_asn1(&top_certificate, &tbs_certificate, CBS_ASN1_SEQUENCE) ||
+
+      //   signatureAlgorithm   AlgorithmIdentifier,
+      !CBS_get_asn1(&top_certificate, &signature_algorithm,
+                    CBS_ASN1_SEQUENCE) ||
+
+      //   signature            BIT STRING  }
+      !CBS_get_asn1(&top_certificate, &signature, CBS_ASN1_BITSTRING) ||
+      CBS_len(&top_certificate) != 0) {
+    return nullptr;
+  }
+
+  int has_version, has_extensions;
+  CBS version, serial, signature_algorithm_inner, issuer, validity, subject,
+      spki, issuer_id, subject_id, extensions_outer;
+  // TBSCertificate  ::=  SEQUENCE  {
+  if (
+      //   version         [0]  Version DEFAULT v1,
+      !CBS_get_optional_asn1(
+          &tbs_certificate, &version, &has_version,
+          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
+
+      //   serialNumber         CertificateSerialNumber,
+      !CBS_get_asn1(&tbs_certificate, &serial, CBS_ASN1_INTEGER) ||
+
+      //   signature            AlgorithmIdentifier,
+      !CBS_get_asn1(&tbs_certificate, &signature_algorithm_inner,
+                    CBS_ASN1_SEQUENCE) ||
+
+      //   issuer               Name,
+      !CBS_get_asn1(&tbs_certificate, &issuer, CBS_ASN1_SEQUENCE) ||
+
+      //   validity             Validity,
+      !CBS_get_asn1(&tbs_certificate, &validity, CBS_ASN1_SEQUENCE) ||
+
+      //   subject              Name,
+      !CBS_get_asn1(&tbs_certificate, &subject, CBS_ASN1_SEQUENCE) ||
+
+      //   subjectPublicKeyInfo SubjectPublicKeyInfo,
+      !CBS_get_asn1_element(&tbs_certificate, &spki, CBS_ASN1_SEQUENCE) ||
+
+      //   issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
+      //                        -- If present, version MUST be v2 or v3
+      !CBS_get_optional_asn1(&tbs_certificate, &issuer_id, nullptr,
+                             CBS_ASN1_CONTEXT_SPECIFIC | 1) ||
+
+      //   subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
+      //                        -- If present, version MUST be v2 or v3
+      !CBS_get_optional_asn1(&tbs_certificate, &subject_id, nullptr,
+                             CBS_ASN1_CONTEXT_SPECIFIC | 2) ||
+
+      //   extensions      [3]  Extensions OPTIONAL
+      //                        -- If present, version MUST be v3 --  }
+      !CBS_get_optional_asn1(
+          &tbs_certificate, &extensions_outer, &has_extensions,
+          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3) ||
+
+      CBS_len(&tbs_certificate) != 0) {
+    return nullptr;
+  }
+
+  result->subject_der_ = CbsToStringPiece(subject);
+
+  unsigned not_before_tag, not_after_tag;
+  CBS not_before, not_after;
+  if (!CBS_get_any_asn1(&validity, &not_before, &not_before_tag) ||
+      !CBS_get_any_asn1(&validity, &not_after, &not_after_tag) ||
+      CBS_len(&validity) != 0) {
+    QUIC_DLOG(WARNING) << "Failed to extract the validity dates";
+    return nullptr;
+  }
+  absl::optional<QuicWallTime> not_before_parsed =
+      ParseDerTime(not_before_tag, CbsToStringPiece(not_before));
+  absl::optional<QuicWallTime> not_after_parsed =
+      ParseDerTime(not_after_tag, CbsToStringPiece(not_after));
+  if (!not_before_parsed.has_value() || !not_after_parsed.has_value()) {
+    QUIC_DLOG(WARNING) << "Failed to parse validity dates";
+    return nullptr;
+  }
+  result->validity_start_ = *not_before_parsed;
+  result->validity_end_ = *not_after_parsed;
+
+  result->public_key_.reset(EVP_parse_public_key(&spki));
+  if (result->public_key_ == nullptr) {
+    QUIC_DLOG(WARNING) << "Failed to parse the public key";
+    return nullptr;
+  }
+  if (!result->ValidatePublicKeyParameters()) {
+    QUIC_DLOG(WARNING) << "Public key has invalid parameters";
+    return nullptr;
+  }
+
+  // Only support X.509v3.
+  if (!has_version ||
+      !CBS_mem_equal(&version, kX509Version, sizeof(kX509Version))) {
+    QUIC_DLOG(WARNING) << "Bad X.509 version";
+    return nullptr;
+  }
+
+  if (!has_extensions) {
+    return nullptr;
+  }
+
+  CBS extensions;
+  if (!CBS_get_asn1(&extensions_outer, &extensions, CBS_ASN1_SEQUENCE) ||
+      CBS_len(&extensions_outer) != 0) {
+    QUIC_DLOG(WARNING) << "Failed to extract the extension sequence";
+    return nullptr;
+  }
+  if (!result->ParseExtensions(extensions)) {
+    QUIC_DLOG(WARNING) << "Failed to parse extensions";
+    return nullptr;
+  }
+
+  return result;
+}
+
+bool CertificateView::ParseExtensions(CBS extensions) {
+  while (CBS_len(&extensions) != 0) {
+    CBS extension, oid, critical, payload;
+    if (
+        // Extension  ::=  SEQUENCE  {
+        !CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) ||
+        //     extnID      OBJECT IDENTIFIER,
+        !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
+        //     critical    BOOLEAN DEFAULT FALSE,
+        !CBS_get_optional_asn1(&extension, &critical, nullptr,
+                               CBS_ASN1_BOOLEAN) ||
+        //     extnValue   OCTET STRING
+        //                 -- contains the DER encoding of an ASN.1 value
+        //                 -- corresponding to the extension type identified
+        //                 -- by extnID
+        !CBS_get_asn1(&extension, &payload, CBS_ASN1_OCTETSTRING) ||
+        CBS_len(&extension) != 0) {
+      QUIC_DLOG(WARNING) << "Bad extension entry";
+      return false;
+    }
+
+    if (CBS_mem_equal(&oid, kSubjectAltNameOid, sizeof(kSubjectAltNameOid))) {
+      CBS alt_names;
+      if (!CBS_get_asn1(&payload, &alt_names, CBS_ASN1_SEQUENCE) ||
+          CBS_len(&payload) != 0) {
+        QUIC_DLOG(WARNING) << "Failed to parse subjectAltName";
+        return false;
+      }
+      while (CBS_len(&alt_names) != 0) {
+        CBS alt_name_cbs;
+        unsigned int alt_name_tag;
+        if (!CBS_get_any_asn1(&alt_names, &alt_name_cbs, &alt_name_tag)) {
+          QUIC_DLOG(WARNING) << "Failed to parse subjectAltName";
+          return false;
+        }
+
+        absl::string_view alt_name = CbsToStringPiece(alt_name_cbs);
+        QuicIpAddress ip_address;
+        // GeneralName ::= CHOICE {
+        switch (alt_name_tag) {
+          // dNSName                   [2]  IA5String,
+          case CBS_ASN1_CONTEXT_SPECIFIC | 2:
+            subject_alt_name_domains_.push_back(alt_name);
+            break;
+
+          // iPAddress                 [7]  OCTET STRING,
+          case CBS_ASN1_CONTEXT_SPECIFIC | 7:
+            if (!ip_address.FromPackedString(alt_name.data(),
+                                             alt_name.size())) {
+              QUIC_DLOG(WARNING) << "Failed to parse subjectAltName IP address";
+              return false;
+            }
+            subject_alt_name_ips_.push_back(ip_address);
+            break;
+
+          default:
+            QUIC_DLOG(INFO) << "Unknown subjectAltName tag " << alt_name_tag;
+            continue;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+std::vector<std::string> CertificateView::LoadPemFromStream(
+    std::istream* input) {
+  std::vector<std::string> result;
+  for (;;) {
+    PemReadResult read_result = ReadNextPemMessage(input);
+    if (read_result.status == PemReadResult::kEof) {
+      return result;
+    }
+    if (read_result.status != PemReadResult::kOk) {
+      return std::vector<std::string>();
+    }
+    if (read_result.type != "CERTIFICATE") {
+      continue;
+    }
+    result.emplace_back(std::move(read_result.contents));
+  }
+}
+
+PublicKeyType CertificateView::public_key_type() const {
+  return PublicKeyTypeFromKey(public_key_.get());
+}
+
+bool CertificateView::ValidatePublicKeyParameters() {
+  // The profile here affects what certificates can be used when QUIC is used as
+  // a server library without any custom certificate provider logic.
+  // The goal is to allow at minimum any certificate that would be allowed on a
+  // regular Web session over TLS 1.3 while ensuring we do not expose any
+  // algorithms we don't want to support long-term.
+  PublicKeyType key_type = PublicKeyTypeFromKey(public_key_.get());
+  switch (key_type) {
+    case PublicKeyType::kRsa:
+      return EVP_PKEY_bits(public_key_.get()) >= 2048;
+    case PublicKeyType::kP256:
+    case PublicKeyType::kP384:
+    case PublicKeyType::kEd25519:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool CertificateView::VerifySignature(absl::string_view data,
+                                      absl::string_view signature,
+                                      uint16_t signature_algorithm) const {
+  if (PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) !=
+      PublicKeyTypeFromKey(public_key_.get())) {
+    QUIC_BUG(quic_bug_10640_1)
+        << "Mismatch between the requested signature algorithm and the "
+           "type of the public key.";
+    return false;
+  }
+
+  bssl::ScopedEVP_MD_CTX md_ctx;
+  EVP_PKEY_CTX* pctx;
+  if (!EVP_DigestVerifyInit(
+          md_ctx.get(), &pctx,
+          SSL_get_signature_algorithm_digest(signature_algorithm), nullptr,
+          public_key_.get())) {
+    return false;
+  }
+  if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
+    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
+        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
+      return false;
+    }
+  }
+  return EVP_DigestVerify(
+      md_ctx.get(), reinterpret_cast<const uint8_t*>(signature.data()),
+      signature.size(), reinterpret_cast<const uint8_t*>(data.data()),
+      data.size());
+}
+
+absl::optional<std::string> CertificateView::GetHumanReadableSubject() const {
+  CBS input = StringPieceToCbs(subject_der_);
+  return DistinguishedNameToString(input);
+}
+
+std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadFromDer(
+    absl::string_view private_key) {
+  std::unique_ptr<CertificatePrivateKey> result(new CertificatePrivateKey());
+  CBS private_key_cbs = StringPieceToCbs(private_key);
+  result->private_key_.reset(EVP_parse_private_key(&private_key_cbs));
+  if (result->private_key_ == nullptr || CBS_len(&private_key_cbs) != 0) {
+    return nullptr;
+  }
+  return result;
+}
+
+std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadPemFromStream(
+    std::istream* input) {
+skip:
+  PemReadResult result = ReadNextPemMessage(input);
+  if (result.status != PemReadResult::kOk) {
+    return nullptr;
+  }
+  // RFC 5958 OneAsymmetricKey message.
+  if (result.type == "PRIVATE KEY") {
+    return LoadFromDer(result.contents);
+  }
+  // Legacy OpenSSL format: PKCS#1 (RFC 8017) RSAPrivateKey message.
+  if (result.type == "RSA PRIVATE KEY") {
+    CBS private_key_cbs = StringPieceToCbs(result.contents);
+    bssl::UniquePtr<RSA> rsa(RSA_parse_private_key(&private_key_cbs));
+    if (rsa == nullptr || CBS_len(&private_key_cbs) != 0) {
+      return nullptr;
+    }
+
+    std::unique_ptr<CertificatePrivateKey> key(new CertificatePrivateKey());
+    key->private_key_.reset(EVP_PKEY_new());
+    EVP_PKEY_assign_RSA(key->private_key_.get(), rsa.release());
+    return key;
+  }
+  // EC keys are sometimes generated with "openssl ecparam -genkey". If the user
+  // forgets -noout, OpenSSL will output a redundant copy of the EC parameters.
+  // Skip those.
+  if (result.type == "EC PARAMETERS") {
+    goto skip;
+  }
+  // Legacy OpenSSL format: RFC 5915 ECPrivateKey message.
+  if (result.type == "EC PRIVATE KEY") {
+    CBS private_key_cbs = StringPieceToCbs(result.contents);
+    bssl::UniquePtr<EC_KEY> ec_key(
+        EC_KEY_parse_private_key(&private_key_cbs, /*group=*/nullptr));
+    if (ec_key == nullptr || CBS_len(&private_key_cbs) != 0) {
+      return nullptr;
+    }
+
+    std::unique_ptr<CertificatePrivateKey> key(new CertificatePrivateKey());
+    key->private_key_.reset(EVP_PKEY_new());
+    EVP_PKEY_assign_EC_KEY(key->private_key_.get(), ec_key.release());
+    return key;
+  }
+  // Unknown format.
+  return nullptr;
+}
+
+std::string CertificatePrivateKey::Sign(absl::string_view input,
+                                        uint16_t signature_algorithm) const {
+  if (!ValidForSignatureAlgorithm(signature_algorithm)) {
+    QUIC_BUG(quic_bug_10640_2)
+        << "Mismatch between the requested signature algorithm and the "
+           "type of the private key.";
+    return "";
+  }
+
+  bssl::ScopedEVP_MD_CTX md_ctx;
+  EVP_PKEY_CTX* pctx;
+  if (!EVP_DigestSignInit(
+          md_ctx.get(), &pctx,
+          SSL_get_signature_algorithm_digest(signature_algorithm),
+          /*e=*/nullptr, private_key_.get())) {
+    return "";
+  }
+  if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
+    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
+        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
+      return "";
+    }
+  }
+
+  std::string output;
+  size_t output_size;
+  if (!EVP_DigestSign(md_ctx.get(), /*out_sig=*/nullptr, &output_size,
+                      reinterpret_cast<const uint8_t*>(input.data()),
+                      input.size())) {
+    return "";
+  }
+  output.resize(output_size);
+  if (!EVP_DigestSign(
+          md_ctx.get(), reinterpret_cast<uint8_t*>(&output[0]), &output_size,
+          reinterpret_cast<const uint8_t*>(input.data()), input.size())) {
+    return "";
+  }
+  output.resize(output_size);
+  return output;
+}
+
+bool CertificatePrivateKey::MatchesPublicKey(
+    const CertificateView& view) const {
+  return EVP_PKEY_cmp(view.public_key(), private_key_.get()) == 1;
+}
+
+bool CertificatePrivateKey::ValidForSignatureAlgorithm(
+    uint16_t signature_algorithm) const {
+  return PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) ==
+         PublicKeyTypeFromKey(private_key_.get());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/certificate_view.h b/quiche/quic/core/crypto/certificate_view.h
new file mode 100644
index 0000000..347cee9
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view.h
@@ -0,0 +1,151 @@
+// Copyright 2020 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_CRYPTO_CERTIFICATE_VIEW_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
+
+#include <istream>
+#include <memory>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/core/crypto/boring_utils.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE PemReadResult {
+  enum Status { kOk, kEof, kError };
+  Status status;
+  std::string contents;
+  // The type of the PEM message (e.g., if the message starts with
+  // "-----BEGIN CERTIFICATE-----", the |type| would be "CERTIFICATE").
+  std::string type;
+};
+
+// Reads |input| line-by-line and returns the next available PEM message.
+QUIC_EXPORT_PRIVATE PemReadResult ReadNextPemMessage(std::istream* input);
+
+// Cryptograhpic algorithms recognized in X.509.
+enum class PublicKeyType {
+  kRsa,
+  kP256,
+  kP384,
+  kEd25519,
+  kUnknown,
+};
+QUIC_EXPORT_PRIVATE std::string PublicKeyTypeToString(PublicKeyType type);
+
+// CertificateView represents a parsed version of a single X.509 certificate. As
+// the word "view" implies, it does not take ownership of the underlying strings
+// and consists primarily of pointers into the certificate that is passed into
+// the parser.
+class QUIC_EXPORT_PRIVATE CertificateView {
+ public:
+  // Parses a single DER-encoded X.509 certificate.  Returns nullptr on parse
+  // error.
+  static std::unique_ptr<CertificateView> ParseSingleCertificate(
+      absl::string_view certificate);
+
+  // Loads all PEM-encoded X.509 certificates found in the |input| stream
+  // without parsing them.  Returns an empty vector if any parsing error occurs.
+  static std::vector<std::string> LoadPemFromStream(std::istream* input);
+
+  QuicWallTime validity_start() const { return validity_start_; }
+  QuicWallTime validity_end() const { return validity_end_; }
+  const EVP_PKEY* public_key() const { return public_key_.get(); }
+
+  const std::vector<absl::string_view>& subject_alt_name_domains() const {
+    return subject_alt_name_domains_;
+  }
+  const std::vector<QuicIpAddress>& subject_alt_name_ips() const {
+    return subject_alt_name_ips_;
+  }
+
+  // Returns a human-readable representation of the Subject field.  The format
+  // is similar to RFC 2253, but does not match it exactly.
+  absl::optional<std::string> GetHumanReadableSubject() const;
+
+  // |signature_algorithm| is a TLS signature algorithm ID.
+  bool VerifySignature(absl::string_view data,
+                       absl::string_view signature,
+                       uint16_t signature_algorithm) const;
+
+  // Returns the type of the key used in the certificate's SPKI.
+  PublicKeyType public_key_type() const;
+
+ private:
+  CertificateView() = default;
+
+  QuicWallTime validity_start_ = QuicWallTime::Zero();
+  QuicWallTime validity_end_ = QuicWallTime::Zero();
+  absl::string_view subject_der_;
+
+  // Public key parsed from SPKI.
+  bssl::UniquePtr<EVP_PKEY> public_key_;
+
+  // SubjectAltName, https://tools.ietf.org/html/rfc5280#section-4.2.1.6
+  std::vector<absl::string_view> subject_alt_name_domains_;
+  std::vector<QuicIpAddress> subject_alt_name_ips_;
+
+  // Called from ParseSingleCertificate().
+  bool ParseExtensions(CBS extensions);
+  bool ValidatePublicKeyParameters();
+};
+
+// CertificatePrivateKey represents a private key that can be used with an X.509
+// certificate.
+class QUIC_EXPORT_PRIVATE CertificatePrivateKey {
+ public:
+  explicit CertificatePrivateKey(bssl::UniquePtr<EVP_PKEY> private_key)
+      : private_key_(std::move(private_key)) {}
+
+  // Loads a DER-encoded PrivateKeyInfo structure (RFC 5958) as a private key.
+  static std::unique_ptr<CertificatePrivateKey> LoadFromDer(
+      absl::string_view private_key);
+
+  // Loads a private key from a PEM file formatted according to RFC 7468.  Also
+  // supports legacy OpenSSL RSA key format ("BEGIN RSA PRIVATE KEY").
+  static std::unique_ptr<CertificatePrivateKey> LoadPemFromStream(
+      std::istream* input);
+
+  // |signature_algorithm| is a TLS signature algorithm ID.
+  std::string Sign(absl::string_view input, uint16_t signature_algorithm) const;
+
+  // Verifies that the private key in question matches the public key of the
+  // certificate |view|.
+  bool MatchesPublicKey(const CertificateView& view) const;
+
+  // Verifies that the private key can be used with the specified TLS signature
+  // algorithm.
+  bool ValidForSignatureAlgorithm(uint16_t signature_algorithm) const;
+
+  EVP_PKEY* private_key() const { return private_key_.get(); }
+
+ private:
+  CertificatePrivateKey() = default;
+
+  bssl::UniquePtr<EVP_PKEY> private_key_;
+};
+
+// Parses a DER-encoded X.509 NameAttribute.  Exposed primarily for testing.
+QUIC_EXPORT_PRIVATE absl::optional<std::string> X509NameAttributeToString(
+    CBS input);
+
+// Parses a DER time based on the specified ASN.1 tag.  Exposed primarily for
+// testing.
+QUIC_EXPORT_PRIVATE absl::optional<quic::QuicWallTime> ParseDerTime(
+    unsigned tag,
+    absl::string_view payload);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
diff --git a/quiche/quic/core/crypto/certificate_view_der_fuzzer.cc b/quiche/quic/core/crypto/certificate_view_der_fuzzer.cc
new file mode 100644
index 0000000..81c91eb
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view_der_fuzzer.cc
@@ -0,0 +1,19 @@
+// Copyright 2020 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 <string>
+
+#include "quiche/quic/core/crypto/certificate_view.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  std::string input(reinterpret_cast<const char*>(data), size);
+
+  std::unique_ptr<quic::CertificateView> view =
+      quic::CertificateView::ParseSingleCertificate(input);
+  if (view != nullptr) {
+    view->GetHumanReadableSubject();
+  }
+  quic::CertificatePrivateKey::LoadFromDer(input);
+  return 0;
+}
diff --git a/quiche/quic/core/crypto/certificate_view_pem_fuzzer.cc b/quiche/quic/core/crypto/certificate_view_pem_fuzzer.cc
new file mode 100644
index 0000000..e6d70e5
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view_pem_fuzzer.cc
@@ -0,0 +1,18 @@
+// Copyright 2020 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 <sstream>
+#include <string>
+
+#include "quiche/quic/core/crypto/certificate_view.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  std::string input(reinterpret_cast<const char*>(data), size);
+  std::stringstream stream(input);
+
+  quic::CertificateView::LoadPemFromStream(&stream);
+  stream.seekg(0);
+  quic::CertificatePrivateKey::LoadPemFromStream(&stream);
+  return 0;
+}
diff --git a/quiche/quic/core/crypto/certificate_view_test.cc b/quiche/quic/core/crypto/certificate_view_test.cc
new file mode 100644
index 0000000..009fd8d
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view_test.cc
@@ -0,0 +1,214 @@
+// Copyright 2020 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 "quiche/quic/core/crypto/certificate_view.h"
+
+#include <memory>
+#include <sstream>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/boring_utils.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+#include "quiche/common/platform/api/quiche_time_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::HasSubstr;
+using ::testing::Optional;
+
+TEST(CertificateViewTest, PemParser) {
+  std::stringstream stream(kTestCertificatePem);
+  PemReadResult result = ReadNextPemMessage(&stream);
+  EXPECT_EQ(result.status, PemReadResult::kOk);
+  EXPECT_EQ(result.type, "CERTIFICATE");
+  EXPECT_EQ(result.contents, kTestCertificate);
+
+  result = ReadNextPemMessage(&stream);
+  EXPECT_EQ(result.status, PemReadResult::kEof);
+}
+
+TEST(CertificateViewTest, Parse) {
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(kTestCertificate);
+  ASSERT_TRUE(view != nullptr);
+
+  EXPECT_THAT(view->subject_alt_name_domains(),
+              ElementsAre(absl::string_view("www.example.org"),
+                          absl::string_view("mail.example.org"),
+                          absl::string_view("mail.example.com")));
+  EXPECT_THAT(view->subject_alt_name_ips(),
+              ElementsAre(QuicIpAddress::Loopback4()));
+  EXPECT_EQ(EVP_PKEY_id(view->public_key()), EVP_PKEY_RSA);
+
+  const QuicWallTime validity_start = QuicWallTime::FromUNIXSeconds(
+      *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 1, 30, 18, 13, 59));
+  EXPECT_EQ(view->validity_start(), validity_start);
+  const QuicWallTime validity_end = QuicWallTime::FromUNIXSeconds(
+      *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 2, 2, 18, 13, 59));
+  EXPECT_EQ(view->validity_end(), validity_end);
+  EXPECT_EQ(view->public_key_type(), PublicKeyType::kRsa);
+  EXPECT_EQ(PublicKeyTypeToString(view->public_key_type()), "RSA");
+
+  EXPECT_EQ("C=US,ST=California,L=Mountain View,O=QUIC Server,CN=127.0.0.1",
+            view->GetHumanReadableSubject());
+}
+
+TEST(CertificateViewTest, ParseCertWithUnknownSanType) {
+  std::stringstream stream(kTestCertWithUnknownSanTypePem);
+  PemReadResult result = ReadNextPemMessage(&stream);
+  EXPECT_EQ(result.status, PemReadResult::kOk);
+  EXPECT_EQ(result.type, "CERTIFICATE");
+
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(result.contents);
+  EXPECT_TRUE(view != nullptr);
+}
+
+TEST(CertificateViewTest, PemSingleCertificate) {
+  std::stringstream pem_stream(kTestCertificatePem);
+  std::vector<std::string> chain =
+      CertificateView::LoadPemFromStream(&pem_stream);
+  EXPECT_THAT(chain, ElementsAre(kTestCertificate));
+}
+
+TEST(CertificateViewTest, PemMultipleCertificates) {
+  std::stringstream pem_stream(kTestCertificateChainPem);
+  std::vector<std::string> chain =
+      CertificateView::LoadPemFromStream(&pem_stream);
+  EXPECT_THAT(chain,
+              ElementsAre(kTestCertificate, HasSubstr("QUIC Server Root CA")));
+}
+
+TEST(CertificateViewTest, PemNoCertificates) {
+  std::stringstream pem_stream("one\ntwo\nthree\n");
+  std::vector<std::string> chain =
+      CertificateView::LoadPemFromStream(&pem_stream);
+  EXPECT_TRUE(chain.empty());
+}
+
+TEST(CertificateViewTest, SignAndVerify) {
+  std::unique_ptr<CertificatePrivateKey> key =
+      CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey);
+  ASSERT_TRUE(key != nullptr);
+
+  std::string data = "A really important message";
+  std::string signature = key->Sign(data, SSL_SIGN_RSA_PSS_RSAE_SHA256);
+  ASSERT_FALSE(signature.empty());
+
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(kTestCertificate);
+  ASSERT_TRUE(view != nullptr);
+  EXPECT_TRUE(key->MatchesPublicKey(*view));
+
+  EXPECT_TRUE(
+      view->VerifySignature(data, signature, SSL_SIGN_RSA_PSS_RSAE_SHA256));
+  EXPECT_FALSE(view->VerifySignature("An unimportant message", signature,
+                                     SSL_SIGN_RSA_PSS_RSAE_SHA256));
+  EXPECT_FALSE(view->VerifySignature(data, "Not a signature",
+                                     SSL_SIGN_RSA_PSS_RSAE_SHA256));
+}
+
+TEST(CertificateViewTest, PrivateKeyPem) {
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(kTestCertificate);
+  ASSERT_TRUE(view != nullptr);
+
+  std::stringstream pem_stream(kTestCertificatePrivateKeyPem);
+  std::unique_ptr<CertificatePrivateKey> pem_key =
+      CertificatePrivateKey::LoadPemFromStream(&pem_stream);
+  ASSERT_TRUE(pem_key != nullptr);
+  EXPECT_TRUE(pem_key->MatchesPublicKey(*view));
+
+  std::stringstream legacy_stream(kTestCertificatePrivateKeyLegacyPem);
+  std::unique_ptr<CertificatePrivateKey> legacy_key =
+      CertificatePrivateKey::LoadPemFromStream(&legacy_stream);
+  ASSERT_TRUE(legacy_key != nullptr);
+  EXPECT_TRUE(legacy_key->MatchesPublicKey(*view));
+}
+
+TEST(CertificateViewTest, PrivateKeyEcdsaPem) {
+  std::stringstream pem_stream(kTestEcPrivateKeyLegacyPem);
+  std::unique_ptr<CertificatePrivateKey> key =
+      CertificatePrivateKey::LoadPemFromStream(&pem_stream);
+  ASSERT_TRUE(key != nullptr);
+  EXPECT_TRUE(key->ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256));
+}
+
+TEST(CertificateViewTest, DerTime) {
+  EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Z"),
+              Optional(QuicWallTime::FromUNIXSeconds(24)));
+  EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19710101000024Z"),
+              Optional(QuicWallTime::FromUNIXSeconds(365 * 86400 + 24)));
+  EXPECT_THAT(ParseDerTime(CBS_ASN1_UTCTIME, "700101000024Z"),
+              Optional(QuicWallTime::FromUNIXSeconds(24)));
+  EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "200101000024Z").has_value());
+
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, ""), absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.001Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Q"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024-0500"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "700101000024ZZ"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.00Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "197O0101000024Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.0O1Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "-9700101000024Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "1970-101000024Z"),
+            absl::nullopt);
+
+  EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "490101000024Z").has_value());
+  // This should parse as 1950, which predates UNIX epoch.
+  EXPECT_FALSE(ParseDerTime(CBS_ASN1_UTCTIME, "500101000024Z").has_value());
+
+  EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101230000Z"),
+              Optional(QuicWallTime::FromUNIXSeconds(23 * 3600)));
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101240000Z"),
+            absl::nullopt);
+}
+
+TEST(CertificateViewTest, NameAttribute) {
+  // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.112411 }
+  // UTF8String { "Test" }
+  std::string unknown_oid =
+      absl::HexStringToBytes("060b2a864886f712040186ee1b0c0454657374");
+  EXPECT_EQ("1.2.840.113554.4.1.112411=Test",
+            X509NameAttributeToString(StringPieceToCbs(unknown_oid)));
+
+  // OBJECT_IDENTIFIER { 2.5.4.3 }
+  // UTF8String { "Bell: \x07" }
+  std::string non_printable =
+      absl::HexStringToBytes("06035504030c0742656c6c3a2007");
+  EXPECT_EQ(R"(CN=Bell: \x07)",
+            X509NameAttributeToString(StringPieceToCbs(non_printable)));
+
+  // OBJECT_IDENTIFIER { "\x55\x80" }
+  // UTF8String { "Test" }
+  std::string invalid_oid = absl::HexStringToBytes("060255800c0454657374");
+  EXPECT_EQ("(5580)=Test",
+            X509NameAttributeToString(StringPieceToCbs(invalid_oid)));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_decrypter.cc b/quiche/quic/core/crypto/chacha20_poly1305_decrypter.cc
new file mode 100644
index 0000000..556998a
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_decrypter.cc
@@ -0,0 +1,43 @@
+// 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 "quiche/quic/core/crypto/chacha20_poly1305_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter()
+    : ChaChaBaseDecrypter(EVP_aead_chacha20_poly1305,
+                          kKeySize,
+                          kAuthTagSize,
+                          kNonceSize,
+                          /* use_ietf_nonce_construction */ false) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+ChaCha20Poly1305Decrypter::~ChaCha20Poly1305Decrypter() {}
+
+uint32_t ChaCha20Poly1305Decrypter::cipher_id() const {
+  return TLS1_CK_CHACHA20_POLY1305_SHA256;
+}
+
+QuicPacketCount ChaCha20Poly1305Decrypter::GetIntegrityLimit() const {
+  // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
+  static_assert(kMaxIncomingPacketSize < 16384,
+                "This key limit requires limits on decryption payload sizes");
+  return 68719476736U;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_decrypter.h b/quiche/quic/core/crypto/chacha20_poly1305_decrypter.h
new file mode 100644
index 0000000..6eb6c87
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_decrypter.h
@@ -0,0 +1,41 @@
+// 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_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/chacha_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ChaCha20Poly1305Decrypter is a QuicDecrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539, except that
+// it truncates the Poly1305 authenticator to 12 bytes. Create an instance
+// by calling QuicDecrypter::Create(kCC20).
+//
+// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix of the
+// nonce is four bytes.
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Decrypter
+    : public ChaChaBaseDecrypter {
+ public:
+  enum {
+    kAuthTagSize = 12,
+  };
+
+  ChaCha20Poly1305Decrypter();
+  ChaCha20Poly1305Decrypter(const ChaCha20Poly1305Decrypter&) = delete;
+  ChaCha20Poly1305Decrypter& operator=(const ChaCha20Poly1305Decrypter&) =
+      delete;
+  ~ChaCha20Poly1305Decrypter() override;
+
+  uint32_t cipher_id() const override;
+  QuicPacketCount GetIntegrityLimit() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_decrypter_test.cc b/quiche/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
new file mode 100644
index 0000000..019c56b
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
@@ -0,0 +1,178 @@
+// 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 "quiche/quic/core/crypto/chacha20_poly1305_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* fixed;
+  const char* aad;
+  const char* ct;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestVector test_vectors[] = {
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "50515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecb",  // "d0600691" truncated
+
+     "4c616469657320616e642047656e746c"
+     "656d656e206f662074686520636c6173"
+     "73206f66202739393a20496620492063"
+     "6f756c64206f6666657220796f75206f"
+     "6e6c79206f6e652074697020666f7220"
+     "746865206675747572652c2073756e73"
+     "637265656e20776f756c642062652069"
+     "742e"},
+    // Modify the ciphertext (Poly1305 authenticator).
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "50515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecc",  // "d0600691" truncated
+
+     nullptr},
+    // Modify the associated data.
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "60515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecb",  // "d0600691" truncated
+
+     nullptr},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(ChaCha20Poly1305Decrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  uint64_t packet_number;
+  absl::string_view nonce_prefix(nonce.data(),
+                                 nonce.size() - sizeof(packet_number));
+  decrypter->SetNoncePrefix(nonce_prefix);
+  memcpy(&packet_number, nonce.data() + nonce_prefix.size(),
+         sizeof(packet_number));
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success = decrypter->DecryptPacket(
+      packet_number, associated_data, ciphertext, output.get(), &output_length,
+      ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class ChaCha20Poly1305DecrypterTest : public QuicTest {};
+
+TEST_F(ChaCha20Poly1305DecrypterTest, Decrypt) {
+  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+    // If not present then decryption is expected to fail.
+    bool has_pt = test_vectors[i].pt;
+
+    // Decode the test vector.
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
+    std::string pt;
+    if (has_pt) {
+      pt = absl::HexStringToBytes(test_vectors[i].pt);
+    }
+
+    ChaCha20Poly1305Decrypter decrypter;
+    ASSERT_TRUE(decrypter.SetKey(key));
+    std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+        &decrypter, fixed + iv,
+        // This deliberately tests that the decrypter can handle an AAD that
+        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
+        ct));
+    if (!decrypted) {
+      EXPECT_FALSE(has_pt);
+      continue;
+    }
+    EXPECT_TRUE(has_pt);
+
+    EXPECT_EQ(12u, ct.size() - decrypted->length());
+    ASSERT_EQ(pt.length(), decrypted->length());
+    quiche::test::CompareCharArraysWithHexError(
+        "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_encrypter.cc b/quiche/quic/core/crypto/chacha20_poly1305_encrypter.cc
new file mode 100644
index 0000000..dcfb523
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_encrypter.cc
@@ -0,0 +1,37 @@
+// 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 "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+ChaCha20Poly1305Encrypter::ChaCha20Poly1305Encrypter()
+    : ChaChaBaseEncrypter(EVP_aead_chacha20_poly1305,
+                          kKeySize,
+                          kAuthTagSize,
+                          kNonceSize,
+                          /* use_ietf_nonce_construction */ false) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+ChaCha20Poly1305Encrypter::~ChaCha20Poly1305Encrypter() {}
+
+QuicPacketCount ChaCha20Poly1305Encrypter::GetConfidentialityLimit() const {
+  // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the
+  // number of possible packets (2^62) and so can be disregarded.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
+  return std::numeric_limits<QuicPacketCount>::max();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_encrypter.h b/quiche/quic/core/crypto/chacha20_poly1305_encrypter.h
new file mode 100644
index 0000000..d37f26c
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_encrypter.h
@@ -0,0 +1,38 @@
+// 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_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/chacha_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ChaCha20Poly1305Encrypter is a QuicEncrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539, except that
+// it truncates the Poly1305 authenticator to 12 bytes. Create an instance
+// by calling QuicEncrypter::Create(kCC20).
+//
+// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix of the
+// nonce is four bytes.
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Encrypter
+    : public ChaChaBaseEncrypter {
+ public:
+  enum {
+    kAuthTagSize = 12,
+  };
+
+  ChaCha20Poly1305Encrypter();
+  ChaCha20Poly1305Encrypter(const ChaCha20Poly1305Encrypter&) = delete;
+  ChaCha20Poly1305Encrypter& operator=(const ChaCha20Poly1305Encrypter&) =
+      delete;
+  ~ChaCha20Poly1305Encrypter() override;
+
+  QuicPacketCount GetConfidentialityLimit() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_encrypter_test.cc b/quiche/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
new file mode 100644
index 0000000..9ae728a
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
@@ -0,0 +1,159 @@
+// 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 "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_decrypter.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of five strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* pt;
+  const char* iv;
+  const char* fixed;
+  const char* aad;
+  const char* ct;
+};
+
+const TestVector test_vectors[] = {
+    {
+        "808182838485868788898a8b8c8d8e8f"
+        "909192939495969798999a9b9c9d9e9f",
+
+        "4c616469657320616e642047656e746c"
+        "656d656e206f662074686520636c6173"
+        "73206f66202739393a20496620492063"
+        "6f756c64206f6666657220796f75206f"
+        "6e6c79206f6e652074697020666f7220"
+        "746865206675747572652c2073756e73"
+        "637265656e20776f756c642062652069"
+        "742e",
+
+        "4041424344454647",
+
+        "07000000",
+
+        "50515253c0c1c2c3c4c5c6c7",
+
+        "d31a8d34648e60db7b86afbc53ef7ec2"
+        "a4aded51296e08fea9e2b5a736ee62d6"
+        "3dbea45e8ca9671282fafb69da92728b"
+        "1a71de0a9e060b2905d6a5b67ecd3b36"
+        "92ddbd7f2d778b8c9803aee328091b58"
+        "fab324e4fad675945585808b4831d7bc"
+        "3ff4def08e4b7a9de576d26586cec64b"
+        "6116"
+        "1ae10b594f09e26a7e902ecb",  // "d0600691" truncated
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(ChaCha20Poly1305Encrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class ChaCha20Poly1305EncrypterTest : public QuicTest {};
+
+TEST_F(ChaCha20Poly1305EncrypterTest, EncryptThenDecrypt) {
+  ChaCha20Poly1305Encrypter encrypter;
+  ChaCha20Poly1305Decrypter decrypter;
+
+  std::string key = absl::HexStringToBytes(test_vectors[0].key);
+  ASSERT_TRUE(encrypter.SetKey(key));
+  ASSERT_TRUE(decrypter.SetKey(key));
+  ASSERT_TRUE(encrypter.SetNoncePrefix("abcd"));
+  ASSERT_TRUE(decrypter.SetNoncePrefix("abcd"));
+
+  uint64_t packet_number = UINT64_C(0x123456789ABC);
+  std::string associated_data = "associated_data";
+  std::string plaintext = "plaintext";
+  char encrypted[1024];
+  size_t len;
+  ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext,
+                                      encrypted, &len,
+                                      ABSL_ARRAYSIZE(encrypted)));
+  absl::string_view ciphertext(encrypted, len);
+  char decrypted[1024];
+  ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data,
+                                      ciphertext, decrypted, &len,
+                                      ABSL_ARRAYSIZE(decrypted)));
+}
+
+TEST_F(ChaCha20Poly1305EncrypterTest, Encrypt) {
+  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+    // Decode the test vector.
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
+
+    ChaCha20Poly1305Encrypter encrypter;
+    ASSERT_TRUE(encrypter.SetKey(key));
+    std::unique_ptr<QuicData> encrypted(EncryptWithNonce(
+        &encrypter, fixed + iv,
+        // This deliberately tests that the encrypter can handle an AAD that
+        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
+        pt));
+    ASSERT_TRUE(encrypted.get());
+    EXPECT_EQ(12u, ct.size() - pt.size());
+    EXPECT_EQ(12u, encrypted->length() - pt.size());
+
+    quiche::test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
+                                                encrypted->length(), ct.data(),
+                                                ct.length());
+  }
+}
+
+TEST_F(ChaCha20Poly1305EncrypterTest, GetMaxPlaintextSize) {
+  ChaCha20Poly1305Encrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
+}
+
+TEST_F(ChaCha20Poly1305EncrypterTest, GetCiphertextSize) {
+  ChaCha20Poly1305Encrypter encrypter;
+  EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc
new file mode 100644
index 0000000..57b5f48
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc
@@ -0,0 +1,45 @@
+// Copyright 2017 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 "quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+ChaCha20Poly1305TlsDecrypter::ChaCha20Poly1305TlsDecrypter()
+    : ChaChaBaseDecrypter(EVP_aead_chacha20_poly1305,
+                          kKeySize,
+                          kAuthTagSize,
+                          kNonceSize,
+                          /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+ChaCha20Poly1305TlsDecrypter::~ChaCha20Poly1305TlsDecrypter() {}
+
+uint32_t ChaCha20Poly1305TlsDecrypter::cipher_id() const {
+  return TLS1_CK_CHACHA20_POLY1305_SHA256;
+}
+
+QuicPacketCount ChaCha20Poly1305TlsDecrypter::GetIntegrityLimit() const {
+  // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
+  static_assert(kMaxIncomingPacketSize < 16384,
+                "This key limit requires limits on decryption payload sizes");
+  return 68719476736U;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h
new file mode 100644
index 0000000..f8108f2
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h
@@ -0,0 +1,39 @@
+// Copyright 2017 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_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/chacha_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ChaCha20Poly1305TlsDecrypter is a QuicDecrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 bytes IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsDecrypter
+    : public ChaChaBaseDecrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  ChaCha20Poly1305TlsDecrypter();
+  ChaCha20Poly1305TlsDecrypter(const ChaCha20Poly1305TlsDecrypter&) = delete;
+  ChaCha20Poly1305TlsDecrypter& operator=(const ChaCha20Poly1305TlsDecrypter&) =
+      delete;
+  ~ChaCha20Poly1305TlsDecrypter() override;
+
+  uint32_t cipher_id() const override;
+  QuicPacketCount GetIntegrityLimit() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
new file mode 100644
index 0000000..0068636
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
@@ -0,0 +1,188 @@
+// Copyright 2017 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 "quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* fixed;
+  const char* aad;
+  const char* ct;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestVector test_vectors[] = {
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "50515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecbd0600691",
+
+     "4c616469657320616e642047656e746c"
+     "656d656e206f662074686520636c6173"
+     "73206f66202739393a20496620492063"
+     "6f756c64206f6666657220796f75206f"
+     "6e6c79206f6e652074697020666f7220"
+     "746865206675747572652c2073756e73"
+     "637265656e20776f756c642062652069"
+     "742e"},
+    // Modify the ciphertext (Poly1305 authenticator).
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "50515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902eccd0600691",
+
+     nullptr},
+    // Modify the associated data.
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "60515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecbd0600691",
+
+     nullptr},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(ChaCha20Poly1305TlsDecrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  decrypter->SetIV(nonce);
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success =
+      decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
+                               &output_length, ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class ChaCha20Poly1305TlsDecrypterTest : public QuicTest {};
+
+TEST_F(ChaCha20Poly1305TlsDecrypterTest, Decrypt) {
+  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+    // If not present then decryption is expected to fail.
+    bool has_pt = test_vectors[i].pt;
+
+    // Decode the test vector.
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
+    std::string pt;
+    if (has_pt) {
+      pt = absl::HexStringToBytes(test_vectors[i].pt);
+    }
+
+    ChaCha20Poly1305TlsDecrypter decrypter;
+    ASSERT_TRUE(decrypter.SetKey(key));
+    std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+        &decrypter, fixed + iv,
+        // This deliberately tests that the decrypter can handle an AAD that
+        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
+        ct));
+    if (!decrypted) {
+      EXPECT_FALSE(has_pt);
+      continue;
+    }
+    EXPECT_TRUE(has_pt);
+
+    EXPECT_EQ(16u, ct.size() - decrypted->length());
+    ASSERT_EQ(pt.length(), decrypted->length());
+    quiche::test::CompareCharArraysWithHexError(
+        "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+  }
+}
+
+TEST_F(ChaCha20Poly1305TlsDecrypterTest, GenerateHeaderProtectionMask) {
+  ChaCha20Poly1305TlsDecrypter decrypter;
+  std::string key = absl::HexStringToBytes(
+      "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
+  std::string sample =
+      absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
+  QuicDataReader sample_reader(sample.data(), sample.size());
+  ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
+  std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
+  std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc
new file mode 100644
index 0000000..12e3153
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc
@@ -0,0 +1,37 @@
+// Copyright 2017 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 "quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+ChaCha20Poly1305TlsEncrypter::ChaCha20Poly1305TlsEncrypter()
+    : ChaChaBaseEncrypter(EVP_aead_chacha20_poly1305,
+                          kKeySize,
+                          kAuthTagSize,
+                          kNonceSize,
+                          /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+ChaCha20Poly1305TlsEncrypter::~ChaCha20Poly1305TlsEncrypter() {}
+
+QuicPacketCount ChaCha20Poly1305TlsEncrypter::GetConfidentialityLimit() const {
+  // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the
+  // number of possible packets (2^62) and so can be disregarded.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
+  return std::numeric_limits<QuicPacketCount>::max();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h
new file mode 100644
index 0000000..e5d8f37
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h
@@ -0,0 +1,36 @@
+// Copyright 2017 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_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/chacha_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ChaCha20Poly1305Encrypter is a QuicEncrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsEncrypter
+    : public ChaChaBaseEncrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  ChaCha20Poly1305TlsEncrypter();
+  ChaCha20Poly1305TlsEncrypter(const ChaCha20Poly1305TlsEncrypter&) = delete;
+  ChaCha20Poly1305TlsEncrypter& operator=(const ChaCha20Poly1305TlsEncrypter&) =
+      delete;
+  ~ChaCha20Poly1305TlsEncrypter() override;
+
+  QuicPacketCount GetConfidentialityLimit() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
new file mode 100644
index 0000000..322651b
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
@@ -0,0 +1,173 @@
+// Copyright 2017 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 "quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of five strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* pt;
+  const char* iv;
+  const char* fixed;
+  const char* aad;
+  const char* ct;
+};
+
+const TestVector test_vectors[] = {
+    {
+        "808182838485868788898a8b8c8d8e8f"
+        "909192939495969798999a9b9c9d9e9f",
+
+        "4c616469657320616e642047656e746c"
+        "656d656e206f662074686520636c6173"
+        "73206f66202739393a20496620492063"
+        "6f756c64206f6666657220796f75206f"
+        "6e6c79206f6e652074697020666f7220"
+        "746865206675747572652c2073756e73"
+        "637265656e20776f756c642062652069"
+        "742e",
+
+        "4041424344454647",
+
+        "07000000",
+
+        "50515253c0c1c2c3c4c5c6c7",
+
+        "d31a8d34648e60db7b86afbc53ef7ec2"
+        "a4aded51296e08fea9e2b5a736ee62d6"
+        "3dbea45e8ca9671282fafb69da92728b"
+        "1a71de0a9e060b2905d6a5b67ecd3b36"
+        "92ddbd7f2d778b8c9803aee328091b58"
+        "fab324e4fad675945585808b4831d7bc"
+        "3ff4def08e4b7a9de576d26586cec64b"
+        "6116"
+        "1ae10b594f09e26a7e902ecbd0600691",
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(ChaCha20Poly1305TlsEncrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class ChaCha20Poly1305TlsEncrypterTest : public QuicTest {};
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, EncryptThenDecrypt) {
+  ChaCha20Poly1305TlsEncrypter encrypter;
+  ChaCha20Poly1305TlsDecrypter decrypter;
+
+  std::string key = absl::HexStringToBytes(test_vectors[0].key);
+  ASSERT_TRUE(encrypter.SetKey(key));
+  ASSERT_TRUE(decrypter.SetKey(key));
+  ASSERT_TRUE(encrypter.SetIV("abcdefghijkl"));
+  ASSERT_TRUE(decrypter.SetIV("abcdefghijkl"));
+
+  uint64_t packet_number = UINT64_C(0x123456789ABC);
+  std::string associated_data = "associated_data";
+  std::string plaintext = "plaintext";
+  char encrypted[1024];
+  size_t len;
+  ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext,
+                                      encrypted, &len,
+                                      ABSL_ARRAYSIZE(encrypted)));
+  absl::string_view ciphertext(encrypted, len);
+  char decrypted[1024];
+  ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data,
+                                      ciphertext, decrypted, &len,
+                                      ABSL_ARRAYSIZE(decrypted)));
+}
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, Encrypt) {
+  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+    // Decode the test vector.
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
+
+    ChaCha20Poly1305TlsEncrypter encrypter;
+    ASSERT_TRUE(encrypter.SetKey(key));
+    std::unique_ptr<QuicData> encrypted(EncryptWithNonce(
+        &encrypter, fixed + iv,
+        // This deliberately tests that the encrypter can handle an AAD that
+        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
+        pt));
+    ASSERT_TRUE(encrypted.get());
+    EXPECT_EQ(16u, ct.size() - pt.size());
+    EXPECT_EQ(16u, encrypted->length() - pt.size());
+
+    quiche::test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
+                                                encrypted->length(), ct.data(),
+                                                ct.length());
+  }
+}
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, GetMaxPlaintextSize) {
+  ChaCha20Poly1305TlsEncrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
+}
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, GetCiphertextSize) {
+  ChaCha20Poly1305TlsEncrypter encrypter;
+  EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
+}
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, GenerateHeaderProtectionMask) {
+  ChaCha20Poly1305TlsEncrypter encrypter;
+  std::string key = absl::HexStringToBytes(
+      "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
+  std::string sample =
+      absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
+  ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
+  std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
+  std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha_base_decrypter.cc b/quiche/quic/core/crypto/chacha_base_decrypter.cc
new file mode 100644
index 0000000..ec8e8a9
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha_base_decrypter.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/chacha_base_decrypter.h"
+
+#include <cstdint>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/chacha.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+bool ChaChaBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) {
+  if (key.size() != GetKeySize()) {
+    QUIC_BUG(quic_bug_10620_1) << "Invalid key size for header protection";
+    return false;
+  }
+  memcpy(pne_key_, key.data(), key.size());
+  return true;
+}
+
+std::string ChaChaBaseDecrypter::GenerateHeaderProtectionMask(
+    QuicDataReader* sample_reader) {
+  absl::string_view sample;
+  if (!sample_reader->ReadStringPiece(&sample, 16)) {
+    return std::string();
+  }
+  const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4;
+  uint32_t counter;
+  QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER)
+      .ReadUInt32(&counter);
+  const uint8_t zeroes[] = {0, 0, 0, 0, 0};
+  std::string out(ABSL_ARRAYSIZE(zeroes), 0);
+  CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
+                   zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter);
+  return out;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha_base_decrypter.h b/quiche/quic/core/crypto/chacha_base_decrypter.h
new file mode 100644
index 0000000..5cd08c7
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha_base_decrypter.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2013 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_CRYPTO_CHACHA_BASE_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/aead_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE ChaChaBaseDecrypter : public AeadBaseDecrypter {
+ public:
+  using AeadBaseDecrypter::AeadBaseDecrypter;
+
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  std::string GenerateHeaderProtectionMask(
+      QuicDataReader* sample_reader) override;
+
+ private:
+  // The key used for packet number encryption.
+  unsigned char pne_key_[kMaxKeySize];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha_base_encrypter.cc b/quiche/quic/core/crypto/chacha_base_encrypter.cc
new file mode 100644
index 0000000..12c1f55
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha_base_encrypter.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/chacha_base_encrypter.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/chacha.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+bool ChaChaBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) {
+  if (key.size() != GetKeySize()) {
+    QUIC_BUG(quic_bug_10656_1) << "Invalid key size for header protection";
+    return false;
+  }
+  memcpy(pne_key_, key.data(), key.size());
+  return true;
+}
+
+std::string ChaChaBaseEncrypter::GenerateHeaderProtectionMask(
+    absl::string_view sample) {
+  if (sample.size() != 16) {
+    return std::string();
+  }
+  const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4;
+  uint32_t counter;
+  QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER)
+      .ReadUInt32(&counter);
+  const uint8_t zeroes[] = {0, 0, 0, 0, 0};
+  std::string out(ABSL_ARRAYSIZE(zeroes), 0);
+  CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
+                   zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter);
+  return out;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha_base_encrypter.h b/quiche/quic/core/crypto/chacha_base_encrypter.h
new file mode 100644
index 0000000..14773ec
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha_base_encrypter.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2013 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_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/aead_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE ChaChaBaseEncrypter : public AeadBaseEncrypter {
+ public:
+  using AeadBaseEncrypter::AeadBaseEncrypter;
+
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
+
+ private:
+  // The key used for packet number encryption.
+  unsigned char pne_key_[kMaxKeySize];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/channel_id.cc b/quiche/quic/core/crypto/channel_id.cc
new file mode 100644
index 0000000..5e222f1
--- /dev/null
+++ b/quiche/quic/core/crypto/channel_id.cc
@@ -0,0 +1,90 @@
+// Copyright 2013 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 "quiche/quic/core/crypto/channel_id.h"
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/ecdsa.h"
+#include "third_party/boringssl/src/include/openssl/nid.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+
+namespace quic {
+
+// static
+const char ChannelIDVerifier::kContextStr[] = "QUIC ChannelID";
+// static
+const char ChannelIDVerifier::kClientToServerStr[] = "client -> server";
+
+// static
+bool ChannelIDVerifier::Verify(absl::string_view key,
+                               absl::string_view signed_data,
+                               absl::string_view signature) {
+  return VerifyRaw(key, signed_data, signature, true);
+}
+
+// static
+bool ChannelIDVerifier::VerifyRaw(absl::string_view key,
+                                  absl::string_view signed_data,
+                                  absl::string_view signature,
+                                  bool is_channel_id_signature) {
+  if (key.size() != 32 * 2 || signature.size() != 32 * 2) {
+    return false;
+  }
+
+  bssl::UniquePtr<EC_GROUP> p256(
+      EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+  if (p256.get() == nullptr) {
+    return false;
+  }
+
+  bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new()), r(BN_new()), s(BN_new());
+
+  ECDSA_SIG sig;
+  sig.r = r.get();
+  sig.s = s.get();
+
+  const uint8_t* key_bytes = reinterpret_cast<const uint8_t*>(key.data());
+  const uint8_t* signature_bytes =
+      reinterpret_cast<const uint8_t*>(signature.data());
+
+  if (BN_bin2bn(key_bytes + 0, 32, x.get()) == nullptr ||
+      BN_bin2bn(key_bytes + 32, 32, y.get()) == nullptr ||
+      BN_bin2bn(signature_bytes + 0, 32, sig.r) == nullptr ||
+      BN_bin2bn(signature_bytes + 32, 32, sig.s) == nullptr) {
+    return false;
+  }
+
+  bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
+  if (point.get() == nullptr ||
+      !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(),
+                                           y.get(), nullptr)) {
+    return false;
+  }
+
+  bssl::UniquePtr<EC_KEY> ecdsa_key(EC_KEY_new());
+  if (ecdsa_key.get() == nullptr ||
+      !EC_KEY_set_group(ecdsa_key.get(), p256.get()) ||
+      !EC_KEY_set_public_key(ecdsa_key.get(), point.get())) {
+    return false;
+  }
+
+  SHA256_CTX sha256;
+  SHA256_Init(&sha256);
+  if (is_channel_id_signature) {
+    SHA256_Update(&sha256, kContextStr, strlen(kContextStr) + 1);
+    SHA256_Update(&sha256, kClientToServerStr, strlen(kClientToServerStr) + 1);
+  }
+  SHA256_Update(&sha256, signed_data.data(), signed_data.size());
+
+  unsigned char digest[SHA256_DIGEST_LENGTH];
+  SHA256_Final(digest, &sha256);
+
+  return ECDSA_do_verify(digest, sizeof(digest), &sig, ecdsa_key.get()) == 1;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/channel_id.h b/quiche/quic/core/crypto/channel_id.h
new file mode 100644
index 0000000..9d20215
--- /dev/null
+++ b/quiche/quic/core/crypto/channel_id.h
@@ -0,0 +1,49 @@
+// Copyright 2013 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_CRYPTO_CHANNEL_ID_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// ChannelIDVerifier verifies ChannelID signatures.
+class QUIC_EXPORT_PRIVATE ChannelIDVerifier {
+ public:
+  ChannelIDVerifier() = delete;
+
+  // kContextStr is prepended to the data to be signed in order to ensure that
+  // a ChannelID signature cannot be used in a different context. (The
+  // terminating NUL byte is inclued.)
+  static const char kContextStr[];
+  // kClientToServerStr follows kContextStr to specify that the ChannelID is
+  // being used in the client to server direction. (The terminating NUL byte is
+  // included.)
+  static const char kClientToServerStr[];
+
+  // Verify returns true iff |signature| is a valid signature of |signed_data|
+  // by |key|.
+  static bool Verify(absl::string_view key,
+                     absl::string_view signed_data,
+                     absl::string_view signature);
+
+  // FOR TESTING ONLY: VerifyRaw returns true iff |signature| is a valid
+  // signature of |signed_data| by |key|. |is_channel_id_signature| indicates
+  // whether |signature| is a ChannelID signature (with kContextStr prepended
+  // to the data to be signed).
+  static bool VerifyRaw(absl::string_view key,
+                        absl::string_view signed_data,
+                        absl::string_view signature,
+                        bool is_channel_id_signature);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
diff --git a/quiche/quic/core/crypto/channel_id_test.cc b/quiche/quic/core/crypto/channel_id_test.cc
new file mode 100644
index 0000000..40e5090
--- /dev/null
+++ b/quiche/quic/core/crypto/channel_id_test.cc
@@ -0,0 +1,287 @@
+// Copyright 2013 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 "quiche/quic/core/crypto/channel_id.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+// The following ECDSA signature verification test vectors for P-256,SHA-256
+// come from the SigVer.rsp file in
+// http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
+// downloaded on 2013-06-11.
+struct TestVector {
+  // Input:
+  const char* msg;
+  const char* qx;
+  const char* qy;
+  const char* r;
+  const char* s;
+
+  // Expected output:
+  bool result;  // true means "P", false means "F"
+};
+
+const TestVector test_vector[] = {
+    {
+        "e4796db5f785f207aa30d311693b3702821dff1168fd2e04c0836825aefd850d"
+        "9aa60326d88cde1a23c7745351392ca2288d632c264f197d05cd424a30336c19"
+        "fd09bb229654f0222fcb881a4b35c290a093ac159ce13409111ff0358411133c"
+        "24f5b8e2090d6db6558afc36f06ca1f6ef779785adba68db27a409859fc4c4a0",
+        "87f8f2b218f49845f6f10eec3877136269f5c1a54736dbdf69f89940cad41555",
+        "e15f369036f49842fac7a86c8a2b0557609776814448b8f5e84aa9f4395205e9",
+        "d19ff48b324915576416097d2544f7cbdf8768b1454ad20e0baac50e211f23b0",
+        "a3e81e59311cdfff2d4784949f7a2cb50ba6c3a91fa54710568e61aca3e847c6",
+        false  // F (3 - S changed)
+    },
+    {
+        "069a6e6b93dfee6df6ef6997cd80dd2182c36653cef10c655d524585655462d6"
+        "83877f95ecc6d6c81623d8fac4e900ed0019964094e7de91f1481989ae187300"
+        "4565789cbf5dc56c62aedc63f62f3b894c9c6f7788c8ecaadc9bd0e81ad91b2b"
+        "3569ea12260e93924fdddd3972af5273198f5efda0746219475017557616170e",
+        "5cf02a00d205bdfee2016f7421807fc38ae69e6b7ccd064ee689fc1a94a9f7d2",
+        "ec530ce3cc5c9d1af463f264d685afe2b4db4b5828d7e61b748930f3ce622a85",
+        "dc23d130c6117fb5751201455e99f36f59aba1a6a21cf2d0e7481a97451d6693",
+        "d6ce7708c18dbf35d4f8aa7240922dc6823f2e7058cbc1484fcad1599db5018c",
+        false  // F (2 - R changed)
+    },
+    {
+        "df04a346cf4d0e331a6db78cca2d456d31b0a000aa51441defdb97bbeb20b94d"
+        "8d746429a393ba88840d661615e07def615a342abedfa4ce912e562af7149598"
+        "96858af817317a840dcff85a057bb91a3c2bf90105500362754a6dd321cdd861"
+        "28cfc5f04667b57aa78c112411e42da304f1012d48cd6a7052d7de44ebcc01de",
+        "2ddfd145767883ffbb0ac003ab4a44346d08fa2570b3120dcce94562422244cb",
+        "5f70c7d11ac2b7a435ccfbbae02c3df1ea6b532cc0e9db74f93fffca7c6f9a64",
+        "9913111cff6f20c5bf453a99cd2c2019a4e749a49724a08774d14e4c113edda8",
+        "9467cd4cd21ecb56b0cab0a9a453b43386845459127a952421f5c6382866c5cc",
+        false  // F (4 - Q changed)
+    },
+    {
+        "e1130af6a38ccb412a9c8d13e15dbfc9e69a16385af3c3f1e5da954fd5e7c45f"
+        "d75e2b8c36699228e92840c0562fbf3772f07e17f1add56588dd45f7450e1217"
+        "ad239922dd9c32695dc71ff2424ca0dec1321aa47064a044b7fe3c2b97d03ce4"
+        "70a592304c5ef21eed9f93da56bb232d1eeb0035f9bf0dfafdcc4606272b20a3",
+        "e424dc61d4bb3cb7ef4344a7f8957a0c5134e16f7a67c074f82e6e12f49abf3c",
+        "970eed7aa2bc48651545949de1dddaf0127e5965ac85d1243d6f60e7dfaee927",
+        "bf96b99aa49c705c910be33142017c642ff540c76349b9dab72f981fd9347f4f",
+        "17c55095819089c2e03b9cd415abdf12444e323075d98f31920b9e0f57ec871c",
+        true  // P (0 )
+    },
+    {
+        "73c5f6a67456ae48209b5f85d1e7de7758bf235300c6ae2bdceb1dcb27a7730f"
+        "b68c950b7fcada0ecc4661d3578230f225a875e69aaa17f1e71c6be5c831f226"
+        "63bac63d0c7a9635edb0043ff8c6f26470f02a7bc56556f1437f06dfa27b487a"
+        "6c4290d8bad38d4879b334e341ba092dde4e4ae694a9c09302e2dbf443581c08",
+        "e0fc6a6f50e1c57475673ee54e3a57f9a49f3328e743bf52f335e3eeaa3d2864",
+        "7f59d689c91e463607d9194d99faf316e25432870816dde63f5d4b373f12f22a",
+        "1d75830cd36f4c9aa181b2c4221e87f176b7f05b7c87824e82e396c88315c407",
+        "cb2acb01dac96efc53a32d4a0d85d0c2e48955214783ecf50a4f0414a319c05a",
+        true  // P (0 )
+    },
+    {
+        "666036d9b4a2426ed6585a4e0fd931a8761451d29ab04bd7dc6d0c5b9e38e6c2"
+        "b263ff6cb837bd04399de3d757c6c7005f6d7a987063cf6d7e8cb38a4bf0d74a"
+        "282572bd01d0f41e3fd066e3021575f0fa04f27b700d5b7ddddf50965993c3f9"
+        "c7118ed78888da7cb221849b3260592b8e632d7c51e935a0ceae15207bedd548",
+        "a849bef575cac3c6920fbce675c3b787136209f855de19ffe2e8d29b31a5ad86",
+        "bf5fe4f7858f9b805bd8dcc05ad5e7fb889de2f822f3d8b41694e6c55c16b471",
+        "25acc3aa9d9e84c7abf08f73fa4195acc506491d6fc37cb9074528a7db87b9d6",
+        "9b21d5b5259ed3f2ef07dfec6cc90d3a37855d1ce122a85ba6a333f307d31537",
+        false  // F (2 - R changed)
+    },
+    {
+        "7e80436bce57339ce8da1b5660149a20240b146d108deef3ec5da4ae256f8f89"
+        "4edcbbc57b34ce37089c0daa17f0c46cd82b5a1599314fd79d2fd2f446bd5a25"
+        "b8e32fcf05b76d644573a6df4ad1dfea707b479d97237a346f1ec632ea5660ef"
+        "b57e8717a8628d7f82af50a4e84b11f21bdff6839196a880ae20b2a0918d58cd",
+        "3dfb6f40f2471b29b77fdccba72d37c21bba019efa40c1c8f91ec405d7dcc5df",
+        "f22f953f1e395a52ead7f3ae3fc47451b438117b1e04d613bc8555b7d6e6d1bb",
+        "548886278e5ec26bed811dbb72db1e154b6f17be70deb1b210107decb1ec2a5a",
+        "e93bfebd2f14f3d827ca32b464be6e69187f5edbd52def4f96599c37d58eee75",
+        false  // F (4 - Q changed)
+    },
+    {
+        "1669bfb657fdc62c3ddd63269787fc1c969f1850fb04c933dda063ef74a56ce1"
+        "3e3a649700820f0061efabf849a85d474326c8a541d99830eea8131eaea584f2"
+        "2d88c353965dabcdc4bf6b55949fd529507dfb803ab6b480cd73ca0ba00ca19c"
+        "438849e2cea262a1c57d8f81cd257fb58e19dec7904da97d8386e87b84948169",
+        "69b7667056e1e11d6caf6e45643f8b21e7a4bebda463c7fdbc13bc98efbd0214",
+        "d3f9b12eb46c7c6fda0da3fc85bc1fd831557f9abc902a3be3cb3e8be7d1aa2f",
+        "288f7a1cd391842cce21f00e6f15471c04dc182fe4b14d92dc18910879799790",
+        "247b3c4e89a3bcadfea73c7bfd361def43715fa382b8c3edf4ae15d6e55e9979",
+        false  // F (1 - Message changed)
+    },
+    {
+        "3fe60dd9ad6caccf5a6f583b3ae65953563446c4510b70da115ffaa0ba04c076"
+        "115c7043ab8733403cd69c7d14c212c655c07b43a7c71b9a4cffe22c2684788e"
+        "c6870dc2013f269172c822256f9e7cc674791bf2d8486c0f5684283e1649576e"
+        "fc982ede17c7b74b214754d70402fb4bb45ad086cf2cf76b3d63f7fce39ac970",
+        "bf02cbcf6d8cc26e91766d8af0b164fc5968535e84c158eb3bc4e2d79c3cc682",
+        "069ba6cb06b49d60812066afa16ecf7b51352f2c03bd93ec220822b1f3dfba03",
+        "f5acb06c59c2b4927fb852faa07faf4b1852bbb5d06840935e849c4d293d1bad",
+        "049dab79c89cc02f1484c437f523e080a75f134917fda752f2d5ca397addfe5d",
+        false  // F (3 - S changed)
+    },
+    {
+        "983a71b9994d95e876d84d28946a041f8f0a3f544cfcc055496580f1dfd4e312"
+        "a2ad418fe69dbc61db230cc0c0ed97e360abab7d6ff4b81ee970a7e97466acfd"
+        "9644f828ffec538abc383d0e92326d1c88c55e1f46a668a039beaa1be631a891"
+        "29938c00a81a3ae46d4aecbf9707f764dbaccea3ef7665e4c4307fa0b0a3075c",
+        "224a4d65b958f6d6afb2904863efd2a734b31798884801fcab5a590f4d6da9de",
+        "178d51fddada62806f097aa615d33b8f2404e6b1479f5fd4859d595734d6d2b9",
+        "87b93ee2fecfda54deb8dff8e426f3c72c8864991f8ec2b3205bb3b416de93d2",
+        "4044a24df85be0cc76f21a4430b75b8e77b932a87f51e4eccbc45c263ebf8f66",
+        false  // F (2 - R changed)
+    },
+    {
+        "4a8c071ac4fd0d52faa407b0fe5dab759f7394a5832127f2a3498f34aac28733"
+        "9e043b4ffa79528faf199dc917f7b066ad65505dab0e11e6948515052ce20cfd"
+        "b892ffb8aa9bf3f1aa5be30a5bbe85823bddf70b39fd7ebd4a93a2f75472c1d4"
+        "f606247a9821f1a8c45a6cb80545de2e0c6c0174e2392088c754e9c8443eb5af",
+        "43691c7795a57ead8c5c68536fe934538d46f12889680a9cb6d055a066228369",
+        "f8790110b3c3b281aa1eae037d4f1234aff587d903d93ba3af225c27ddc9ccac",
+        "8acd62e8c262fa50dd9840480969f4ef70f218ebf8ef9584f199031132c6b1ce",
+        "cfca7ed3d4347fb2a29e526b43c348ae1ce6c60d44f3191b6d8ea3a2d9c92154",
+        false  // F (3 - S changed)
+    },
+    {
+        "0a3a12c3084c865daf1d302c78215d39bfe0b8bf28272b3c0b74beb4b7409db0"
+        "718239de700785581514321c6440a4bbaea4c76fa47401e151e68cb6c29017f0"
+        "bce4631290af5ea5e2bf3ed742ae110b04ade83a5dbd7358f29a85938e23d87a"
+        "c8233072b79c94670ff0959f9c7f4517862ff829452096c78f5f2e9a7e4e9216",
+        "9157dbfcf8cf385f5bb1568ad5c6e2a8652ba6dfc63bc1753edf5268cb7eb596",
+        "972570f4313d47fc96f7c02d5594d77d46f91e949808825b3d31f029e8296405",
+        "dfaea6f297fa320b707866125c2a7d5d515b51a503bee817de9faa343cc48eeb",
+        "8f780ad713f9c3e5a4f7fa4c519833dfefc6a7432389b1e4af463961f09764f2",
+        false  // F (1 - Message changed)
+    },
+    {
+        "785d07a3c54f63dca11f5d1a5f496ee2c2f9288e55007e666c78b007d95cc285"
+        "81dce51f490b30fa73dc9e2d45d075d7e3a95fb8a9e1465ad191904124160b7c"
+        "60fa720ef4ef1c5d2998f40570ae2a870ef3e894c2bc617d8a1dc85c3c557749"
+        "28c38789b4e661349d3f84d2441a3b856a76949b9f1f80bc161648a1cad5588e",
+        "072b10c081a4c1713a294f248aef850e297991aca47fa96a7470abe3b8acfdda",
+        "9581145cca04a0fb94cedce752c8f0370861916d2a94e7c647c5373ce6a4c8f5",
+        "09f5483eccec80f9d104815a1be9cc1a8e5b12b6eb482a65c6907b7480cf4f19",
+        "a4f90e560c5e4eb8696cb276e5165b6a9d486345dedfb094a76e8442d026378d",
+        false  // F (4 - Q changed)
+    },
+    {
+        "76f987ec5448dd72219bd30bf6b66b0775c80b394851a43ff1f537f140a6e722"
+        "9ef8cd72ad58b1d2d20298539d6347dd5598812bc65323aceaf05228f738b5ad"
+        "3e8d9fe4100fd767c2f098c77cb99c2992843ba3eed91d32444f3b6db6cd212d"
+        "d4e5609548f4bb62812a920f6e2bf1581be1ebeebdd06ec4e971862cc42055ca",
+        "09308ea5bfad6e5adf408634b3d5ce9240d35442f7fe116452aaec0d25be8c24",
+        "f40c93e023ef494b1c3079b2d10ef67f3170740495ce2cc57f8ee4b0618b8ee5",
+        "5cc8aa7c35743ec0c23dde88dabd5e4fcd0192d2116f6926fef788cddb754e73",
+        "9c9c045ebaa1b828c32f82ace0d18daebf5e156eb7cbfdc1eff4399a8a900ae7",
+        false  // F (1 - Message changed)
+    },
+    {
+        "60cd64b2cd2be6c33859b94875120361a24085f3765cb8b2bf11e026fa9d8855"
+        "dbe435acf7882e84f3c7857f96e2baab4d9afe4588e4a82e17a78827bfdb5ddb"
+        "d1c211fbc2e6d884cddd7cb9d90d5bf4a7311b83f352508033812c776a0e00c0"
+        "03c7e0d628e50736c7512df0acfa9f2320bd102229f46495ae6d0857cc452a84",
+        "2d98ea01f754d34bbc3003df5050200abf445ec728556d7ed7d5c54c55552b6d",
+        "9b52672742d637a32add056dfd6d8792f2a33c2e69dafabea09b960bc61e230a",
+        "06108e525f845d0155bf60193222b3219c98e3d49424c2fb2a0987f825c17959",
+        "62b5cdd591e5b507e560167ba8f6f7cda74673eb315680cb89ccbc4eec477dce",
+        true  // P (0 )
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, false}};
+
+// Returns true if |ch| is a lowercase hexadecimal digit.
+bool IsHexDigit(char ch) {
+  return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f');
+}
+
+// Converts a lowercase hexadecimal digit to its integer value.
+int HexDigitToInt(char ch) {
+  if ('0' <= ch && ch <= '9') {
+    return ch - '0';
+  }
+  return ch - 'a' + 10;
+}
+
+// |in| is a string consisting of lowercase hexadecimal digits, where
+// every two digits represent one byte. |out| is a buffer of size |max_len|.
+// Converts |in| to bytes and stores the bytes in the |out| buffer. The
+// number of bytes converted is returned in |*out_len|. Returns true on
+// success, false on failure.
+bool DecodeHexString(const char* in,
+                     char* out,
+                     size_t* out_len,
+                     size_t max_len) {
+  if (!in) {
+    *out_len = static_cast<size_t>(-1);
+    return true;
+  }
+  *out_len = 0;
+  while (*in != '\0') {
+    if (!IsHexDigit(*in) || !IsHexDigit(*(in + 1))) {
+      return false;
+    }
+    if (*out_len >= max_len) {
+      return false;
+    }
+    out[*out_len] = HexDigitToInt(*in) * 16 + HexDigitToInt(*(in + 1));
+    (*out_len)++;
+    in += 2;
+  }
+  return true;
+}
+
+}  // namespace
+
+class ChannelIDTest : public QuicTest {};
+
+// A known answer test for ChannelIDVerifier.
+TEST_F(ChannelIDTest, VerifyKnownAnswerTest) {
+  char msg[1024];
+  size_t msg_len;
+  char key[64];
+  size_t qx_len;
+  size_t qy_len;
+  char signature[64];
+  size_t r_len;
+  size_t s_len;
+
+  for (size_t i = 0; test_vector[i].msg != nullptr; i++) {
+    SCOPED_TRACE(i);
+    // Decode the test vector.
+    ASSERT_TRUE(
+        DecodeHexString(test_vector[i].msg, msg, &msg_len, sizeof(msg)));
+    ASSERT_TRUE(DecodeHexString(test_vector[i].qx, key, &qx_len, sizeof(key)));
+    ASSERT_TRUE(DecodeHexString(test_vector[i].qy, key + qx_len, &qy_len,
+                                sizeof(key) - qx_len));
+    ASSERT_TRUE(DecodeHexString(test_vector[i].r, signature, &r_len,
+                                sizeof(signature)));
+    ASSERT_TRUE(DecodeHexString(test_vector[i].s, signature + r_len, &s_len,
+                                sizeof(signature) - r_len));
+
+    // The test vector's lengths should look sane.
+    EXPECT_EQ(sizeof(key) / 2, qx_len);
+    EXPECT_EQ(sizeof(key) / 2, qy_len);
+    EXPECT_EQ(sizeof(signature) / 2, r_len);
+    EXPECT_EQ(sizeof(signature) / 2, s_len);
+
+    EXPECT_EQ(test_vector[i].result,
+              ChannelIDVerifier::VerifyRaw(
+                  absl::string_view(key, sizeof(key)),
+                  absl::string_view(msg, msg_len),
+                  absl::string_view(signature, sizeof(signature)), false));
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/client_proof_source.cc b/quiche/quic/core/crypto/client_proof_source.cc
new file mode 100644
index 0000000..9d4795c
--- /dev/null
+++ b/quiche/quic/core/crypto/client_proof_source.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2021 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 "quiche/quic/core/crypto/client_proof_source.h"
+
+#include "absl/strings/match.h"
+
+namespace quic {
+
+bool DefaultClientProofSource::AddCertAndKey(
+    std::vector<std::string> server_hostnames,
+    quiche::QuicheReferenceCountedPointer<Chain> chain,
+    CertificatePrivateKey private_key) {
+  if (!ValidateCertAndKey(chain, private_key)) {
+    return false;
+  }
+
+  auto cert_and_key =
+      std::make_shared<CertAndKey>(std::move(chain), std::move(private_key));
+  for (const std::string& domain : server_hostnames) {
+    cert_and_keys_[domain] = cert_and_key;
+  }
+  return true;
+}
+
+const ClientProofSource::CertAndKey* DefaultClientProofSource::GetCertAndKey(
+    absl::string_view hostname) const {
+  const CertAndKey* result = LookupExact(hostname);
+  if (result != nullptr || hostname == "*") {
+    return result;
+  }
+
+  // Either a full or a wildcard domain lookup failed. In the former case,
+  // derive the wildcard domain and look it up.
+  if (hostname.size() > 1 && !absl::StartsWith(hostname, "*.")) {
+    auto dot_pos = hostname.find('.');
+    if (dot_pos != std::string::npos) {
+      std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
+      const CertAndKey* result = LookupExact(wildcard);
+      if (result != nullptr) {
+        return result;
+      }
+    }
+  }
+
+  // Return default cert, if any.
+  return LookupExact("*");
+}
+
+const ClientProofSource::CertAndKey* DefaultClientProofSource::LookupExact(
+    absl::string_view map_key) const {
+  const auto it = cert_and_keys_.find(map_key);
+  QUIC_DVLOG(1) << "LookupExact(" << map_key
+                << ") found:" << (it != cert_and_keys_.end());
+  if (it != cert_and_keys_.end()) {
+    return it->second.get();
+  }
+  return nullptr;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/client_proof_source.h b/quiche/quic/core/crypto/client_proof_source.h
new file mode 100644
index 0000000..d1450f7
--- /dev/null
+++ b/quiche/quic/core/crypto/client_proof_source.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2021 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_CRYPTO_CLIENT_PROOF_SOURCE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
+
+#include <memory>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+
+namespace quic {
+
+// ClientProofSource is the interface for a QUIC client to provide client certs
+// and keys based on server hostname. It is only used by TLS handshakes.
+class QUIC_EXPORT_PRIVATE ClientProofSource {
+ public:
+  using Chain = ProofSource::Chain;
+
+  virtual ~ClientProofSource() {}
+
+  struct QUIC_EXPORT_PRIVATE CertAndKey {
+    CertAndKey(quiche::QuicheReferenceCountedPointer<Chain> chain,
+               CertificatePrivateKey private_key)
+        : chain(std::move(chain)), private_key(std::move(private_key)) {}
+
+    quiche::QuicheReferenceCountedPointer<Chain> chain;
+    CertificatePrivateKey private_key;
+  };
+
+  // Get the client certificate to be sent to the server with |server_hostname|
+  // and its corresponding private key. It returns nullptr if the cert and key
+  // can not be found.
+  //
+  // |server_hostname| is typically a full domain name(www.foo.com), but it
+  // could also be a wildcard domain(*.foo.com), or a "*" which will return the
+  // default cert.
+  virtual const CertAndKey* GetCertAndKey(
+      absl::string_view server_hostname) const = 0;
+};
+
+// DefaultClientProofSource is an implementation that simply keeps an in memory
+// map of server hostnames to certs.
+class QUIC_EXPORT_PRIVATE DefaultClientProofSource : public ClientProofSource {
+ public:
+  ~DefaultClientProofSource() override {}
+
+  // Associate all hostnames in |server_hostnames| with {|chain|,|private_key|}.
+  // Elements of |server_hostnames| can be full domain names(www.foo.com),
+  // wildcard domains(*.foo.com), or "*" which means the given cert chain is the
+  // default one.
+  // If any element of |server_hostnames| is already associated with a cert
+  // chain, it will be updated to be associated with the new cert chain.
+  bool AddCertAndKey(std::vector<std::string> server_hostnames,
+                     quiche::QuicheReferenceCountedPointer<Chain> chain,
+                     CertificatePrivateKey private_key);
+
+  // ClientProofSource implementation
+  const CertAndKey* GetCertAndKey(absl::string_view hostname) const override;
+
+ private:
+  const CertAndKey* LookupExact(absl::string_view map_key) const;
+  absl::flat_hash_map<std::string, std::shared_ptr<CertAndKey>> cert_and_keys_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
diff --git a/quiche/quic/core/crypto/client_proof_source_test.cc b/quiche/quic/core/crypto/client_proof_source_test.cc
new file mode 100644
index 0000000..a35e0aa
--- /dev/null
+++ b/quiche/quic/core/crypto/client_proof_source_test.cc
@@ -0,0 +1,215 @@
+// Copyright (c) 2021 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 "quiche/quic/core/crypto/client_proof_source.h"
+
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+
+namespace quic {
+namespace test {
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+TestCertChain() {
+  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+      new ClientProofSource::Chain({std::string(kTestCertificate)}));
+}
+
+CertificatePrivateKey TestPrivateKey() {
+  CBS private_key_cbs;
+  CBS_init(&private_key_cbs,
+           reinterpret_cast<const uint8_t*>(kTestCertificatePrivateKey.data()),
+           kTestCertificatePrivateKey.size());
+
+  return CertificatePrivateKey(
+      bssl::UniquePtr<EVP_PKEY>(EVP_parse_private_key(&private_key_cbs)));
+}
+
+const ClientProofSource::CertAndKey* TestCertAndKey() {
+  static const ClientProofSource::CertAndKey cert_and_key(TestCertChain(),
+                                                          TestPrivateKey());
+  return &cert_and_key;
+}
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+NullCertChain() {
+  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>();
+}
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+EmptyCertChain() {
+  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+      new ClientProofSource::Chain(std::vector<std::string>()));
+}
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain> BadCertChain() {
+  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+      new ClientProofSource::Chain({"This is the content of a bad cert."}));
+}
+
+CertificatePrivateKey EmptyPrivateKey() {
+  return CertificatePrivateKey(bssl::UniquePtr<EVP_PKEY>(EVP_PKEY_new()));
+}
+
+#define VERIFY_CERT_AND_KEY_MATCHES(lhs, rhs) \
+  do {                                        \
+    SCOPED_TRACE(testing::Message());         \
+    VerifyCertAndKeyMatches(lhs, rhs);        \
+  } while (0)
+
+void VerifyCertAndKeyMatches(const ClientProofSource::CertAndKey* lhs,
+                             const ClientProofSource::CertAndKey* rhs) {
+  if (lhs == rhs) {
+    return;
+  }
+
+  if (lhs == nullptr) {
+    ADD_FAILURE() << "lhs is nullptr, but rhs is not";
+    return;
+  }
+
+  if (rhs == nullptr) {
+    ADD_FAILURE() << "rhs is nullptr, but lhs is not";
+    return;
+  }
+
+  if (1 != EVP_PKEY_cmp(lhs->private_key.private_key(),
+                        rhs->private_key.private_key())) {
+    ADD_FAILURE() << "Private keys mismatch";
+    return;
+  }
+
+  const ClientProofSource::Chain* lhs_chain = lhs->chain.get();
+  const ClientProofSource::Chain* rhs_chain = rhs->chain.get();
+
+  if (lhs_chain == rhs_chain) {
+    return;
+  }
+
+  if (lhs_chain == nullptr) {
+    ADD_FAILURE() << "lhs->chain is nullptr, but rhs->chain is not";
+    return;
+  }
+
+  if (rhs_chain == nullptr) {
+    ADD_FAILURE() << "rhs->chain is nullptr, but lhs->chain is not";
+    return;
+  }
+
+  if (lhs_chain->certs.size() != rhs_chain->certs.size()) {
+    ADD_FAILURE() << "Cert chain length differ. lhs:" << lhs_chain->certs.size()
+                  << ", rhs:" << rhs_chain->certs.size();
+    return;
+  }
+
+  for (size_t i = 0; i < lhs_chain->certs.size(); ++i) {
+    if (lhs_chain->certs[i] != rhs_chain->certs[i]) {
+      ADD_FAILURE() << "The " << i << "-th certs differ.";
+      return;
+    }
+  }
+
+  // All good.
+}
+
+TEST(DefaultClientProofSource, FullDomain) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com"}, TestCertChain(),
+                                         TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  EXPECT_EQ(proof_source.GetCertAndKey("*.google.com"), nullptr);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, WildcardDomain) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(proof_source.AddCertAndKey({"*.google.com"}, TestCertChain(),
+                                         TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
+                              TestCertAndKey());
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, DefaultDomain) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(
+      proof_source.AddCertAndKey({"*"}, TestCertChain(), TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
+                              TestCertAndKey());
+}
+
+TEST(DefaultClientProofSource, FullAndWildcard) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com", "*.google.com"},
+                                         TestCertChain(), TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
+                              TestCertAndKey());
+  EXPECT_EQ(proof_source.GetCertAndKey("www.example.com"), nullptr);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, FullWildcardAndDefault) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(
+      proof_source.AddCertAndKey({"www.google.com", "*.google.com", "*"},
+                                 TestCertChain(), TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.example.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
+                              TestCertAndKey());
+}
+
+TEST(DefaultClientProofSource, EmptyCerts) {
+  DefaultClientProofSource proof_source;
+  bool ok;
+  EXPECT_QUIC_BUG(
+      ok = proof_source.AddCertAndKey({"*"}, NullCertChain(), TestPrivateKey()),
+      "Certificate chain is empty");
+  ASSERT_FALSE(ok);
+
+  EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey({"*"}, EmptyCertChain(),
+                                                  TestPrivateKey()),
+                  "Certificate chain is empty");
+  ASSERT_FALSE(ok);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, BadCerts) {
+  DefaultClientProofSource proof_source;
+  bool ok;
+  EXPECT_QUIC_BUG(
+      ok = proof_source.AddCertAndKey({"*"}, BadCertChain(), TestPrivateKey()),
+      "Unabled to parse leaf certificate");
+  ASSERT_FALSE(ok);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, KeyMismatch) {
+  DefaultClientProofSource proof_source;
+  bool ok;
+  EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey(
+                      {"www.google.com"}, TestCertChain(), EmptyPrivateKey()),
+                  "Private key does not match the leaf certificate");
+  ASSERT_FALSE(ok);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_framer.cc b/quiche/quic/core/crypto/crypto_framer.cc
new file mode 100644
index 0000000..db4e0b0
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_framer.cc
@@ -0,0 +1,358 @@
+// 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 "quiche/quic/core/crypto/crypto_framer.h"
+
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kQuicTagSize = sizeof(QuicTag);
+const size_t kCryptoEndOffsetSize = sizeof(uint32_t);
+const size_t kNumEntriesSize = sizeof(uint16_t);
+
+// OneShotVisitor is a framer visitor that records a single handshake message.
+class OneShotVisitor : public CryptoFramerVisitorInterface {
+ public:
+  OneShotVisitor() : error_(false) {}
+
+  void OnError(CryptoFramer* /*framer*/) override { error_ = true; }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+    out_ = std::make_unique<CryptoHandshakeMessage>(message);
+  }
+
+  bool error() const { return error_; }
+
+  std::unique_ptr<CryptoHandshakeMessage> release() { return std::move(out_); }
+
+ private:
+  std::unique_ptr<CryptoHandshakeMessage> out_;
+  bool error_;
+};
+
+}  // namespace
+
+CryptoFramer::CryptoFramer()
+    : visitor_(nullptr),
+      error_detail_(""),
+      num_entries_(0),
+      values_len_(0),
+      process_truncated_messages_(false) {
+  Clear();
+}
+
+CryptoFramer::~CryptoFramer() {}
+
+// static
+std::unique_ptr<CryptoHandshakeMessage> CryptoFramer::ParseMessage(
+    absl::string_view in) {
+  OneShotVisitor visitor;
+  CryptoFramer framer;
+
+  framer.set_visitor(&visitor);
+  if (!framer.ProcessInput(in) || visitor.error() ||
+      framer.InputBytesRemaining()) {
+    return nullptr;
+  }
+
+  return visitor.release();
+}
+
+QuicErrorCode CryptoFramer::error() const {
+  return error_;
+}
+
+const std::string& CryptoFramer::error_detail() const {
+  return error_detail_;
+}
+
+bool CryptoFramer::ProcessInput(absl::string_view input,
+                                EncryptionLevel /*level*/) {
+  return ProcessInput(input);
+}
+
+bool CryptoFramer::ProcessInput(absl::string_view input) {
+  QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
+  if (error_ != QUIC_NO_ERROR) {
+    return false;
+  }
+  error_ = Process(input);
+  if (error_ != QUIC_NO_ERROR) {
+    QUICHE_DCHECK(!error_detail_.empty());
+    visitor_->OnError(this);
+    return false;
+  }
+
+  return true;
+}
+
+size_t CryptoFramer::InputBytesRemaining() const {
+  return buffer_.length();
+}
+
+bool CryptoFramer::HasTag(QuicTag tag) const {
+  if (state_ != STATE_READING_VALUES) {
+    return false;
+  }
+  for (const auto& it : tags_and_lengths_) {
+    if (it.first == tag) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void CryptoFramer::ForceHandshake() {
+  QuicDataReader reader(buffer_.data(), buffer_.length(),
+                        quiche::HOST_BYTE_ORDER);
+  for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
+    absl::string_view value;
+    if (reader.BytesRemaining() < item.second) {
+      break;
+    }
+    reader.ReadStringPiece(&value, item.second);
+    message_.SetStringPiece(item.first, value);
+  }
+  visitor_->OnHandshakeMessage(message_);
+}
+
+// static
+std::unique_ptr<QuicData> CryptoFramer::ConstructHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  size_t num_entries = message.tag_value_map().size();
+  size_t pad_length = 0;
+  bool need_pad_tag = false;
+  bool need_pad_value = false;
+
+  size_t len = message.size();
+  if (len < message.minimum_size()) {
+    need_pad_tag = true;
+    need_pad_value = true;
+    num_entries++;
+
+    size_t delta = message.minimum_size() - len;
+    const size_t overhead = kQuicTagSize + kCryptoEndOffsetSize;
+    if (delta > overhead) {
+      pad_length = delta - overhead;
+    }
+    len += overhead + pad_length;
+  }
+
+  if (num_entries > kMaxEntries) {
+    return nullptr;
+  }
+
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get(), quiche::HOST_BYTE_ORDER);
+  if (!writer.WriteTag(message.tag())) {
+    QUICHE_DCHECK(false) << "Failed to write message tag.";
+    return nullptr;
+  }
+  if (!writer.WriteUInt16(static_cast<uint16_t>(num_entries))) {
+    QUICHE_DCHECK(false) << "Failed to write size.";
+    return nullptr;
+  }
+  if (!writer.WriteUInt16(0)) {
+    QUICHE_DCHECK(false) << "Failed to write padding.";
+    return nullptr;
+  }
+
+  uint32_t end_offset = 0;
+  // Tags and offsets
+  for (auto it = message.tag_value_map().begin();
+       it != message.tag_value_map().end(); ++it) {
+    if (it->first == kPAD && need_pad_tag) {
+      // Existing PAD tags are only checked when padding needs to be added
+      // because parts of the code may need to reserialize received messages
+      // and those messages may, legitimately include padding.
+      QUICHE_DCHECK(false)
+          << "Message needed padding but already contained a PAD tag";
+      return nullptr;
+    }
+
+    if (it->first > kPAD && need_pad_tag) {
+      need_pad_tag = false;
+      if (!WritePadTag(&writer, pad_length, &end_offset)) {
+        return nullptr;
+      }
+    }
+
+    if (!writer.WriteTag(it->first)) {
+      QUICHE_DCHECK(false) << "Failed to write tag.";
+      return nullptr;
+    }
+    end_offset += it->second.length();
+    if (!writer.WriteUInt32(end_offset)) {
+      QUICHE_DCHECK(false) << "Failed to write end offset.";
+      return nullptr;
+    }
+  }
+
+  if (need_pad_tag) {
+    if (!WritePadTag(&writer, pad_length, &end_offset)) {
+      return nullptr;
+    }
+  }
+
+  // Values
+  for (auto it = message.tag_value_map().begin();
+       it != message.tag_value_map().end(); ++it) {
+    if (it->first > kPAD && need_pad_value) {
+      need_pad_value = false;
+      if (!writer.WriteRepeatedByte('-', pad_length)) {
+        QUICHE_DCHECK(false) << "Failed to write padding.";
+        return nullptr;
+      }
+    }
+
+    if (!writer.WriteBytes(it->second.data(), it->second.length())) {
+      QUICHE_DCHECK(false) << "Failed to write value.";
+      return nullptr;
+    }
+  }
+
+  if (need_pad_value) {
+    if (!writer.WriteRepeatedByte('-', pad_length)) {
+      QUICHE_DCHECK(false) << "Failed to write padding.";
+      return nullptr;
+    }
+  }
+
+  return std::make_unique<QuicData>(buffer.release(), len, true);
+}
+
+void CryptoFramer::Clear() {
+  message_.Clear();
+  tags_and_lengths_.clear();
+  error_ = QUIC_NO_ERROR;
+  error_detail_ = "";
+  state_ = STATE_READING_TAG;
+}
+
+QuicErrorCode CryptoFramer::Process(absl::string_view input) {
+  // Add this data to the buffer.
+  buffer_.append(input.data(), input.length());
+  QuicDataReader reader(buffer_.data(), buffer_.length(),
+                        quiche::HOST_BYTE_ORDER);
+
+  switch (state_) {
+    case STATE_READING_TAG:
+      if (reader.BytesRemaining() < kQuicTagSize) {
+        break;
+      }
+      QuicTag message_tag;
+      reader.ReadTag(&message_tag);
+      message_.set_tag(message_tag);
+      state_ = STATE_READING_NUM_ENTRIES;
+      ABSL_FALLTHROUGH_INTENDED;
+    case STATE_READING_NUM_ENTRIES:
+      if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16_t)) {
+        break;
+      }
+      reader.ReadUInt16(&num_entries_);
+      if (num_entries_ > kMaxEntries) {
+        error_detail_ = absl::StrCat(num_entries_, " entries");
+        return QUIC_CRYPTO_TOO_MANY_ENTRIES;
+      }
+      uint16_t padding;
+      reader.ReadUInt16(&padding);
+
+      tags_and_lengths_.reserve(num_entries_);
+      state_ = STATE_READING_TAGS_AND_LENGTHS;
+      values_len_ = 0;
+      ABSL_FALLTHROUGH_INTENDED;
+    case STATE_READING_TAGS_AND_LENGTHS: {
+      if (reader.BytesRemaining() <
+          num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) {
+        break;
+      }
+
+      uint32_t last_end_offset = 0;
+      for (unsigned i = 0; i < num_entries_; ++i) {
+        QuicTag tag;
+        reader.ReadTag(&tag);
+        if (i > 0 && tag <= tags_and_lengths_[i - 1].first) {
+          if (tag == tags_and_lengths_[i - 1].first) {
+            error_detail_ = absl::StrCat("Duplicate tag:", tag);
+            return QUIC_CRYPTO_DUPLICATE_TAG;
+          }
+          error_detail_ = absl::StrCat("Tag ", tag, " out of order");
+          return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
+        }
+
+        uint32_t end_offset;
+        reader.ReadUInt32(&end_offset);
+
+        if (end_offset < last_end_offset) {
+          error_detail_ =
+              absl::StrCat("End offset: ", end_offset, " vs ", last_end_offset);
+          return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
+        }
+        tags_and_lengths_.push_back(std::make_pair(
+            tag, static_cast<size_t>(end_offset - last_end_offset)));
+        last_end_offset = end_offset;
+      }
+      values_len_ = last_end_offset;
+      state_ = STATE_READING_VALUES;
+      ABSL_FALLTHROUGH_INTENDED;
+    }
+    case STATE_READING_VALUES:
+      if (reader.BytesRemaining() < values_len_) {
+        if (!process_truncated_messages_) {
+          break;
+        }
+        QUIC_LOG(ERROR) << "Trunacted message. Missing "
+                        << values_len_ - reader.BytesRemaining() << " bytes.";
+      }
+      for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
+        absl::string_view value;
+        if (!reader.ReadStringPiece(&value, item.second)) {
+          QUICHE_DCHECK(process_truncated_messages_);
+          // Store an empty value.
+          message_.SetStringPiece(item.first, "");
+          continue;
+        }
+        message_.SetStringPiece(item.first, value);
+      }
+      visitor_->OnHandshakeMessage(message_);
+      Clear();
+      state_ = STATE_READING_TAG;
+      break;
+  }
+  // Save any remaining data.
+  buffer_ = std::string(reader.PeekRemainingPayload());
+  return QUIC_NO_ERROR;
+}
+
+// static
+bool CryptoFramer::WritePadTag(QuicDataWriter* writer,
+                               size_t pad_length,
+                               uint32_t* end_offset) {
+  if (!writer->WriteTag(kPAD)) {
+    QUICHE_DCHECK(false) << "Failed to write tag.";
+    return false;
+  }
+  *end_offset += pad_length;
+  if (!writer->WriteUInt32(*end_offset)) {
+    QUICHE_DCHECK(false) << "Failed to write end offset.";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_framer.h b/quiche/quic/core/crypto/crypto_framer.h
new file mode 100644
index 0000000..919ec09
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_framer.h
@@ -0,0 +1,137 @@
+// 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_CRYPTO_CRYPTO_FRAMER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_message_parser.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class CryptoFramer;
+class QuicData;
+class QuicDataWriter;
+
+class QUIC_EXPORT_PRIVATE CryptoFramerVisitorInterface {
+ public:
+  virtual ~CryptoFramerVisitorInterface() {}
+
+  // Called if an error is detected.
+  virtual void OnError(CryptoFramer* framer) = 0;
+
+  // Called when a complete handshake message has been parsed.
+  virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) = 0;
+};
+
+// A class for framing the crypto messages that are exchanged in a QUIC
+// session.
+class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser {
+ public:
+  CryptoFramer();
+
+  ~CryptoFramer() override;
+
+  // ParseMessage parses exactly one message from the given
+  // absl::string_view. If there is an error, the message is truncated,
+  // or the message has trailing garbage then nullptr will be returned.
+  static std::unique_ptr<CryptoHandshakeMessage> ParseMessage(
+      absl::string_view in);
+
+  // Set callbacks to be called from the framer.  A visitor must be set, or
+  // else the framer will crash.  It is acceptable for the visitor to do
+  // nothing.  If this is called multiple times, only the last visitor
+  // will be used.  |visitor| will be owned by the framer.
+  void set_visitor(CryptoFramerVisitorInterface* visitor) {
+    visitor_ = visitor;
+  }
+
+  QuicErrorCode error() const override;
+  const std::string& error_detail() const override;
+
+  // Processes input data, which must be delivered in order. Returns
+  // false if there was an error, and true otherwise. ProcessInput optionally
+  // takes an EncryptionLevel, but it is ignored. The variant with the
+  // EncryptionLevel is provided to match the CryptoMessageParser interface.
+  bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
+  bool ProcessInput(absl::string_view input);
+
+  // Returns the number of bytes of buffered input data remaining to be
+  // parsed.
+  size_t InputBytesRemaining() const override;
+
+  // Checks if the specified tag has been seen. Returns |true| if it
+  // has, and |false| if it has not or a CHLO has not been seen.
+  bool HasTag(QuicTag tag) const;
+
+  // Even if the CHLO has not been fully received, force processing of
+  // the handshake message. This is dangerous and should not be used
+  // except as a mechanism of last resort.
+  void ForceHandshake();
+
+  // Returns a new QuicData owned by the caller that contains a serialized
+  // |message|, or nullptr if there was an error.
+  static std::unique_ptr<QuicData> ConstructHandshakeMessage(
+      const CryptoHandshakeMessage& message);
+
+  // Debug only method which permits processing truncated messages.
+  void set_process_truncated_messages(bool process_truncated_messages) {
+    process_truncated_messages_ = process_truncated_messages;
+  }
+
+ private:
+  // Clears per-message state.  Does not clear the visitor.
+  void Clear();
+
+  // Process does does the work of |ProcessInput|, but returns an error code,
+  // doesn't set error_ and doesn't call |visitor_->OnError()|.
+  QuicErrorCode Process(absl::string_view input);
+
+  static bool WritePadTag(QuicDataWriter* writer,
+                          size_t pad_length,
+                          uint32_t* end_offset);
+
+  // Represents the current state of the parsing state machine.
+  enum CryptoFramerState {
+    STATE_READING_TAG,
+    STATE_READING_NUM_ENTRIES,
+    STATE_READING_TAGS_AND_LENGTHS,
+    STATE_READING_VALUES
+  };
+
+  // Visitor to invoke when messages are parsed.
+  CryptoFramerVisitorInterface* visitor_;
+  // Last error.
+  QuicErrorCode error_;
+  // Remaining unparsed data.
+  std::string buffer_;
+  // Current state of the parsing.
+  CryptoFramerState state_;
+  // The message currently being parsed.
+  CryptoHandshakeMessage message_;
+  // The issue which caused |error_|
+  std::string error_detail_;
+  // Number of entires in the message currently being parsed.
+  uint16_t num_entries_;
+  // tags_and_lengths_ contains the tags that are currently being parsed and
+  // their lengths.
+  std::vector<std::pair<QuicTag, size_t>> tags_and_lengths_;
+  // Cumulative length of all values in the message currently being parsed.
+  size_t values_len_;
+  // Set to true to allow of processing of truncated messages for debugging.
+  bool process_truncated_messages_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
diff --git a/quiche/quic/core/crypto/crypto_framer_test.cc b/quiche/quic/core/crypto/crypto_framer_test.cc
new file mode 100644
index 0000000..558d3e4
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_framer_test.cc
@@ -0,0 +1,466 @@
+// 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 "quiche/quic/core/crypto/crypto_framer.h"
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+char* AsChars(unsigned char* data) {
+  return reinterpret_cast<char*>(data);
+}
+
+class TestCryptoVisitor : public CryptoFramerVisitorInterface {
+ public:
+  TestCryptoVisitor() : error_count_(0) {}
+
+  void OnError(CryptoFramer* framer) override {
+    QUIC_DLOG(ERROR) << "CryptoFramer Error: " << framer->error();
+    ++error_count_;
+  }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+    messages_.push_back(message);
+  }
+
+  // Counters from the visitor callbacks.
+  int error_count_;
+
+  std::vector<CryptoHandshakeMessage> messages_;
+};
+
+TEST(CryptoFramerTest, ConstructHandshakeMessage) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(0x12345678, "abcdef");
+  message.SetStringPiece(0x12345679, "ghijk");
+  message.SetStringPiece(0x1234567A, "lmnopqr");
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x03, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // tag 3
+      0x7A, 0x56, 0x34, 0x12,
+      // end offset 3
+      0x12, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+      // value 3
+      'l', 'm', 'n', 'o', 'p', 'q', 'r',
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(0x12345678, "abcdef");
+  message.SetStringPiece(0x12345679, "ghijk");
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(0x12345678, "");
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x01, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x00, 0x00, 0x00, 0x00,
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  for (uint32_t key = 1; key <= kMaxEntries + 1; ++key) {
+    message.SetStringPiece(key, "abcdef");
+  }
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  EXPECT_TRUE(data == nullptr);
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(0x01020304, "test");
+  message.set_minimum_size(64);
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      'P', 'A', 'D', 0,
+      // end offset 1
+      0x24, 0x00, 0x00, 0x00,
+      // tag 2
+      0x04, 0x03, 0x02, 0x01,
+      // end offset 2
+      0x28, 0x00, 0x00, 0x00,
+      // 36 bytes of padding.
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+      '-', '-', '-', '-', '-', '-',
+      // value 2
+      't', 'e', 's', 't',
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(1, "");
+  message.set_minimum_size(64);
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x01, 0x00, 0x00, 0x00,
+      // end offset 1
+      0x00, 0x00, 0x00, 0x00,
+      // tag 2
+      'P', 'A', 'D', 0,
+      // end offset 2
+      0x28, 0x00, 0x00, 0x00,
+      // 40 bytes of padding.
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ProcessInput) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+  };
+
+  EXPECT_TRUE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_EQ(0u, framer.InputBytesRemaining());
+  EXPECT_EQ(0, visitor.error_count_);
+  ASSERT_EQ(1u, visitor.messages_.size());
+  const CryptoHandshakeMessage& message = visitor.messages_[0];
+  EXPECT_EQ(0xFFAA7733, message.tag());
+  EXPECT_EQ(2u, message.tag_value_map().size());
+  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
+  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
+}
+
+TEST(CryptoFramerTest, ProcessInputWithThreeKeys) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x03, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // tag 3
+      0x7A, 0x56, 0x34, 0x12,
+      // end offset 3
+      0x12, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+      // value 3
+      'l', 'm', 'n', 'o', 'p', 'q', 'r',
+  };
+
+  EXPECT_TRUE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_EQ(0u, framer.InputBytesRemaining());
+  EXPECT_EQ(0, visitor.error_count_);
+  ASSERT_EQ(1u, visitor.messages_.size());
+  const CryptoHandshakeMessage& message = visitor.messages_[0];
+  EXPECT_EQ(0xFFAA7733, message.tag());
+  EXPECT_EQ(3u, message.tag_value_map().size());
+  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
+  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
+  EXPECT_EQ("lmnopqr", crypto_test_utils::GetValueForTag(message, 0x1234567A));
+}
+
+TEST(CryptoFramerTest, ProcessInputIncrementally) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+  };
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(input); i++) {
+    EXPECT_TRUE(framer.ProcessInput(absl::string_view(AsChars(input) + i, 1)));
+  }
+  EXPECT_EQ(0u, framer.InputBytesRemaining());
+  ASSERT_EQ(1u, visitor.messages_.size());
+  const CryptoHandshakeMessage& message = visitor.messages_[0];
+  EXPECT_EQ(0xFFAA7733, message.tag());
+  EXPECT_EQ(2u, message.tag_value_map().size());
+  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
+  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
+}
+
+TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x13,
+      // end offset 1
+      0x01, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x02, 0x00, 0x00, 0x00,
+  };
+
+  EXPECT_FALSE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x01, 0x00, 0x00, 0x00,
+      // tag 2
+      0x78, 0x56, 0x34, 0x13,
+      // end offset 2
+      0x00, 0x00, 0x00, 0x00,
+  };
+
+  EXPECT_FALSE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST(CryptoFramerTest, ProcessInputTooManyEntries) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0xA0, 0x00,
+      // padding
+      0x00, 0x00,
+  };
+
+  EXPECT_FALSE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TOO_MANY_ENTRIES));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST(CryptoFramerTest, ProcessInputZeroLength) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x00, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x05, 0x00, 0x00, 0x00,
+  };
+
+  EXPECT_TRUE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_EQ(0, visitor.error_count_);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_handshake.cc b/quiche/quic/core/crypto/crypto_handshake.cc
new file mode 100644
index 0000000..bc17a97
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/crypto_handshake.h"
+
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+
+namespace quic {
+
+QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters()
+    : key_exchange(0),
+      aead(0),
+      token_binding_key_param(0),
+      sct_supported_by_client(false) {}
+
+QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() {}
+
+CrypterPair::CrypterPair() {}
+
+CrypterPair::~CrypterPair() {}
+
+// static
+const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion";
+
+// static
+const char QuicCryptoConfig::kCETVLabel[] = "QUIC CETV block";
+
+// static
+const char QuicCryptoConfig::kForwardSecureLabel[] =
+    "QUIC forward secure key expansion";
+
+QuicCryptoConfig::QuicCryptoConfig() = default;
+
+QuicCryptoConfig::~QuicCryptoConfig() = default;
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_handshake.h b/quiche/quic/core/crypto/crypto_handshake.h
new file mode 100644
index 0000000..d44f65e
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake.h
@@ -0,0 +1,189 @@
+// Copyright (c) 2013 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_CRYPTO_CRYPTO_HANDSHAKE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class SynchronousKeyExchange;
+class QuicDecrypter;
+class QuicEncrypter;
+
+// HandshakeFailureReason enum values are uploaded to UMA, they cannot be
+// changed.
+enum HandshakeFailureReason {
+  HANDSHAKE_OK = 0,
+
+  // Failure reasons for an invalid client nonce in CHLO.
+  //
+  // The default error value for nonce verification failures from strike
+  // register (covers old strike registers and unknown failures).
+  CLIENT_NONCE_UNKNOWN_FAILURE = 1,
+  // Client nonce had incorrect length.
+  CLIENT_NONCE_INVALID_FAILURE = 2,
+  // Client nonce is not unique.
+  CLIENT_NONCE_NOT_UNIQUE_FAILURE = 3,
+  // Client orbit is invalid or incorrect.
+  CLIENT_NONCE_INVALID_ORBIT_FAILURE = 4,
+  // Client nonce's timestamp is not in the strike register's valid time range.
+  CLIENT_NONCE_INVALID_TIME_FAILURE = 5,
+  // Strike register's RPC call timed out, client nonce couldn't be verified.
+  CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT = 6,
+  // Strike register is down, client nonce couldn't be verified.
+  CLIENT_NONCE_STRIKE_REGISTER_FAILURE = 7,
+
+  // Failure reasons for an invalid server nonce in CHLO.
+  //
+  // Unbox of server nonce failed.
+  SERVER_NONCE_DECRYPTION_FAILURE = 8,
+  // Decrypted server nonce had incorrect length.
+  SERVER_NONCE_INVALID_FAILURE = 9,
+  // Server nonce is not unique.
+  SERVER_NONCE_NOT_UNIQUE_FAILURE = 10,
+  // Server nonce's timestamp is not in the strike register's valid time range.
+  SERVER_NONCE_INVALID_TIME_FAILURE = 11,
+  // The server requires handshake confirmation.
+  SERVER_NONCE_REQUIRED_FAILURE = 20,
+
+  // Failure reasons for an invalid server config in CHLO.
+  //
+  // Missing Server config id (kSCID) tag.
+  SERVER_CONFIG_INCHOATE_HELLO_FAILURE = 12,
+  // Couldn't find the Server config id (kSCID).
+  SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE = 13,
+
+  // Failure reasons for an invalid source-address token.
+  //
+  // Missing Source-address token (kSourceAddressTokenTag) tag.
+  SOURCE_ADDRESS_TOKEN_INVALID_FAILURE = 14,
+  // Unbox of Source-address token failed.
+  SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE = 15,
+  // Couldn't parse the unbox'ed Source-address token.
+  SOURCE_ADDRESS_TOKEN_PARSE_FAILURE = 16,
+  // Source-address token is for a different IP address.
+  SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE = 17,
+  // The source-address token has a timestamp in the future.
+  SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE = 18,
+  // The source-address token has expired.
+  SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE = 19,
+
+  // The expected leaf certificate hash could not be validated.
+  INVALID_EXPECTED_LEAF_CERTIFICATE = 21,
+
+  MAX_FAILURE_REASON = 22,
+};
+
+// These errors will be packed into an uint32_t and we don't want to set the
+// most significant bit, which may be misinterpreted as the sign bit.
+static_assert(MAX_FAILURE_REASON <= 32, "failure reason out of sync");
+
+// A CrypterPair contains the encrypter and decrypter for an encryption level.
+struct QUIC_EXPORT_PRIVATE CrypterPair {
+  CrypterPair();
+  CrypterPair(CrypterPair&&) = default;
+  ~CrypterPair();
+
+  std::unique_ptr<QuicEncrypter> encrypter;
+  std::unique_ptr<QuicDecrypter> decrypter;
+};
+
+// Parameters negotiated by the crypto handshake.
+struct QUIC_EXPORT_PRIVATE QuicCryptoNegotiatedParameters
+    : public quiche::QuicheReferenceCounted {
+  // Initializes the members to 0 or empty values.
+  QuicCryptoNegotiatedParameters();
+
+  QuicTag key_exchange;
+  QuicTag aead;
+  std::string initial_premaster_secret;
+  std::string forward_secure_premaster_secret;
+  // initial_subkey_secret is used as the PRK input to the HKDF used when
+  // performing key extraction that needs to happen before forward-secure keys
+  // are available.
+  std::string initial_subkey_secret;
+  // subkey_secret is used as the PRK input to the HKDF used for key extraction.
+  std::string subkey_secret;
+  CrypterPair initial_crypters;
+  CrypterPair forward_secure_crypters;
+  // Normalized SNI: converted to lower case and trailing '.' removed.
+  std::string sni;
+  std::string client_nonce;
+  std::string server_nonce;
+  // hkdf_input_suffix contains the HKDF input following the label: the
+  // ConnectionId, client hello and server config. This is only populated in the
+  // client because only the client needs to derive the forward secure keys at a
+  // later time from the initial keys.
+  std::string hkdf_input_suffix;
+  // cached_certs contains the cached certificates that a client used when
+  // sending a client hello.
+  std::vector<std::string> cached_certs;
+  // client_key_exchange is used by clients to store the ephemeral KeyExchange
+  // for the connection.
+  std::unique_ptr<SynchronousKeyExchange> client_key_exchange;
+  // channel_id is set by servers to a ChannelID key when the client correctly
+  // proves possession of the corresponding private key. It consists of 32
+  // bytes of x coordinate, followed by 32 bytes of y coordinate. Both values
+  // are big-endian and the pair is a P-256 public key.
+  std::string channel_id;
+  QuicTag token_binding_key_param;
+
+  // Used when generating proof signature when sending server config updates.
+
+  // Used to generate cert chain when sending server config updates.
+  std::string client_cached_cert_hashes;
+
+  // Default to false; set to true if the client indicates that it supports sct
+  // by sending CSCT tag with an empty value in client hello.
+  bool sct_supported_by_client;
+
+  // Parameters only populated for TLS handshakes. These will be 0 for
+  // connections not using TLS, or if the TLS handshake is not finished yet.
+  uint16_t cipher_suite = 0;
+  uint16_t key_exchange_group = 0;
+  uint16_t peer_signature_algorithm = 0;
+
+ protected:
+  ~QuicCryptoNegotiatedParameters() override;
+};
+
+// QuicCryptoConfig contains common configuration between clients and servers.
+class QUIC_EXPORT_PRIVATE QuicCryptoConfig {
+ public:
+  // kInitialLabel is a constant that is used when deriving the initial
+  // (non-forward secure) keys for the connection in order to tie the resulting
+  // key to this protocol.
+  static const char kInitialLabel[];
+
+  // kCETVLabel is a constant that is used when deriving the keys for the
+  // encrypted tag/value block in the client hello.
+  static const char kCETVLabel[];
+
+  // kForwardSecureLabel is a constant that is used when deriving the forward
+  // secure keys for the connection in order to tie the resulting key to this
+  // protocol.
+  static const char kForwardSecureLabel[];
+
+  QuicCryptoConfig();
+  QuicCryptoConfig(const QuicCryptoConfig&) = delete;
+  QuicCryptoConfig& operator=(const QuicCryptoConfig&) = delete;
+  ~QuicCryptoConfig();
+
+  // Key exchange methods. The following two members' values correspond by
+  // index.
+  QuicTagVector kexs;
+  // Authenticated encryption with associated data (AEAD) algorithms.
+  QuicTagVector aead;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
diff --git a/quiche/quic/core/crypto/crypto_handshake_message.cc b/quiche/quic/core/crypto/crypto_handshake_message.cc
new file mode 100644
index 0000000..474036e
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake_message.cc
@@ -0,0 +1,382 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/crypto_handshake_message.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+CryptoHandshakeMessage::CryptoHandshakeMessage() : tag_(0), minimum_size_(0) {}
+
+CryptoHandshakeMessage::CryptoHandshakeMessage(
+    const CryptoHandshakeMessage& other)
+    : tag_(other.tag_),
+      tag_value_map_(other.tag_value_map_),
+      minimum_size_(other.minimum_size_) {
+  // Don't copy serialized_. unique_ptr doesn't have a copy constructor.
+  // The new object can lazily reconstruct serialized_.
+}
+
+CryptoHandshakeMessage::CryptoHandshakeMessage(CryptoHandshakeMessage&& other) =
+    default;
+
+CryptoHandshakeMessage::~CryptoHandshakeMessage() {}
+
+CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
+    const CryptoHandshakeMessage& other) {
+  tag_ = other.tag_;
+  tag_value_map_ = other.tag_value_map_;
+  // Don't copy serialized_. unique_ptr doesn't have an assignment operator.
+  // However, invalidate serialized_.
+  serialized_.reset();
+  minimum_size_ = other.minimum_size_;
+  return *this;
+}
+
+CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
+    CryptoHandshakeMessage&& other) = default;
+
+bool CryptoHandshakeMessage::operator==(
+    const CryptoHandshakeMessage& rhs) const {
+  return tag_ == rhs.tag_ && tag_value_map_ == rhs.tag_value_map_ &&
+         minimum_size_ == rhs.minimum_size_;
+}
+
+bool CryptoHandshakeMessage::operator!=(
+    const CryptoHandshakeMessage& rhs) const {
+  return !(*this == rhs);
+}
+
+void CryptoHandshakeMessage::Clear() {
+  tag_ = 0;
+  tag_value_map_.clear();
+  minimum_size_ = 0;
+  serialized_.reset();
+}
+
+const QuicData& CryptoHandshakeMessage::GetSerialized() const {
+  if (!serialized_) {
+    serialized_ = CryptoFramer::ConstructHandshakeMessage(*this);
+  }
+  return *serialized_;
+}
+
+void CryptoHandshakeMessage::MarkDirty() {
+  serialized_.reset();
+}
+
+void CryptoHandshakeMessage::SetVersionVector(
+    QuicTag tag,
+    ParsedQuicVersionVector versions) {
+  QuicVersionLabelVector version_labels;
+  for (const ParsedQuicVersion& version : versions) {
+    version_labels.push_back(
+        quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version)));
+  }
+  SetVector(tag, version_labels);
+}
+
+void CryptoHandshakeMessage::SetVersion(QuicTag tag,
+                                        ParsedQuicVersion version) {
+  SetValue(tag,
+           quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version)));
+}
+
+void CryptoHandshakeMessage::SetStringPiece(QuicTag tag,
+                                            absl::string_view value) {
+  tag_value_map_[tag] = std::string(value);
+}
+
+void CryptoHandshakeMessage::Erase(QuicTag tag) {
+  tag_value_map_.erase(tag);
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetTaglist(
+    QuicTag tag,
+    QuicTagVector* out_tags) const {
+  auto it = tag_value_map_.find(tag);
+  QuicErrorCode ret = QUIC_NO_ERROR;
+
+  if (it == tag_value_map_.end()) {
+    ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  } else if (it->second.size() % sizeof(QuicTag) != 0) {
+    ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  if (ret != QUIC_NO_ERROR) {
+    out_tags->clear();
+    return ret;
+  }
+
+  size_t num_tags = it->second.size() / sizeof(QuicTag);
+  out_tags->resize(num_tags);
+  for (size_t i = 0; i < num_tags; ++i) {
+    QuicTag tag;
+    memcpy(&tag, it->second.data() + i * sizeof(tag), sizeof(tag));
+    (*out_tags)[i] = tag;
+  }
+  return ret;
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetVersionLabelList(
+    QuicTag tag,
+    QuicVersionLabelVector* out) const {
+  QuicErrorCode error = GetTaglist(tag, out);
+  if (error != QUIC_NO_ERROR) {
+    return error;
+  }
+
+  for (size_t i = 0; i < out->size(); ++i) {
+    (*out)[i] = quiche::QuicheEndian::HostToNet32((*out)[i]);
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetVersionLabel(
+    QuicTag tag,
+    QuicVersionLabel* out) const {
+  QuicErrorCode error = GetUint32(tag, out);
+  if (error != QUIC_NO_ERROR) {
+    return error;
+  }
+
+  *out = quiche::QuicheEndian::HostToNet32(*out);
+  return QUIC_NO_ERROR;
+}
+
+bool CryptoHandshakeMessage::GetStringPiece(QuicTag tag,
+                                            absl::string_view* out) const {
+  auto it = tag_value_map_.find(tag);
+  if (it == tag_value_map_.end()) {
+    return false;
+  }
+  *out = it->second;
+  return true;
+}
+
+bool CryptoHandshakeMessage::HasStringPiece(QuicTag tag) const {
+  return tag_value_map_.find(tag) != tag_value_map_.end();
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetNthValue24(
+    QuicTag tag,
+    unsigned index,
+    absl::string_view* out) const {
+  absl::string_view value;
+  if (!GetStringPiece(tag, &value)) {
+    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  }
+
+  for (unsigned i = 0;; i++) {
+    if (value.empty()) {
+      return QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND;
+    }
+    if (value.size() < 3) {
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+
+    const unsigned char* data =
+        reinterpret_cast<const unsigned char*>(value.data());
+    size_t size = static_cast<size_t>(data[0]) |
+                  (static_cast<size_t>(data[1]) << 8) |
+                  (static_cast<size_t>(data[2]) << 16);
+    value.remove_prefix(3);
+
+    if (value.size() < size) {
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+
+    if (i == index) {
+      *out = absl::string_view(value.data(), size);
+      return QUIC_NO_ERROR;
+    }
+
+    value.remove_prefix(size);
+  }
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag,
+                                                uint32_t* out) const {
+  return GetPOD(tag, out, sizeof(uint32_t));
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetUint64(QuicTag tag,
+                                                uint64_t* out) const {
+  return GetPOD(tag, out, sizeof(uint64_t));
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetStatelessResetToken(
+    QuicTag tag,
+    StatelessResetToken* out) const {
+  return GetPOD(tag, out, kStatelessResetTokenLength);
+}
+
+size_t CryptoHandshakeMessage::size() const {
+  size_t ret = sizeof(QuicTag) + sizeof(uint16_t) /* number of entries */ +
+               sizeof(uint16_t) /* padding */;
+  ret += (sizeof(QuicTag) + sizeof(uint32_t) /* end offset */) *
+         tag_value_map_.size();
+  for (auto i = tag_value_map_.begin(); i != tag_value_map_.end(); ++i) {
+    ret += i->second.size();
+  }
+
+  return ret;
+}
+
+void CryptoHandshakeMessage::set_minimum_size(size_t min_bytes) {
+  if (min_bytes == minimum_size_) {
+    return;
+  }
+  serialized_.reset();
+  minimum_size_ = min_bytes;
+}
+
+size_t CryptoHandshakeMessage::minimum_size() const {
+  return minimum_size_;
+}
+
+std::string CryptoHandshakeMessage::DebugString() const {
+  return DebugStringInternal(0);
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetPOD(QuicTag tag,
+                                             void* out,
+                                             size_t len) const {
+  auto it = tag_value_map_.find(tag);
+  QuicErrorCode ret = QUIC_NO_ERROR;
+
+  if (it == tag_value_map_.end()) {
+    ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  } else if (it->second.size() != len) {
+    ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  if (ret != QUIC_NO_ERROR) {
+    memset(out, 0, len);
+    return ret;
+  }
+
+  memcpy(out, it->second.data(), len);
+  return ret;
+}
+
+std::string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const {
+  std::string ret =
+      std::string(2 * indent, ' ') + QuicTagToString(tag_) + "<\n";
+  ++indent;
+  for (auto it = tag_value_map_.begin(); it != tag_value_map_.end(); ++it) {
+    ret += std::string(2 * indent, ' ') + QuicTagToString(it->first) + ": ";
+
+    bool done = false;
+    switch (it->first) {
+      case kICSL:
+      case kCFCW:
+      case kSFCW:
+      case kIRTT:
+      case kMIUS:
+      case kMIBS:
+      case kTCID:
+      case kMAD:
+        // uint32_t value
+        if (it->second.size() == 4) {
+          uint32_t value;
+          memcpy(&value, it->second.data(), sizeof(value));
+          absl::StrAppend(&ret, value);
+          done = true;
+        }
+        break;
+      case kKEXS:
+      case kAEAD:
+      case kCOPT:
+      case kPDMD:
+      case kVER:
+        // tag lists
+        if (it->second.size() % sizeof(QuicTag) == 0) {
+          for (size_t j = 0; j < it->second.size(); j += sizeof(QuicTag)) {
+            QuicTag tag;
+            memcpy(&tag, it->second.data() + j, sizeof(tag));
+            if (j > 0) {
+              ret += ",";
+            }
+            ret += "'" + QuicTagToString(tag) + "'";
+          }
+          done = true;
+        }
+        break;
+      case kRREJ:
+        // uint32_t lists
+        if (it->second.size() % sizeof(uint32_t) == 0) {
+          for (size_t j = 0; j < it->second.size(); j += sizeof(uint32_t)) {
+            uint32_t value;
+            memcpy(&value, it->second.data() + j, sizeof(value));
+            if (j > 0) {
+              ret += ",";
+            }
+            ret += CryptoUtils::HandshakeFailureReasonToString(
+                static_cast<HandshakeFailureReason>(value));
+          }
+          done = true;
+        }
+        break;
+      case kCADR:
+        // IP address and port
+        if (!it->second.empty()) {
+          QuicSocketAddressCoder decoder;
+          if (decoder.Decode(it->second.data(), it->second.size())) {
+            ret += QuicSocketAddress(decoder.ip(), decoder.port()).ToString();
+            done = true;
+          }
+        }
+        break;
+      case kSCFG:
+        // nested messages.
+        if (!it->second.empty()) {
+          std::unique_ptr<CryptoHandshakeMessage> msg(
+              CryptoFramer::ParseMessage(it->second));
+          if (msg) {
+            ret += "\n";
+            ret += msg->DebugStringInternal(indent + 1);
+
+            done = true;
+          }
+        }
+        break;
+      case kPAD:
+        ret += absl::StrFormat("(%d bytes of padding)", it->second.size());
+        done = true;
+        break;
+      case kSNI:
+      case kUAID:
+        ret += "\"" + it->second + "\"";
+        done = true;
+        break;
+    }
+
+    if (!done) {
+      // If there's no specific format for this tag, or the value is invalid,
+      // then just use hex.
+      ret += "0x" + absl::BytesToHexString(it->second);
+    }
+    ret += "\n";
+  }
+  --indent;
+  ret += std::string(2 * indent, ' ') + ">";
+  return ret;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_handshake_message.h b/quiche/quic/core/crypto/crypto_handshake_message.h
new file mode 100644
index 0000000..4785fa8
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake_message.h
@@ -0,0 +1,160 @@
+// Copyright (c) 2013 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_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An intermediate format of a handshake message that's convenient for a
+// CryptoFramer to serialize from or parse into.
+class QUIC_EXPORT_PRIVATE CryptoHandshakeMessage {
+ public:
+  CryptoHandshakeMessage();
+  CryptoHandshakeMessage(const CryptoHandshakeMessage& other);
+  CryptoHandshakeMessage(CryptoHandshakeMessage&& other);
+  ~CryptoHandshakeMessage();
+
+  CryptoHandshakeMessage& operator=(const CryptoHandshakeMessage& other);
+  CryptoHandshakeMessage& operator=(CryptoHandshakeMessage&& other);
+
+  bool operator==(const CryptoHandshakeMessage& rhs) const;
+  bool operator!=(const CryptoHandshakeMessage& rhs) const;
+
+  // Clears state.
+  void Clear();
+
+  // GetSerialized returns the serialized form of this message and caches the
+  // result. Subsequently altering the message does not invalidate the cache.
+  const QuicData& GetSerialized() const;
+
+  // MarkDirty invalidates the cache created by |GetSerialized|.
+  void MarkDirty();
+
+  // SetValue sets an element with the given tag to the raw, memory contents of
+  // |v|.
+  template <class T>
+  void SetValue(QuicTag tag, const T& v) {
+    tag_value_map_[tag] =
+        std::string(reinterpret_cast<const char*>(&v), sizeof(v));
+  }
+
+  // SetVector sets an element with the given tag to the raw contents of an
+  // array of elements in |v|.
+  template <class T>
+  void SetVector(QuicTag tag, const std::vector<T>& v) {
+    if (v.empty()) {
+      tag_value_map_[tag] = std::string();
+    } else {
+      tag_value_map_[tag] = std::string(reinterpret_cast<const char*>(&v[0]),
+                                        v.size() * sizeof(T));
+    }
+  }
+
+  // Sets an element with the given tag to the on-the-wire representation of
+  // |version|.
+  void SetVersion(QuicTag tag, ParsedQuicVersion version);
+
+  // Sets an element with the given tag to the on-the-wire representation of
+  // the elements in |versions|.
+  void SetVersionVector(QuicTag tag, ParsedQuicVersionVector versions);
+
+  // Returns the message tag.
+  QuicTag tag() const { return tag_; }
+  // Sets the message tag.
+  void set_tag(QuicTag tag) { tag_ = tag; }
+
+  const QuicTagValueMap& tag_value_map() const { return tag_value_map_; }
+
+  void SetStringPiece(QuicTag tag, absl::string_view value);
+
+  // Erase removes a tag/value, if present, from the message.
+  void Erase(QuicTag tag);
+
+  // GetTaglist finds an element with the given tag containing zero or more
+  // tags. If such a tag doesn't exist, it returns an error code. Otherwise it
+  // populates |out_tags| with the tags and returns QUIC_NO_ERROR.
+  QuicErrorCode GetTaglist(QuicTag tag, QuicTagVector* out_tags) const;
+
+  // GetVersionLabelList finds an element with the given tag containing zero or
+  // more version labels. If such a tag doesn't exist, it returns an error code.
+  // Otherwise it populates |out| with the labels and returns QUIC_NO_ERROR.
+  QuicErrorCode GetVersionLabelList(QuicTag tag,
+                                    QuicVersionLabelVector* out) const;
+
+  // GetVersionLabel finds an element with the given tag containing a single
+  // version label. If such a tag doesn't exist, it returns an error code.
+  // Otherwise it populates |out| with the label and returns QUIC_NO_ERROR.
+  QuicErrorCode GetVersionLabel(QuicTag tag, QuicVersionLabel* out) const;
+
+  bool GetStringPiece(QuicTag tag, absl::string_view* out) const;
+  bool HasStringPiece(QuicTag tag) const;
+
+  // GetNthValue24 interprets the value with the given tag to be a series of
+  // 24-bit, length prefixed values and it returns the subvalue with the given
+  // index.
+  QuicErrorCode GetNthValue24(QuicTag tag,
+                              unsigned index,
+                              absl::string_view* out) const;
+  QuicErrorCode GetUint32(QuicTag tag, uint32_t* out) const;
+  QuicErrorCode GetUint64(QuicTag tag, uint64_t* out) const;
+
+  QuicErrorCode GetStatelessResetToken(QuicTag tag,
+                                       StatelessResetToken* out) const;
+
+  // size returns 4 (message tag) + 2 (uint16_t, number of entries) +
+  // (4 (tag) + 4 (end offset))*tag_value_map_.size() + ∑ value sizes.
+  size_t size() const;
+
+  // set_minimum_size sets the minimum number of bytes that the message should
+  // consume. The CryptoFramer will add a PAD tag as needed when serializing in
+  // order to ensure this. Setting a value of 0 disables padding.
+  //
+  // Padding is useful in order to ensure that messages are a minimum size. A
+  // QUIC server can require a minimum size in order to reduce the
+  // amplification factor of any mirror DoS attack.
+  void set_minimum_size(size_t min_bytes);
+
+  size_t minimum_size() const;
+
+  // DebugString returns a multi-line, string representation of the message
+  // suitable for including in debug output.
+  std::string DebugString() const;
+
+ private:
+  // GetPOD is a utility function for extracting a plain-old-data value. If
+  // |tag| exists in the message, and has a value of exactly |len| bytes then
+  // it copies |len| bytes of data into |out|. Otherwise |len| bytes at |out|
+  // are zeroed out.
+  //
+  // If used to copy integers then this assumes that the machine is
+  // little-endian.
+  QuicErrorCode GetPOD(QuicTag tag, void* out, size_t len) const;
+
+  std::string DebugStringInternal(size_t indent) const;
+
+  QuicTag tag_;
+  QuicTagValueMap tag_value_map_;
+
+  size_t minimum_size_;
+
+  // The serialized form of the handshake message. This member is constructed
+  // lazily.
+  mutable std::unique_ptr<QuicData> serialized_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
diff --git a/quiche/quic/core/crypto/crypto_handshake_message_test.cc b/quiche/quic/core/crypto/crypto_handshake_message_test.cc
new file mode 100644
index 0000000..bdc051c
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake_message_test.cc
@@ -0,0 +1,105 @@
+// Copyright (c) 2015 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 "quiche/quic/core/crypto/crypto_handshake_message.h"
+
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(CryptoHandshakeMessageTest, DebugString) {
+  const char* str = "SHLO<\n>";
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kSHLO);
+  EXPECT_EQ(str, message.DebugString());
+
+  // Test copy
+  CryptoHandshakeMessage message2(message);
+  EXPECT_EQ(str, message2.DebugString());
+
+  // Test move
+  CryptoHandshakeMessage message3(std::move(message));
+  EXPECT_EQ(str, message3.DebugString());
+
+  // Test assign
+  CryptoHandshakeMessage message4 = message3;
+  EXPECT_EQ(str, message4.DebugString());
+
+  // Test move-assign
+  CryptoHandshakeMessage message5 = std::move(message3);
+  EXPECT_EQ(str, message5.DebugString());
+}
+
+TEST(CryptoHandshakeMessageTest, DebugStringWithUintVector) {
+  const char* str =
+      "REJ <\n  RREJ: "
+      "SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,"
+      "CLIENT_NONCE_NOT_UNIQUE_FAILURE\n>";
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kREJ);
+  std::vector<uint32_t> reasons = {
+      SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+      CLIENT_NONCE_NOT_UNIQUE_FAILURE};
+  message.SetVector(kRREJ, reasons);
+  EXPECT_EQ(str, message.DebugString());
+
+  // Test copy
+  CryptoHandshakeMessage message2(message);
+  EXPECT_EQ(str, message2.DebugString());
+
+  // Test move
+  CryptoHandshakeMessage message3(std::move(message));
+  EXPECT_EQ(str, message3.DebugString());
+
+  // Test assign
+  CryptoHandshakeMessage message4 = message3;
+  EXPECT_EQ(str, message4.DebugString());
+
+  // Test move-assign
+  CryptoHandshakeMessage message5 = std::move(message3);
+  EXPECT_EQ(str, message5.DebugString());
+}
+
+TEST(CryptoHandshakeMessageTest, DebugStringWithTagVector) {
+  const char* str = "CHLO<\n  COPT: 'TBBR','PAD ','BYTE'\n>";
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kCHLO);
+  message.SetVector(kCOPT, QuicTagVector{kTBBR, kPAD, kBYTE});
+  EXPECT_EQ(str, message.DebugString());
+
+  // Test copy
+  CryptoHandshakeMessage message2(message);
+  EXPECT_EQ(str, message2.DebugString());
+
+  // Test move
+  CryptoHandshakeMessage message3(std::move(message));
+  EXPECT_EQ(str, message3.DebugString());
+
+  // Test assign
+  CryptoHandshakeMessage message4 = message3;
+  EXPECT_EQ(str, message4.DebugString());
+
+  // Test move-assign
+  CryptoHandshakeMessage message5 = std::move(message3);
+  EXPECT_EQ(str, message5.DebugString());
+}
+
+TEST(CryptoHandshakeMessageTest, HasStringPiece) {
+  CryptoHandshakeMessage message;
+  EXPECT_FALSE(message.HasStringPiece(kALPN));
+  message.SetStringPiece(kALPN, "foo");
+  EXPECT_TRUE(message.HasStringPiece(kALPN));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_message_parser.h b/quiche/quic/core/crypto/crypto_message_parser.h
new file mode 100644
index 0000000..f819209
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_message_parser.h
@@ -0,0 +1,35 @@
+// 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_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE CryptoMessageParser {
+ public:
+  virtual ~CryptoMessageParser() {}
+
+  virtual QuicErrorCode error() const = 0;
+  virtual const std::string& error_detail() const = 0;
+
+  // Processes input data, which must be delivered in order. The input data
+  // being processed was received at encryption level |level|. Returns
+  // false if there was an error, and true otherwise.
+  virtual bool ProcessInput(absl::string_view input, EncryptionLevel level) = 0;
+
+  // Returns the number of bytes of buffered input data remaining to be
+  // parsed.
+  virtual size_t InputBytesRemaining() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
diff --git a/quiche/quic/core/crypto/crypto_message_printer_bin.cc b/quiche/quic/core/crypto/crypto_message_printer_bin.cc
new file mode 100644
index 0000000..eb7393d
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_message_printer_bin.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2019 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.
+
+// Dumps the contents of a QUIC crypto handshake message in a human readable
+// format.
+//
+// Usage: crypto_message_printer_bin <hex of message>
+
+#include <iostream>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+namespace quic {
+
+class CryptoMessagePrinter : public ::quic::CryptoFramerVisitorInterface {
+ public:
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+    cout << message.DebugString() << endl;
+  }
+
+  void OnError(CryptoFramer* framer) override {
+    cerr << "Error code: " << framer->error() << endl;
+    cerr << "Error details: " << framer->error_detail() << endl;
+  }
+};
+
+}  // namespace quic
+
+int main(int argc, char* argv[]) {
+  const char* usage = "Usage: crypto_message_printer <hex>";
+  std::vector<std::string> messages =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+  if (messages.size() != 1) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    exit(0);
+  }
+
+  quic::CryptoMessagePrinter printer;
+  quic::CryptoFramer framer;
+  framer.set_visitor(&printer);
+  framer.set_process_truncated_messages(true);
+  std::string input = absl::HexStringToBytes(messages[0]);
+  if (!framer.ProcessInput(input)) {
+    return 1;
+  }
+  if (framer.InputBytesRemaining() != 0) {
+    cerr << "Input partially consumed. " << framer.InputBytesRemaining()
+         << " bytes remaining." << endl;
+    return 2;
+  }
+  return 0;
+}
diff --git a/quiche/quic/core/crypto/crypto_protocol.h b/quiche/quic/core/crypto/crypto_protocol.h
new file mode 100644
index 0000000..ab21cb5
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_protocol.h
@@ -0,0 +1,512 @@
+// 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_CRYPTO_CRYPTO_PROTOCOL_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
+
+#include <cstddef>
+#include <string>
+
+#include "quiche/quic/core/quic_tag.h"
+
+// Version and Crypto tags are written to the wire with a big-endian
+// representation of the name of the tag.  For example
+// the client hello tag (CHLO) will be written as the
+// following 4 bytes: 'C' 'H' 'L' 'O'.  Since it is
+// stored in memory as a little endian uint32_t, we need
+// to reverse the order of the bytes.
+//
+// We use a macro to ensure that no static initialisers are created. Use the
+// MakeQuicTag function in normal code.
+#define TAG(a, b, c, d) \
+  static_cast<QuicTag>((d << 24) + (c << 16) + (b << 8) + a)
+
+namespace quic {
+
+using ServerConfigID = std::string;
+
+// The following tags have been deprecated and should not be reused:
+// "1CON", "BBQ4", "NCON", "RCID", "SREJ", "TBKP", "TB10", "SCLS", "SMHL",
+// "QNZR", "B2HI", "H2PR", "FIFO", "LIFO", "RRWS", "QNSP", "B2CL", "CHSP",
+// "BPTE", "ACKD", "AKD2", "AKD4", "MAD1", "MAD4", "MAD5", "ACD0", "ACKQ",
+// "TLPR", "CCS\0"
+
+// clang-format off
+const QuicTag kCHLO = TAG('C', 'H', 'L', 'O');   // Client hello
+const QuicTag kSHLO = TAG('S', 'H', 'L', 'O');   // Server hello
+const QuicTag kSCFG = TAG('S', 'C', 'F', 'G');   // Server config
+const QuicTag kREJ  = TAG('R', 'E', 'J', '\0');  // Reject
+const QuicTag kCETV = TAG('C', 'E', 'T', 'V');   // Client encrypted tag-value
+                                                 // pairs
+const QuicTag kPRST = TAG('P', 'R', 'S', 'T');   // Public reset
+const QuicTag kSCUP = TAG('S', 'C', 'U', 'P');   // Server config update
+const QuicTag kALPN = TAG('A', 'L', 'P', 'N');   // Application-layer protocol
+
+// Key exchange methods
+const QuicTag kP256 = TAG('P', '2', '5', '6');   // ECDH, Curve P-256
+const QuicTag kC255 = TAG('C', '2', '5', '5');   // ECDH, Curve25519
+
+// AEAD algorithms
+const QuicTag kAESG = TAG('A', 'E', 'S', 'G');   // AES128 + GCM-12
+const QuicTag kCC20 = TAG('C', 'C', '2', '0');   // ChaCha20 + Poly1305 RFC7539
+
+// Congestion control feedback types
+const QuicTag kQBIC = TAG('Q', 'B', 'I', 'C');   // TCP cubic
+
+// Connection options (COPT) values
+const QuicTag kAFCW = TAG('A', 'F', 'C', 'W');   // Auto-tune flow control
+                                                 // receive windows.
+const QuicTag kIFW5 = TAG('I', 'F', 'W', '5');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 32KB. (2^5 KB).
+const QuicTag kIFW6 = TAG('I', 'F', 'W', '6');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 64KB. (2^6 KB).
+const QuicTag kIFW7 = TAG('I', 'F', 'W', '7');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 128KB. (2^7 KB).
+const QuicTag kIFW8 = TAG('I', 'F', 'W', '8');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 256KB. (2^8 KB).
+const QuicTag kIFW9 = TAG('I', 'F', 'W', '9');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 512KB. (2^9 KB).
+const QuicTag kIFWA = TAG('I', 'F', 'W', 'a');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 1MB. (2^0xa KB).
+const QuicTag kTBBR = TAG('T', 'B', 'B', 'R');   // Reduced Buffer Bloat TCP
+const QuicTag k1RTT = TAG('1', 'R', 'T', 'T');   // STARTUP in BBR for 1 RTT
+const QuicTag k2RTT = TAG('2', 'R', 'T', 'T');   // STARTUP in BBR for 2 RTTs
+const QuicTag kLRTT = TAG('L', 'R', 'T', 'T');   // Exit STARTUP in BBR on loss
+const QuicTag kBBS1 = TAG('B', 'B', 'S', '1');   // DEPRECATED
+const QuicTag kBBS2 = TAG('B', 'B', 'S', '2');   // More aggressive packet
+                                                 // conservation in BBR STARTUP
+const QuicTag kBBS3 = TAG('B', 'B', 'S', '3');   // Slowstart packet
+                                                 // conservation in BBR STARTUP
+const QuicTag kBBS4 = TAG('B', 'B', 'S', '4');   // DEPRECATED
+const QuicTag kBBS5 = TAG('B', 'B', 'S', '5');   // DEPRECATED
+const QuicTag kBBRR = TAG('B', 'B', 'R', 'R');   // Rate-based recovery in BBR
+const QuicTag kBBR1 = TAG('B', 'B', 'R', '1');   // DEPRECATED
+const QuicTag kBBR2 = TAG('B', 'B', 'R', '2');   // DEPRECATED
+const QuicTag kBBR3 = TAG('B', 'B', 'R', '3');   // Fully drain the queue once
+                                                 // per cycle
+const QuicTag kBBR4 = TAG('B', 'B', 'R', '4');   // 20 RTT ack aggregation
+const QuicTag kBBR5 = TAG('B', 'B', 'R', '5');   // 40 RTT ack aggregation
+const QuicTag kBBR9 = TAG('B', 'B', 'R', '9');   // DEPRECATED
+const QuicTag kBBRA = TAG('B', 'B', 'R', 'A');   // Starts a new ack aggregation
+                                                 // epoch if a full round has
+                                                 // passed
+const QuicTag kBBRB = TAG('B', 'B', 'R', 'B');   // Use send rate in BBR's
+                                                 // MaxAckHeightTracker
+const QuicTag kBBRS = TAG('B', 'B', 'R', 'S');   // DEPRECATED
+const QuicTag kBBQ1 = TAG('B', 'B', 'Q', '1');   // BBR with lower 2.77 STARTUP
+                                                 // pacing and CWND gain.
+const QuicTag kBBQ2 = TAG('B', 'B', 'Q', '2');   // BBRv2 with 2.885 STARTUP and
+                                                 // DRAIN CWND gain.
+const QuicTag kBBQ3 = TAG('B', 'B', 'Q', '3');   // BBR with ack aggregation
+                                                 // compensation in STARTUP.
+const QuicTag kBBQ5 = TAG('B', 'B', 'Q', '5');   // Expire ack aggregation upon
+                                                 // bandwidth increase in
+                                                 // STARTUP.
+const QuicTag kBBQ6 = TAG('B', 'B', 'Q', '6');   // Reduce STARTUP gain to 25%
+                                                 // more than BW increase.
+const QuicTag kBBQ7 = TAG('B', 'B', 'Q', '7');   // Reduce bw_lo by
+                                                 // bytes_lost/min_rtt.
+const QuicTag kBBQ8 = TAG('B', 'B', 'Q', '8');   // Reduce bw_lo by
+                                                 // bw_lo * bytes_lost/inflight
+const QuicTag kBBQ9 = TAG('B', 'B', 'Q', '9');   // Reduce bw_lo by
+                                                 // bw_lo * bytes_lost/cwnd
+const QuicTag kBBQ0 = TAG('B', 'B', 'Q', '0');   // Increase bytes_acked in
+                                                 // PROBE_UP when app limited.
+const QuicTag kRENO = TAG('R', 'E', 'N', 'O');   // Reno Congestion Control
+const QuicTag kTPCC = TAG('P', 'C', 'C', '\0');  // Performance-Oriented
+                                                 // Congestion Control
+const QuicTag kBYTE = TAG('B', 'Y', 'T', 'E');   // TCP cubic or reno in bytes
+const QuicTag kIW03 = TAG('I', 'W', '0', '3');   // Force ICWND to 3
+const QuicTag kIW10 = TAG('I', 'W', '1', '0');   // Force ICWND to 10
+const QuicTag kIW20 = TAG('I', 'W', '2', '0');   // Force ICWND to 20
+const QuicTag kIW50 = TAG('I', 'W', '5', '0');   // Force ICWND to 50
+const QuicTag kB2ON = TAG('B', '2', 'O', 'N');   // Enable BBRv2
+const QuicTag kB2NA = TAG('B', '2', 'N', 'A');   // For BBRv2, do not add ack
+                                                 // height to queueing threshold
+const QuicTag kB2NE = TAG('B', '2', 'N', 'E');   // For BBRv2, always exit
+                                                 // STARTUP on loss, even if
+                                                 // bandwidth growth exceeds
+                                                 // threshold.
+const QuicTag kB2RP = TAG('B', '2', 'R', 'P');   // For BBRv2, run PROBE_RTT on
+                                                 // the regular schedule
+const QuicTag kB2LO = TAG('B', '2', 'L', 'O');   // Ignore inflight_lo in BBR2
+const QuicTag kB2HR = TAG('B', '2', 'H', 'R');   // 15% inflight_hi headroom.
+const QuicTag kB2SL = TAG('B', '2', 'S', 'L');   // When exiting STARTUP due to
+                                                 // loss, set inflight_hi to the
+                                                 // max of bdp and max bytes
+                                                 // delivered in round.
+const QuicTag kB2H2 = TAG('B', '2', 'H', '2');   // When exiting PROBE_UP due to
+                                                 // loss, set inflight_hi to the
+                                                 // max of inflight@send and max
+                                                 // bytes delivered in round.
+const QuicTag kB2RC = TAG('B', '2', 'R', 'C');   // Disable Reno-coexistence for
+                                                 // BBR2.
+const QuicTag kBSAO = TAG('B', 'S', 'A', 'O');   // Avoid Overestimation in
+                                                 // Bandwidth Sampler with ack
+                                                 // aggregation
+const QuicTag kB2DL = TAG('B', '2', 'D', 'L');   // Increase inflight_hi based
+                                                 // on delievered, not inflight.
+const QuicTag kB201 = TAG('B', '2', '0', '1');   // In PROBE_UP, check if cwnd
+                                                 // limited before aggregation
+                                                 // epoch, instead of ack event.
+const QuicTag kB202 = TAG('B', '2', '0', '2');   // Do not exit PROBE_UP if
+                                                 // inflight dips below 1.25*BW.
+const QuicTag kB203 = TAG('B', '2', '0', '3');   // Ignore inflight_hi until
+                                                 // PROBE_UP is exited.
+const QuicTag kB204 = TAG('B', '2', '0', '4');   // Reduce extra acked when
+                                                 // MaxBW incrases.
+const QuicTag kB205 = TAG('B', '2', '0', '5');   // Add extra acked to CWND in
+                                                 // STARTUP.
+const QuicTag kB206 = TAG('B', '2', '0', '6');   // Exit STARTUP after 2 losses.
+const QuicTag kB207 = TAG('B', '2', '0', '7');   // Exit STARTUP on persistent
+                                                 // queue
+const QuicTag kNTLP = TAG('N', 'T', 'L', 'P');   // No tail loss probe
+const QuicTag k1TLP = TAG('1', 'T', 'L', 'P');   // 1 tail loss probe
+const QuicTag k1RTO = TAG('1', 'R', 'T', 'O');   // Send 1 packet upon RTO
+const QuicTag kNRTO = TAG('N', 'R', 'T', 'O');   // CWND reduction on loss
+const QuicTag kTIME = TAG('T', 'I', 'M', 'E');   // Time based loss detection
+const QuicTag kATIM = TAG('A', 'T', 'I', 'M');   // Adaptive time loss detection
+const QuicTag kMIN1 = TAG('M', 'I', 'N', '1');   // Min CWND of 1 packet
+const QuicTag kMIN4 = TAG('M', 'I', 'N', '4');   // Min CWND of 4 packets,
+                                                 // with a min rate of 1 BDP.
+const QuicTag kMAD0 = TAG('M', 'A', 'D', '0');   // Ignore ack delay
+const QuicTag kMAD2 = TAG('M', 'A', 'D', '2');   // No min TLP
+const QuicTag kMAD3 = TAG('M', 'A', 'D', '3');   // No min RTO
+const QuicTag k1ACK = TAG('1', 'A', 'C', 'K');   // 1 fast ack for reordering
+const QuicTag kAKD3 = TAG('A', 'K', 'D', '3');   // Ack decimation style acking
+                                                 // with 1/8 RTT acks.
+const QuicTag kAKDU = TAG('A', 'K', 'D', 'U');   // Unlimited number of packets
+                                                 // received before acking
+const QuicTag kAFFE = TAG('A', 'F', 'F', 'E');   // Enable client receiving
+                                                 // AckFrequencyFrame.
+const QuicTag kAFF1 = TAG('A', 'F', 'F', '1');   // Use SRTT in building
+                                                 // AckFrequencyFrame.
+const QuicTag kAFF2 = TAG('A', 'F', 'F', '2');   // Send AckFrequencyFrame upon
+                                                 // handshake completion.
+const QuicTag kSSLR = TAG('S', 'S', 'L', 'R');   // Slow Start Large Reduction.
+const QuicTag kNPRR = TAG('N', 'P', 'R', 'R');   // Pace at unity instead of PRR
+const QuicTag k2RTO = TAG('2', 'R', 'T', 'O');   // Close connection on 2 RTOs
+const QuicTag k3RTO = TAG('3', 'R', 'T', 'O');   // Close connection on 3 RTOs
+const QuicTag k4RTO = TAG('4', 'R', 'T', 'O');   // Close connection on 4 RTOs
+const QuicTag k5RTO = TAG('5', 'R', 'T', 'O');   // Close connection on 5 RTOs
+const QuicTag k6RTO = TAG('6', 'R', 'T', 'O');   // Close connection on 6 RTOs
+const QuicTag kCBHD = TAG('C', 'B', 'H', 'D');   // Client only blackhole
+                                                 // detection.
+const QuicTag kNBHD = TAG('N', 'B', 'H', 'D');   // No blackhole detection.
+const QuicTag kCONH = TAG('C', 'O', 'N', 'H');   // Conservative Handshake
+                                                 // Retransmissions.
+const QuicTag kLFAK = TAG('L', 'F', 'A', 'K');   // Don't invoke FACK on the
+                                                 // first ack.
+const QuicTag kSTMP = TAG('S', 'T', 'M', 'P');   // DEPRECATED
+const QuicTag kEACK = TAG('E', 'A', 'C', 'K');   // Bundle ack-eliciting frame
+                                                 // with an ACK after PTO/RTO
+
+const QuicTag kILD0 = TAG('I', 'L', 'D', '0');   // IETF style loss detection
+                                                 // (default with 1/8 RTT time
+                                                 // threshold)
+const QuicTag kILD1 = TAG('I', 'L', 'D', '1');   // IETF style loss detection
+                                                 // with 1/4 RTT time threshold
+const QuicTag kILD2 = TAG('I', 'L', 'D', '2');   // IETF style loss detection
+                                                 // with adaptive packet
+                                                 // threshold
+const QuicTag kILD3 = TAG('I', 'L', 'D', '3');   // IETF style loss detection
+                                                 // with 1/4 RTT time threshold
+                                                 // and adaptive packet
+                                                 // threshold
+const QuicTag kILD4 = TAG('I', 'L', 'D', '4');   // IETF style loss detection
+                                                 // with both adaptive time
+                                                 // threshold (default 1/4 RTT)
+                                                 // and adaptive packet
+                                                 // threshold
+const QuicTag kRUNT = TAG('R', 'U', 'N', 'T');   // No packet threshold loss
+                                                 // detection for "runt" packet.
+const QuicTag kNSTP = TAG('N', 'S', 'T', 'P');   // No stop waiting frames.
+const QuicTag kNRTT = TAG('N', 'R', 'T', 'T');   // Ignore initial RTT
+
+const QuicTag k1PTO = TAG('1', 'P', 'T', 'O');   // Send 1 packet upon PTO.
+const QuicTag k2PTO = TAG('2', 'P', 'T', 'O');   // Send 2 packets upon PTO.
+
+const QuicTag k6PTO = TAG('6', 'P', 'T', 'O');   // Closes connection on 6
+                                                 // consecutive PTOs.
+const QuicTag k7PTO = TAG('7', 'P', 'T', 'O');   // Closes connection on 7
+                                                 // consecutive PTOs.
+const QuicTag k8PTO = TAG('8', 'P', 'T', 'O');   // Closes connection on 8
+                                                 // consecutive PTOs.
+const QuicTag kPTOS = TAG('P', 'T', 'O', 'S');   // Skip packet number before
+                                                 // sending the last PTO.
+const QuicTag kPTOA = TAG('P', 'T', 'O', 'A');   // Do not add max ack delay
+                                                 // when computing PTO timeout
+                                                 // if an immediate ACK is
+                                                 // expected.
+const QuicTag kPEB1 = TAG('P', 'E', 'B', '1');   // Start exponential backoff
+                                                 // since 1st PTO.
+const QuicTag kPEB2 = TAG('P', 'E', 'B', '2');   // Start exponential backoff
+                                                 // since 2nd PTO.
+const QuicTag kPVS1 = TAG('P', 'V', 'S', '1');   // Use 2 * rttvar when
+                                                 // calculating PTO timeout.
+const QuicTag kPAG1 = TAG('P', 'A', 'G', '1');   // Make 1st PTO more aggressive
+const QuicTag kPAG2 = TAG('P', 'A', 'G', '2');   // Make first 2 PTOs more
+                                                 // aggressive
+const QuicTag kPSDA = TAG('P', 'S', 'D', 'A');   // Use standard deviation when
+                                                 // calculating PTO timeout.
+const QuicTag kPLE1 = TAG('P', 'L', 'E', '1');   // Arm the 1st PTO with
+                                                 // earliest in flight sent time
+                                                 // and at least 0.5*srtt from
+                                                 // last sent packet.
+const QuicTag kPLE2 = TAG('P', 'L', 'E', '2');   // Arm the 1st PTO with
+                                                 // earliest in flight sent time
+                                                 // and at least 1.5*srtt from
+                                                 // last sent packet.
+const QuicTag kAPTO = TAG('A', 'P', 'T', 'O');   // Use 1.5 * initial RTT before
+                                                 // any RTT sample is available.
+
+const QuicTag kELDT = TAG('E', 'L', 'D', 'T');   // Enable Loss Detection Tuning
+
+// TODO(haoyuewang) Remove RVCM option once
+// --quic_remove_connection_migration_connection_option is deprecated.
+const QuicTag kRVCM = TAG('R', 'V', 'C', 'M');   // Validate the new address
+                                                 // upon client address change.
+
+// Optional support of truncated Connection IDs.  If sent by a peer, the value
+// is the minimum number of bytes allowed for the connection ID sent to the
+// peer.
+const QuicTag kTCID = TAG('T', 'C', 'I', 'D');   // Connection ID truncation.
+
+// Multipath option.
+const QuicTag kMPTH = TAG('M', 'P', 'T', 'H');   // Enable multipath.
+
+const QuicTag kNCMR = TAG('N', 'C', 'M', 'R');   // Do not attempt connection
+                                                 // migration.
+
+// Allows disabling defer_send_in_response_to_packets in QuicConnection.
+const QuicTag kDFER = TAG('D', 'F', 'E', 'R');   // Do not defer sending.
+
+// Disable Pacing offload option.
+const QuicTag kNPCO = TAG('N', 'P', 'C', 'O');    // No pacing offload.
+
+// Enable bandwidth resumption experiment.
+const QuicTag kBWRE = TAG('B', 'W', 'R', 'E');  // Bandwidth resumption.
+const QuicTag kBWMX = TAG('B', 'W', 'M', 'X');  // Max bandwidth resumption.
+const QuicTag kBWRS = TAG('B', 'W', 'R', 'S');  // Server bandwidth resumption.
+const QuicTag kBWS2 = TAG('B', 'W', 'S', '2');  // Server bw resumption v2.
+const QuicTag kBWS3 = TAG('B', 'W', 'S', '3');  // QUIC Initial CWND - Control.
+const QuicTag kBWS4 = TAG('B', 'W', 'S', '4');  // QUIC Initial CWND - Enabled.
+const QuicTag kBWS5 = TAG('B', 'W', 'S', '5');  // QUIC Initial CWND up and down
+const QuicTag kBWS6 = TAG('B', 'W', 'S', '6');  // QUIC Initial CWND - Enabled
+                                                // with 0.5 * default
+                                                // multiplier.
+const QuicTag kBWP0 = TAG('B', 'W', 'P', '0');  // QUIC Initial CWND - SPDY
+                                                // priority 0.
+const QuicTag kBWP1 = TAG('B', 'W', 'P', '1');  // QUIC Initial CWND - SPDY
+                                                // priorities 0 and 1.
+const QuicTag kBWP2 = TAG('B', 'W', 'P', '2');  // QUIC Initial CWND - SPDY
+                                                // priorities 0, 1 and 2.
+const QuicTag kBWP3 = TAG('B', 'W', 'P', '3');  // QUIC Initial CWND - SPDY
+                                                // priorities 0, 1, 2 and 3.
+const QuicTag kBWP4 = TAG('B', 'W', 'P', '4');  // QUIC Initial CWND - SPDY
+                                                // priorities >= 0, 1, 2, 3 and
+                                                // 4.
+const QuicTag kBWG4 = TAG('B', 'W', 'G', '4');  // QUIC Initial CWND -
+                                                // Bandwidth model 1.
+const QuicTag kBWG7 = TAG('B', 'W', 'G', '7');  // QUIC Initial CWND -
+                                                // Bandwidth model 2.
+const QuicTag kBWG8 = TAG('B', 'W', 'G', '8');  // QUIC Initial CWND -
+                                                // Bandwidth model 3.
+const QuicTag kBWS7 = TAG('B', 'W', 'S', '7');  // QUIC Initial CWND - Enabled
+                                                // with 0.75 * default
+                                                // multiplier.
+const QuicTag kBWM3 = TAG('B', 'W', 'M', '3');  // Consider overshooting if
+                                                // bytes lost after bandwidth
+                                                // resumption * 3 > IW.
+const QuicTag kBWM4 = TAG('B', 'W', 'M', '4');  // Consider overshooting if
+                                                // bytes lost after bandwidth
+                                                // resumption * 4 > IW.
+const QuicTag kICW1 = TAG('I', 'C', 'W', '1');  // Max initial congestion window
+                                                // 100.
+const QuicTag kDTOS = TAG('D', 'T', 'O', 'S');  // Enable overshooting
+                                                // detection.
+
+const QuicTag kFIDT = TAG('F', 'I', 'D', 'T');  // Extend idle timer by PTO
+                                                // instead of the whole idle
+                                                // timeout.
+
+const QuicTag k3AFF = TAG('3', 'A', 'F', 'F');  // 3 anti amplification factor.
+const QuicTag k10AF = TAG('1', '0', 'A', 'F');  // 10 anti amplification factor.
+
+// Enable path MTU discovery experiment.
+const QuicTag kMTUH = TAG('M', 'T', 'U', 'H');  // High-target MTU discovery.
+const QuicTag kMTUL = TAG('M', 'T', 'U', 'L');  // Low-target MTU discovery.
+
+const QuicTag kNSLC = TAG('N', 'S', 'L', 'C');  // Always send connection close
+                                                // for idle timeout.
+const QuicTag kNCHP = TAG('N', 'C', 'H', 'P');  // No chaos protection.
+const QuicTag kNBPE = TAG('N', 'B', 'P', 'E');  // No BoringSSL Permutes
+                                                // TLS Extensions.
+
+// Proof types (i.e. certificate types)
+// NOTE: although it would be silly to do so, specifying both kX509 and kX59R
+// is allowed and is equivalent to specifying only kX509.
+const QuicTag kX509 = TAG('X', '5', '0', '9');   // X.509 certificate, all key
+                                                 // types
+const QuicTag kX59R = TAG('X', '5', '9', 'R');   // X.509 certificate, RSA keys
+                                                 // only
+const QuicTag kCHID = TAG('C', 'H', 'I', 'D');   // Channel ID.
+
+// Client hello tags
+const QuicTag kVER  = TAG('V', 'E', 'R', '\0');  // Version
+const QuicTag kNONC = TAG('N', 'O', 'N', 'C');   // The client's nonce
+const QuicTag kNONP = TAG('N', 'O', 'N', 'P');   // The client's proof nonce
+const QuicTag kKEXS = TAG('K', 'E', 'X', 'S');   // Key exchange methods
+const QuicTag kAEAD = TAG('A', 'E', 'A', 'D');   // Authenticated
+                                                 // encryption algorithms
+const QuicTag kCOPT = TAG('C', 'O', 'P', 'T');   // Connection options
+const QuicTag kCLOP = TAG('C', 'L', 'O', 'P');   // Client connection options
+const QuicTag kICSL = TAG('I', 'C', 'S', 'L');   // Idle network timeout
+const QuicTag kMIBS = TAG('M', 'I', 'D', 'S');   // Max incoming bidi streams
+const QuicTag kMIUS = TAG('M', 'I', 'U', 'S');   // Max incoming unidi streams
+const QuicTag kADE  = TAG('A', 'D', 'E', 0);     // Ack Delay Exponent (IETF
+                                                 // QUIC ACK Frame Only).
+const QuicTag kIRTT = TAG('I', 'R', 'T', 'T');   // Estimated initial RTT in us.
+const QuicTag kTRTT = TAG('T', 'R', 'T', 'T');   // If server receives an rtt
+                                                 // from an address token, set
+                                                 // it as the initial rtt.
+const QuicTag kSNI  = TAG('S', 'N', 'I', '\0');  // Server name
+                                                 // indication
+const QuicTag kPUBS = TAG('P', 'U', 'B', 'S');   // Public key values
+const QuicTag kSCID = TAG('S', 'C', 'I', 'D');   // Server config id
+const QuicTag kORBT = TAG('O', 'B', 'I', 'T');   // Server orbit.
+const QuicTag kPDMD = TAG('P', 'D', 'M', 'D');   // Proof demand.
+const QuicTag kPROF = TAG('P', 'R', 'O', 'F');   // Proof (signature).
+const QuicTag kCCRT = TAG('C', 'C', 'R', 'T');   // Cached certificate
+const QuicTag kEXPY = TAG('E', 'X', 'P', 'Y');   // Expiry
+const QuicTag kSTTL = TAG('S', 'T', 'T', 'L');   // Server Config TTL
+const QuicTag kSFCW = TAG('S', 'F', 'C', 'W');   // Initial stream flow control
+                                                 // receive window.
+const QuicTag kCFCW = TAG('C', 'F', 'C', 'W');   // Initial session/connection
+                                                 // flow control receive window.
+const QuicTag kUAID = TAG('U', 'A', 'I', 'D');   // Client's User Agent ID.
+const QuicTag kXLCT = TAG('X', 'L', 'C', 'T');   // Expected leaf certificate.
+const QuicTag kQLVE = TAG('Q', 'L', 'V', 'E');   // Legacy Version
+                                                 // Encapsulation.
+
+const QuicTag kPDP1 = TAG('P', 'D', 'P', '1');   // Path degrading triggered
+                                                 // at 1PTO.
+
+const QuicTag kPDP2 = TAG('P', 'D', 'P', '2');   // Path degrading triggered
+                                                 // at 2PTO.
+
+const QuicTag kPDP3 = TAG('P', 'D', 'P', '3');   // Path degrading triggered
+                                                 // at 3PTO.
+
+const QuicTag kPDP4 = TAG('P', 'D', 'P', '4');   // Path degrading triggered
+                                                 // at 4PTO.
+
+const QuicTag kPDP5 = TAG('P', 'D', 'P', '5');   // Path degrading triggered
+                                                 // at 5PTO.
+
+const QuicTag kQNZ2 = TAG('Q', 'N', 'Z', '2');   // Turn off QUIC crypto 0-RTT.
+
+const QuicTag kMAD  = TAG('M', 'A', 'D', 0);     // Max Ack Delay (IETF QUIC)
+
+const QuicTag kIGNP = TAG('I', 'G', 'N', 'P');   // Do not use PING only packet
+                                                 // for RTT measure or
+                                                 // congestion control.
+
+const QuicTag kSRWP = TAG('S', 'R', 'W', 'P');   // Enable retransmittable on
+                                                 // wire PING (ROWP) on the
+                                                 // server side.
+const QuicTag kGSR0 = TAG('G', 'S', 'R', '0');   // Selective Resumption
+
+const QuicTag kINVC = TAG('I', 'N', 'V', 'C');   // Send connection close for
+                                                 // INVALID_VERSION
+
+// Client Hints triggers.
+const QuicTag kGWCH = TAG('G', 'W', 'C', 'H');
+const QuicTag kYTCH = TAG('Y', 'T', 'C', 'H');
+const QuicTag kACH0 = TAG('A', 'C', 'H', '0');
+
+// Rejection tags
+const QuicTag kRREJ = TAG('R', 'R', 'E', 'J');   // Reasons for server sending
+
+// Server hello tags
+const QuicTag kCADR = TAG('C', 'A', 'D', 'R');   // Client IP address and port
+const QuicTag kASAD = TAG('A', 'S', 'A', 'D');   // Alternate Server IP address
+                                                 // and port.
+const QuicTag kSRST = TAG('S', 'R', 'S', 'T');   // Stateless reset token used
+                                                 // in IETF public reset packet
+
+// CETV tags
+const QuicTag kCIDK = TAG('C', 'I', 'D', 'K');   // ChannelID key
+const QuicTag kCIDS = TAG('C', 'I', 'D', 'S');   // ChannelID signature
+
+// Public reset tags
+const QuicTag kRNON = TAG('R', 'N', 'O', 'N');   // Public reset nonce proof
+const QuicTag kRSEQ = TAG('R', 'S', 'E', 'Q');   // Rejected packet number
+
+// Universal tags
+const QuicTag kPAD  = TAG('P', 'A', 'D', '\0');  // Padding
+
+// Stats collection tags
+const QuicTag kEPID = TAG('E', 'P', 'I', 'D');  // Endpoint identifier.
+
+// clang-format on
+
+// These tags have a special form so that they appear either at the beginning
+// or the end of a handshake message. Since handshake messages are sorted by
+// tag value, the tags with 0 at the end will sort first and those with 255 at
+// the end will sort last.
+//
+// The certificate chain should have a tag that will cause it to be sorted at
+// the end of any handshake messages because it's likely to be large and the
+// client might be able to get everything that it needs from the small values at
+// the beginning.
+//
+// Likewise tags with random values should be towards the beginning of the
+// message because the server mightn't hold state for a rejected client hello
+// and therefore the client may have issues reassembling the rejection message
+// in the event that it sent two client hellos.
+const QuicTag kServerNonceTag = TAG('S', 'N', 'O', 0);  // The server's nonce
+const QuicTag kSourceAddressTokenTag =
+    TAG('S', 'T', 'K', 0);  // Source-address token
+const QuicTag kCertificateTag = TAG('C', 'R', 'T', 255);  // Certificate chain
+const QuicTag kCertificateSCTTag =
+    TAG('C', 'S', 'C', 'T');  // Signed cert timestamp (RFC6962) of leaf cert.
+
+#undef TAG
+
+const size_t kMaxEntries = 128;  // Max number of entries in a message.
+
+const size_t kNonceSize = 32;  // Size in bytes of the connection nonce.
+
+const size_t kOrbitSize = 8;  // Number of bytes in an orbit value.
+
+// kProofSignatureLabel is prepended to the CHLO hash and server configs before
+// signing to avoid any cross-protocol attacks on the signature.
+const char kProofSignatureLabel[] = "QUIC CHLO and server config signature";
+
+// kClientHelloMinimumSize is the minimum size of a client hello. Client hellos
+// will have PAD tags added in order to ensure this minimum is met and client
+// hellos smaller than this will be an error. This minimum size reduces the
+// amplification factor of any mirror DoS attack.
+//
+// A client may pad an inchoate client hello to a size larger than
+// kClientHelloMinimumSize to make it more likely to receive a complete
+// rejection message.
+const size_t kClientHelloMinimumSize = 1024;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
diff --git a/quiche/quic/core/crypto/crypto_secret_boxer.cc b/quiche/quic/core/crypto/crypto_secret_boxer.cc
new file mode 100644
index 0000000..f61a3fc
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_secret_boxer.cc
@@ -0,0 +1,148 @@
+// Copyright (c) 2013 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 <cstdint>
+#include <string>
+
+#include "quiche/quic/core/crypto/crypto_secret_boxer.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// kSIVNonceSize contains the number of bytes of nonce in each AES-GCM-SIV box.
+// AES-GCM-SIV takes a 12-byte nonce and, since the messages are so small, each
+// key is good for more than 2^64 source-address tokens. See table 1 of
+// https://eprint.iacr.org/2017/168.pdf
+static const size_t kSIVNonceSize = 12;
+
+// AES-GCM-SIV comes in AES-128 and AES-256 flavours. The AES-256 version is
+// used here so that the key size matches the 256-bit XSalsa20 keys that we
+// used to use.
+static const size_t kBoxKeySize = 32;
+
+struct CryptoSecretBoxer::State {
+  // ctxs are the initialised AEAD contexts. These objects contain the
+  // scheduled AES state for each of the keys.
+  std::vector<bssl::UniquePtr<EVP_AEAD_CTX>> ctxs;
+};
+
+CryptoSecretBoxer::CryptoSecretBoxer() {}
+
+CryptoSecretBoxer::~CryptoSecretBoxer() {}
+
+// static
+size_t CryptoSecretBoxer::GetKeySize() {
+  return kBoxKeySize;
+}
+
+// kAEAD is the AEAD used for boxing: AES-256-GCM-SIV.
+static const EVP_AEAD* (*const kAEAD)() = EVP_aead_aes_256_gcm_siv;
+
+bool CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) {
+  if (keys.empty()) {
+    QUIC_LOG(DFATAL) << "No keys supplied!";
+    return false;
+  }
+  const EVP_AEAD* const aead = kAEAD();
+  std::unique_ptr<State> new_state(new State);
+
+  for (const std::string& key : keys) {
+    QUICHE_DCHECK_EQ(kBoxKeySize, key.size());
+    bssl::UniquePtr<EVP_AEAD_CTX> ctx(
+        EVP_AEAD_CTX_new(aead, reinterpret_cast<const uint8_t*>(key.data()),
+                         key.size(), EVP_AEAD_DEFAULT_TAG_LENGTH));
+    if (!ctx) {
+      ERR_clear_error();
+      QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_init failed";
+      return false;
+    }
+
+    new_state->ctxs.push_back(std::move(ctx));
+  }
+
+  QuicWriterMutexLock l(&lock_);
+  state_ = std::move(new_state);
+  return true;
+}
+
+std::string CryptoSecretBoxer::Box(QuicRandom* rand,
+                                   absl::string_view plaintext) const {
+  // The box is formatted as:
+  //   12 bytes of random nonce
+  //   n bytes of ciphertext
+  //   16 bytes of authenticator
+  size_t out_len =
+      kSIVNonceSize + plaintext.size() + EVP_AEAD_max_overhead(kAEAD());
+
+  std::string ret;
+  ret.resize(out_len);
+  uint8_t* out = reinterpret_cast<uint8_t*>(const_cast<char*>(ret.data()));
+
+  // Write kSIVNonceSize bytes of random nonce to the beginning of the output
+  // buffer.
+  rand->RandBytes(out, kSIVNonceSize);
+  const uint8_t* const nonce = out;
+  out += kSIVNonceSize;
+  out_len -= kSIVNonceSize;
+
+  size_t bytes_written;
+  {
+    QuicReaderMutexLock l(&lock_);
+    if (!EVP_AEAD_CTX_seal(state_->ctxs[0].get(), out, &bytes_written, out_len,
+                           nonce, kSIVNonceSize,
+                           reinterpret_cast<const uint8_t*>(plaintext.data()),
+                           plaintext.size(), nullptr, 0)) {
+      ERR_clear_error();
+      QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_seal failed";
+      return "";
+    }
+  }
+
+  QUICHE_DCHECK_EQ(out_len, bytes_written);
+  return ret;
+}
+
+bool CryptoSecretBoxer::Unbox(absl::string_view in_ciphertext,
+                              std::string* out_storage,
+                              absl::string_view* out) const {
+  if (in_ciphertext.size() < kSIVNonceSize) {
+    return false;
+  }
+
+  const uint8_t* const nonce =
+      reinterpret_cast<const uint8_t*>(in_ciphertext.data());
+  const uint8_t* const ciphertext = nonce + kSIVNonceSize;
+  const size_t ciphertext_len = in_ciphertext.size() - kSIVNonceSize;
+
+  out_storage->resize(ciphertext_len);
+
+  bool ok = false;
+  {
+    QuicReaderMutexLock l(&lock_);
+    for (const bssl::UniquePtr<EVP_AEAD_CTX>& ctx : state_->ctxs) {
+      size_t bytes_written;
+      if (EVP_AEAD_CTX_open(ctx.get(),
+                            reinterpret_cast<uint8_t*>(
+                                const_cast<char*>(out_storage->data())),
+                            &bytes_written, ciphertext_len, nonce,
+                            kSIVNonceSize, ciphertext, ciphertext_len, nullptr,
+                            0)) {
+        ok = true;
+        *out = absl::string_view(out_storage->data(), bytes_written);
+        break;
+      }
+
+      ERR_clear_error();
+    }
+  }
+
+  return ok;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_secret_boxer.h b/quiche/quic/core/crypto/crypto_secret_boxer.h
new file mode 100644
index 0000000..3010e14
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_secret_boxer.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2013 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_CRYPTO_CRYPTO_SECRET_BOXER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
+
+namespace quic {
+
+class QuicRandom;
+
+// CryptoSecretBoxer encrypts small chunks of plaintext (called 'boxing') and
+// then, later, can authenticate+decrypt the resulting boxes. This object is
+// thread-safe.
+class QUIC_EXPORT_PRIVATE CryptoSecretBoxer {
+ public:
+  CryptoSecretBoxer();
+  CryptoSecretBoxer(const CryptoSecretBoxer&) = delete;
+  CryptoSecretBoxer& operator=(const CryptoSecretBoxer&) = delete;
+  ~CryptoSecretBoxer();
+
+  // GetKeySize returns the number of bytes in a key.
+  static size_t GetKeySize();
+
+  // SetKeys sets a list of encryption keys. The first key in the list will be
+  // used by |Box|, but all supplied keys will be tried by |Unbox|, to handle
+  // key skew across the fleet. This must be called before |Box| or |Unbox|.
+  // Keys must be |GetKeySize()| bytes long. No change is made if any key is
+  // invalid, or if there are no keys supplied.
+  bool SetKeys(const std::vector<std::string>& keys);
+
+  // Box encrypts |plaintext| using a random nonce generated from |rand| and
+  // returns the resulting ciphertext. Since an authenticator and nonce are
+  // included, the result will be slightly larger than |plaintext|. The first
+  // key in the vector supplied to |SetKeys| will be used. |SetKeys| must be
+  // called before calling this method.
+  std::string Box(QuicRandom* rand, absl::string_view plaintext) const;
+
+  // Unbox takes the result of a previous call to |Box| in |ciphertext| and
+  // authenticates+decrypts it. If |ciphertext| cannot be decrypted with any of
+  // the supplied keys, the function returns false. Otherwise, |out_storage| is
+  // used to store the result and |out| is set to point into |out_storage| and
+  // contains the original plaintext.
+  bool Unbox(absl::string_view ciphertext,
+             std::string* out_storage,
+             absl::string_view* out) const;
+
+ private:
+  struct State;
+
+  mutable QuicMutex lock_;
+
+  // state_ is an opaque pointer to whatever additional state the concrete
+  // implementation of CryptoSecretBoxer requires.
+  std::unique_ptr<State> state_ QUIC_GUARDED_BY(lock_);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
diff --git a/quiche/quic/core/crypto/crypto_secret_boxer_test.cc b/quiche/quic/core/crypto/crypto_secret_boxer_test.cc
new file mode 100644
index 0000000..2c499fc
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_secret_boxer_test.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/crypto_secret_boxer.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class CryptoSecretBoxerTest : public QuicTest {};
+
+TEST_F(CryptoSecretBoxerTest, BoxAndUnbox) {
+  absl::string_view message("hello world");
+
+  CryptoSecretBoxer boxer;
+  boxer.SetKeys({std::string(CryptoSecretBoxer::GetKeySize(), 0x11)});
+
+  const std::string box = boxer.Box(QuicRandom::GetInstance(), message);
+
+  std::string storage;
+  absl::string_view result;
+  EXPECT_TRUE(boxer.Unbox(box, &storage, &result));
+  EXPECT_EQ(result, message);
+
+  EXPECT_FALSE(boxer.Unbox(std::string(1, 'X') + box, &storage, &result));
+  EXPECT_FALSE(
+      boxer.Unbox(box.substr(1, std::string::npos), &storage, &result));
+  EXPECT_FALSE(boxer.Unbox(std::string(), &storage, &result));
+  EXPECT_FALSE(boxer.Unbox(
+      std::string(1, box[0] ^ 0x80) + box.substr(1, std::string::npos),
+      &storage, &result));
+}
+
+// Helper function to test whether one boxer can decode the output of another.
+static bool CanDecode(const CryptoSecretBoxer& decoder,
+                      const CryptoSecretBoxer& encoder) {
+  absl::string_view message("hello world");
+  const std::string boxed = encoder.Box(QuicRandom::GetInstance(), message);
+  std::string storage;
+  absl::string_view result;
+  bool ok = decoder.Unbox(boxed, &storage, &result);
+  if (ok) {
+    EXPECT_EQ(result, message);
+  }
+  return ok;
+}
+
+TEST_F(CryptoSecretBoxerTest, MultipleKeys) {
+  std::string key_11(CryptoSecretBoxer::GetKeySize(), 0x11);
+  std::string key_12(CryptoSecretBoxer::GetKeySize(), 0x12);
+
+  CryptoSecretBoxer boxer_11, boxer_12, boxer;
+  EXPECT_TRUE(boxer_11.SetKeys({key_11}));
+  EXPECT_TRUE(boxer_12.SetKeys({key_12}));
+  EXPECT_TRUE(boxer.SetKeys({key_12, key_11}));
+
+  // Neither single-key boxer can decode the other's tokens.
+  EXPECT_FALSE(CanDecode(boxer_11, boxer_12));
+  EXPECT_FALSE(CanDecode(boxer_12, boxer_11));
+
+  // |boxer| encodes with the first key, which is key_12.
+  EXPECT_TRUE(CanDecode(boxer_12, boxer));
+  EXPECT_FALSE(CanDecode(boxer_11, boxer));
+
+  // The boxer with both keys can decode tokens from either single-key boxer.
+  EXPECT_TRUE(CanDecode(boxer, boxer_11));
+  EXPECT_TRUE(CanDecode(boxer, boxer_12));
+
+  // After we flush key_11 from |boxer|, it can no longer decode tokens from
+  // |boxer_11|.
+  EXPECT_TRUE(boxer.SetKeys({key_12}));
+  EXPECT_FALSE(CanDecode(boxer, boxer_11));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_server_test.cc b/quiche/quic/core/crypto/crypto_server_test.cc
new file mode 100644
index 0000000..3dcf18a
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_server_test.cc
@@ -0,0 +1,1128 @@
+// Copyright (c) 2013 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 <algorithm>
+#include <cstdint>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/match.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/failing_proof_source.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+class DummyProofVerifierCallback : public ProofVerifierCallback {
+ public:
+  DummyProofVerifierCallback() {}
+  ~DummyProofVerifierCallback() override {}
+
+  void Run(bool /*ok*/,
+           const std::string& /*error_details*/,
+           std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
+    QUICHE_DCHECK(false);
+  }
+};
+
+const char kOldConfigId[] = "old-config-id";
+
+}  // namespace
+
+struct TestParams {
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
+    os << "  versions: "
+       << ParsedQuicVersionVectorToString(p.supported_versions) << " }";
+    return os;
+  }
+
+  // Versions supported by client and server.
+  ParsedQuicVersionVector supported_versions;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  std::string rv = ParsedQuicVersionVectorToString(p.supported_versions);
+  std::replace(rv.begin(), rv.end(), ',', '_');
+  return rv;
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+
+  // Start with all versions, remove highest on each iteration.
+  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  while (!supported_versions.empty()) {
+    params.push_back({supported_versions});
+    supported_versions.erase(supported_versions.begin());
+  }
+
+  return params;
+}
+
+class CryptoServerTest : public QuicTestWithParam<TestParams> {
+ public:
+  CryptoServerTest()
+      : rand_(QuicRandom::GetInstance()),
+        client_address_(QuicIpAddress::Loopback4(), 1234),
+        client_version_(UnsupportedQuicVersion()),
+        config_(QuicCryptoServerConfig::TESTING,
+                rand_,
+                crypto_test_utils::ProofSourceForTesting(),
+                KeyExchangeSource::Default()),
+        peer_(&config_),
+        compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+        params_(new QuicCryptoNegotiatedParameters),
+        signed_config_(new QuicSignedServerConfig),
+        chlo_packet_size_(kDefaultMaxPacketSize) {
+    supported_versions_ = GetParam().supported_versions;
+    config_.set_enable_serving_sct(true);
+
+    client_version_ = supported_versions_.front();
+    client_version_label_ = CreateQuicVersionLabel(client_version_);
+    client_version_string_ =
+        std::string(reinterpret_cast<const char*>(&client_version_label_),
+                    sizeof(client_version_label_));
+  }
+
+  void SetUp() override {
+    QuicCryptoServerConfig::ConfigOptions old_config_options;
+    old_config_options.id = kOldConfigId;
+    config_.AddDefaultConfig(rand_, &clock_, old_config_options);
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+    QuicServerConfigProtobuf primary_config =
+        config_.GenerateConfig(rand_, &clock_, config_options_);
+    primary_config.set_primary_time(clock_.WallNow().ToUNIXSeconds());
+    std::unique_ptr<CryptoHandshakeMessage> msg(
+        config_.AddConfig(primary_config, clock_.WallNow()));
+
+    absl::string_view orbit;
+    QUICHE_CHECK(msg->GetStringPiece(kORBT, &orbit));
+    QUICHE_CHECK_EQ(sizeof(orbit_), orbit.size());
+    memcpy(orbit_, orbit.data(), orbit.size());
+
+    char public_value[32];
+    memset(public_value, 42, sizeof(public_value));
+
+    nonce_hex_ = "#" + absl::BytesToHexString(GenerateNonce());
+    pub_hex_ = "#" + absl::BytesToHexString(
+                         absl::string_view(public_value, sizeof(public_value)));
+
+    CryptoHandshakeMessage client_hello =
+        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                       {"AEAD", "AESG"},
+                                       {"KEXS", "C255"},
+                                       {"PUBS", pub_hex_},
+                                       {"NONC", nonce_hex_},
+                                       {"CSCT", ""},
+                                       {"VER\0", client_version_string_}},
+                                      kClientHelloMinimumSize);
+    ShouldSucceed(client_hello);
+    // The message should be rejected because the source-address token is
+    // missing.
+    CheckRejectTag();
+    const HandshakeFailureReason kRejectReasons[] = {
+        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+
+    absl::string_view srct;
+    ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
+    srct_hex_ = "#" + absl::BytesToHexString(srct);
+
+    absl::string_view scfg;
+    ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg));
+    server_config_ = CryptoFramer::ParseMessage(scfg);
+
+    absl::string_view scid;
+    ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid));
+    scid_hex_ = "#" + absl::BytesToHexString(scid);
+
+    signed_config_ =
+        quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>(
+            new QuicSignedServerConfig());
+    QUICHE_DCHECK(signed_config_->chain.get() == nullptr);
+  }
+
+  // Helper used to accept the result of ValidateClientHello and pass
+  // it on to ProcessClientHello.
+  class ValidateCallback : public ValidateClientHelloResultCallback {
+   public:
+    ValidateCallback(CryptoServerTest* test,
+                     bool should_succeed,
+                     const char* error_substr,
+                     bool* called)
+        : test_(test),
+          should_succeed_(should_succeed),
+          error_substr_(error_substr),
+          called_(called) {
+      *called_ = false;
+    }
+
+    void Run(quiche::QuicheReferenceCountedPointer<Result> result,
+             std::unique_ptr<ProofSource::Details> /* details */) override {
+      ASSERT_FALSE(*called_);
+      test_->ProcessValidationResult(std::move(result), should_succeed_,
+                                     error_substr_);
+      *called_ = true;
+    }
+
+   private:
+    CryptoServerTest* test_;
+    const bool should_succeed_;
+    const char* const error_substr_;
+    bool* called_;
+  };
+
+  void CheckServerHello(const CryptoHandshakeMessage& server_hello) {
+    QuicVersionLabelVector versions;
+    server_hello.GetVersionLabelList(kVER, &versions);
+    ASSERT_EQ(supported_versions_.size(), versions.size());
+    for (size_t i = 0; i < versions.size(); ++i) {
+      EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[i]), versions[i]);
+    }
+
+    absl::string_view address;
+    ASSERT_TRUE(server_hello.GetStringPiece(kCADR, &address));
+    QuicSocketAddressCoder decoder;
+    ASSERT_TRUE(decoder.Decode(address.data(), address.size()));
+    EXPECT_EQ(client_address_.host(), decoder.ip());
+    EXPECT_EQ(client_address_.port(), decoder.port());
+  }
+
+  void ShouldSucceed(const CryptoHandshakeMessage& message) {
+    bool called = false;
+    QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
+    config_.ValidateClientHello(
+        message, client_address_, server_address,
+        supported_versions_.front().transport_version, &clock_, signed_config_,
+        std::make_unique<ValidateCallback>(this, true, "", &called));
+    EXPECT_TRUE(called);
+  }
+
+  void ShouldFailMentioning(const char* error_substr,
+                            const CryptoHandshakeMessage& message) {
+    bool called = false;
+    ShouldFailMentioning(error_substr, message, &called);
+    EXPECT_TRUE(called);
+  }
+
+  void ShouldFailMentioning(const char* error_substr,
+                            const CryptoHandshakeMessage& message,
+                            bool* called) {
+    QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
+    config_.ValidateClientHello(
+        message, client_address_, server_address,
+        supported_versions_.front().transport_version, &clock_, signed_config_,
+        std::make_unique<ValidateCallback>(this, false, error_substr, called));
+  }
+
+  class ProcessCallback : public ProcessClientHelloResultCallback {
+   public:
+    ProcessCallback(
+        quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,
+        bool should_succeed, const char* error_substr, bool* called,
+        CryptoHandshakeMessage* out)
+        : result_(std::move(result)),
+          should_succeed_(should_succeed),
+          error_substr_(error_substr),
+          called_(called),
+          out_(out) {
+      *called_ = false;
+    }
+
+    void Run(QuicErrorCode error,
+             const std::string& error_details,
+             std::unique_ptr<CryptoHandshakeMessage> message,
+             std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
+             std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
+        override {
+      if (should_succeed_) {
+        ASSERT_EQ(error, QUIC_NO_ERROR)
+            << "Message failed with error " << error_details << ": "
+            << result_->client_hello.DebugString();
+      } else {
+        ASSERT_NE(error, QUIC_NO_ERROR)
+            << "Message didn't fail: " << result_->client_hello.DebugString();
+        EXPECT_TRUE(absl::StrContains(error_details, error_substr_))
+            << error_substr_ << " not in " << error_details;
+      }
+      if (message != nullptr) {
+        *out_ = *message;
+      }
+      *called_ = true;
+    }
+
+   private:
+    const quiche::QuicheReferenceCountedPointer<ValidateCallback::Result>
+        result_;
+    const bool should_succeed_;
+    const char* const error_substr_;
+    bool* called_;
+    CryptoHandshakeMessage* out_;
+  };
+
+  void ProcessValidationResult(
+      quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,
+      bool should_succeed, const char* error_substr) {
+    QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
+    bool called;
+    config_.ProcessClientHello(
+        result, /*reject_only=*/false,
+        /*connection_id=*/TestConnectionId(1), server_address, client_address_,
+        supported_versions_.front(), supported_versions_, &clock_, rand_,
+        &compressed_certs_cache_, params_, signed_config_,
+        /*total_framing_overhead=*/50, chlo_packet_size_,
+        std::make_unique<ProcessCallback>(result, should_succeed, error_substr,
+                                          &called, &out_));
+    EXPECT_TRUE(called);
+  }
+
+  std::string GenerateNonce() {
+    std::string nonce;
+    CryptoUtils::GenerateNonce(
+        clock_.WallNow(), rand_,
+        absl::string_view(reinterpret_cast<const char*>(orbit_),
+                          sizeof(orbit_)),
+        &nonce);
+    return nonce;
+  }
+
+  void CheckRejectReasons(
+      const HandshakeFailureReason* expected_handshake_failures,
+      size_t expected_count) {
+    QuicTagVector reject_reasons;
+    static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
+    QuicErrorCode error_code = out_.GetTaglist(kRREJ, &reject_reasons);
+    ASSERT_THAT(error_code, IsQuicNoError());
+
+    EXPECT_EQ(expected_count, reject_reasons.size());
+    for (size_t i = 0; i < reject_reasons.size(); ++i) {
+      EXPECT_EQ(static_cast<QuicTag>(expected_handshake_failures[i]),
+                reject_reasons[i]);
+    }
+  }
+
+  void CheckRejectTag() {
+    ASSERT_EQ(kREJ, out_.tag()) << QuicTagToString(out_.tag());
+  }
+
+  std::string XlctHexString() {
+    uint64_t xlct = crypto_test_utils::LeafCertHashForTesting();
+    return "#" + absl::BytesToHexString(absl::string_view(
+                     reinterpret_cast<char*>(&xlct), sizeof(xlct)));
+  }
+
+ protected:
+  QuicRandom* const rand_;
+  MockRandom rand_for_id_generation_;
+  MockClock clock_;
+  QuicSocketAddress client_address_;
+  ParsedQuicVersionVector supported_versions_;
+  ParsedQuicVersion client_version_;
+  QuicVersionLabel client_version_label_;
+  std::string client_version_string_;
+  QuicCryptoServerConfig config_;
+  QuicCryptoServerConfigPeer peer_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+  QuicCryptoServerConfig::ConfigOptions config_options_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
+  CryptoHandshakeMessage out_;
+  uint8_t orbit_[kOrbitSize];
+  size_t chlo_packet_size_;
+
+  // These strings contain hex escaped values from the server suitable for using
+  // when constructing client hello messages.
+  std::string nonce_hex_, pub_hex_, srct_hex_, scid_hex_;
+  std::unique_ptr<CryptoHandshakeMessage> server_config_;
+};
+
+INSTANTIATE_TEST_SUITE_P(CryptoServerTests,
+                         CryptoServerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(CryptoServerTest, BadSNI) {
+  // clang-format off
+  std::vector<std::string> badSNIs = {
+    "",
+    "#00",
+    "#ff00",
+    "127.0.0.1",
+    "ffee::1",
+  };
+  // clang-format on
+
+  for (const std::string& bad_sni : badSNIs) {
+    CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+        {{"PDMD", "X509"}, {"SNI", bad_sni}, {"VER\0", client_version_string_}},
+        kClientHelloMinimumSize);
+    ShouldFailMentioning("SNI", msg);
+    const HandshakeFailureReason kRejectReasons[] = {
+        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+  }
+
+  // Check that SNIs without dots are allowed
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"SNI", "foo"}, {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+  ShouldSucceed(msg);
+}
+
+TEST_P(CryptoServerTest, DefaultCert) {
+  // Check that the server replies with a default certificate when no SNI is
+  // specified. The CHLO is constructed to generate a REJ with certs, so must
+  // not contain a valid STK, and must include PDMD.
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  absl::string_view cert, proof, cert_sct;
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+  EXPECT_NE(0u, cert.size());
+  EXPECT_NE(0u, proof.size());
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+  EXPECT_LT(0u, cert_sct.size());
+}
+
+TEST_P(CryptoServerTest, RejectTooLarge) {
+  // Check that the server replies with no certificate when a CHLO is
+  // constructed with a PDMD but no SKT when the REJ would be too large.
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
+  config_.set_chlo_multiplier(1);
+
+  ShouldSucceed(msg);
+  absl::string_view cert, proof, cert_sct;
+  EXPECT_FALSE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_FALSE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, RejectNotTooLarge) {
+  // When the CHLO packet is large enough, ensure that a full REJ is sent.
+  chlo_packet_size_ *= 5;
+
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
+  config_.set_chlo_multiplier(1);
+
+  ShouldSucceed(msg);
+  absl::string_view cert, proof, cert_sct;
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
+  // Check that the server replies with no certificate when a CHLO is
+  // constructed with a PDMD but no SKT when the REJ would be too large.
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
+  config_.set_chlo_multiplier(1);
+
+  ShouldSucceed(msg);
+  absl::string_view cert, proof, cert_sct;
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+  EXPECT_NE(0u, cert.size());
+  EXPECT_NE(0u, proof.size());
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, BadSourceAddressToken) {
+  // Invalid source-address tokens should be ignored.
+  // clang-format off
+  static const char* const kBadSourceAddressTokens[] = {
+    "",
+    "foo",
+    "#0000",
+    "#0000000000000000000000000000000000000000",
+  };
+  // clang-format on
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadSourceAddressTokens); i++) {
+    CryptoHandshakeMessage msg =
+        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                       {"STK", kBadSourceAddressTokens[i]},
+                                       {"VER\0", client_version_string_}},
+                                      kClientHelloMinimumSize);
+    ShouldSucceed(msg);
+    const HandshakeFailureReason kRejectReasons[] = {
+        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+  }
+}
+
+TEST_P(CryptoServerTest, BadClientNonce) {
+  // clang-format off
+  static const char* const kBadNonces[] = {
+    "",
+    "#0000",
+    "#0000000000000000000000000000000000000000",
+  };
+  // clang-format on
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadNonces); i++) {
+    // Invalid nonces should be ignored, in an inchoate CHLO.
+
+    CryptoHandshakeMessage msg =
+        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                       {"NONC", kBadNonces[i]},
+                                       {"VER\0", client_version_string_}},
+                                      kClientHelloMinimumSize);
+
+    ShouldSucceed(msg);
+    const HandshakeFailureReason kRejectReasons[] = {
+        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+
+    // Invalid nonces should result in CLIENT_NONCE_INVALID_FAILURE.
+    CryptoHandshakeMessage msg1 =
+        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                       {"AEAD", "AESG"},
+                                       {"KEXS", "C255"},
+                                       {"SCID", scid_hex_},
+                                       {"#004b5453", srct_hex_},
+                                       {"PUBS", pub_hex_},
+                                       {"NONC", kBadNonces[i]},
+                                       {"NONP", kBadNonces[i]},
+                                       {"XLCT", XlctHexString()},
+                                       {"VER\0", client_version_string_}},
+                                      kClientHelloMinimumSize);
+
+    ShouldSucceed(msg1);
+
+    CheckRejectTag();
+    const HandshakeFailureReason kRejectReasons1[] = {
+        CLIENT_NONCE_INVALID_FAILURE};
+    CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
+  }
+}
+
+TEST_P(CryptoServerTest, NoClientNonce) {
+  // No client nonces should result in INCHOATE_HELLO_FAILURE.
+
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+
+  CryptoHandshakeMessage msg1 =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"XLCT", XlctHexString()},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  ShouldSucceed(msg1);
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons1[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
+}
+
+TEST_P(CryptoServerTest, DowngradeAttack) {
+  if (supported_versions_.size() == 1) {
+    // No downgrade attack is possible if the server only supports one version.
+    return;
+  }
+  // Set the client's preferred version to a supported version that
+  // is not the "current" version (supported_versions_.front()).
+  std::string bad_version =
+      ParsedQuicVersionToString(supported_versions_.back());
+
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"VER\0", bad_version}}, kClientHelloMinimumSize);
+
+  ShouldFailMentioning("Downgrade", msg);
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptServerConfig) {
+  // This tests corrupted server config.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", (std::string(1, 'X') + scid_hex_)},
+       {"#004b5453", srct_hex_},
+       {"PUBS", pub_hex_},
+       {"NONC", nonce_hex_},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptSourceAddressToken) {
+  // This tests corrupted source address token.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", scid_hex_},
+       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
+       {"PUBS", pub_hex_},
+       {"NONC", nonce_hex_},
+       {"XLCT", XlctHexString()},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons[] = {
+      SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptSourceAddressTokenIsStillAccepted) {
+  // This tests corrupted source address token.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", scid_hex_},
+       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
+       {"PUBS", pub_hex_},
+       {"NONC", nonce_hex_},
+       {"XLCT", XlctHexString()},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  config_.set_validate_source_address_token(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+}
+
+TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) {
+  // This test corrupts client nonce and source address token.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", scid_hex_},
+       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
+       {"PUBS", pub_hex_},
+       {"NONC", (std::string(1, 'X') + nonce_hex_)},
+       {"XLCT", XlctHexString()},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons[] = {
+      SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptMultipleTags) {
+  // This test corrupts client nonce, server nonce and source address token.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", scid_hex_},
+       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
+       {"PUBS", pub_hex_},
+       {"NONC", (std::string(1, 'X') + nonce_hex_)},
+       {"NONP", (std::string(1, 'X') + nonce_hex_)},
+       {"SNO\0", (std::string(1, 'X') + nonce_hex_)},
+       {"XLCT", XlctHexString()},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  CheckRejectTag();
+
+  const HandshakeFailureReason kRejectReasons[] = {
+      SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, NoServerNonce) {
+  // When no server nonce is present and no strike register is configured,
+  // the CHLO should be rejected.
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"NONP", nonce_hex_},
+                                     {"XLCT", XlctHexString()},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+
+  // Even without a server nonce, this ClientHello should be accepted in
+  // version 33.
+  ASSERT_EQ(kSHLO, out_.tag());
+  CheckServerHello(out_);
+}
+
+TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) {
+  client_address_ = QuicSocketAddress(QuicIpAddress::Loopback6(), 1234);
+
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PDMD", "X509"},
+                                     {"SCID", kOldConfigId},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"NONP", "123456789012345678901234567890"},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", XlctHexString()}},
+                                    kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  // The message should be rejected because the source-address token is no
+  // longer valid.
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons[] = {
+      SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+
+  absl::string_view cert, proof, scfg_str;
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_TRUE(out_.GetStringPiece(kSCFG, &scfg_str));
+  std::unique_ptr<CryptoHandshakeMessage> scfg(
+      CryptoFramer::ParseMessage(scfg_str));
+  absl::string_view scid;
+  EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
+  EXPECT_NE(scid, kOldConfigId);
+
+  // Get certs from compressed certs.
+  std::vector<std::string> cached_certs;
+
+  std::vector<std::string> certs;
+  ASSERT_TRUE(CertCompressor::DecompressChain(cert, cached_certs, &certs));
+
+  // Check that the proof in the REJ message is valid.
+  std::unique_ptr<ProofVerifier> proof_verifier(
+      crypto_test_utils::ProofVerifierForTesting());
+  std::unique_ptr<ProofVerifyContext> verify_context(
+      crypto_test_utils::ProofVerifyContextForTesting());
+  std::unique_ptr<ProofVerifyDetails> details;
+  std::string error_details;
+  std::unique_ptr<ProofVerifierCallback> callback(
+      new DummyProofVerifierCallback());
+  const std::string chlo_hash =
+      CryptoUtils::HashHandshakeMessage(msg, Perspective::IS_SERVER);
+  EXPECT_EQ(QUIC_SUCCESS,
+            proof_verifier->VerifyProof(
+                "test.example.com", 443, (std::string(scfg_str)),
+                client_version_.transport_version, chlo_hash, certs, "",
+                (std::string(proof)), verify_context.get(), &error_details,
+                &details, std::move(callback)));
+}
+
+TEST_P(CryptoServerTest, RejectInvalidXlct) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", "#0102030405060708"}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+
+  const HandshakeFailureReason kRejectReasons[] = {
+      INVALID_EXPECTED_LEAF_CERTIFICATE};
+
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, ValidXlct) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", XlctHexString()}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+}
+
+TEST_P(CryptoServerTest, NonceInSHLO) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", XlctHexString()}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+
+  absl::string_view nonce;
+  EXPECT_TRUE(out_.GetStringPiece(kServerNonceTag, &nonce));
+}
+
+TEST_P(CryptoServerTest, ProofSourceFailure) {
+  // Install a ProofSource which will unconditionally fail
+  peer_.ResetProofSource(std::unique_ptr<ProofSource>(new FailingProofSource));
+
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // Just ensure that we don't crash as occurred in b/33916924.
+  ShouldFailMentioning("", msg);
+}
+
+// Regression test for crbug.com/723604
+// For 2RTT, if the first CHLO from the client contains hashes of cached
+// certs (stored in CCRT tag) but the second CHLO does not, then the second REJ
+// from the server should not contain hashes of cached certs.
+TEST_P(CryptoServerTest, TwoRttServerDropCachedCerts) {
+  // Send inchoate CHLO to get cert chain from server. This CHLO is only for
+  // the purpose of getting the server's certs; it is not part of the 2RTT
+  // handshake.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+  ShouldSucceed(msg);
+
+  // Decompress cert chain from server to individual certs.
+  absl::string_view certs_compressed;
+  ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
+  ASSERT_NE(0u, certs_compressed.size());
+  std::vector<std::string> certs;
+  ASSERT_TRUE(CertCompressor::DecompressChain(certs_compressed,
+                                              /*cached_certs=*/{}, &certs));
+
+  // Start 2-RTT. Client sends CHLO with bad source-address token and hashes of
+  // the certs, which tells the server that the client has cached those certs.
+  config_.set_chlo_multiplier(1);
+  const char kBadSourceAddressToken[] = "";
+  msg.SetStringPiece(kSourceAddressTokenTag, kBadSourceAddressToken);
+  std::vector<uint64_t> hashes(certs.size());
+  for (size_t i = 0; i < certs.size(); ++i) {
+    hashes[i] = QuicUtils::QuicUtils::FNV1a_64_Hash(certs[i]);
+  }
+  msg.SetVector(kCCRT, hashes);
+  ShouldSucceed(msg);
+
+  // Server responds with inchoate REJ containing valid source-address token.
+  absl::string_view srct;
+  ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
+
+  // Client now drops cached certs; sends CHLO with updated source-address
+  // token but no hashes of certs.
+  msg.SetStringPiece(kSourceAddressTokenTag, srct);
+  msg.Erase(kCCRT);
+  ShouldSucceed(msg);
+
+  // Server response's cert chain should not contain hashes of
+  // previously-cached certs.
+  ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
+  ASSERT_NE(0u, certs_compressed.size());
+  ASSERT_TRUE(CertCompressor::DecompressChain(certs_compressed,
+                                              /*cached_certs=*/{}, &certs));
+}
+
+class CryptoServerConfigGenerationTest : public QuicTest {};
+
+TEST_F(CryptoServerConfigGenerationTest, Determinism) {
+  // Test that using a deterministic PRNG causes the server-config to be
+  // deterministic.
+
+  MockRandom rand_a, rand_b;
+  const QuicCryptoServerConfig::ConfigOptions options;
+  MockClock clock;
+
+  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  std::unique_ptr<CryptoHandshakeMessage> scfg_a(
+      a.AddDefaultConfig(&rand_a, &clock, options));
+  std::unique_ptr<CryptoHandshakeMessage> scfg_b(
+      b.AddDefaultConfig(&rand_b, &clock, options));
+
+  ASSERT_EQ(scfg_a->DebugString(), scfg_b->DebugString());
+}
+
+TEST_F(CryptoServerConfigGenerationTest, SCIDVaries) {
+  // This test ensures that the server config ID varies for different server
+  // configs.
+
+  MockRandom rand_a, rand_b;
+  const QuicCryptoServerConfig::ConfigOptions options;
+  MockClock clock;
+
+  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  rand_b.ChangeValue();
+  QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  std::unique_ptr<CryptoHandshakeMessage> scfg_a(
+      a.AddDefaultConfig(&rand_a, &clock, options));
+  std::unique_ptr<CryptoHandshakeMessage> scfg_b(
+      b.AddDefaultConfig(&rand_b, &clock, options));
+
+  absl::string_view scid_a, scid_b;
+  EXPECT_TRUE(scfg_a->GetStringPiece(kSCID, &scid_a));
+  EXPECT_TRUE(scfg_b->GetStringPiece(kSCID, &scid_b));
+
+  EXPECT_NE(scid_a, scid_b);
+}
+
+TEST_F(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
+  MockRandom rand_a;
+  const QuicCryptoServerConfig::ConfigOptions options;
+  MockClock clock;
+
+  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  std::unique_ptr<CryptoHandshakeMessage> scfg(
+      a.AddDefaultConfig(&rand_a, &clock, options));
+
+  absl::string_view scid;
+  EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
+  // Need to take a copy of |scid| has we're about to call |Erase|.
+  const std::string scid_str(scid);
+
+  scfg->Erase(kSCID);
+  scfg->MarkDirty();
+  const QuicData& serialized(scfg->GetSerialized());
+
+  uint8_t digest[SHA256_DIGEST_LENGTH];
+  SHA256(reinterpret_cast<const uint8_t*>(serialized.data()),
+         serialized.length(), digest);
+
+  // scid is a SHA-256 hash, truncated to 16 bytes.
+  ASSERT_EQ(scid.size(), 16u);
+  EXPECT_EQ(0, memcmp(digest, scid_str.c_str(), scid.size()));
+}
+
+// Those tests were declared incorrectly and thus never ran in first place.
+// TODO(b/147891553): figure out if we should fix or delete those.
+#if 0
+
+class CryptoServerTestNoConfig : public CryptoServerTest {
+ public:
+  void SetUp() override {
+    // Deliberately don't add a config so that we can test this situation.
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(CryptoServerTestsNoConfig,
+                         CryptoServerTestNoConfig,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(CryptoServerTestNoConfig, DontCrash) {
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldFailMentioning("No config", msg);
+
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+class CryptoServerTestOldVersion : public CryptoServerTest {
+ public:
+  void SetUp() override {
+    client_version_ = supported_versions_.back();
+    client_version_string_ = ParsedQuicVersionToString(client_version_);
+    CryptoServerTest::SetUp();
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(CryptoServerTestsOldVersion,
+                         CryptoServerTestOldVersion,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", "#0100000000000000"}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+}
+
+TEST_P(CryptoServerTestOldVersion, XlctNotRequired) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+}
+
+#endif  // 0
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_utils.cc b/quiche/quic/core/crypto/crypto_utils.cc
new file mode 100644
index 0000000..d40c734
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_utils.cc
@@ -0,0 +1,790 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/crypto_utils.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/hkdf.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_decrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_hkdf.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+namespace {
+
+// Implements the HKDF-Expand-Label function as defined in section 7.1 of RFC
+// 8446. The HKDF-Expand-Label function takes 4 explicit arguments (Secret,
+// Label, Context, and Length), as well as implicit PRF which is the hash
+// function negotiated by TLS. Its use in QUIC (as needed by the QUIC stack,
+// instead of as used internally by the TLS stack) is only for deriving initial
+// secrets for obfuscation, for calculating packet protection keys and IVs from
+// the corresponding packet protection secret and key update in the same quic
+// session. None of these uses need a Context (a zero-length context is
+// provided), so this argument is omitted here.
+//
+// The implicit PRF is explicitly passed into HkdfExpandLabel as |prf|; the
+// Secret, Label, and Length are passed in as |secret|, |label|, and
+// |out_len|, respectively. The resulting expanded secret is returned.
+std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf,
+                                     const std::vector<uint8_t>& secret,
+                                     const std::string& label, size_t out_len) {
+  bssl::ScopedCBB quic_hkdf_label;
+  CBB inner_label;
+  const char label_prefix[] = "tls13 ";
+  // 20 = size(u16) + size(u8) + len("tls13 ") +
+  //      max_len("client in", "server in", "quicv2 key", ... ) +
+  //      size(u8);
+  static const size_t max_quic_hkdf_label_length = 20;
+  if (!CBB_init(quic_hkdf_label.get(), max_quic_hkdf_label_length) ||
+      !CBB_add_u16(quic_hkdf_label.get(), out_len) ||
+      !CBB_add_u8_length_prefixed(quic_hkdf_label.get(), &inner_label) ||
+      !CBB_add_bytes(&inner_label,
+                     reinterpret_cast<const uint8_t*>(label_prefix),
+                     ABSL_ARRAYSIZE(label_prefix) - 1) ||
+      !CBB_add_bytes(&inner_label,
+                     reinterpret_cast<const uint8_t*>(label.data()),
+                     label.size()) ||
+      // Zero length |Context|.
+      !CBB_add_u8(quic_hkdf_label.get(), 0) ||
+      !CBB_flush(quic_hkdf_label.get())) {
+    QUIC_LOG(ERROR) << "Building HKDF label failed";
+    return std::vector<uint8_t>();
+  }
+  std::vector<uint8_t> out;
+  out.resize(out_len);
+  if (!HKDF_expand(out.data(), out_len, prf, secret.data(), secret.size(),
+                   CBB_data(quic_hkdf_label.get()),
+                   CBB_len(quic_hkdf_label.get()))) {
+    QUIC_LOG(ERROR) << "Running HKDF-Expand-Label failed";
+    return std::vector<uint8_t>();
+  }
+  return out;
+}
+
+}  // namespace
+
+const std::string getLabelForVersion(const ParsedQuicVersion& version,
+                                     const absl::string_view& predicate) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync with HKDF labels");
+  if (version == ParsedQuicVersion::V2Draft01()) {
+    return absl::StrCat("quicv2 ", predicate);
+  } else {
+    return absl::StrCat("quic ", predicate);
+  }
+}
+
+void CryptoUtils::InitializeCrypterSecrets(
+    const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+    const ParsedQuicVersion& version, QuicCrypter* crypter) {
+  SetKeyAndIV(prf, pp_secret, version, crypter);
+  std::vector<uint8_t> header_protection_key = GenerateHeaderProtectionKey(
+      prf, pp_secret, version, crypter->GetKeySize());
+  crypter->SetHeaderProtectionKey(
+      absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
+                        header_protection_key.size()));
+}
+
+void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
+                              const std::vector<uint8_t>& pp_secret,
+                              const ParsedQuicVersion& version,
+                              QuicCrypter* crypter) {
+  std::vector<uint8_t> key =
+      HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "key"),
+                      crypter->GetKeySize());
+  std::vector<uint8_t> iv = HkdfExpandLabel(
+      prf, pp_secret, getLabelForVersion(version, "iv"), crypter->GetIVSize());
+  crypter->SetKey(
+      absl::string_view(reinterpret_cast<char*>(key.data()), key.size()));
+  crypter->SetIV(
+      absl::string_view(reinterpret_cast<char*>(iv.data()), iv.size()));
+}
+
+std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey(
+    const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+    const ParsedQuicVersion& version, size_t out_len) {
+  return HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "hp"),
+                         out_len);
+}
+
+std::vector<uint8_t> CryptoUtils::GenerateNextKeyPhaseSecret(
+    const EVP_MD* prf, const ParsedQuicVersion& version,
+    const std::vector<uint8_t>& current_secret) {
+  return HkdfExpandLabel(prf, current_secret, getLabelForVersion(version, "ku"),
+                         current_secret.size());
+}
+
+namespace {
+
+// Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.2
+const uint8_t kDraft29InitialSalt[] = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2,
+                                       0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
+                                       0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99};
+const uint8_t kRFCv1InitialSalt[] = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34,
+                                     0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
+                                     0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a};
+const uint8_t kV2Draft01InitialSalt[] = {
+    0xa7, 0x07, 0xc2, 0x03, 0xa5, 0x9b, 0x47, 0x18, 0x4a, 0x1d,
+    0x62, 0xca, 0x57, 0x04, 0x06, 0xea, 0x7a, 0xe3, 0xe5, 0xd3};
+
+// Salts used by deployed versions of QUIC. When introducing a new version,
+// generate a new salt by running `openssl rand -hex 20`.
+
+// Salt to use for initial obfuscators in version Q050.
+const uint8_t kQ050Salt[] = {0x50, 0x45, 0x74, 0xef, 0xd0, 0x66, 0xfe,
+                             0x2f, 0x9d, 0x94, 0x5c, 0xfc, 0xdb, 0xd3,
+                             0xa7, 0xf0, 0xd3, 0xb5, 0x6b, 0x45};
+// Salt to use for initial obfuscators in
+// ParsedQuicVersion::ReservedForNegotiation().
+const uint8_t kReservedForNegotiationSalt[] = {
+    0xf9, 0x64, 0xbf, 0x45, 0x3a, 0x1f, 0x1b, 0x80, 0xa5, 0xf8,
+    0x82, 0x03, 0x77, 0xd4, 0xaf, 0xca, 0x58, 0x0e, 0xe7, 0x43};
+
+const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
+                                     size_t* out_len) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync with initial encryption salts");
+  if (version == ParsedQuicVersion::V2Draft01()) {
+    *out_len = ABSL_ARRAYSIZE(kV2Draft01InitialSalt);
+    return kV2Draft01InitialSalt;
+  } else if (version == ParsedQuicVersion::RFCv1()) {
+    *out_len = ABSL_ARRAYSIZE(kRFCv1InitialSalt);
+    return kRFCv1InitialSalt;
+  } else if (version == ParsedQuicVersion::Draft29()) {
+    *out_len = ABSL_ARRAYSIZE(kDraft29InitialSalt);
+    return kDraft29InitialSalt;
+  } else if (version == ParsedQuicVersion::Q050()) {
+    *out_len = ABSL_ARRAYSIZE(kQ050Salt);
+    return kQ050Salt;
+  } else if (version == ParsedQuicVersion::ReservedForNegotiation()) {
+    *out_len = ABSL_ARRAYSIZE(kReservedForNegotiationSalt);
+    return kReservedForNegotiationSalt;
+  }
+  QUIC_BUG(quic_bug_10699_1)
+      << "No initial obfuscation salt for version " << version;
+  *out_len = ABSL_ARRAYSIZE(kReservedForNegotiationSalt);
+  return kReservedForNegotiationSalt;
+}
+
+const char kPreSharedKeyLabel[] = "QUIC PSK";
+
+// Retry Integrity Protection Keys and Nonces.
+// https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.8
+// When introducing a new Google version, generate a new key by running
+// `openssl rand -hex 16`.
+const uint8_t kDraft29RetryIntegrityKey[] = {0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a,
+                                             0x09, 0xd0, 0x57, 0x28, 0x15, 0x5a,
+                                             0x6c, 0xb9, 0x6b, 0xe1};
+const uint8_t kDraft29RetryIntegrityNonce[] = {
+    0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, 0x53, 0x0a, 0x8c, 0x1c};
+const uint8_t kRFCv1RetryIntegrityKey[] = {0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66,
+                                           0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54,
+                                           0xe3, 0x68, 0xc8, 0x4e};
+const uint8_t kRFCv1RetryIntegrityNonce[] = {
+    0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb};
+const uint8_t kV2Draft01RetryIntegrityKey[] = {
+    0xba, 0x85, 0x8d, 0xc7, 0xb4, 0x3d, 0xe5, 0xdb,
+    0xf8, 0x76, 0x17, 0xff, 0x4a, 0xb2, 0x53, 0xdb};
+const uint8_t kV2Draft01RetryIntegrityNonce[] = {
+    0x14, 0x1b, 0x99, 0xc2, 0x39, 0xb0, 0x3e, 0x78, 0x5d, 0x6a, 0x2e, 0x9f};
+// Retry integrity key used by ParsedQuicVersion::ReservedForNegotiation().
+const uint8_t kReservedForNegotiationRetryIntegrityKey[] = {
+    0xf2, 0xcd, 0x8f, 0xe0, 0x36, 0xd0, 0x25, 0x35,
+    0x03, 0xe6, 0x7c, 0x7b, 0xd2, 0x44, 0xca, 0xd9};
+// When introducing a new Google version, generate a new nonce by running
+// `openssl rand -hex 12`.
+// Retry integrity nonce used by ParsedQuicVersion::ReservedForNegotiation().
+const uint8_t kReservedForNegotiationRetryIntegrityNonce[] = {
+    0x35, 0x9f, 0x16, 0xd1, 0xed, 0x80, 0x90, 0x8e, 0xec, 0x85, 0xc4, 0xd6};
+
+bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version,
+                                  absl::string_view* key,
+                                  absl::string_view* nonce) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync with retry integrity keys");
+  if (!version.UsesTls()) {
+    QUIC_BUG(quic_bug_10699_2)
+        << "Attempted to get retry integrity keys for invalid version "
+        << version;
+    return false;
+  } else if (version == ParsedQuicVersion::V2Draft01()) {
+    *key = absl::string_view(
+        reinterpret_cast<const char*>(kV2Draft01RetryIntegrityKey),
+        ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityKey));
+    *nonce = absl::string_view(
+        reinterpret_cast<const char*>(kV2Draft01RetryIntegrityNonce),
+        ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityNonce));
+    return true;
+  } else if (version == ParsedQuicVersion::RFCv1()) {
+    *key = absl::string_view(
+        reinterpret_cast<const char*>(kRFCv1RetryIntegrityKey),
+        ABSL_ARRAYSIZE(kRFCv1RetryIntegrityKey));
+    *nonce = absl::string_view(
+        reinterpret_cast<const char*>(kRFCv1RetryIntegrityNonce),
+        ABSL_ARRAYSIZE(kRFCv1RetryIntegrityNonce));
+    return true;
+  } else if (version == ParsedQuicVersion::Draft29()) {
+    *key = absl::string_view(
+        reinterpret_cast<const char*>(kDraft29RetryIntegrityKey),
+        ABSL_ARRAYSIZE(kDraft29RetryIntegrityKey));
+    *nonce = absl::string_view(
+        reinterpret_cast<const char*>(kDraft29RetryIntegrityNonce),
+        ABSL_ARRAYSIZE(kDraft29RetryIntegrityNonce));
+    return true;
+  } else if (version == ParsedQuicVersion::ReservedForNegotiation()) {
+    *key = absl::string_view(
+        reinterpret_cast<const char*>(kReservedForNegotiationRetryIntegrityKey),
+        ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityKey));
+    *nonce = absl::string_view(
+        reinterpret_cast<const char*>(
+            kReservedForNegotiationRetryIntegrityNonce),
+        ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityNonce));
+    return true;
+  }
+  QUIC_BUG(quic_bug_10699_3)
+      << "Attempted to get retry integrity keys for version " << version;
+  return false;
+}
+
+}  // namespace
+
+// static
+void CryptoUtils::CreateInitialObfuscators(Perspective perspective,
+                                           ParsedQuicVersion version,
+                                           QuicConnectionId connection_id,
+                                           CrypterPair* crypters) {
+  QUIC_DLOG(INFO) << "Creating "
+                  << (perspective == Perspective::IS_CLIENT ? "client"
+                                                            : "server")
+                  << " crypters for version " << version << " with CID "
+                  << connection_id;
+  if (!version.UsesInitialObfuscators()) {
+    crypters->encrypter = std::make_unique<NullEncrypter>(perspective);
+    crypters->decrypter = std::make_unique<NullDecrypter>(perspective);
+    return;
+  }
+  QUIC_BUG_IF(quic_bug_12871_1, !QuicUtils::IsConnectionIdValidForVersion(
+                                    connection_id, version.transport_version))
+      << "CreateTlsInitialCrypters: attempted to use connection ID "
+      << connection_id << " which is invalid with version " << version;
+  const EVP_MD* hash = EVP_sha256();
+
+  size_t salt_len;
+  const uint8_t* salt = InitialSaltForVersion(version, &salt_len);
+  std::vector<uint8_t> handshake_secret;
+  handshake_secret.resize(EVP_MAX_MD_SIZE);
+  size_t handshake_secret_len;
+  const bool hkdf_extract_success =
+      HKDF_extract(handshake_secret.data(), &handshake_secret_len, hash,
+                   reinterpret_cast<const uint8_t*>(connection_id.data()),
+                   connection_id.length(), salt, salt_len);
+  QUIC_BUG_IF(quic_bug_12871_2, !hkdf_extract_success)
+      << "HKDF_extract failed when creating initial crypters";
+  handshake_secret.resize(handshake_secret_len);
+
+  const std::string client_label = "client in";
+  const std::string server_label = "server in";
+  std::string encryption_label, decryption_label;
+  if (perspective == Perspective::IS_CLIENT) {
+    encryption_label = client_label;
+    decryption_label = server_label;
+  } else {
+    encryption_label = server_label;
+    decryption_label = client_label;
+  }
+  std::vector<uint8_t> encryption_secret = HkdfExpandLabel(
+      hash, handshake_secret, encryption_label, EVP_MD_size(hash));
+  crypters->encrypter = std::make_unique<Aes128GcmEncrypter>();
+  InitializeCrypterSecrets(hash, encryption_secret, version,
+                           crypters->encrypter.get());
+
+  std::vector<uint8_t> decryption_secret = HkdfExpandLabel(
+      hash, handshake_secret, decryption_label, EVP_MD_size(hash));
+  crypters->decrypter = std::make_unique<Aes128GcmDecrypter>();
+  InitializeCrypterSecrets(hash, decryption_secret, version,
+                           crypters->decrypter.get());
+}
+
+// static
+bool CryptoUtils::ValidateRetryIntegrityTag(
+    ParsedQuicVersion version, QuicConnectionId original_connection_id,
+    absl::string_view retry_without_tag, absl::string_view integrity_tag) {
+  unsigned char computed_integrity_tag[kRetryIntegrityTagLength];
+  if (integrity_tag.length() != ABSL_ARRAYSIZE(computed_integrity_tag)) {
+    QUIC_BUG(quic_bug_10699_4)
+        << "Invalid retry integrity tag length " << integrity_tag.length();
+    return false;
+  }
+  char retry_pseudo_packet[kMaxIncomingPacketSize + 256];
+  QuicDataWriter writer(ABSL_ARRAYSIZE(retry_pseudo_packet),
+                        retry_pseudo_packet);
+  if (!writer.WriteLengthPrefixedConnectionId(original_connection_id)) {
+    QUIC_BUG(quic_bug_10699_5)
+        << "Failed to write original connection ID in retry pseudo packet";
+    return false;
+  }
+  if (!writer.WriteStringPiece(retry_without_tag)) {
+    QUIC_BUG(quic_bug_10699_6)
+        << "Failed to write retry without tag in retry pseudo packet";
+    return false;
+  }
+  absl::string_view key;
+  absl::string_view nonce;
+  if (!RetryIntegrityKeysForVersion(version, &key, &nonce)) {
+    // RetryIntegrityKeysForVersion already logs failures.
+    return false;
+  }
+  Aes128GcmEncrypter crypter;
+  crypter.SetKey(key);
+  absl::string_view associated_data(writer.data(), writer.length());
+  absl::string_view plaintext;  // Plaintext is empty.
+  if (!crypter.Encrypt(nonce, associated_data, plaintext,
+                       computed_integrity_tag)) {
+    QUIC_BUG(quic_bug_10699_7) << "Failed to compute retry integrity tag";
+    return false;
+  }
+  if (CRYPTO_memcmp(computed_integrity_tag, integrity_tag.data(),
+                    ABSL_ARRAYSIZE(computed_integrity_tag)) != 0) {
+    QUIC_DLOG(ERROR) << "Failed to validate retry integrity tag";
+    return false;
+  }
+  return true;
+}
+
+// static
+void CryptoUtils::GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
+                                absl::string_view orbit, std::string* nonce) {
+  // a 4-byte timestamp + 28 random bytes.
+  nonce->reserve(kNonceSize);
+  nonce->resize(kNonceSize);
+
+  uint32_t gmt_unix_time = static_cast<uint32_t>(now.ToUNIXSeconds());
+  // The time in the nonce must be encoded in big-endian because the
+  // strike-register depends on the nonces being ordered by time.
+  (*nonce)[0] = static_cast<char>(gmt_unix_time >> 24);
+  (*nonce)[1] = static_cast<char>(gmt_unix_time >> 16);
+  (*nonce)[2] = static_cast<char>(gmt_unix_time >> 8);
+  (*nonce)[3] = static_cast<char>(gmt_unix_time);
+  size_t bytes_written = 4;
+
+  if (orbit.size() == 8) {
+    memcpy(&(*nonce)[bytes_written], orbit.data(), orbit.size());
+    bytes_written += orbit.size();
+  }
+
+  random_generator->RandBytes(&(*nonce)[bytes_written],
+                              kNonceSize - bytes_written);
+}
+
+// static
+bool CryptoUtils::DeriveKeys(
+    const ParsedQuicVersion& version, absl::string_view premaster_secret,
+    QuicTag aead, absl::string_view client_nonce,
+    absl::string_view server_nonce, absl::string_view pre_shared_key,
+    const std::string& hkdf_input, Perspective perspective,
+    Diversification diversification, CrypterPair* crypters,
+    std::string* subkey_secret) {
+  // If the connection is using PSK, concatenate it with the pre-master secret.
+  std::unique_ptr<char[]> psk_premaster_secret;
+  if (!pre_shared_key.empty()) {
+    const absl::string_view label(kPreSharedKeyLabel);
+    const size_t psk_premaster_secret_size = label.size() + 1 +
+                                             pre_shared_key.size() + 8 +
+                                             premaster_secret.size() + 8;
+
+    psk_premaster_secret = std::make_unique<char[]>(psk_premaster_secret_size);
+    QuicDataWriter writer(psk_premaster_secret_size, psk_premaster_secret.get(),
+                          quiche::HOST_BYTE_ORDER);
+
+    if (!writer.WriteStringPiece(label) || !writer.WriteUInt8(0) ||
+        !writer.WriteStringPiece(pre_shared_key) ||
+        !writer.WriteUInt64(pre_shared_key.size()) ||
+        !writer.WriteStringPiece(premaster_secret) ||
+        !writer.WriteUInt64(premaster_secret.size()) ||
+        writer.remaining() != 0) {
+      return false;
+    }
+
+    premaster_secret = absl::string_view(psk_premaster_secret.get(),
+                                         psk_premaster_secret_size);
+  }
+
+  crypters->encrypter = QuicEncrypter::Create(version, aead);
+  crypters->decrypter = QuicDecrypter::Create(version, aead);
+
+  size_t key_bytes = crypters->encrypter->GetKeySize();
+  size_t nonce_prefix_bytes = crypters->encrypter->GetNoncePrefixSize();
+  if (version.UsesInitialObfuscators()) {
+    nonce_prefix_bytes = crypters->encrypter->GetIVSize();
+  }
+  size_t subkey_secret_bytes =
+      subkey_secret == nullptr ? 0 : premaster_secret.length();
+
+  absl::string_view nonce = client_nonce;
+  std::string nonce_storage;
+  if (!server_nonce.empty()) {
+    nonce_storage = std::string(client_nonce) + std::string(server_nonce);
+    nonce = nonce_storage;
+  }
+
+  QuicHKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes,
+                nonce_prefix_bytes, subkey_secret_bytes);
+
+  // Key derivation depends on the key diversification method being employed.
+  // both the client and the server support never doing key diversification.
+  // The server also supports immediate diversification, and the client
+  // supports pending diversification.
+  switch (diversification.mode()) {
+    case Diversification::NEVER: {
+      if (perspective == Perspective::IS_SERVER) {
+        if (!crypters->encrypter->SetKey(hkdf.server_write_key()) ||
+            !crypters->encrypter->SetNoncePrefixOrIV(version,
+                                                     hkdf.server_write_iv()) ||
+            !crypters->encrypter->SetHeaderProtectionKey(
+                hkdf.server_hp_key()) ||
+            !crypters->decrypter->SetKey(hkdf.client_write_key()) ||
+            !crypters->decrypter->SetNoncePrefixOrIV(version,
+                                                     hkdf.client_write_iv()) ||
+            !crypters->decrypter->SetHeaderProtectionKey(
+                hkdf.client_hp_key())) {
+          return false;
+        }
+      } else {
+        if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
+            !crypters->encrypter->SetNoncePrefixOrIV(version,
+                                                     hkdf.client_write_iv()) ||
+            !crypters->encrypter->SetHeaderProtectionKey(
+                hkdf.client_hp_key()) ||
+            !crypters->decrypter->SetKey(hkdf.server_write_key()) ||
+            !crypters->decrypter->SetNoncePrefixOrIV(version,
+                                                     hkdf.server_write_iv()) ||
+            !crypters->decrypter->SetHeaderProtectionKey(
+                hkdf.server_hp_key())) {
+          return false;
+        }
+      }
+      break;
+    }
+    case Diversification::PENDING: {
+      if (perspective == Perspective::IS_SERVER) {
+        QUIC_BUG(quic_bug_10699_8)
+            << "Pending diversification is only for clients.";
+        return false;
+      }
+
+      if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
+          !crypters->encrypter->SetNoncePrefixOrIV(version,
+                                                   hkdf.client_write_iv()) ||
+          !crypters->encrypter->SetHeaderProtectionKey(hkdf.client_hp_key()) ||
+          !crypters->decrypter->SetPreliminaryKey(hkdf.server_write_key()) ||
+          !crypters->decrypter->SetNoncePrefixOrIV(version,
+                                                   hkdf.server_write_iv()) ||
+          !crypters->decrypter->SetHeaderProtectionKey(hkdf.server_hp_key())) {
+        return false;
+      }
+      break;
+    }
+    case Diversification::NOW: {
+      if (perspective == Perspective::IS_CLIENT) {
+        QUIC_BUG(quic_bug_10699_9)
+            << "Immediate diversification is only for servers.";
+        return false;
+      }
+
+      std::string key, nonce_prefix;
+      QuicDecrypter::DiversifyPreliminaryKey(
+          hkdf.server_write_key(), hkdf.server_write_iv(),
+          *diversification.nonce(), key_bytes, nonce_prefix_bytes, &key,
+          &nonce_prefix);
+      if (!crypters->decrypter->SetKey(hkdf.client_write_key()) ||
+          !crypters->decrypter->SetNoncePrefixOrIV(version,
+                                                   hkdf.client_write_iv()) ||
+          !crypters->decrypter->SetHeaderProtectionKey(hkdf.client_hp_key()) ||
+          !crypters->encrypter->SetKey(key) ||
+          !crypters->encrypter->SetNoncePrefixOrIV(version, nonce_prefix) ||
+          !crypters->encrypter->SetHeaderProtectionKey(hkdf.server_hp_key())) {
+        return false;
+      }
+      break;
+    }
+    default:
+      QUICHE_DCHECK(false);
+  }
+
+  if (subkey_secret != nullptr) {
+    *subkey_secret = std::string(hkdf.subkey_secret());
+  }
+
+  return true;
+}
+
+// static
+uint64_t CryptoUtils::ComputeLeafCertHash(absl::string_view cert) {
+  return QuicUtils::FNV1a_64_Hash(cert);
+}
+
+QuicErrorCode CryptoUtils::ValidateServerHello(
+    const CryptoHandshakeMessage& server_hello,
+    const ParsedQuicVersionVector& negotiated_versions,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  if (server_hello.tag() != kSHLO) {
+    *error_details = "Bad tag";
+    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+  }
+
+  QuicVersionLabelVector supported_version_labels;
+  if (server_hello.GetVersionLabelList(kVER, &supported_version_labels) !=
+      QUIC_NO_ERROR) {
+    *error_details = "server hello missing version list";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  return ValidateServerHelloVersions(supported_version_labels,
+                                     negotiated_versions, error_details);
+}
+
+QuicErrorCode CryptoUtils::ValidateServerHelloVersions(
+    const QuicVersionLabelVector& server_versions,
+    const ParsedQuicVersionVector& negotiated_versions,
+    std::string* error_details) {
+  if (!negotiated_versions.empty()) {
+    bool mismatch = server_versions.size() != negotiated_versions.size();
+    for (size_t i = 0; i < server_versions.size() && !mismatch; ++i) {
+      mismatch =
+          server_versions[i] != CreateQuicVersionLabel(negotiated_versions[i]);
+    }
+    // The server sent a list of supported versions, and the connection
+    // reports that there was a version negotiation during the handshake.
+    // Ensure that these two lists are identical.
+    if (mismatch) {
+      *error_details = absl::StrCat(
+          "Downgrade attack detected: ServerVersions(", server_versions.size(),
+          ")[", QuicVersionLabelVectorToString(server_versions, ",", 30),
+          "] NegotiatedVersions(", negotiated_versions.size(), ")[",
+          ParsedQuicVersionVectorToString(negotiated_versions, ",", 30), "]");
+      return QUIC_VERSION_NEGOTIATION_MISMATCH;
+    }
+  }
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode CryptoUtils::ValidateClientHello(
+    const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
+    const ParsedQuicVersionVector& supported_versions,
+    std::string* error_details) {
+  if (client_hello.tag() != kCHLO) {
+    *error_details = "Bad tag";
+    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+  }
+
+  // If the client's preferred version is not the version we are currently
+  // speaking, then the client went through a version negotiation.  In this
+  // case, we need to make sure that we actually do not support this version
+  // and that it wasn't a downgrade attack.
+  QuicVersionLabel client_version_label;
+  if (client_hello.GetVersionLabel(kVER, &client_version_label) !=
+      QUIC_NO_ERROR) {
+    *error_details = "client hello missing version list";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+  return ValidateClientHelloVersion(client_version_label, version,
+                                    supported_versions, error_details);
+}
+
+QuicErrorCode CryptoUtils::ValidateClientHelloVersion(
+    QuicVersionLabel client_version, ParsedQuicVersion connection_version,
+    const ParsedQuicVersionVector& supported_versions,
+    std::string* error_details) {
+  if (client_version != CreateQuicVersionLabel(connection_version)) {
+    // Check to see if |client_version| is actually on the supported versions
+    // list. If not, the server doesn't support that version and it's not a
+    // downgrade attack.
+    for (size_t i = 0; i < supported_versions.size(); ++i) {
+      if (client_version == CreateQuicVersionLabel(supported_versions[i])) {
+        *error_details = absl::StrCat(
+            "Downgrade attack detected: ClientVersion[",
+            QuicVersionLabelToString(client_version), "] ConnectionVersion[",
+            ParsedQuicVersionToString(connection_version),
+            "] SupportedVersions(", supported_versions.size(), ")[",
+            ParsedQuicVersionVectorToString(supported_versions, ",", 30), "]");
+        return QUIC_VERSION_NEGOTIATION_MISMATCH;
+      }
+    }
+  }
+  return QUIC_NO_ERROR;
+}
+
+// static
+bool CryptoUtils::ValidateChosenVersion(
+    const QuicVersionLabel& version_information_chosen_version,
+    const ParsedQuicVersion& session_version, std::string* error_details) {
+  if (version_information_chosen_version !=
+      CreateQuicVersionLabel(session_version)) {
+    *error_details = absl::StrCat(
+        "Detected version mismatch: version_information contained ",
+        QuicVersionLabelToString(version_information_chosen_version),
+        " instead of ", ParsedQuicVersionToString(session_version));
+    return false;
+  }
+  return true;
+}
+
+// static
+bool CryptoUtils::ValidateServerVersions(
+    const QuicVersionLabelVector& version_information_other_versions,
+    const ParsedQuicVersion& session_version,
+    const ParsedQuicVersionVector& client_original_supported_versions,
+    std::string* error_details) {
+  if (client_original_supported_versions.empty()) {
+    // We did not receive a version negotiation packet.
+    return true;
+  }
+  // Parse the server's other versions.
+  ParsedQuicVersionVector parsed_other_versions =
+      ParseQuicVersionLabelVector(version_information_other_versions);
+  // Find the first version that we originally supported that is listed in the
+  // server's other versions.
+  ParsedQuicVersion expected_version = ParsedQuicVersion::Unsupported();
+  for (const ParsedQuicVersion& client_version :
+       client_original_supported_versions) {
+    if (std::find(parsed_other_versions.begin(), parsed_other_versions.end(),
+                  client_version) != parsed_other_versions.end()) {
+      expected_version = client_version;
+      break;
+    }
+  }
+  if (expected_version != session_version) {
+    *error_details = absl::StrCat(
+        "Downgrade attack detected: used ",
+        ParsedQuicVersionToString(session_version), " but ServerVersions(",
+        version_information_other_versions.size(), ")[",
+        QuicVersionLabelVectorToString(version_information_other_versions, ",",
+                                       30),
+        "] ClientOriginalVersions(", client_original_supported_versions.size(),
+        ")[",
+        ParsedQuicVersionVectorToString(client_original_supported_versions, ",",
+                                        30),
+        "]");
+    return false;
+  }
+  return true;
+}
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x
+
+// Returns the name of the HandshakeFailureReason as a char*
+// static
+const char* CryptoUtils::HandshakeFailureReasonToString(
+    HandshakeFailureReason reason) {
+  switch (reason) {
+    RETURN_STRING_LITERAL(HANDSHAKE_OK);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_UNKNOWN_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_NOT_UNIQUE_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_ORBIT_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_TIME_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_FAILURE);
+
+    RETURN_STRING_LITERAL(SERVER_NONCE_DECRYPTION_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_NONCE_NOT_UNIQUE_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_TIME_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_NONCE_REQUIRED_FAILURE);
+
+    RETURN_STRING_LITERAL(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
+
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_INVALID_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_PARSE_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE);
+
+    RETURN_STRING_LITERAL(INVALID_EXPECTED_LEAF_CERTIFICATE);
+    RETURN_STRING_LITERAL(MAX_FAILURE_REASON);
+  }
+  // Return a default value so that we return this when |reason| doesn't match
+  // any HandshakeFailureReason.. This can happen when the message by the peer
+  // (attacker) has invalid reason.
+  return "INVALID_HANDSHAKE_FAILURE_REASON";
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+
+// static
+std::string CryptoUtils::EarlyDataReasonToString(
+    ssl_early_data_reason_t reason) {
+  const char* reason_string = SSL_early_data_reason_string(reason);
+  if (reason_string != nullptr) {
+    return std::string("ssl_early_data_") + reason_string;
+  }
+  QUIC_BUG_IF(quic_bug_12871_3,
+              reason < 0 || reason > ssl_early_data_reason_max_value)
+      << "Unknown ssl_early_data_reason_t " << reason;
+  return "unknown ssl_early_data_reason_t";
+}
+
+// static
+std::string CryptoUtils::HashHandshakeMessage(
+    const CryptoHandshakeMessage& message, Perspective /*perspective*/) {
+  std::string output;
+  const QuicData& serialized = message.GetSerialized();
+  uint8_t digest[SHA256_DIGEST_LENGTH];
+  SHA256(reinterpret_cast<const uint8_t*>(serialized.data()),
+         serialized.length(), digest);
+  output.assign(reinterpret_cast<const char*>(digest), sizeof(digest));
+  return output;
+}
+
+// static
+bool CryptoUtils::GetSSLCapabilities(const SSL* ssl,
+                                     bssl::UniquePtr<uint8_t>* capabilities,
+                                     size_t* capabilities_len) {
+  uint8_t* buffer;
+  CBB cbb;
+
+  if (!CBB_init(&cbb, 128) || !SSL_serialize_capabilities(ssl, &cbb) ||
+      !CBB_finish(&cbb, &buffer, capabilities_len)) {
+    return false;
+  }
+
+  *capabilities = bssl::UniquePtr<uint8_t>(buffer);
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_utils.h b/quiche/quic/core/crypto/crypto_utils.h
new file mode 100644
index 0000000..1f618d9
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_utils.h
@@ -0,0 +1,255 @@
+// Copyright (c) 2013 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.
+
+// Some helpers for quic crypto
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/quic_crypter.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicRandom;
+
+class QUIC_EXPORT_PRIVATE CryptoUtils {
+ public:
+  CryptoUtils() = delete;
+
+  // Diversification is a utility class that's used to act like a union type.
+  // Values can be created by calling the functions like |NoDiversification|,
+  // below.
+  class QUIC_EXPORT_PRIVATE Diversification {
+   public:
+    enum Mode {
+      NEVER,  // Key diversification will never be used. Forward secure
+              // crypters will always use this mode.
+
+      PENDING,  // Key diversification will happen when a nonce is later
+                // received. This should only be used by clients initial
+                // decrypters which are waiting on the divesification nonce
+                // from the server.
+
+      NOW,  // Key diversification will happen immediate based on the nonce.
+            // This should only be used by servers initial encrypters.
+    };
+
+    Diversification(const Diversification& diversification) = default;
+
+    static Diversification Never() { return Diversification(NEVER, nullptr); }
+    static Diversification Pending() {
+      return Diversification(PENDING, nullptr);
+    }
+    static Diversification Now(DiversificationNonce* nonce) {
+      return Diversification(NOW, nonce);
+    }
+
+    Mode mode() const { return mode_; }
+    DiversificationNonce* nonce() const {
+      QUICHE_DCHECK_EQ(mode_, NOW);
+      return nonce_;
+    }
+
+   private:
+    Diversification(Mode mode, DiversificationNonce* nonce)
+        : mode_(mode), nonce_(nonce) {}
+
+    Mode mode_;
+    DiversificationNonce* nonce_;
+  };
+
+  // InitializeCrypterSecrets derives the key and IV and header protection key
+  // from the given packet protection secret |pp_secret| and sets those fields
+  // on the given QuicCrypter |*crypter|.
+  // This follows the derivation described in section 7.3 of RFC 8446, except
+  // with the label prefix in HKDF-Expand-Label changed from "tls13 " to "quic "
+  // as described in draft-ietf-quic-tls-14, section 5.1, or "quicv2 " as
+  // described in draft-ietf-quic-v2-01.
+  static void InitializeCrypterSecrets(const EVP_MD* prf,
+                                       const std::vector<uint8_t>& pp_secret,
+                                       const ParsedQuicVersion& version,
+                                       QuicCrypter* crypter);
+
+  // Derives the key and IV from the packet protection secret and sets those
+  // fields on the given QuicCrypter |*crypter|, but does not set the header
+  // protection key. GenerateHeaderProtectionKey/SetHeaderProtectionKey must be
+  // called before using |crypter|.
+  static void SetKeyAndIV(const EVP_MD* prf,
+                          const std::vector<uint8_t>& pp_secret,
+                          const ParsedQuicVersion& version,
+                          QuicCrypter* crypter);
+
+  // Derives the header protection key from the packet protection secret.
+  static std::vector<uint8_t> GenerateHeaderProtectionKey(
+      const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+      const ParsedQuicVersion& version, size_t out_len);
+
+  // Given a secret for key phase n, return the secret for phase n+1.
+  static std::vector<uint8_t> GenerateNextKeyPhaseSecret(
+      const EVP_MD* prf, const ParsedQuicVersion& version,
+      const std::vector<uint8_t>& current_secret);
+
+  // IETF QUIC encrypts ENCRYPTION_INITIAL messages with a version-specific key
+  // (to prevent network observers that are not aware of that QUIC version from
+  // making decisions based on the TLS handshake). This packet protection secret
+  // is derived from the connection ID in the client's Initial packet.
+  //
+  // This function takes that |connection_id| and creates the encrypter and
+  // decrypter (put in |*crypters|) to use for this packet protection, as well
+  // as setting the key and IV on those crypters. For older versions of QUIC
+  // that do not use the new IETF style ENCRYPTION_INITIAL obfuscators, this
+  // function puts a NullEncrypter and NullDecrypter in |*crypters|.
+  static void CreateInitialObfuscators(Perspective perspective,
+                                       ParsedQuicVersion version,
+                                       QuicConnectionId connection_id,
+                                       CrypterPair* crypters);
+
+  // IETF QUIC Retry packets carry a retry integrity tag to detect packet
+  // corruption and make it harder for an attacker to spoof. This function
+  // checks whether a given retry packet is valid.
+  static bool ValidateRetryIntegrityTag(ParsedQuicVersion version,
+                                        QuicConnectionId original_connection_id,
+                                        absl::string_view retry_without_tag,
+                                        absl::string_view integrity_tag);
+
+  // Generates the connection nonce. The nonce is formed as:
+  //   <4 bytes> current time
+  //   <8 bytes> |orbit| (or random if |orbit| is empty)
+  //   <20 bytes> random
+  static void GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
+                            absl::string_view orbit, std::string* nonce);
+
+  // DeriveKeys populates |crypters->encrypter|, |crypters->decrypter|, and
+  // |subkey_secret| (optional -- may be null) given the contents of
+  // |premaster_secret|, |client_nonce|, |server_nonce| and |hkdf_input|. |aead|
+  // determines which cipher will be used. |perspective| controls whether the
+  // server's keys are assigned to |encrypter| or |decrypter|. |server_nonce| is
+  // optional and, if non-empty, is mixed into the key derivation.
+  // |subkey_secret| will have the same length as |premaster_secret|.
+  //
+  // If |pre_shared_key| is non-empty, it is incorporated into the key
+  // derivation parameters.  If it is empty, the key derivation is unaltered.
+  //
+  // If the mode of |diversification| is NEVER, the the crypters will be
+  // configured to never perform key diversification. If the mode is
+  // NOW (which is only for servers, then the encrypter will be keyed via a
+  // two-step process that uses the nonce from |diversification|.
+  // If the mode is PENDING (which is only for servres), then the
+  // decrypter will only be keyed to a preliminary state: a call to
+  // |SetDiversificationNonce| with a diversification nonce will be needed to
+  // complete keying.
+  static bool DeriveKeys(const ParsedQuicVersion& version,
+                         absl::string_view premaster_secret, QuicTag aead,
+                         absl::string_view client_nonce,
+                         absl::string_view server_nonce,
+                         absl::string_view pre_shared_key,
+                         const std::string& hkdf_input, Perspective perspective,
+                         Diversification diversification, CrypterPair* crypters,
+                         std::string* subkey_secret);
+
+  // Computes the FNV-1a hash of the provided DER-encoded cert for use in the
+  // XLCT tag.
+  static uint64_t ComputeLeafCertHash(absl::string_view cert);
+
+  // Validates that |server_hello| is actually an SHLO message and that it is
+  // not part of a downgrade attack.
+  //
+  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+  // code and sets |error_details|.
+  static QuicErrorCode ValidateServerHello(
+      const CryptoHandshakeMessage& server_hello,
+      const ParsedQuicVersionVector& negotiated_versions,
+      std::string* error_details);
+
+  // Validates that the |server_versions| received do not indicate that the
+  // ServerHello is part of a downgrade attack. |negotiated_versions| must
+  // contain the list of versions received in the server's version negotiation
+  // packet (or be empty if no such packet was received).
+  //
+  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+  // code and sets |error_details|.
+  static QuicErrorCode ValidateServerHelloVersions(
+      const QuicVersionLabelVector& server_versions,
+      const ParsedQuicVersionVector& negotiated_versions,
+      std::string* error_details);
+
+  // Validates that |client_hello| is actually a CHLO and that this is not part
+  // of a downgrade attack.
+  // This includes verifiying versions and detecting downgrade attacks.
+  //
+  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+  // code and sets |error_details|.
+  static QuicErrorCode ValidateClientHello(
+      const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
+      const ParsedQuicVersionVector& supported_versions,
+      std::string* error_details);
+
+  // Validates that the |client_version| received does not indicate that a
+  // downgrade attack has occurred. |connection_version| is the version of the
+  // QuicConnection, and |supported_versions| is all versions that that
+  // QuicConnection supports.
+  //
+  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+  // code and sets |error_details|.
+  static QuicErrorCode ValidateClientHelloVersion(
+      QuicVersionLabel client_version, ParsedQuicVersion connection_version,
+      const ParsedQuicVersionVector& supported_versions,
+      std::string* error_details);
+
+  // Validates that the chosen version from the version_information matches the
+  // version from the session. Returns true if they match, otherwise returns
+  // false and fills in |error_details|.
+  static bool ValidateChosenVersion(
+      const QuicVersionLabel& version_information_chosen_version,
+      const ParsedQuicVersion& session_version, std::string* error_details);
+
+  // Validates that there was no downgrade attack involving a version
+  // negotiation packet. This verifies that if the client was initially
+  // configured with |client_original_supported_versions| and it had received a
+  // version negotiation packet with |version_information_other_versions|, then
+  // it would have selected |session_version|. Returns true if they match (or if
+  // |client_original_supported_versions| is empty indicating no version
+  // negotiation packet was received), otherwise returns
+  // false and fills in |error_details|.
+  static bool ValidateServerVersions(
+      const QuicVersionLabelVector& version_information_other_versions,
+      const ParsedQuicVersion& session_version,
+      const ParsedQuicVersionVector& client_original_supported_versions,
+      std::string* error_details);
+
+  // Returns the name of the HandshakeFailureReason as a char*
+  static const char* HandshakeFailureReasonToString(
+      HandshakeFailureReason reason);
+
+  // Returns the name of an ssl_early_data_reason_t as a char*
+  static std::string EarlyDataReasonToString(ssl_early_data_reason_t reason);
+
+  // Returns a hash of the serialized |message|.
+  static std::string HashHandshakeMessage(const CryptoHandshakeMessage& message,
+                                          Perspective perspective);
+
+  // Wraps SSL_serialize_capabilities. Return nullptr if failed.
+  static bool GetSSLCapabilities(const SSL* ssl,
+                                 bssl::UniquePtr<uint8_t>* capabilities,
+                                 size_t* capabilities_len);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
diff --git a/quiche/quic/core/crypto/crypto_utils_test.cc b/quiche/quic/core/crypto/crypto_utils_test.cc
new file mode 100644
index 0000000..6452367
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_utils_test.cc
@@ -0,0 +1,262 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/crypto_utils.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class CryptoUtilsTest : public QuicTest {};
+
+TEST_F(CryptoUtilsTest, HandshakeFailureReasonToString) {
+  EXPECT_STREQ("HANDSHAKE_OK",
+               CryptoUtils::HandshakeFailureReasonToString(HANDSHAKE_OK));
+  EXPECT_STREQ("CLIENT_NONCE_UNKNOWN_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_UNKNOWN_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_INVALID_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_INVALID_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_NOT_UNIQUE_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_NOT_UNIQUE_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_INVALID_ORBIT_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_INVALID_ORBIT_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_INVALID_TIME_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_INVALID_TIME_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT));
+  EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_STRIKE_REGISTER_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_DECRYPTION_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_DECRYPTION_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_INVALID_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_INVALID_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_NOT_UNIQUE_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_NOT_UNIQUE_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_INVALID_TIME_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_INVALID_TIME_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_REQUIRED_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_REQUIRED_FAILURE));
+  EXPECT_STREQ("SERVER_CONFIG_INCHOATE_HELLO_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_CONFIG_INCHOATE_HELLO_FAILURE));
+  EXPECT_STREQ("SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_INVALID_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_INVALID_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_PARSE_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_PARSE_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE));
+  EXPECT_STREQ("INVALID_EXPECTED_LEAF_CERTIFICATE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   INVALID_EXPECTED_LEAF_CERTIFICATE));
+  EXPECT_STREQ("MAX_FAILURE_REASON",
+               CryptoUtils::HandshakeFailureReasonToString(MAX_FAILURE_REASON));
+  EXPECT_STREQ(
+      "INVALID_HANDSHAKE_FAILURE_REASON",
+      CryptoUtils::HandshakeFailureReasonToString(
+          static_cast<HandshakeFailureReason>(MAX_FAILURE_REASON + 1)));
+}
+
+TEST_F(CryptoUtilsTest, AuthTagLengths) {
+  for (const auto& version : AllSupportedVersions()) {
+    for (QuicTag algo : {kAESG, kCC20}) {
+      SCOPED_TRACE(version);
+      std::unique_ptr<QuicEncrypter> encrypter(
+          QuicEncrypter::Create(version, algo));
+      size_t auth_tag_size = 12;
+      if (version.UsesInitialObfuscators()) {
+        auth_tag_size = 16;
+      }
+      EXPECT_EQ(encrypter->GetCiphertextSize(0), auth_tag_size);
+    }
+  }
+}
+
+TEST_F(CryptoUtilsTest, ValidateChosenVersion) {
+  for (const ParsedQuicVersion& v1 : AllSupportedVersions()) {
+    for (const ParsedQuicVersion& v2 : AllSupportedVersions()) {
+      std::string error_details;
+      bool success = CryptoUtils::ValidateChosenVersion(
+          CreateQuicVersionLabel(v1), v2, &error_details);
+      EXPECT_EQ(success, v1 == v2);
+      EXPECT_EQ(success, error_details.empty());
+    }
+  }
+}
+
+TEST_F(CryptoUtilsTest, ValidateServerVersionsNoVersionNegotiation) {
+  QuicVersionLabelVector version_information_other_versions;
+  ParsedQuicVersionVector client_original_supported_versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    std::string error_details;
+    EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
+        version_information_other_versions, version,
+        client_original_supported_versions, &error_details));
+    EXPECT_TRUE(error_details.empty());
+  }
+}
+
+TEST_F(CryptoUtilsTest, ValidateServerVersionsWithVersionNegotiation) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicVersionLabelVector version_information_other_versions{
+        CreateQuicVersionLabel(version)};
+    ParsedQuicVersionVector client_original_supported_versions{
+        ParsedQuicVersion::ReservedForNegotiation(), version};
+    std::string error_details;
+    EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
+        version_information_other_versions, version,
+        client_original_supported_versions, &error_details));
+    EXPECT_TRUE(error_details.empty());
+  }
+}
+
+TEST_F(CryptoUtilsTest, ValidateServerVersionsWithDowngrade) {
+  if (AllSupportedVersions().size() <= 1) {
+    // We are not vulnerable to downgrade if we only support one version.
+    return;
+  }
+  ParsedQuicVersion client_version = AllSupportedVersions().front();
+  ParsedQuicVersion server_version = AllSupportedVersions().back();
+  ASSERT_NE(client_version, server_version);
+  QuicVersionLabelVector version_information_other_versions{
+      CreateQuicVersionLabel(client_version)};
+  ParsedQuicVersionVector client_original_supported_versions{
+      ParsedQuicVersion::ReservedForNegotiation(), server_version};
+  std::string error_details;
+  EXPECT_FALSE(CryptoUtils::ValidateServerVersions(
+      version_information_other_versions, server_version,
+      client_original_supported_versions, &error_details));
+  EXPECT_FALSE(error_details.empty());
+}
+
+// Test that the library is using the correct labels for each version, and
+// therefore generating correct obfuscators, using the test vectors in appendix
+// A of each RFC or internet-draft.
+TEST_F(CryptoUtilsTest, ValidateCryptoLabels) {
+  // if the number of HTTP/3 QUIC versions has changed, we need to change the
+  // expected_keys hardcoded into this test. Regrettably, this is not a
+  // compile-time constant.
+  EXPECT_EQ(AllSupportedVersionsWithTls().size(), 3u);
+  const char draft_29_key[] = {// test vector from draft-ietf-quic-tls-29, A.1
+                               0x14,
+                               static_cast<char>(0x9d),
+                               0x0b,
+                               0x16,
+                               0x62,
+                               static_cast<char>(0xab),
+                               static_cast<char>(0x87),
+                               0x1f,
+                               static_cast<char>(0xbe),
+                               0x63,
+                               static_cast<char>(0xc4),
+                               static_cast<char>(0x9b),
+                               0x5e,
+                               0x65,
+                               0x5a,
+                               0x5d};
+  const char v1_key[] = {// test vector from RFC 9001, A.1
+                         static_cast<char>(0xcf),
+                         0x3a,
+                         0x53,
+                         0x31,
+                         0x65,
+                         0x3c,
+                         0x36,
+                         0x4c,
+                         static_cast<char>(0x88),
+                         static_cast<char>(0xf0),
+                         static_cast<char>(0xf3),
+                         0x79,
+                         static_cast<char>(0xb6),
+                         0x06,
+                         0x7e,
+                         0x37};
+  const char v2_01_key[] = {// test vector from draft-ietf-quic-v2-01
+                            0x15,
+                            static_cast<char>(0xd5),
+                            static_cast<char>(0xb4),
+                            static_cast<char>(0xd9),
+                            static_cast<char>(0xa2),
+                            static_cast<char>(0xb8),
+                            static_cast<char>(0x91),
+                            0x6a,
+                            static_cast<char>(0xa3),
+                            static_cast<char>(0x9b),
+                            0x1b,
+                            static_cast<char>(0xfe),
+                            0x57,
+                            0x4d,
+                            0x2a,
+                            static_cast<char>(0xad)};
+  const char connection_id[] =  // test vector from both docs
+      {static_cast<char>(0x83),
+       static_cast<char>(0x94),
+       static_cast<char>(0xc8),
+       static_cast<char>(0xf0),
+       0x3e,
+       0x51,
+       0x57,
+       0x08};
+  const QuicConnectionId cid(connection_id, sizeof(connection_id));
+  const char* key_str;
+  size_t key_size;
+  for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
+    if (version == ParsedQuicVersion::Draft29()) {
+      key_str = draft_29_key;
+      key_size = sizeof(draft_29_key);
+    } else if (version == ParsedQuicVersion::RFCv1()) {
+      key_str = v1_key;
+      key_size = sizeof(v1_key);
+    } else {  // draft-ietf-quic-v2-01
+      key_str = v2_01_key;
+      key_size = sizeof(v2_01_key);
+    }
+    const absl::string_view expected_key{key_str, key_size};
+
+    CrypterPair crypters;
+    CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version, cid,
+                                          &crypters);
+    EXPECT_EQ(crypters.encrypter->GetKey(), expected_key);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/curve25519_key_exchange.cc b/quiche/quic/core/crypto/curve25519_key_exchange.cc
new file mode 100644
index 0000000..f84da2a
--- /dev/null
+++ b/quiche/quic/core/crypto/curve25519_key_exchange.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/curve25519_key_exchange.h"
+
+#include <cstdint>
+#include <cstring>
+#include <string>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/curve25519.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+Curve25519KeyExchange::Curve25519KeyExchange() {}
+
+Curve25519KeyExchange::~Curve25519KeyExchange() {}
+
+// static
+std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New(
+    QuicRandom* rand) {
+  std::unique_ptr<Curve25519KeyExchange> result =
+      New(Curve25519KeyExchange::NewPrivateKey(rand));
+  QUIC_BUG_IF(quic_bug_12891_1, result == nullptr);
+  return result;
+}
+
+// static
+std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New(
+    absl::string_view private_key) {
+  // We don't want to #include the BoringSSL headers in the public header file,
+  // so we use literals for the sizes of private_key_ and public_key_. Here we
+  // assert that those values are equal to the values from the BoringSSL
+  // header.
+  static_assert(
+      sizeof(Curve25519KeyExchange::private_key_) == X25519_PRIVATE_KEY_LEN,
+      "header out of sync");
+  static_assert(
+      sizeof(Curve25519KeyExchange::public_key_) == X25519_PUBLIC_VALUE_LEN,
+      "header out of sync");
+
+  if (private_key.size() != X25519_PRIVATE_KEY_LEN) {
+    return nullptr;
+  }
+
+  // Use absl::WrapUnique(new) instead of std::make_unique because
+  // Curve25519KeyExchange has a private constructor.
+  auto ka = absl::WrapUnique(new Curve25519KeyExchange);
+  memcpy(ka->private_key_, private_key.data(), X25519_PRIVATE_KEY_LEN);
+  X25519_public_from_private(ka->public_key_, ka->private_key_);
+  return ka;
+}
+
+// static
+std::string Curve25519KeyExchange::NewPrivateKey(QuicRandom* rand) {
+  uint8_t private_key[X25519_PRIVATE_KEY_LEN];
+  rand->RandBytes(private_key, sizeof(private_key));
+  return std::string(reinterpret_cast<char*>(private_key), sizeof(private_key));
+}
+
+bool Curve25519KeyExchange::CalculateSharedKeySync(
+    absl::string_view peer_public_value,
+    std::string* shared_key) const {
+  if (peer_public_value.size() != X25519_PUBLIC_VALUE_LEN) {
+    return false;
+  }
+
+  uint8_t result[X25519_PUBLIC_VALUE_LEN];
+  if (!X25519(result, private_key_,
+              reinterpret_cast<const uint8_t*>(peer_public_value.data()))) {
+    return false;
+  }
+
+  shared_key->assign(reinterpret_cast<char*>(result), sizeof(result));
+  return true;
+}
+
+absl::string_view Curve25519KeyExchange::public_value() const {
+  return absl::string_view(reinterpret_cast<const char*>(public_key_),
+                           sizeof(public_key_));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/curve25519_key_exchange.h b/quiche/quic/core/crypto/curve25519_key_exchange.h
new file mode 100644
index 0000000..34a49f9
--- /dev/null
+++ b/quiche/quic/core/crypto/curve25519_key_exchange.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2013 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_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicRandom;
+
+// Curve25519KeyExchange implements a SynchronousKeyExchange using
+// elliptic-curve Diffie-Hellman on curve25519. See http://cr.yp.to/ecdh.html
+class QUIC_EXPORT_PRIVATE Curve25519KeyExchange
+    : public SynchronousKeyExchange {
+ public:
+  ~Curve25519KeyExchange() override;
+
+  // New generates a private key and then creates new key-exchange object.
+  static std::unique_ptr<Curve25519KeyExchange> New(QuicRandom* rand);
+
+  // New creates a new key-exchange object from a private key. If |private_key|
+  // is invalid, nullptr is returned.
+  static std::unique_ptr<Curve25519KeyExchange> New(
+      absl::string_view private_key);
+
+  // NewPrivateKey returns a private key, generated from |rand|, suitable for
+  // passing to |New|.
+  static std::string NewPrivateKey(QuicRandom* rand);
+
+  // SynchronousKeyExchange interface.
+  bool CalculateSharedKeySync(absl::string_view peer_public_value,
+                              std::string* shared_key) const override;
+  absl::string_view public_value() const override;
+  QuicTag type() const override { return kC255; }
+
+ private:
+  Curve25519KeyExchange();
+
+  uint8_t private_key_[32];
+  uint8_t public_key_[32];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
diff --git a/quiche/quic/core/crypto/curve25519_key_exchange_test.cc b/quiche/quic/core/crypto/curve25519_key_exchange_test.cc
new file mode 100644
index 0000000..551ee0e
--- /dev/null
+++ b/quiche/quic/core/crypto/curve25519_key_exchange_test.cc
@@ -0,0 +1,104 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/curve25519_key_exchange.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class Curve25519KeyExchangeTest : public QuicTest {
+ public:
+  // Holds the result of a key exchange callback.
+  class TestCallbackResult {
+   public:
+    void set_ok(bool ok) { ok_ = ok; }
+    bool ok() { return ok_; }
+
+   private:
+    bool ok_ = false;
+  };
+
+  // Key exchange callback which sets the result into the specified
+  // TestCallbackResult.
+  class TestCallback : public AsynchronousKeyExchange::Callback {
+   public:
+    TestCallback(TestCallbackResult* result) : result_(result) {}
+    virtual ~TestCallback() = default;
+
+    void Run(bool ok) { result_->set_ok(ok); }
+
+   private:
+    TestCallbackResult* result_;
+  };
+};
+
+// SharedKey just tests that the basic key exchange identity holds: that both
+// parties end up with the same key.
+TEST_F(Curve25519KeyExchangeTest, SharedKey) {
+  QuicRandom* const rand = QuicRandom::GetInstance();
+
+  for (int i = 0; i < 5; i++) {
+    const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
+    const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
+
+    std::unique_ptr<Curve25519KeyExchange> alice(
+        Curve25519KeyExchange::New(alice_key));
+    std::unique_ptr<Curve25519KeyExchange> bob(
+        Curve25519KeyExchange::New(bob_key));
+
+    const absl::string_view alice_public(alice->public_value());
+    const absl::string_view bob_public(bob->public_value());
+
+    std::string alice_shared, bob_shared;
+    ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
+    ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
+    ASSERT_EQ(alice_shared, bob_shared);
+  }
+}
+
+// SharedKeyAsync just tests that the basic asynchronous key exchange identity
+// holds: that both parties end up with the same key.
+TEST_F(Curve25519KeyExchangeTest, SharedKeyAsync) {
+  QuicRandom* const rand = QuicRandom::GetInstance();
+
+  for (int i = 0; i < 5; i++) {
+    const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
+    const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
+
+    std::unique_ptr<Curve25519KeyExchange> alice(
+        Curve25519KeyExchange::New(alice_key));
+    std::unique_ptr<Curve25519KeyExchange> bob(
+        Curve25519KeyExchange::New(bob_key));
+
+    const absl::string_view alice_public(alice->public_value());
+    const absl::string_view bob_public(bob->public_value());
+
+    std::string alice_shared, bob_shared;
+    TestCallbackResult alice_result;
+    ASSERT_FALSE(alice_result.ok());
+    alice->CalculateSharedKeyAsync(
+        bob_public, &alice_shared,
+        std::make_unique<TestCallback>(&alice_result));
+    ASSERT_TRUE(alice_result.ok());
+    TestCallbackResult bob_result;
+    ASSERT_FALSE(bob_result.ok());
+    bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
+                                 std::make_unique<TestCallback>(&bob_result));
+    ASSERT_TRUE(bob_result.ok());
+    ASSERT_EQ(alice_shared, bob_shared);
+    ASSERT_NE(0u, alice_shared.length());
+    ASSERT_NE(0u, bob_shared.length());
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/key_exchange.cc b/quiche/quic/core/crypto/key_exchange.cc
new file mode 100644
index 0000000..4a5947b
--- /dev/null
+++ b/quiche/quic/core/crypto/key_exchange.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2019 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 "quiche/quic/core/crypto/key_exchange.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/curve25519_key_exchange.h"
+#include "quiche/quic/core/crypto/p256_key_exchange.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
+    QuicTag type,
+    absl::string_view private_key) {
+  switch (type) {
+    case kC255:
+      return Curve25519KeyExchange::New(private_key);
+    case kP256:
+      return P256KeyExchange::New(private_key);
+    default:
+      QUIC_BUG(quic_bug_10712_1)
+          << "Unknown key exchange method: " << QuicTagToString(type);
+      return nullptr;
+  }
+}
+
+std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
+    QuicTag type,
+    QuicRandom* rand) {
+  switch (type) {
+    case kC255:
+      return Curve25519KeyExchange::New(rand);
+    case kP256:
+      return P256KeyExchange::New();
+    default:
+      QUIC_BUG(quic_bug_10712_2)
+          << "Unknown key exchange method: " << QuicTagToString(type);
+      return nullptr;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/key_exchange.h b/quiche/quic/core/crypto/key_exchange.h
new file mode 100644
index 0000000..74c44ee
--- /dev/null
+++ b/quiche/quic/core/crypto/key_exchange.h
@@ -0,0 +1,105 @@
+// Copyright (c) 2013 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_CRYPTO_KEY_EXCHANGE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicRandom;
+
+// Interface for a Diffie-Hellman key exchange with an asynchronous interface.
+// This allows for implementations which hold the private key locally, as well
+// as ones which make an RPC to an external key-exchange service.
+class QUIC_EXPORT_PRIVATE AsynchronousKeyExchange {
+ public:
+  virtual ~AsynchronousKeyExchange() = default;
+
+  // Callback base class for receiving the results of an async call to
+  // CalculateSharedKeys.
+  class QUIC_EXPORT_PRIVATE Callback {
+   public:
+    Callback() = default;
+    virtual ~Callback() = default;
+
+    // Invoked upon completion of CalculateSharedKeysAsync.
+    //
+    // |ok| indicates whether the operation completed successfully.  If false,
+    // then the value pointed to by |shared_key| passed in to
+    // CalculateSharedKeyAsync is undefined.
+    virtual void Run(bool ok) = 0;
+
+   private:
+    Callback(const Callback&) = delete;
+    Callback& operator=(const Callback&) = delete;
+  };
+
+  // CalculateSharedKey computes the shared key between a private key which is
+  // conceptually owned by this object (though it may not be physically located
+  // in this process) and a public value from the peer.  Callers should expect
+  // that |callback| might be invoked synchronously.  Results will be written
+  // into |*shared_key|.
+  virtual void CalculateSharedKeyAsync(
+      absl::string_view peer_public_value,
+      std::string* shared_key,
+      std::unique_ptr<Callback> callback) const = 0;
+
+  // Tag indicating the key-exchange algorithm this object will use.
+  virtual QuicTag type() const = 0;
+};
+
+// Interface for a Diffie-Hellman key exchange with both synchronous and
+// asynchronous interfaces.  Only implementations which hold the private key
+// locally should implement this interface.
+class QUIC_EXPORT_PRIVATE SynchronousKeyExchange
+    : public AsynchronousKeyExchange {
+ public:
+  virtual ~SynchronousKeyExchange() = default;
+
+  // AyncKeyExchange API.  Note that this method is marked 'final.'  Subclasses
+  // should implement CalculateSharedKeySync only.
+  void CalculateSharedKeyAsync(absl::string_view peer_public_value,
+                               std::string* shared_key,
+                               std::unique_ptr<Callback> callback) const final {
+    const bool ok = CalculateSharedKeySync(peer_public_value, shared_key);
+    callback->Run(ok);
+  }
+
+  // CalculateSharedKey computes the shared key between a local private key and
+  // a public value from the peer.  Results will be written into |*shared_key|.
+  virtual bool CalculateSharedKeySync(absl::string_view peer_public_value,
+                                      std::string* shared_key) const = 0;
+
+  // public_value returns the local public key which can be sent to a peer in
+  // order to complete a key exchange. The returned absl::string_view is
+  // a reference to a member of this object and is only valid for as long as it
+  // exists.
+  virtual absl::string_view public_value() const = 0;
+};
+
+// Create a SynchronousKeyExchange object which will use a keypair generated
+// from |private_key|, and a key-exchange algorithm specified by |type|, which
+// must be one of {kC255, kC256}.  Returns nullptr if |private_key| or |type| is
+// invalid.
+std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
+    QuicTag type,
+    absl::string_view private_key);
+
+// Create a SynchronousKeyExchange object which will use a keypair generated
+// from |rand|, and a key-exchange algorithm specified by |type|, which must be
+// one of {kC255, kC256}.  Returns nullptr if |type| is invalid.
+std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
+    QuicTag type,
+    QuicRandom* rand);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
diff --git a/quiche/quic/core/crypto/null_decrypter.cc b/quiche/quic/core/crypto/null_decrypter.cc
new file mode 100644
index 0000000..5287ce9
--- /dev/null
+++ b/quiche/quic/core/crypto/null_decrypter.cc
@@ -0,0 +1,136 @@
+// 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 "quiche/quic/core/crypto/null_decrypter.h"
+
+#include <cstdint>
+
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+NullDecrypter::NullDecrypter(Perspective perspective)
+    : perspective_(perspective) {}
+
+bool NullDecrypter::SetKey(absl::string_view key) {
+  return key.empty();
+}
+
+bool NullDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
+  return nonce_prefix.empty();
+}
+
+bool NullDecrypter::SetIV(absl::string_view iv) {
+  return iv.empty();
+}
+
+bool NullDecrypter::SetHeaderProtectionKey(absl::string_view key) {
+  return key.empty();
+}
+
+bool NullDecrypter::SetPreliminaryKey(absl::string_view /*key*/) {
+  QUIC_BUG(quic_bug_10652_1) << "Should not be called";
+  return false;
+}
+
+bool NullDecrypter::SetDiversificationNonce(
+    const DiversificationNonce& /*nonce*/) {
+  QUIC_BUG(quic_bug_10652_2) << "Should not be called";
+  return true;
+}
+
+bool NullDecrypter::DecryptPacket(uint64_t /*packet_number*/,
+                                  absl::string_view associated_data,
+                                  absl::string_view ciphertext,
+                                  char* output,
+                                  size_t* output_length,
+                                  size_t max_output_length) {
+  QuicDataReader reader(ciphertext.data(), ciphertext.length(),
+                        quiche::HOST_BYTE_ORDER);
+  absl::uint128 hash;
+
+  if (!ReadHash(&reader, &hash)) {
+    return false;
+  }
+
+  absl::string_view plaintext = reader.ReadRemainingPayload();
+  if (plaintext.length() > max_output_length) {
+    QUIC_BUG(quic_bug_10652_3)
+        << "Output buffer must be larger than the plaintext.";
+    return false;
+  }
+  if (hash != ComputeHash(associated_data, plaintext)) {
+    return false;
+  }
+  // Copy the plaintext to output.
+  memcpy(output, plaintext.data(), plaintext.length());
+  *output_length = plaintext.length();
+  return true;
+}
+
+std::string NullDecrypter::GenerateHeaderProtectionMask(
+    QuicDataReader* /*sample_reader*/) {
+  return std::string(5, 0);
+}
+
+size_t NullDecrypter::GetKeySize() const {
+  return 0;
+}
+
+size_t NullDecrypter::GetNoncePrefixSize() const {
+  return 0;
+}
+
+size_t NullDecrypter::GetIVSize() const {
+  return 0;
+}
+
+absl::string_view NullDecrypter::GetKey() const {
+  return absl::string_view();
+}
+
+absl::string_view NullDecrypter::GetNoncePrefix() const {
+  return absl::string_view();
+}
+
+uint32_t NullDecrypter::cipher_id() const {
+  return 0;
+}
+
+QuicPacketCount NullDecrypter::GetIntegrityLimit() const {
+  return std::numeric_limits<QuicPacketCount>::max();
+}
+
+bool NullDecrypter::ReadHash(QuicDataReader* reader, absl::uint128* hash) {
+  uint64_t lo;
+  uint32_t hi;
+  if (!reader->ReadUInt64(&lo) || !reader->ReadUInt32(&hi)) {
+    return false;
+  }
+  *hash = absl::MakeUint128(hi, lo);
+  return true;
+}
+
+absl::uint128 NullDecrypter::ComputeHash(const absl::string_view data1,
+                                         const absl::string_view data2) const {
+  absl::uint128 correct_hash;
+  if (perspective_ == Perspective::IS_CLIENT) {
+    // Peer is a server.
+    correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Server");
+  } else {
+    // Peer is a client.
+    correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Client");
+  }
+  absl::uint128 mask = absl::MakeUint128(UINT64_C(0x0), UINT64_C(0xffffffff));
+  mask <<= 96;
+  correct_hash &= ~mask;
+  return correct_hash;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/null_decrypter.h b/quiche/quic/core/crypto/null_decrypter.h
new file mode 100644
index 0000000..05e1103
--- /dev/null
+++ b/quiche/quic/core/crypto/null_decrypter.h
@@ -0,0 +1,65 @@
+// 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_CRYPTO_NULL_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicDataReader;
+
+// A NullDecrypter is a QuicDecrypter used before a crypto negotiation
+// has occurred.  It does not actually decrypt the payload, but does
+// verify a hash (fnv128) over both the payload and associated data.
+class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
+ public:
+  explicit NullDecrypter(Perspective perspective);
+  NullDecrypter(const NullDecrypter&) = delete;
+  NullDecrypter& operator=(const NullDecrypter&) = delete;
+  ~NullDecrypter() override {}
+
+  // QuicDecrypter implementation
+  bool SetKey(absl::string_view key) override;
+  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
+  bool SetIV(absl::string_view iv) override;
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  bool SetPreliminaryKey(absl::string_view key) override;
+  bool SetDiversificationNonce(const DiversificationNonce& nonce) override;
+  bool DecryptPacket(uint64_t packet_number,
+                     absl::string_view associated_data,
+                     absl::string_view ciphertext,
+                     char* output,
+                     size_t* output_length,
+                     size_t max_output_length) override;
+  std::string GenerateHeaderProtectionMask(
+      QuicDataReader* sample_reader) override;
+  size_t GetKeySize() const override;
+  size_t GetNoncePrefixSize() const override;
+  size_t GetIVSize() const override;
+  absl::string_view GetKey() const override;
+  absl::string_view GetNoncePrefix() const override;
+
+  uint32_t cipher_id() const override;
+  QuicPacketCount GetIntegrityLimit() const override;
+
+ private:
+  bool ReadHash(QuicDataReader* reader, absl::uint128* hash);
+  absl::uint128 ComputeHash(absl::string_view data1,
+                            absl::string_view data2) const;
+
+  Perspective perspective_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/null_decrypter_test.cc b/quiche/quic/core/crypto/null_decrypter_test.cc
new file mode 100644
index 0000000..ad06bea
--- /dev/null
+++ b/quiche/quic/core/crypto/null_decrypter_test.cc
@@ -0,0 +1,136 @@
+// 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 "quiche/quic/core/crypto/null_decrypter.h"
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class NullDecrypterTest : public QuicTestWithParam<bool> {};
+
+TEST_F(NullDecrypterTest, DecryptClient) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x97,
+      0xdc,
+      0x27,
+      0x2f,
+      0x18,
+      0xa8,
+      0x56,
+      0x73,
+      0xdf,
+      0x8d,
+      0x1d,
+      0xd0,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  const char* data = reinterpret_cast<const char*>(expected);
+  size_t len = ABSL_ARRAYSIZE(expected);
+  NullDecrypter decrypter(Perspective::IS_SERVER);
+  char buffer[256];
+  size_t length = 0;
+  ASSERT_TRUE(decrypter.DecryptPacket(
+      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
+  EXPECT_LT(0u, length);
+  EXPECT_EQ("goodbye!", absl::string_view(buffer, length));
+}
+
+TEST_F(NullDecrypterTest, DecryptServer) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x63,
+      0x5e,
+      0x08,
+      0x03,
+      0x32,
+      0x80,
+      0x8f,
+      0x73,
+      0xdf,
+      0x8d,
+      0x1d,
+      0x1a,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  const char* data = reinterpret_cast<const char*>(expected);
+  size_t len = ABSL_ARRAYSIZE(expected);
+  NullDecrypter decrypter(Perspective::IS_CLIENT);
+  char buffer[256];
+  size_t length = 0;
+  ASSERT_TRUE(decrypter.DecryptPacket(
+      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
+  EXPECT_LT(0u, length);
+  EXPECT_EQ("goodbye!", absl::string_view(buffer, length));
+}
+
+TEST_F(NullDecrypterTest, BadHash) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x46,
+      0x11,
+      0xea,
+      0x5f,
+      0xcf,
+      0x1d,
+      0x66,
+      0x5b,
+      0xba,
+      0xf0,
+      0xbc,
+      0xfd,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  const char* data = reinterpret_cast<const char*>(expected);
+  size_t len = ABSL_ARRAYSIZE(expected);
+  NullDecrypter decrypter(Perspective::IS_CLIENT);
+  char buffer[256];
+  size_t length = 0;
+  ASSERT_FALSE(decrypter.DecryptPacket(
+      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
+}
+
+TEST_F(NullDecrypterTest, ShortInput) {
+  unsigned char expected[] = {
+      // fnv hash (truncated)
+      0x46, 0x11, 0xea, 0x5f, 0xcf, 0x1d, 0x66, 0x5b, 0xba, 0xf0, 0xbc,
+  };
+  const char* data = reinterpret_cast<const char*>(expected);
+  size_t len = ABSL_ARRAYSIZE(expected);
+  NullDecrypter decrypter(Perspective::IS_CLIENT);
+  char buffer[256];
+  size_t length = 0;
+  ASSERT_FALSE(decrypter.DecryptPacket(
+      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/null_encrypter.cc b/quiche/quic/core/crypto/null_encrypter.cc
new file mode 100644
index 0000000..8df815b
--- /dev/null
+++ b/quiche/quic/core/crypto/null_encrypter.cc
@@ -0,0 +1,103 @@
+// 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 "quiche/quic/core/crypto/null_encrypter.h"
+
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+
+const size_t kHashSizeShort = 12;  // size of uint128 serialized short
+
+NullEncrypter::NullEncrypter(Perspective perspective)
+    : perspective_(perspective) {}
+
+bool NullEncrypter::SetKey(absl::string_view key) {
+  return key.empty();
+}
+
+bool NullEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
+  return nonce_prefix.empty();
+}
+
+bool NullEncrypter::SetIV(absl::string_view iv) {
+  return iv.empty();
+}
+
+bool NullEncrypter::SetHeaderProtectionKey(absl::string_view key) {
+  return key.empty();
+}
+
+bool NullEncrypter::EncryptPacket(uint64_t /*packet_number*/,
+                                  absl::string_view associated_data,
+                                  absl::string_view plaintext,
+                                  char* output,
+                                  size_t* output_length,
+                                  size_t max_output_length) {
+  const size_t len = plaintext.size() + GetHashLength();
+  if (max_output_length < len) {
+    return false;
+  }
+  absl::uint128 hash;
+  if (perspective_ == Perspective::IS_SERVER) {
+    hash =
+        QuicUtils::FNV1a_128_Hash_Three(associated_data, plaintext, "Server");
+  } else {
+    hash =
+        QuicUtils::FNV1a_128_Hash_Three(associated_data, plaintext, "Client");
+  }
+  // TODO(ianswett): memmove required for in place encryption.  Placing the
+  // hash at the end would allow use of memcpy, doing nothing for in place.
+  memmove(output + GetHashLength(), plaintext.data(), plaintext.length());
+  QuicUtils::SerializeUint128Short(hash,
+                                   reinterpret_cast<unsigned char*>(output));
+  *output_length = len;
+  return true;
+}
+
+std::string NullEncrypter::GenerateHeaderProtectionMask(
+    absl::string_view /*sample*/) {
+  return std::string(5, 0);
+}
+
+size_t NullEncrypter::GetKeySize() const {
+  return 0;
+}
+
+size_t NullEncrypter::GetNoncePrefixSize() const {
+  return 0;
+}
+
+size_t NullEncrypter::GetIVSize() const {
+  return 0;
+}
+
+size_t NullEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
+  return ciphertext_size - std::min(ciphertext_size, GetHashLength());
+}
+
+size_t NullEncrypter::GetCiphertextSize(size_t plaintext_size) const {
+  return plaintext_size + GetHashLength();
+}
+
+QuicPacketCount NullEncrypter::GetConfidentialityLimit() const {
+  return std::numeric_limits<QuicPacketCount>::max();
+}
+
+absl::string_view NullEncrypter::GetKey() const {
+  return absl::string_view();
+}
+
+absl::string_view NullEncrypter::GetNoncePrefix() const {
+  return absl::string_view();
+}
+
+size_t NullEncrypter::GetHashLength() const {
+  return kHashSizeShort;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/null_encrypter.h b/quiche/quic/core/crypto/null_encrypter.h
new file mode 100644
index 0000000..cdcf66c
--- /dev/null
+++ b/quiche/quic/core/crypto/null_encrypter.h
@@ -0,0 +1,56 @@
+// 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_CRYPTO_NULL_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A NullEncrypter is a QuicEncrypter used before a crypto negotiation
+// has occurred.  It does not actually encrypt the payload, but does
+// generate a MAC (fnv128) over both the payload and associated data.
+class QUIC_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
+ public:
+  explicit NullEncrypter(Perspective perspective);
+  NullEncrypter(const NullEncrypter&) = delete;
+  NullEncrypter& operator=(const NullEncrypter&) = delete;
+  ~NullEncrypter() override {}
+
+  // QuicEncrypter implementation
+  bool SetKey(absl::string_view key) override;
+  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
+  bool SetIV(absl::string_view iv) override;
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  bool EncryptPacket(uint64_t packet_number,
+                     absl::string_view associated_data,
+                     absl::string_view plaintext,
+                     char* output,
+                     size_t* output_length,
+                     size_t max_output_length) override;
+  std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
+  size_t GetKeySize() const override;
+  size_t GetNoncePrefixSize() const override;
+  size_t GetIVSize() const override;
+  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
+  size_t GetCiphertextSize(size_t plaintext_size) const override;
+  QuicPacketCount GetConfidentialityLimit() const override;
+  absl::string_view GetKey() const override;
+  absl::string_view GetNoncePrefix() const override;
+
+ private:
+  size_t GetHashLength() const;
+
+  Perspective perspective_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/null_encrypter_test.cc b/quiche/quic/core/crypto/null_encrypter_test.cc
new file mode 100644
index 0000000..26a143e
--- /dev/null
+++ b/quiche/quic/core/crypto/null_encrypter_test.cc
@@ -0,0 +1,102 @@
+// 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 "quiche/quic/core/crypto/null_encrypter.h"
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class NullEncrypterTest : public QuicTestWithParam<bool> {};
+
+TEST_F(NullEncrypterTest, EncryptClient) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x97,
+      0xdc,
+      0x27,
+      0x2f,
+      0x18,
+      0xa8,
+      0x56,
+      0x73,
+      0xdf,
+      0x8d,
+      0x1d,
+      0xd0,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  char encrypted[256];
+  size_t encrypted_len = 0;
+  NullEncrypter encrypter(Perspective::IS_CLIENT);
+  ASSERT_TRUE(encrypter.EncryptPacket(0, "hello world!", "goodbye!", encrypted,
+                                      &encrypted_len, 256));
+  quiche::test::CompareCharArraysWithHexError(
+      "encrypted data", encrypted, encrypted_len,
+      reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected));
+}
+
+TEST_F(NullEncrypterTest, EncryptServer) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x63,
+      0x5e,
+      0x08,
+      0x03,
+      0x32,
+      0x80,
+      0x8f,
+      0x73,
+      0xdf,
+      0x8d,
+      0x1d,
+      0x1a,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  char encrypted[256];
+  size_t encrypted_len = 0;
+  NullEncrypter encrypter(Perspective::IS_SERVER);
+  ASSERT_TRUE(encrypter.EncryptPacket(0, "hello world!", "goodbye!", encrypted,
+                                      &encrypted_len, 256));
+  quiche::test::CompareCharArraysWithHexError(
+      "encrypted data", encrypted, encrypted_len,
+      reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected));
+}
+
+TEST_F(NullEncrypterTest, GetMaxPlaintextSize) {
+  NullEncrypter encrypter(Perspective::IS_CLIENT);
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
+  EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11));
+}
+
+TEST_F(NullEncrypterTest, GetCiphertextSize) {
+  NullEncrypter encrypter(Perspective::IS_CLIENT);
+  EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/p256_key_exchange.cc b/quiche/quic/core/crypto/p256_key_exchange.cc
new file mode 100644
index 0000000..3cff503
--- /dev/null
+++ b/quiche/quic/core/crypto/p256_key_exchange.cc
@@ -0,0 +1,122 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/p256_key_exchange.h"
+
+#include <cstdint>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/ecdh.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+P256KeyExchange::P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key,
+                                 const uint8_t* public_key)
+    : private_key_(std::move(private_key)) {
+  memcpy(public_key_, public_key, sizeof(public_key_));
+}
+
+P256KeyExchange::~P256KeyExchange() {}
+
+// static
+std::unique_ptr<P256KeyExchange> P256KeyExchange::New() {
+  return New(P256KeyExchange::NewPrivateKey());
+}
+
+// static
+std::unique_ptr<P256KeyExchange> P256KeyExchange::New(absl::string_view key) {
+  if (key.empty()) {
+    QUIC_DLOG(INFO) << "Private key is empty";
+    return nullptr;
+  }
+
+  const uint8_t* keyp = reinterpret_cast<const uint8_t*>(key.data());
+  bssl::UniquePtr<EC_KEY> private_key(
+      d2i_ECPrivateKey(nullptr, &keyp, key.size()));
+  if (!private_key.get() || !EC_KEY_check_key(private_key.get())) {
+    QUIC_DLOG(INFO) << "Private key is invalid.";
+    return nullptr;
+  }
+
+  uint8_t public_key[kUncompressedP256PointBytes];
+  if (EC_POINT_point2oct(EC_KEY_get0_group(private_key.get()),
+                         EC_KEY_get0_public_key(private_key.get()),
+                         POINT_CONVERSION_UNCOMPRESSED, public_key,
+                         sizeof(public_key), nullptr) != sizeof(public_key)) {
+    QUIC_DLOG(INFO) << "Can't get public key.";
+    return nullptr;
+  }
+
+  return absl::WrapUnique(
+      new P256KeyExchange(std::move(private_key), public_key));
+}
+
+// static
+std::string P256KeyExchange::NewPrivateKey() {
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+  if (!key.get() || !EC_KEY_generate_key(key.get())) {
+    QUIC_DLOG(INFO) << "Can't generate a new private key.";
+    return std::string();
+  }
+
+  int key_len = i2d_ECPrivateKey(key.get(), nullptr);
+  if (key_len <= 0) {
+    QUIC_DLOG(INFO) << "Can't convert private key to string";
+    return std::string();
+  }
+  std::unique_ptr<uint8_t[]> private_key(new uint8_t[key_len]);
+  uint8_t* keyp = private_key.get();
+  if (!i2d_ECPrivateKey(key.get(), &keyp)) {
+    QUIC_DLOG(INFO) << "Can't convert private key to string.";
+    return std::string();
+  }
+  return std::string(reinterpret_cast<char*>(private_key.get()), key_len);
+}
+
+bool P256KeyExchange::CalculateSharedKeySync(
+    absl::string_view peer_public_value,
+    std::string* shared_key) const {
+  if (peer_public_value.size() != kUncompressedP256PointBytes) {
+    QUIC_DLOG(INFO) << "Peer public value is invalid";
+    return false;
+  }
+
+  bssl::UniquePtr<EC_POINT> point(
+      EC_POINT_new(EC_KEY_get0_group(private_key_.get())));
+  if (!point.get() ||
+      !EC_POINT_oct2point(/* also test if point is on curve */
+                          EC_KEY_get0_group(private_key_.get()), point.get(),
+                          reinterpret_cast<const uint8_t*>(
+                              peer_public_value.data()),
+                          peer_public_value.size(), nullptr)) {
+    QUIC_DLOG(INFO) << "Can't convert peer public value to curve point.";
+    return false;
+  }
+
+  uint8_t result[kP256FieldBytes];
+  if (ECDH_compute_key(result, sizeof(result), point.get(), private_key_.get(),
+                       nullptr) != sizeof(result)) {
+    QUIC_DLOG(INFO) << "Can't compute ECDH shared key.";
+    return false;
+  }
+
+  shared_key->assign(reinterpret_cast<char*>(result), sizeof(result));
+  return true;
+}
+
+absl::string_view P256KeyExchange::public_value() const {
+  return absl::string_view(reinterpret_cast<const char*>(public_key_),
+                           sizeof(public_key_));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/p256_key_exchange.h b/quiche/quic/core/crypto/p256_key_exchange.h
new file mode 100644
index 0000000..4b23973
--- /dev/null
+++ b/quiche/quic/core/crypto/p256_key_exchange.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2013 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_CRYPTO_P256_KEY_EXCHANGE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// P256KeyExchange implements a SynchronousKeyExchange using elliptic-curve
+// Diffie-Hellman on NIST P-256.
+class QUIC_EXPORT_PRIVATE P256KeyExchange : public SynchronousKeyExchange {
+ public:
+  ~P256KeyExchange() override;
+
+  // New generates a private key and then creates new key-exchange object.
+  static std::unique_ptr<P256KeyExchange> New();
+
+  // New creates a new key-exchange object from a private key. If |private_key|
+  // is invalid, nullptr is returned.
+  static std::unique_ptr<P256KeyExchange> New(absl::string_view private_key);
+
+  // NewPrivateKey returns a private key, suitable for passing to |New|.
+  // If |NewPrivateKey| can't generate a private key, it returns an empty
+  // string.
+  static std::string NewPrivateKey();
+
+  // SynchronousKeyExchange interface.
+  bool CalculateSharedKeySync(absl::string_view peer_public_value,
+                              std::string* shared_key) const override;
+  absl::string_view public_value() const override;
+  QuicTag type() const override { return kP256; }
+
+ private:
+  enum {
+    // A P-256 field element consists of 32 bytes.
+    kP256FieldBytes = 32,
+    // A P-256 point in uncompressed form consists of 0x04 (to denote
+    // that the point is uncompressed) followed by two, 32-byte field
+    // elements.
+    kUncompressedP256PointBytes = 1 + 2 * kP256FieldBytes,
+    // The first byte in an uncompressed P-256 point.
+    kUncompressedECPointForm = 0x04,
+  };
+
+  // P256KeyExchange wraps |private_key|, and expects |public_key| consists of
+  // |kUncompressedP256PointBytes| bytes.
+  P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key,
+                  const uint8_t* public_key);
+  P256KeyExchange(const P256KeyExchange&) = delete;
+  P256KeyExchange& operator=(const P256KeyExchange&) = delete;
+
+  bssl::UniquePtr<EC_KEY> private_key_;
+  // The public key stored as an uncompressed P-256 point.
+  uint8_t public_key_[kUncompressedP256PointBytes];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
diff --git a/quiche/quic/core/crypto/p256_key_exchange_test.cc b/quiche/quic/core/crypto/p256_key_exchange_test.cc
new file mode 100644
index 0000000..c9bc7d3
--- /dev/null
+++ b/quiche/quic/core/crypto/p256_key_exchange_test.cc
@@ -0,0 +1,109 @@
+// Copyright (c) 2013 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 "quiche/quic/core/crypto/p256_key_exchange.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class P256KeyExchangeTest : public QuicTest {
+ public:
+  // Holds the result of a key exchange callback.
+  class TestCallbackResult {
+   public:
+    void set_ok(bool ok) { ok_ = ok; }
+    bool ok() { return ok_; }
+
+   private:
+    bool ok_ = false;
+  };
+
+  // Key exchange callback which sets the result into the specified
+  // TestCallbackResult.
+  class TestCallback : public AsynchronousKeyExchange::Callback {
+   public:
+    TestCallback(TestCallbackResult* result) : result_(result) {}
+    virtual ~TestCallback() = default;
+
+    void Run(bool ok) { result_->set_ok(ok); }
+
+   private:
+    TestCallbackResult* result_;
+  };
+};
+
+// SharedKeyAsync just tests that the basic asynchronous key exchange identity
+// holds: that both parties end up with the same key.
+TEST_F(P256KeyExchangeTest, SharedKey) {
+  for (int i = 0; i < 5; i++) {
+    std::string alice_private(P256KeyExchange::NewPrivateKey());
+    std::string bob_private(P256KeyExchange::NewPrivateKey());
+
+    ASSERT_FALSE(alice_private.empty());
+    ASSERT_FALSE(bob_private.empty());
+    ASSERT_NE(alice_private, bob_private);
+
+    std::unique_ptr<P256KeyExchange> alice(P256KeyExchange::New(alice_private));
+    std::unique_ptr<P256KeyExchange> bob(P256KeyExchange::New(bob_private));
+
+    ASSERT_TRUE(alice != nullptr);
+    ASSERT_TRUE(bob != nullptr);
+
+    const absl::string_view alice_public(alice->public_value());
+    const absl::string_view bob_public(bob->public_value());
+
+    std::string alice_shared, bob_shared;
+    ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
+    ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
+    ASSERT_EQ(alice_shared, bob_shared);
+  }
+}
+
+// SharedKey just tests that the basic key exchange identity holds: that both
+// parties end up with the same key.
+TEST_F(P256KeyExchangeTest, AsyncSharedKey) {
+  for (int i = 0; i < 5; i++) {
+    std::string alice_private(P256KeyExchange::NewPrivateKey());
+    std::string bob_private(P256KeyExchange::NewPrivateKey());
+
+    ASSERT_FALSE(alice_private.empty());
+    ASSERT_FALSE(bob_private.empty());
+    ASSERT_NE(alice_private, bob_private);
+
+    std::unique_ptr<P256KeyExchange> alice(P256KeyExchange::New(alice_private));
+    std::unique_ptr<P256KeyExchange> bob(P256KeyExchange::New(bob_private));
+
+    ASSERT_TRUE(alice != nullptr);
+    ASSERT_TRUE(bob != nullptr);
+
+    const absl::string_view alice_public(alice->public_value());
+    const absl::string_view bob_public(bob->public_value());
+
+    std::string alice_shared, bob_shared;
+    TestCallbackResult alice_result;
+    ASSERT_FALSE(alice_result.ok());
+    alice->CalculateSharedKeyAsync(
+        bob_public, &alice_shared,
+        std::make_unique<TestCallback>(&alice_result));
+    ASSERT_TRUE(alice_result.ok());
+    TestCallbackResult bob_result;
+    ASSERT_FALSE(bob_result.ok());
+    bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
+                                 std::make_unique<TestCallback>(&bob_result));
+    ASSERT_TRUE(bob_result.ok());
+    ASSERT_EQ(alice_shared, bob_shared);
+    ASSERT_NE(0u, alice_shared.length());
+    ASSERT_NE(0u, bob_shared.length());
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/proof_source.cc b/quiche/quic/core/crypto/proof_source.cc
new file mode 100644
index 0000000..95fb446
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source.cc
@@ -0,0 +1,59 @@
+// Copyright (c) 2016 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 "quiche/quic/core/crypto/proof_source.h"
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+CryptoBuffers::~CryptoBuffers() {
+  for (size_t i = 0; i < value.size(); i++) {
+    CRYPTO_BUFFER_free(value[i]);
+  }
+}
+
+ProofSource::Chain::Chain(const std::vector<std::string>& certs)
+    : certs(certs) {}
+
+ProofSource::Chain::~Chain() {}
+
+CryptoBuffers ProofSource::Chain::ToCryptoBuffers() const {
+  CryptoBuffers crypto_buffers;
+  crypto_buffers.value.reserve(certs.size());
+  for (size_t i = 0; i < certs.size(); i++) {
+    crypto_buffers.value.push_back(
+        CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(certs[i].data()),
+                          certs[i].length(), nullptr));
+  }
+  return crypto_buffers;
+}
+
+bool ValidateCertAndKey(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const CertificatePrivateKey& key) {
+  if (chain.get() == nullptr || chain->certs.empty()) {
+    QUIC_BUG(quic_proof_source_empty_chain) << "Certificate chain is empty";
+    return false;
+  }
+
+  std::unique_ptr<CertificateView> leaf =
+      CertificateView::ParseSingleCertificate(chain->certs[0]);
+  if (leaf == nullptr) {
+    QUIC_BUG(quic_proof_source_unparsable_leaf_cert)
+        << "Unabled to parse leaf certificate";
+    return false;
+  }
+
+  if (!key.MatchesPublicKey(*leaf)) {
+    QUIC_BUG(quic_proof_source_key_mismatch)
+        << "Private key does not match the leaf certificate";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/proof_source.h b/quiche/quic/core/crypto/proof_source.h
new file mode 100644
index 0000000..e725409
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source.h
@@ -0,0 +1,355 @@
+// Copyright (c) 2013 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_CRYPTO_PROOF_SOURCE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/quic_crypto_proof.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+namespace test {
+class FakeProofSourceHandle;
+}  // namespace test
+
+// CryptoBuffers is a RAII class to own a std::vector<CRYPTO_BUFFER*> and the
+// buffers the elements point to.
+struct QUIC_EXPORT_PRIVATE CryptoBuffers {
+  CryptoBuffers() = default;
+  CryptoBuffers(const CryptoBuffers&) = delete;
+  CryptoBuffers(CryptoBuffers&&) = default;
+  ~CryptoBuffers();
+
+  std::vector<CRYPTO_BUFFER*> value;
+};
+
+// ProofSource is an interface by which a QUIC server can obtain certificate
+// chains and signatures that prove its identity.
+class QUIC_EXPORT_PRIVATE ProofSource {
+ public:
+  // Chain is a reference-counted wrapper for a vector of stringified
+  // certificates.
+  struct QUIC_EXPORT_PRIVATE Chain : public quiche::QuicheReferenceCounted {
+    explicit Chain(const std::vector<std::string>& certs);
+    Chain(const Chain&) = delete;
+    Chain& operator=(const Chain&) = delete;
+
+    CryptoBuffers ToCryptoBuffers() const;
+
+    const std::vector<std::string> certs;
+
+   protected:
+    ~Chain() override;
+  };
+
+  // Details is an abstract class which acts as a container for any
+  // implementation-specific details that a ProofSource wants to return.
+  class QUIC_EXPORT_PRIVATE Details {
+   public:
+    virtual ~Details() {}
+  };
+
+  // Callback base class for receiving the results of an async call to GetProof.
+  class QUIC_EXPORT_PRIVATE Callback {
+   public:
+    Callback() {}
+    virtual ~Callback() {}
+
+    // Invoked upon completion of GetProof.
+    //
+    // |ok| indicates whether the operation completed successfully.  If false,
+    // the values of the remaining three arguments are undefined.
+    //
+    // |chain| is a reference-counted pointer to an object representing the
+    // certificate chain.
+    //
+    // |signature| contains the signature of the server config.
+    //
+    // |leaf_cert_sct| holds the signed timestamp (RFC6962) of the leaf cert.
+    //
+    // |details| holds a pointer to an object representing the statistics, if
+    // any, gathered during the operation of GetProof.  If no stats are
+    // available, this will be nullptr.
+    virtual void Run(bool ok,
+                     const quiche::QuicheReferenceCountedPointer<Chain>& chain,
+                     const QuicCryptoProof& proof,
+                     std::unique_ptr<Details> details) = 0;
+
+   private:
+    Callback(const Callback&) = delete;
+    Callback& operator=(const Callback&) = delete;
+  };
+
+  // Base class for signalling the completion of a call to ComputeTlsSignature.
+  class QUIC_EXPORT_PRIVATE SignatureCallback {
+   public:
+    SignatureCallback() {}
+    virtual ~SignatureCallback() = default;
+
+    // Invoked upon completion of ComputeTlsSignature.
+    //
+    // |ok| indicates whether the operation completed successfully.
+    //
+    // |signature| contains the signature of the data provided to
+    // ComputeTlsSignature. Its value is undefined if |ok| is false.
+    //
+    // |details| holds a pointer to an object representing the statistics, if
+    // any, gathered during the operation of ComputeTlsSignature.  If no stats
+    // are available, this will be nullptr.
+    virtual void Run(bool ok,
+                     std::string signature,
+                     std::unique_ptr<Details> details) = 0;
+
+   private:
+    SignatureCallback(const SignatureCallback&) = delete;
+    SignatureCallback& operator=(const SignatureCallback&) = delete;
+  };
+
+  virtual ~ProofSource() {}
+
+  // GetProof finds a certificate chain for |hostname| (in leaf-first order),
+  // and calculates a signature of |server_config| using that chain.
+  //
+  // The signature uses SHA-256 as the hash function and PSS padding when the
+  // key is RSA.
+  //
+  // The signature uses SHA-256 as the hash function when the key is ECDSA.
+  // The signature may use an ECDSA key.
+  //
+  // The signature depends on |chlo_hash| which means that the signature can not
+  // be cached.
+  //
+  // |hostname| may be empty to signify that a default certificate should be
+  // used.
+  //
+  // This function may be called concurrently.
+  //
+  // Callers should expect that |callback| might be invoked synchronously.
+  virtual void GetProof(const QuicSocketAddress& server_address,
+                        const QuicSocketAddress& client_address,
+                        const std::string& hostname,
+                        const std::string& server_config,
+                        QuicTransportVersion transport_version,
+                        absl::string_view chlo_hash,
+                        std::unique_ptr<Callback> callback) = 0;
+
+  // Returns the certificate chain for |hostname| in leaf-first order.
+  //
+  // Sets *cert_matched_sni to true if the certificate matched the given
+  // hostname, false if a default cert not matching the hostname was used.
+  virtual quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, const std::string& hostname,
+      bool* cert_matched_sni) = 0;
+
+  // Computes a signature using the private key of the certificate for
+  // |hostname|. The value in |in| is signed using the algorithm specified by
+  // |signature_algorithm|, which is an |SSL_SIGN_*| value (as defined in TLS
+  // 1.3). Implementations can only assume that |in| is valid during the call to
+  // ComputeTlsSignature - an implementation computing signatures asynchronously
+  // must copy it if the value to be signed is used outside of this function.
+  //
+  // Callers should expect that |callback| might be invoked synchronously.
+  virtual void ComputeTlsSignature(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      const std::string& hostname,
+      uint16_t signature_algorithm,
+      absl::string_view in,
+      std::unique_ptr<SignatureCallback> callback) = 0;
+
+  // Return the list of TLS signature algorithms that is acceptable by the
+  // ComputeTlsSignature method. If the entire BoringSSL's default list of
+  // supported signature algorithms are acceptable, return an empty list.
+  //
+  // If returns a non-empty list, ComputeTlsSignature will only be called with a
+  // algorithm in the list.
+  virtual absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+      const = 0;
+
+  class QUIC_EXPORT_PRIVATE DecryptCallback {
+   public:
+    DecryptCallback() = default;
+    virtual ~DecryptCallback() = default;
+
+    virtual void Run(std::vector<uint8_t> plaintext) = 0;
+
+   private:
+    DecryptCallback(const Callback&) = delete;
+    DecryptCallback& operator=(const Callback&) = delete;
+  };
+
+  // TicketCrypter is an interface for managing encryption and decryption of TLS
+  // session tickets. A TicketCrypter gets used as an
+  // SSL_CTX_set_ticket_aead_method in BoringSSL, which has a synchronous
+  // Encrypt/Seal operation and a potentially asynchronous Decrypt/Open
+  // operation. This interface allows for ticket decryptions to be performed on
+  // a remote service.
+  class QUIC_EXPORT_PRIVATE TicketCrypter {
+   public:
+    TicketCrypter() = default;
+    virtual ~TicketCrypter() = default;
+
+    // MaxOverhead returns the maximum number of bytes of overhead that may get
+    // added when encrypting the ticket.
+    virtual size_t MaxOverhead() = 0;
+
+    // Encrypt takes a serialized TLS session ticket in |in|, encrypts it, and
+    // returns the encrypted ticket. The resulting value must not be larger than
+    // MaxOverhead bytes larger than |in|. If encryption fails, this method
+    // returns an empty vector.
+    //
+    // If |encryption_key| is nonempty, this method should use it for minting
+    // TLS resumption tickets.  If it is empty, this method may use an
+    // internally cached encryption key, if available.
+    virtual std::vector<uint8_t> Encrypt(absl::string_view in,
+                                         absl::string_view encryption_key) = 0;
+
+    // Decrypt takes an encrypted ticket |in|, decrypts it, and calls
+    // |callback->Run| with the decrypted ticket, which must not be larger than
+    // |in|. If decryption fails, the callback is invoked with an empty
+    // vector.
+    virtual void Decrypt(absl::string_view in,
+                         std::unique_ptr<DecryptCallback> callback) = 0;
+  };
+
+  // Returns the TicketCrypter used for encrypting and decrypting TLS
+  // session tickets, or nullptr if that functionality is not supported. The
+  // TicketCrypter returned (if not nullptr) must be valid for the lifetime of
+  // the ProofSource, and the caller does not take ownership of said
+  // TicketCrypter.
+  virtual TicketCrypter* GetTicketCrypter() = 0;
+};
+
+// ProofSourceHandleCallback is an interface that contains the callbacks when
+// the operations in ProofSourceHandle completes.
+// TODO(wub): Consider deprecating ProofSource by moving all functionalities of
+// ProofSource into ProofSourceHandle.
+class QUIC_EXPORT_PRIVATE ProofSourceHandleCallback {
+ public:
+  virtual ~ProofSourceHandleCallback() = default;
+
+  // Called when a ProofSourceHandle::SelectCertificate operation completes.
+  // |ok| indicates whether the operation was successful.
+  // |is_sync| indicates whether the operation completed synchronously, i.e.
+  //      whether it is completed before ProofSourceHandle::SelectCertificate
+  //      returned.
+  // |chain| the certificate chain in leaf-first order.
+  // |handshake_hints| (optional) handshake hints that can be used by
+  //      SSL_set_handshake_hints.
+  // |ticket_encryption_key| (optional) encryption key to be used for minting
+  //      TLS resumption tickets.
+  // |cert_matched_sni| is true if the certificate matched the SNI hostname,
+  //      false if a non-matching default cert was used.
+  // |delayed_ssl_config| contains SSL configs to be applied on the SSL object.
+  //
+  // When called asynchronously(is_sync=false), this method will be responsible
+  // to continue the handshake from where it left off.
+  virtual void OnSelectCertificateDone(
+      bool ok, bool is_sync, const ProofSource::Chain* chain,
+      absl::string_view handshake_hints,
+      absl::string_view ticket_encryption_key, bool cert_matched_sni,
+      QuicDelayedSSLConfig delayed_ssl_config) = 0;
+
+  // Called when a ProofSourceHandle::ComputeSignature operation completes.
+  virtual void OnComputeSignatureDone(
+      bool ok,
+      bool is_sync,
+      std::string signature,
+      std::unique_ptr<ProofSource::Details> details) = 0;
+
+  // Return true iff ProofSourceHandle::ComputeSignature won't be called later.
+  // The handle can use this function to release resources promptly.
+  virtual bool WillNotCallComputeSignature() const = 0;
+};
+
+// ProofSourceHandle is an interface by which a TlsServerHandshaker can obtain
+// certificate chains and signatures that prove its identity.
+// The operations this interface supports are similar to those in ProofSource,
+// the main difference is that ProofSourceHandle is per-handshaker, so
+// an implementation can have states that are shared by multiple calls on the
+// same handle.
+//
+// A handle object is owned by a TlsServerHandshaker. Since there might be an
+// async operation pending when the handle destructs, an implementation must
+// ensure when such operations finish, their corresponding callback method won't
+// be invoked.
+//
+// A handle will have at most one async operation pending at a time.
+class QUIC_EXPORT_PRIVATE ProofSourceHandle {
+ public:
+  virtual ~ProofSourceHandle() = default;
+
+  // Close the handle. Cancel the pending operation, if any.
+  // Once called, any completion method on |callback()| won't be invoked, and
+  // future SelectCertificate and ComputeSignature calls should return failure.
+  virtual void CloseHandle() = 0;
+
+  // Starts a select certificate operation. If the operation is not cancelled
+  // when it completes, callback()->OnSelectCertificateDone will be invoked.
+  //
+  // server_address and client_address should be normalized by the caller before
+  // sending down to this function.
+  //
+  // If the operation is handled synchronously:
+  // - QUIC_SUCCESS or QUIC_FAILURE will be returned.
+  // - callback()->OnSelectCertificateDone should be invoked before the function
+  //   returns.
+  //
+  // If the operation is handled asynchronously:
+  // - QUIC_PENDING will be returned.
+  // - When the operation is done, callback()->OnSelectCertificateDone should be
+  //   invoked.
+  virtual QuicAsyncStatus SelectCertificate(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      absl::string_view ssl_capabilities,
+      const std::string& hostname,
+      absl::string_view client_hello,
+      const std::string& alpn,
+      absl::optional<std::string> alps,
+      const std::vector<uint8_t>& quic_transport_params,
+      const absl::optional<std::vector<uint8_t>>& early_data_context,
+      const QuicSSLConfig& ssl_config) = 0;
+
+  // Starts a compute signature operation. If the operation is not cancelled
+  // when it completes, callback()->OnComputeSignatureDone will be invoked.
+  //
+  // See the comments of SelectCertificate for sync vs. async operations.
+  virtual QuicAsyncStatus ComputeSignature(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      const std::string& hostname,
+      uint16_t signature_algorithm,
+      absl::string_view in,
+      size_t max_signature_size) = 0;
+
+ protected:
+  // Returns the object that will be notified when an operation completes.
+  virtual ProofSourceHandleCallback* callback() = 0;
+
+ private:
+  friend class test::FakeProofSourceHandle;
+};
+
+// Returns true if |chain| contains a parsable DER-encoded X.509 leaf cert and
+// it matches with |key|.
+QUIC_EXPORT_PRIVATE bool ValidateCertAndKey(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const CertificatePrivateKey& key);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
diff --git a/quiche/quic/core/crypto/proof_source_x509.cc b/quiche/quic/core/crypto/proof_source_x509.cc
new file mode 100644
index 0000000..275efc0
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source_x509.cc
@@ -0,0 +1,149 @@
+// Copyright 2020 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 "quiche/quic/core/crypto/proof_source_x509.h"
+
+#include <memory>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+std::unique_ptr<ProofSourceX509> ProofSourceX509::Create(
+    quiche::QuicheReferenceCountedPointer<Chain> default_chain,
+    CertificatePrivateKey default_key) {
+  std::unique_ptr<ProofSourceX509> result(new ProofSourceX509());
+  if (!result->AddCertificateChain(default_chain, std::move(default_key))) {
+    return nullptr;
+  }
+  result->default_certificate_ = &result->certificates_.front();
+  return result;
+}
+
+void ProofSourceX509::GetProof(
+    const QuicSocketAddress& /*server_address*/,
+    const QuicSocketAddress& /*client_address*/,
+    const std::string& hostname,
+    const std::string& server_config,
+    QuicTransportVersion /*transport_version*/,
+    absl::string_view chlo_hash,
+    std::unique_ptr<ProofSource::Callback> callback) {
+  QuicCryptoProof proof;
+
+  size_t payload_size = sizeof(kProofSignatureLabel) + sizeof(uint32_t) +
+                        chlo_hash.size() + server_config.size();
+  auto payload = std::make_unique<char[]>(payload_size);
+  QuicDataWriter payload_writer(payload_size, payload.get(),
+                                quiche::Endianness::HOST_BYTE_ORDER);
+  bool success = payload_writer.WriteBytes(kProofSignatureLabel,
+                                           sizeof(kProofSignatureLabel)) &&
+                 payload_writer.WriteUInt32(chlo_hash.size()) &&
+                 payload_writer.WriteStringPiece(chlo_hash) &&
+                 payload_writer.WriteStringPiece(server_config);
+  if (!success) {
+    callback->Run(/*ok=*/false, nullptr, proof, nullptr);
+    return;
+  }
+
+  Certificate* certificate = GetCertificate(hostname, &proof.cert_matched_sni);
+  proof.signature =
+      certificate->key.Sign(absl::string_view(payload.get(), payload_size),
+                            SSL_SIGN_RSA_PSS_RSAE_SHA256);
+  callback->Run(/*ok=*/!proof.signature.empty(), certificate->chain, proof,
+                nullptr);
+}
+
+quiche::QuicheReferenceCountedPointer<ProofSource::Chain>
+ProofSourceX509::GetCertChain(const QuicSocketAddress& /*server_address*/,
+                              const QuicSocketAddress& /*client_address*/,
+                              const std::string& hostname,
+                              bool* cert_matched_sni) {
+  return GetCertificate(hostname, cert_matched_sni)->chain;
+}
+
+void ProofSourceX509::ComputeTlsSignature(
+    const QuicSocketAddress& /*server_address*/,
+    const QuicSocketAddress& /*client_address*/,
+    const std::string& hostname,
+    uint16_t signature_algorithm,
+    absl::string_view in,
+    std::unique_ptr<ProofSource::SignatureCallback> callback) {
+  bool cert_matched_sni;
+  std::string signature = GetCertificate(hostname, &cert_matched_sni)
+                              ->key.Sign(in, signature_algorithm);
+  callback->Run(/*ok=*/!signature.empty(), signature, nullptr);
+}
+
+absl::InlinedVector<uint16_t, 8>
+ProofSourceX509::SupportedTlsSignatureAlgorithms() const {
+  // Let ComputeTlsSignature() report an error if a bad signature algorithm is
+  // requested.
+  return {};
+}
+
+ProofSource::TicketCrypter* ProofSourceX509::GetTicketCrypter() {
+  return nullptr;
+}
+
+bool ProofSourceX509::AddCertificateChain(
+    quiche::QuicheReferenceCountedPointer<Chain> chain,
+    CertificatePrivateKey key) {
+  if (chain->certs.empty()) {
+    QUIC_BUG(quic_bug_10644_1) << "Empty certificate chain supplied.";
+    return false;
+  }
+
+  std::unique_ptr<CertificateView> leaf =
+      CertificateView::ParseSingleCertificate(chain->certs[0]);
+  if (leaf == nullptr) {
+    QUIC_BUG(quic_bug_10644_2)
+        << "Unable to parse X.509 leaf certificate in the supplied chain.";
+    return false;
+  }
+  if (!key.MatchesPublicKey(*leaf)) {
+    QUIC_BUG(quic_bug_10644_3)
+        << "Private key does not match the leaf certificate.";
+    return false;
+  }
+
+  certificates_.push_front(Certificate{
+      chain,
+      std::move(key),
+  });
+  Certificate* certificate = &certificates_.front();
+
+  for (absl::string_view host : leaf->subject_alt_name_domains()) {
+    certificate_map_[std::string(host)] = certificate;
+  }
+  return true;
+}
+
+ProofSourceX509::Certificate* ProofSourceX509::GetCertificate(
+    const std::string& hostname, bool* cert_matched_sni) const {
+  auto it = certificate_map_.find(hostname);
+  if (it != certificate_map_.end()) {
+    *cert_matched_sni = true;
+    return it->second;
+  }
+  auto dot_pos = hostname.find('.');
+  if (dot_pos != std::string::npos) {
+    std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
+    it = certificate_map_.find(wildcard);
+    if (it != certificate_map_.end()) {
+      *cert_matched_sni = true;
+      return it->second;
+    }
+  }
+  *cert_matched_sni = false;
+  return default_certificate_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/proof_source_x509.h b/quiche/quic/core/crypto/proof_source_x509.h
new file mode 100644
index 0000000..107a4c8
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source_x509.h
@@ -0,0 +1,78 @@
+// Copyright 2020 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_CRYPTO_PROOF_SOURCE_X509_H_
+#define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
+
+#include <forward_list>
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "absl/container/node_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+
+namespace quic {
+
+// ProofSourceX509 accepts X.509 certificates with private keys and picks a
+// certificate internally based on its SubjectAltName value.
+class QUIC_EXPORT_PRIVATE ProofSourceX509 : public ProofSource {
+ public:
+  // Creates a proof source that uses |default_chain| when no SubjectAltName
+  // value matches.  Returns nullptr if |default_chain| is invalid.
+  static std::unique_ptr<ProofSourceX509> Create(
+      quiche::QuicheReferenceCountedPointer<Chain> default_chain,
+      CertificatePrivateKey default_key);
+
+  // ProofSource implementation.
+  void GetProof(const QuicSocketAddress& server_address,
+                const QuicSocketAddress& client_address,
+                const std::string& hostname,
+                const std::string& server_config,
+                QuicTransportVersion transport_version,
+                absl::string_view chlo_hash,
+                std::unique_ptr<Callback> callback) override;
+  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, const std::string& hostname,
+      bool* cert_matched_sni) override;
+  void ComputeTlsSignature(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, const std::string& hostname,
+      uint16_t signature_algorithm, absl::string_view in,
+      std::unique_ptr<SignatureCallback> callback) override;
+  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+      const override;
+  TicketCrypter* GetTicketCrypter() override;
+
+  // Adds a certificate chain to the verifier.  Returns false if the chain is
+  // not valid.  Newer certificates will override older certificates with the
+  // same SubjectAltName value.
+  ABSL_MUST_USE_RESULT bool AddCertificateChain(
+      quiche::QuicheReferenceCountedPointer<Chain> chain,
+      CertificatePrivateKey key);
+
+ private:
+  ProofSourceX509() = default;
+
+  struct QUIC_EXPORT_PRIVATE Certificate {
+    quiche::QuicheReferenceCountedPointer<Chain> chain;
+    CertificatePrivateKey key;
+  };
+
+  // Looks up certficiate for hostname, returns the default if no certificate is
+  // found.
+  Certificate* GetCertificate(const std::string& hostname,
+                              bool* cert_matched_sni) const;
+
+  std::forward_list<Certificate> certificates_;
+  Certificate* default_certificate_;
+  absl::node_hash_map<std::string, Certificate*> certificate_map_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
diff --git a/quiche/quic/core/crypto/proof_source_x509_test.cc b/quiche/quic/core/crypto/proof_source_x509_test.cc
new file mode 100644
index 0000000..63ba310
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source_x509_test.cc
@@ -0,0 +1,143 @@
+// Copyright 2020 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 "quiche/quic/core/crypto/proof_source_x509.h"
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+quiche::QuicheReferenceCountedPointer<ProofSource::Chain> MakeChain(
+    absl::string_view cert) {
+  return quiche::QuicheReferenceCountedPointer<ProofSource::Chain>(
+      new ProofSource::Chain(std::vector<std::string>{std::string(cert)}));
+}
+
+class ProofSourceX509Test : public QuicTest {
+ public:
+  ProofSourceX509Test()
+      : test_chain_(MakeChain(kTestCertificate)),
+        wildcard_chain_(MakeChain(kWildcardCertificate)),
+        test_key_(
+            CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey)),
+        wildcard_key_(CertificatePrivateKey::LoadFromDer(
+            kWildcardCertificatePrivateKey)) {
+    QUICHE_CHECK(test_key_ != nullptr);
+    QUICHE_CHECK(wildcard_key_ != nullptr);
+  }
+
+ protected:
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> test_chain_,
+      wildcard_chain_;
+  std::unique_ptr<CertificatePrivateKey> test_key_, wildcard_key_;
+};
+
+TEST_F(ProofSourceX509Test, AddCertificates) {
+  std::unique_ptr<ProofSourceX509> proof_source =
+      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
+  ASSERT_TRUE(proof_source != nullptr);
+  EXPECT_TRUE(proof_source->AddCertificateChain(wildcard_chain_,
+                                                std::move(*wildcard_key_)));
+}
+
+TEST_F(ProofSourceX509Test, AddCertificateKeyMismatch) {
+  std::unique_ptr<ProofSourceX509> proof_source =
+      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
+  ASSERT_TRUE(proof_source != nullptr);
+  test_key_ = CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey);
+  EXPECT_QUIC_BUG((void)proof_source->AddCertificateChain(
+                      wildcard_chain_, std::move(*test_key_)),
+                  "Private key does not match");
+}
+
+TEST_F(ProofSourceX509Test, CertificateSelection) {
+  std::unique_ptr<ProofSourceX509> proof_source =
+      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
+  ASSERT_TRUE(proof_source != nullptr);
+  ASSERT_TRUE(proof_source->AddCertificateChain(wildcard_chain_,
+                                                std::move(*wildcard_key_)));
+
+  // Default certificate.
+  bool cert_matched_sni;
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "unknown.test", &cert_matched_sni)
+                ->certs[0],
+            kTestCertificate);
+  EXPECT_FALSE(cert_matched_sni);
+  // mail.example.org is explicitly a SubjectAltName in kTestCertificate.
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "mail.example.org", &cert_matched_sni)
+                ->certs[0],
+            kTestCertificate);
+  EXPECT_TRUE(cert_matched_sni);
+  // www.foo.test is in kWildcardCertificate.
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "www.foo.test", &cert_matched_sni)
+                ->certs[0],
+            kWildcardCertificate);
+  EXPECT_TRUE(cert_matched_sni);
+  // *.wildcard.test is in kWildcardCertificate.
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "www.wildcard.test", &cert_matched_sni)
+                ->certs[0],
+            kWildcardCertificate);
+  EXPECT_TRUE(cert_matched_sni);
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "etc.wildcard.test", &cert_matched_sni)
+                ->certs[0],
+            kWildcardCertificate);
+  EXPECT_TRUE(cert_matched_sni);
+  // wildcard.test itself is not in kWildcardCertificate.
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "wildcard.test", &cert_matched_sni)
+                ->certs[0],
+            kTestCertificate);
+  EXPECT_FALSE(cert_matched_sni);
+}
+
+TEST_F(ProofSourceX509Test, TlsSignature) {
+  class Callback : public ProofSource::SignatureCallback {
+   public:
+    void Run(bool ok,
+             std::string signature,
+             std::unique_ptr<ProofSource::Details> /*details*/) override {
+      ASSERT_TRUE(ok);
+      std::unique_ptr<CertificateView> view =
+          CertificateView::ParseSingleCertificate(kTestCertificate);
+      EXPECT_TRUE(view->VerifySignature("Test data", signature,
+                                        SSL_SIGN_RSA_PSS_RSAE_SHA256));
+    }
+  };
+
+  std::unique_ptr<ProofSourceX509> proof_source =
+      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
+  ASSERT_TRUE(proof_source != nullptr);
+
+  proof_source->ComputeTlsSignature(QuicSocketAddress(), QuicSocketAddress(),
+                                    "example.com", SSL_SIGN_RSA_PSS_RSAE_SHA256,
+                                    "Test data", std::make_unique<Callback>());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/proof_verifier.h b/quiche/quic/core/crypto/proof_verifier.h
new file mode 100644
index 0000000..3478ca6
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_verifier.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2013 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_CRYPTO_PROOF_VERIFIER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// ProofVerifyDetails is an abstract class that acts as a container for any
+// implementation specific details that a ProofVerifier wishes to return. These
+// details are saved in the CachedState for the origin in question.
+class QUIC_EXPORT_PRIVATE ProofVerifyDetails {
+ public:
+  virtual ~ProofVerifyDetails() {}
+
+  // Returns an new ProofVerifyDetails object with the same contents
+  // as this one.
+  virtual ProofVerifyDetails* Clone() const = 0;
+};
+
+// ProofVerifyContext is an abstract class that acts as a container for any
+// implementation specific context that a ProofVerifier needs.
+class QUIC_EXPORT_PRIVATE ProofVerifyContext {
+ public:
+  virtual ~ProofVerifyContext() {}
+};
+
+// ProofVerifierCallback provides a generic mechanism for a ProofVerifier to
+// call back after an asynchronous verification.
+class QUIC_EXPORT_PRIVATE ProofVerifierCallback {
+ public:
+  virtual ~ProofVerifierCallback() {}
+
+  // Run is called on the original thread to mark the completion of an
+  // asynchonous verification. If |ok| is true then the certificate is valid
+  // and |error_details| is unused. Otherwise, |error_details| contains a
+  // description of the error. |details| contains implementation-specific
+  // details of the verification. |Run| may take ownership of |details| by
+  // calling |release| on it.
+  virtual void Run(bool ok,
+                   const std::string& error_details,
+                   std::unique_ptr<ProofVerifyDetails>* details) = 0;
+};
+
+// A ProofVerifier checks the signature on a server config, and the certificate
+// chain that backs the public key.
+class QUIC_EXPORT_PRIVATE ProofVerifier {
+ public:
+  virtual ~ProofVerifier() {}
+
+  // VerifyProof checks that |signature| is a valid signature of
+  // |server_config| by the public key in the leaf certificate of |certs|, and
+  // that |certs| is a valid chain for |hostname|. On success, it returns
+  // QUIC_SUCCESS. On failure, it returns QUIC_FAILURE and sets |*error_details|
+  // to a description of the problem. In either case it may set |*details|,
+  // which the caller takes ownership of.
+  //
+  // |context| specifies an implementation specific struct (which may be nullptr
+  // for some implementations) that provides useful information for the
+  // verifier, e.g. logging handles.
+  //
+  // This function may also return QUIC_PENDING, in which case the ProofVerifier
+  // will call back, on the original thread, via |callback| when complete.
+  //
+  // The signature uses SHA-256 as the hash function and PSS padding in the
+  // case of RSA.
+  virtual QuicAsyncStatus VerifyProof(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::string& server_config,
+      QuicTransportVersion transport_version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& certs,
+      const std::string& cert_sct,
+      const std::string& signature,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      std::unique_ptr<ProofVerifierCallback> callback) = 0;
+
+  // VerifyCertChain checks that |certs| is a valid chain for |hostname|. On
+  // success, it returns QUIC_SUCCESS. On failure, it returns QUIC_FAILURE and
+  // sets |*error_details| to a description of the problem. In either case it
+  // may set |*details|, which the caller takes ownership of.
+  //
+  // |context| specifies an implementation specific struct (which may be nullptr
+  // for some implementations) that provides useful information for the
+  // verifier, e.g. logging handles.
+  //
+  // If certificate verification fails, a TLS alert will be sent when closing
+  // the connection. This alert defaults to certificate_unknown. By setting
+  // |*out_alert|, a different alert can be sent to provide a more specific
+  // reason why verification failed.
+  //
+  // This function may also return QUIC_PENDING, in which case the ProofVerifier
+  // will call back, on the original thread, via |callback| when complete.
+  // In this case, the ProofVerifier will take ownership of |callback|.
+  virtual QuicAsyncStatus VerifyCertChain(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::vector<std::string>& certs,
+      const std::string& ocsp_response,
+      const std::string& cert_sct,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) = 0;
+
+  // Returns a ProofVerifyContext instance which can be use for subsequent
+  // verifications. Applications may chose create a different context and
+  // supply it for verifications instead.
+  virtual std::unique_ptr<ProofVerifyContext> CreateDefaultContext() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
diff --git a/quiche/quic/core/crypto/quic_client_session_cache.cc b/quiche/quic/core/crypto/quic_client_session_cache.cc
new file mode 100644
index 0000000..32f115d
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_client_session_cache.cc
@@ -0,0 +1,173 @@
+// Copyright (c) 2021 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 "quiche/quic/core/crypto/quic_client_session_cache.h"
+
+#include "quiche/quic/core/quic_clock.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kDefaultMaxEntries = 1024;
+// Returns false if the SSL |session| doesn't exist or it is expired at |now|.
+bool IsValid(SSL_SESSION* session, uint64_t now) {
+  if (!session) return false;
+
+  // now_u64 may be slightly behind because of differences in how
+  // time is calculated at this layer versus BoringSSL.
+  // Add a second of wiggle room to account for this.
+  return !(now + 1 < SSL_SESSION_get_time(session) ||
+           now >= SSL_SESSION_get_time(session) +
+                      SSL_SESSION_get_timeout(session));
+}
+
+bool DoApplicationStatesMatch(const ApplicationState* state,
+                              ApplicationState* other) {
+  if ((state && !other) || (!state && other)) return false;
+  if ((!state && !other) || *state == *other) return true;
+  return false;
+}
+
+}  // namespace
+
+QuicClientSessionCache::QuicClientSessionCache()
+    : QuicClientSessionCache(kDefaultMaxEntries) {}
+
+QuicClientSessionCache::QuicClientSessionCache(size_t max_entries)
+    : cache_(max_entries) {}
+
+QuicClientSessionCache::~QuicClientSessionCache() { Clear(); }
+
+void QuicClientSessionCache::Insert(const QuicServerId& server_id,
+                                    bssl::UniquePtr<SSL_SESSION> session,
+                                    const TransportParameters& params,
+                                    const ApplicationState* application_state) {
+  QUICHE_DCHECK(session) << "TLS session is not inserted into client cache.";
+  auto iter = cache_.Lookup(server_id);
+  if (iter == cache_.end()) {
+    CreateAndInsertEntry(server_id, std::move(session), params,
+                         application_state);
+    return;
+  }
+
+  QUICHE_DCHECK(iter->second->params);
+  // The states are both the same, so only need to insert sessions.
+  if (params == *iter->second->params &&
+      DoApplicationStatesMatch(application_state,
+                               iter->second->application_state.get())) {
+    iter->second->PushSession(std::move(session));
+    return;
+  }
+  // Erase the existing entry because this Insert call must come from a
+  // different QUIC session.
+  cache_.Erase(iter);
+  CreateAndInsertEntry(server_id, std::move(session), params,
+                       application_state);
+}
+
+std::unique_ptr<QuicResumptionState> QuicClientSessionCache::Lookup(
+    const QuicServerId& server_id, QuicWallTime now, const SSL_CTX* /*ctx*/) {
+  auto iter = cache_.Lookup(server_id);
+  if (iter == cache_.end()) return nullptr;
+
+  if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
+    QUIC_DLOG(INFO) << "TLS Session expired for host:" << server_id.host();
+    cache_.Erase(iter);
+    return nullptr;
+  }
+  auto state = std::make_unique<QuicResumptionState>();
+  state->tls_session = iter->second->PopSession();
+  if (iter->second->params != nullptr) {
+    state->transport_params =
+        std::make_unique<TransportParameters>(*iter->second->params);
+  }
+  if (iter->second->application_state != nullptr) {
+    state->application_state =
+        std::make_unique<ApplicationState>(*iter->second->application_state);
+  }
+  if (!iter->second->token.empty()) {
+    state->token = iter->second->token;
+    // Clear token after use.
+    iter->second->token.clear();
+  }
+
+  return state;
+}
+
+void QuicClientSessionCache::ClearEarlyData(const QuicServerId& server_id) {
+  auto iter = cache_.Lookup(server_id);
+  if (iter == cache_.end()) return;
+  for (auto& session : iter->second->sessions) {
+    if (session) {
+      QUIC_DLOG(INFO) << "Clear early data for for host: " << server_id.host();
+      session.reset(SSL_SESSION_copy_without_early_data(session.get()));
+    }
+  }
+}
+
+void QuicClientSessionCache::OnNewTokenReceived(const QuicServerId& server_id,
+                                                absl::string_view token) {
+  if (token.empty()) {
+    return;
+  }
+  auto iter = cache_.Lookup(server_id);
+  if (iter == cache_.end()) {
+    return;
+  }
+  iter->second->token = std::string(token);
+}
+
+void QuicClientSessionCache::RemoveExpiredEntries(QuicWallTime now) {
+  auto iter = cache_.begin();
+  while (iter != cache_.end()) {
+    if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
+      iter = cache_.Erase(iter);
+    } else {
+      ++iter;
+    }
+  }
+}
+
+void QuicClientSessionCache::Clear() { cache_.Clear(); }
+
+void QuicClientSessionCache::CreateAndInsertEntry(
+    const QuicServerId& server_id, bssl::UniquePtr<SSL_SESSION> session,
+    const TransportParameters& params,
+    const ApplicationState* application_state) {
+  auto entry = std::make_unique<Entry>();
+  entry->PushSession(std::move(session));
+  entry->params = std::make_unique<TransportParameters>(params);
+  if (application_state) {
+    entry->application_state =
+        std::make_unique<ApplicationState>(*application_state);
+  }
+  cache_.Insert(server_id, std::move(entry));
+}
+
+QuicClientSessionCache::Entry::Entry() = default;
+QuicClientSessionCache::Entry::Entry(Entry&&) = default;
+QuicClientSessionCache::Entry::~Entry() = default;
+
+void QuicClientSessionCache::Entry::PushSession(
+    bssl::UniquePtr<SSL_SESSION> session) {
+  if (sessions[0] != nullptr) {
+    sessions[1] = std::move(sessions[0]);
+  }
+  sessions[0] = std::move(session);
+}
+
+bssl::UniquePtr<SSL_SESSION> QuicClientSessionCache::Entry::PopSession() {
+  if (sessions[0] == nullptr) return nullptr;
+  bssl::UniquePtr<SSL_SESSION> session = std::move(sessions[0]);
+  sessions[0] = std::move(sessions[1]);
+  sessions[1] = nullptr;
+  return session;
+}
+
+SSL_SESSION* QuicClientSessionCache::Entry::PeekSession() {
+  return sessions[0].get();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_client_session_cache.h b/quiche/quic/core/crypto/quic_client_session_cache.h
new file mode 100644
index 0000000..e568db6
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_client_session_cache.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2021 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_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
+
+#include <memory>
+
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/quic_lru_cache.h"
+#include "quiche/quic/core/quic_server_id.h"
+
+namespace quic {
+
+namespace test {
+class QuicClientSessionCachePeer;
+}  // namespace test
+
+// QuicClientSessionCache maps from QuicServerId to information used to resume
+// TLS sessions for that server.
+class QUIC_EXPORT_PRIVATE QuicClientSessionCache : public SessionCache {
+ public:
+  QuicClientSessionCache();
+  explicit QuicClientSessionCache(size_t max_entries);
+  ~QuicClientSessionCache() override;
+
+  void Insert(const QuicServerId& server_id,
+              bssl::UniquePtr<SSL_SESSION> session,
+              const TransportParameters& params,
+              const ApplicationState* application_state) override;
+
+  std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id,
+                                              QuicWallTime now,
+                                              const SSL_CTX* ctx) override;
+
+  void ClearEarlyData(const QuicServerId& server_id) override;
+
+  void OnNewTokenReceived(const QuicServerId& server_id,
+                          absl::string_view token) override;
+
+  void RemoveExpiredEntries(QuicWallTime now) override;
+
+  void Clear() override;
+
+  size_t size() const { return cache_.Size(); }
+
+ private:
+  friend class test::QuicClientSessionCachePeer;
+
+  struct QUIC_EXPORT_PRIVATE Entry {
+    Entry();
+    Entry(Entry&&);
+    ~Entry();
+
+    // Adds a new |session| onto sessions, dropping the oldest one if two are
+    // already stored.
+    void PushSession(bssl::UniquePtr<SSL_SESSION> session);
+
+    // Retrieves the latest session from the entry, meanwhile removing it.
+    bssl::UniquePtr<SSL_SESSION> PopSession();
+
+    SSL_SESSION* PeekSession();
+
+    bssl::UniquePtr<SSL_SESSION> sessions[2];
+    std::unique_ptr<TransportParameters> params;
+    std::unique_ptr<ApplicationState> application_state;
+    std::string token;  // An opaque string received in NEW_TOKEN frame.
+  };
+
+  // Creates a new entry and insert into |cache_|.
+  void CreateAndInsertEntry(const QuicServerId& server_id,
+                            bssl::UniquePtr<SSL_SESSION> session,
+                            const TransportParameters& params,
+                            const ApplicationState* application_state);
+
+  QuicLRUCache<QuicServerId, Entry, QuicServerIdHash> cache_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
diff --git a/quiche/quic/core/crypto/quic_client_session_cache_test.cc b/quiche/quic/core/crypto/quic_client_session_cache_test.cc
new file mode 100644
index 0000000..880770a
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_client_session_cache_test.cc
@@ -0,0 +1,440 @@
+// Copyright (c) 2021 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 "quiche/quic/core/crypto/quic_client_session_cache.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+const QuicTime::Delta kTimeout = QuicTime::Delta::FromSeconds(1000);
+const QuicVersionLabel kFakeVersionLabel = 0x01234567;
+const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
+const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
+const uint8_t kFakeStatelessResetTokenData[16] = {
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
+const uint64_t kFakeMaxPacketSize = 9001;
+const uint64_t kFakeInitialMaxData = 101;
+const bool kFakeDisableMigration = true;
+const auto kCustomParameter1 =
+    static_cast<TransportParameters::TransportParameterId>(0xffcd);
+const char* kCustomParameter1Value = "foo";
+const auto kCustomParameter2 =
+    static_cast<TransportParameters::TransportParameterId>(0xff34);
+const char* kCustomParameter2Value = "bar";
+
+std::vector<uint8_t> CreateFakeStatelessResetToken() {
+  return std::vector<uint8_t>(
+      kFakeStatelessResetTokenData,
+      kFakeStatelessResetTokenData + sizeof(kFakeStatelessResetTokenData));
+}
+
+TransportParameters::LegacyVersionInformation
+CreateFakeLegacyVersionInformation() {
+  TransportParameters::LegacyVersionInformation legacy_version_information;
+  legacy_version_information.version = kFakeVersionLabel;
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
+  return legacy_version_information;
+}
+
+TransportParameters::VersionInformation CreateFakeVersionInformation() {
+  TransportParameters::VersionInformation version_information;
+  version_information.chosen_version = kFakeVersionLabel;
+  version_information.other_versions.push_back(kFakeVersionLabel);
+  return version_information;
+}
+
+// Make a TransportParameters that has a few fields set to help test comparison.
+std::unique_ptr<TransportParameters> MakeFakeTransportParams() {
+  auto params = std::make_unique<TransportParameters>();
+  params->perspective = Perspective::IS_CLIENT;
+  params->legacy_version_information = CreateFakeLegacyVersionInformation();
+  params->version_information = CreateFakeVersionInformation();
+  params->max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  params->stateless_reset_token = CreateFakeStatelessResetToken();
+  params->max_udp_payload_size.set_value(kFakeMaxPacketSize);
+  params->initial_max_data.set_value(kFakeInitialMaxData);
+  params->disable_active_migration = kFakeDisableMigration;
+  params->custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  params->custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+  return params;
+}
+
+// Generated by running TlsClientHandshakerTest.ZeroRttResumption and in
+// TlsClientHandshaker::InsertSession calling SSL_SESSION_to_bytes to serialize
+// the received 0-RTT capable ticket.
+static const char kCachedSession[] =
+    "30820ad7020101020203040402130104206594ce84e61a866b56163c4ba09079aebf1d4f"
+    "6cbcbd38dc9d7066a38a76c9cf0420ec9062063582a4cc0a44f9ff93256a195153ba6032"
+    "0cf3c9189990932d838adaa10602046196f7b9a205020302a300a382039f3082039b3082"
+    "0183a00302010202021001300d06092a864886f70d010105050030623111300f06035504"
+    "030c08426f677573204941310b300906035504080c024d41310b30090603550406130255"
+    "533121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d"
+    "3110300e060355040a0c07426f6775734941301e170d3231303132383136323030315a17"
+    "0d3331303132363136323030315a3069311d301b06035504030c14746573745f6563632e"
+    "6578616d706c652e636f6d310b300906035504080c024d41310b30090603550406130255"
+    "53311e301c06092a864886f70d010901160f626f67757340626f6775732e636f6d310e30"
+    "0c060355040a0c05426f6775733059301306072a8648ce3d020106082a8648ce3d030107"
+    "034200041ba5e2b6f24e64990b9f24ae6d23473d8c77fbcfb7f554f36559529a69a57170"
+    "a10a81b7fe4a36ebf37b0a8c5e467a8443d8b8c002892aa5c1194bd843f42c9aa31f301d"
+    "301b0603551d11041430128210746573742e6578616d706c652e636f6d300d06092a8648"
+    "86f70d0101050500038202010019921d54ac06948763d609215f64f5d6540e3da886c6c9"
+    "61bc737a437719b4621416ef1229f39282d7d3234e1a5d57535473066233bd246eec8e96"
+    "1e0633cf4fe014c800e62599981820ec33d92e74ded0fa2953db1d81e19cb6890b6305b6"
+    "3ede8d3e9fcf3c09f3f57283acf08aa57be4ee9a68d00bb3e2ded5920c619b5d83e5194a"
+    "adb77ae5d61ed3e0a5670f0ae61cc3197329f0e71e3364dcab0405e9e4a6646adef8f022"
+    "6415ec16c8046307b1769029fe780bd576114dde2fa9b4a32aa70bc436549a24ee4907a9"
+    "045f6457ce8dfd8d62cc65315afe798ae1a948eefd70b035d415e73569c48fb20085de1a"
+    "87de039e6b0b9a5fcb4069df27f3a7a1409e72d1ac739c72f29ef786134207e61c79855f"
+    "c22e3ee5f6ad59a7b1ff0f18d79776f1c95efaebbebe381664132a58a1e7ff689945b7e0"
+    "88634b0872feeefbf6be020884b994c6a7ff435f2b3f609077ff97cb509cfa17ff479b34"
+    "e633e4b5bc46b20c5f27c80a2e2943f795a928acd5a3fc43c3af8425ad600c048b41d87e"
+    "6361bc72fc4e5e44680a3d325674ba6ffa760d2fc7d9e4847a8e0dd9d35a543324e18b94"
+    "2d42af6391ed1dd54a39e3f4a4c6b32486eb4ba72815dbd89c56fc053743a0b0483ce676"
+    "15defce6800c629b99d0cbc56da162487f475b7c246099eaf1e6d10a022b2f49c6af1da3"
+    "e8ed66096f267c4a76976b9572db7456ef90278330a4020400aa81b60481b3494e534543"
+    "55524500f3439e548c21d2ad6e5634cc1cc0045730819702010102020304040213010400"
+    "0420ec9062063582a4cc0a44f9ff93256a195153ba60320cf3c9189990932d838adaa106"
+    "02046196f7b9a205020302a300a4020400b20302011db5060404130800cdb807020500ff"
+    "ffffffb9050203093a80ba0404026833bb030101ffbc23042100d27d985bfce04833f02d"
+    "38366b219f4def42bc4ba1b01844d1778db11731487dbd020400be020400b20302011db3"
+    "8205da308205d6308203bea00302010202021000300d06092a864886f70d010105050030"
+    "62310b3009060355040613025553310b300906035504080c024d413110300e060355040a"
+    "0c07426f67757343413111300f06035504030c08426f6775732043413121301f06092a86"
+    "4886f70d0109011612626f67757340626f6775732d63612e636f6d3020170d3231303132"
+    "383136313935385a180f32303730303531313136313935385a30623111300f0603550403"
+    "0c08426f677573204941310b300906035504080c024d41310b3009060355040613025553"
+    "3121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d31"
+    "10300e060355040a0c07426f677573494130820222300d06092a864886f70d0101010500"
+    "0382020f003082020a028202010096c03a0ffc61bcedcd5ec9bf6f848b8a066b43f08377"
+    "3af518a6a0044f22e666e24d2ae741954e344302c4be04612185bd53bcd848eb322bf900"
+    "724eb0848047d647033ffbddb00f01d1de7c1cdb684f83c9bf5fd18ff60afad5a53b0d7d"
+    "2c2a50abc38df019cd7f50194d05bc4597a1ef8570ea04069a2c36d74496af126573ca18"
+    "8e470009b56250fadf2a04e837ee3837b36b1f08b7a0cfe2533d05f26484ce4e30203d01"
+    "517fffd3da63d0341079ddce16e9ab4dbf9d4049e5cc52326031e645dd682fe6220d9e0e"
+    "95451f5a82f3e1720dc13e8499466426a0bdbea9f6a76b3c9228dd3c79ab4dcc4c145ef0"
+    "e78d1ee8bfd4650692d7e28a54bed809d8f7b37fe24c586be59cc46638531cb291c8c156"
+    "8f08d67e768e51563e95a639c1f138b275ffad6a6a2a042ba9e26ad63c2ce63b600013f0"
+    "a6f0703ee51c4f457f7bab0391c2fc4c5bb3213742c9cf9941bff68cc2e1cc96139d35ed"
+    "1885244ddde0bf658416c486701841b81f7b17503d08c59a4db08a2a80755e007aa3b6c7"
+    "eadcaa9e07c8325f3689f100de23970b12c9d9f6d0a8fb35ba0fd75c64410318db4a13ac"
+    "3972ad16cdf6408af37013c7bcd7c42f20d6d04c3e39436c7531e8dafa219dd04b784ef0"
+    "3c70ee5a4782b33cafa925aa3deca62a14aed704f179b932efabc2b0c5c15a8a99bfc9e6"
+    "189dce7da50ea303594b6af9c933dd54b6e9d17c472d0203010001a38193308190300f06"
+    "03551d130101ff040530030101ff301d0603551d0e041604141a98e80029a80992b7e5e0"
+    "068ab9b3486cd839d6301f0603551d23041830168014780beeefe2fa419c48a438bdb30b"
+    "e37ef0b7a94e300b0603551d0f0404030202a430130603551d25040c300a06082b060105"
+    "05070301301b0603551d11041430128207426f67757343418207426f6775734941300d06"
+    "092a864886f70d010105050003820201009e822ed8064b1aabaddf1340010ea147f68c06"
+    "5a5a599ea305349f1b0e545a00817d6e55c7bf85560fab429ca72186c4d520b52f5cc121"
+    "abd068b06f3111494431d2522efa54642f907059e7db80b73bb5ecf621377195b8700bba"
+    "df798cece8c67a9571548d0e6592e81ae5d934877cb170aef18d3b97f635600fe0890d98"
+    "f88b33fe3d1fd34c1c915beae4e5c0b133f476c40b21d220f16ce9cdd9e8f97a36a31723"
+    "68875f052c9271648d9cb54687c6fdc3ea96f2908003bc5e5e79de00a21da7b8429f8b08"
+    "af4c4d34641e386d72eabf5f01f106363f2ffd18969bf0bb9a4d17627c6427ff772c4308"
+    "83c276feef5fc6dba9582c22fdbe9df7e8dfca375695f028ed588df54f3c86462dbf4c07"
+    "91d80ca738988a1419c86bb4dd8d738b746921f01f39422e5ffd488b6f00195b996e6392"
+    "3a820a32cd78b5989f339c0fcf4f269103964a30a16347d0ffdc8df1f3653ddc1515fa09"
+    "22c7aef1af1fbcb23e93ae7622ab1ee11fcfa98319bad4c37c091cad46bd0337b3cc78b5"
+    "5b9f1ea7994acc1f89c49a0b4cb540d2137e266fd43e56a9b5b778217b6f77df530e1eaf"
+    "b3417262b5ddb86d3c6c5ac51e3f326c650dcc2434473973b7182c66220d1f3871bde7ee"
+    "47d3f359d3d4c5bdd61baa684c03db4c75f9d6690c9e6e3abe6eaf5fa2c33c4daf26b373"
+    "d85a1e8a7d671ac4a0a97b14e36e81280de4593bbb12da7695b5060404130800cdb60301"
+    "0100b70402020403b807020500ffffffffb9050203093a80ba0404026833bb030101ffbd"
+    "020400be020400";
+
+class QuicClientSessionCacheTest : public QuicTest {
+ public:
+  QuicClientSessionCacheTest() : ssl_ctx_(SSL_CTX_new(TLS_method())) {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+ protected:
+  bssl::UniquePtr<SSL_SESSION> NewSSLSession() {
+    std::string cached_session =
+        absl::HexStringToBytes(absl::string_view(kCachedSession));
+    SSL_SESSION* session = SSL_SESSION_from_bytes(
+        reinterpret_cast<const uint8_t*>(cached_session.data()),
+        cached_session.size(), ssl_ctx_.get());
+    QUICHE_DCHECK(session);
+    return bssl::UniquePtr<SSL_SESSION>(session);
+  }
+
+  bssl::UniquePtr<SSL_SESSION> MakeTestSession(
+      QuicTime::Delta timeout = kTimeout) {
+    bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
+    SSL_SESSION_set_time(session.get(), clock_.WallNow().ToUNIXSeconds());
+    SSL_SESSION_set_timeout(session.get(), timeout.ToSeconds());
+    return session;
+  }
+
+  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+  MockClock clock_;
+};
+
+// Tests that simple insertion and lookup work correctly.
+TEST_F(QuicClientSessionCacheTest, SingleSession) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+
+  auto params2 = MakeFakeTransportParams();
+  auto session2 = MakeTestSession();
+  SSL_SESSION* unowned2 = session2.get();
+  QuicServerId id2("b.com", 443);
+
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(0u, cache.size());
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  EXPECT_EQ(1u, cache.size());
+  EXPECT_EQ(
+      *params,
+      *(cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->transport_params));
+  EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
+  // No session is available for id1, even though the entry exists.
+  EXPECT_EQ(1u, cache.size());
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  // Lookup() will trigger a deletion of invalid entry.
+  EXPECT_EQ(0u, cache.size());
+
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+  QuicServerId id3("c.com", 443);
+  cache.Insert(id3, std::move(session3), *params, nullptr);
+  cache.Insert(id2, std::move(session2), *params2, nullptr);
+  EXPECT_EQ(2u, cache.size());
+  EXPECT_EQ(
+      unowned2,
+      cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(
+      unowned3,
+      cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+
+  // Verify that the cache is cleared after Lookups.
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(nullptr, cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(0u, cache.size());
+}
+
+TEST_F(QuicClientSessionCacheTest, MultipleSessions) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+  SSL_SESSION* unowned2 = session2.get();
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id1, std::move(session2), *params, nullptr);
+  cache.Insert(id1, std::move(session3), *params, nullptr);
+  // The latest session is popped first.
+  EXPECT_EQ(
+      unowned3,
+      cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(
+      unowned2,
+      cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  // Only two sessions are cached.
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+// Test that when a different TransportParameter is inserted for
+// the same server id, the existing entry is removed.
+TEST_F(QuicClientSessionCacheTest, DifferentTransportParams) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id1, std::move(session2), *params, nullptr);
+  // tweak the transport parameters a little bit.
+  params->perspective = Perspective::IS_SERVER;
+  cache.Insert(id1, std::move(session3), *params, nullptr);
+  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_EQ(unowned3, resumption_state->tls_session.get());
+  EXPECT_EQ(*params.get(), *resumption_state->transport_params);
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+TEST_F(QuicClientSessionCacheTest, DifferentApplicationState) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+  ApplicationState state;
+  state.push_back('a');
+
+  cache.Insert(id1, std::move(session), *params, &state);
+  cache.Insert(id1, std::move(session2), *params, &state);
+  cache.Insert(id1, std::move(session3), *params, nullptr);
+  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_EQ(unowned3, resumption_state->tls_session.get());
+  EXPECT_EQ(nullptr, resumption_state->application_state);
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+TEST_F(QuicClientSessionCacheTest, BothStatesDifferent) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+  ApplicationState state;
+  state.push_back('a');
+
+  cache.Insert(id1, std::move(session), *params, &state);
+  cache.Insert(id1, std::move(session2), *params, &state);
+  params->perspective = Perspective::IS_SERVER;
+  cache.Insert(id1, std::move(session3), *params, nullptr);
+  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_EQ(unowned3, resumption_state->tls_session.get());
+  EXPECT_EQ(*params.get(), *resumption_state->transport_params);
+  EXPECT_EQ(nullptr, resumption_state->application_state);
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+// When the size limit is exceeded, the oldest entry should be erased.
+TEST_F(QuicClientSessionCacheTest, SizeLimit) {
+  QuicClientSessionCache cache(2);
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+
+  auto session2 = MakeTestSession();
+  SSL_SESSION* unowned2 = session2.get();
+  QuicServerId id2("b.com", 443);
+
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+  QuicServerId id3("c.com", 443);
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id2, std::move(session2), *params, nullptr);
+  cache.Insert(id3, std::move(session3), *params, nullptr);
+
+  EXPECT_EQ(2u, cache.size());
+  EXPECT_EQ(
+      unowned2,
+      cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(
+      unowned3,
+      cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+TEST_F(QuicClientSessionCacheTest, ClearEarlyData) {
+  QuicClientSessionCache cache;
+  SSL_CTX_set_early_data_enabled(ssl_ctx_.get(), 1);
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+
+  EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
+  EXPECT_TRUE(SSL_SESSION_early_data_capable(session2.get()));
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id1, std::move(session2), *params, nullptr);
+
+  cache.ClearEarlyData(id1);
+
+  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_FALSE(
+      SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
+  resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_FALSE(
+      SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+// Expired session isn't considered valid and nullptr will be returned upon
+// Lookup.
+TEST_F(QuicClientSessionCacheTest, Expiration) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+
+  auto session2 = MakeTestSession(3 * kTimeout);
+  SSL_SESSION* unowned2 = session2.get();
+  QuicServerId id2("b.com", 443);
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id2, std::move(session2), *params, nullptr);
+
+  EXPECT_EQ(2u, cache.size());
+  // Expire the session.
+  clock_.AdvanceTime(kTimeout * 2);
+  // The entry has not been removed yet.
+  EXPECT_EQ(2u, cache.size());
+
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(1u, cache.size());
+  EXPECT_EQ(
+      unowned2,
+      cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(1u, cache.size());
+}
+
+TEST_F(QuicClientSessionCacheTest, RemoveExpiredEntriesAndClear) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  quic::QuicServerId id1("a.com", 443);
+
+  auto session2 = MakeTestSession(3 * kTimeout);
+  quic::QuicServerId id2("b.com", 443);
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id2, std::move(session2), *params, nullptr);
+
+  EXPECT_EQ(2u, cache.size());
+  // Expire the session.
+  clock_.AdvanceTime(kTimeout * 2);
+  // The entry has not been removed yet.
+  EXPECT_EQ(2u, cache.size());
+
+  // Flush expired sessions.
+  cache.RemoveExpiredEntries(clock_.WallNow());
+
+  // session is expired and should be flushed.
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(1u, cache.size());
+
+  cache.Clear();
+  EXPECT_EQ(0u, cache.size());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_compressed_certs_cache.cc b/quiche/quic/core/crypto/quic_compressed_certs_cache.cc
new file mode 100644
index 0000000..9627aba
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_compressed_certs_cache.cc
@@ -0,0 +1,119 @@
+// Copyright 2016 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 <string>
+
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+
+namespace quic {
+
+namespace {
+
+// Inline helper function for extending a 64-bit |seed| in-place with a 64-bit
+// |value|. Based on Boost's hash_combine function.
+inline void hash_combine(uint64_t* seed, const uint64_t& val) {
+  (*seed) ^= val + 0x9e3779b9 + ((*seed) << 6) + ((*seed) >> 2);
+}
+
+}  // namespace
+
+const size_t QuicCompressedCertsCache::kQuicCompressedCertsCacheSize = 225;
+
+QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts()
+    : chain(nullptr),
+      client_cached_cert_hashes(nullptr) {}
+
+QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string* client_cached_cert_hashes)
+    : chain(chain), client_cached_cert_hashes(client_cached_cert_hashes) {}
+
+QuicCompressedCertsCache::UncompressedCerts::~UncompressedCerts() {}
+
+QuicCompressedCertsCache::CachedCerts::CachedCerts() {}
+
+QuicCompressedCertsCache::CachedCerts::CachedCerts(
+    const UncompressedCerts& uncompressed_certs,
+    const std::string& compressed_cert)
+    : chain_(uncompressed_certs.chain),
+      client_cached_cert_hashes_(*uncompressed_certs.client_cached_cert_hashes),
+      compressed_cert_(compressed_cert) {}
+
+QuicCompressedCertsCache::CachedCerts::CachedCerts(const CachedCerts& other) =
+    default;
+
+QuicCompressedCertsCache::CachedCerts::~CachedCerts() {}
+
+bool QuicCompressedCertsCache::CachedCerts::MatchesUncompressedCerts(
+    const UncompressedCerts& uncompressed_certs) const {
+  return (client_cached_cert_hashes_ ==
+              *uncompressed_certs.client_cached_cert_hashes &&
+          chain_ == uncompressed_certs.chain);
+}
+
+const std::string* QuicCompressedCertsCache::CachedCerts::compressed_cert()
+    const {
+  return &compressed_cert_;
+}
+
+QuicCompressedCertsCache::QuicCompressedCertsCache(int64_t max_num_certs)
+    : certs_cache_(max_num_certs) {}
+
+QuicCompressedCertsCache::~QuicCompressedCertsCache() {
+  // Underlying cache must be cleared before destruction.
+  certs_cache_.Clear();
+}
+
+const std::string* QuicCompressedCertsCache::GetCompressedCert(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string& client_cached_cert_hashes) {
+  UncompressedCerts uncompressed_certs(chain, &client_cached_cert_hashes);
+
+  uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);
+
+  CachedCerts* cached_value = nullptr;
+  auto iter = certs_cache_.Lookup(key);
+  if (iter != certs_cache_.end()) {
+    cached_value = iter->second.get();
+  }
+  if (cached_value != nullptr &&
+      cached_value->MatchesUncompressedCerts(uncompressed_certs)) {
+    return cached_value->compressed_cert();
+  }
+  return nullptr;
+}
+
+void QuicCompressedCertsCache::Insert(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string& client_cached_cert_hashes,
+    const std::string& compressed_cert) {
+  UncompressedCerts uncompressed_certs(chain, &client_cached_cert_hashes);
+
+  uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);
+
+  // Insert one unit to the cache.
+  std::unique_ptr<CachedCerts> cached_certs(
+      new CachedCerts(uncompressed_certs, compressed_cert));
+  certs_cache_.Insert(key, std::move(cached_certs));
+}
+
+size_t QuicCompressedCertsCache::MaxSize() {
+  return certs_cache_.MaxSize();
+}
+
+size_t QuicCompressedCertsCache::Size() {
+  return certs_cache_.Size();
+}
+
+uint64_t QuicCompressedCertsCache::ComputeUncompressedCertsHash(
+    const UncompressedCerts& uncompressed_certs) {
+  uint64_t hash =
+      std::hash<std::string>()(*uncompressed_certs.client_cached_cert_hashes);
+
+  hash_combine(&hash,
+               reinterpret_cast<uint64_t>(uncompressed_certs.chain.get()));
+  return hash;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_compressed_certs_cache.h b/quiche/quic/core/crypto/quic_compressed_certs_cache.h
new file mode 100644
index 0000000..918981e
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_compressed_certs_cache.h
@@ -0,0 +1,103 @@
+// Copyright 2016 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_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
+
+#include <string>
+#include <vector>
+
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/quic_lru_cache.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicCompressedCertsCache is a cache to track most recently compressed certs.
+class QUIC_EXPORT_PRIVATE QuicCompressedCertsCache {
+ public:
+  explicit QuicCompressedCertsCache(int64_t max_num_certs);
+  ~QuicCompressedCertsCache();
+
+  // Returns the pointer to the cached compressed cert if
+  // |chain, client_cached_cert_hashes| hits cache.
+  // Otherwise, return nullptr.
+  // Returned pointer might become invalid on the next call to Insert().
+  const std::string* GetCompressedCert(
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const std::string& client_cached_cert_hashes);
+
+  // Inserts the specified
+  // |chain, client_cached_cert_hashes, compressed_cert| tuple to the cache.
+  // If the insertion causes the cache to become overfull, entries will
+  // be deleted in an LRU order to make room.
+  void Insert(
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const std::string& client_cached_cert_hashes,
+      const std::string& compressed_cert);
+
+  // Returns max number of cache entries the cache can carry.
+  size_t MaxSize();
+
+  // Returns current number of cache entries in the cache.
+  size_t Size();
+
+  // Default size of the QuicCompressedCertsCache per server side investigation.
+  static const size_t kQuicCompressedCertsCacheSize;
+
+ private:
+  // A wrapper of the tuple:
+  //   |chain, client_cached_cert_hashes|
+  // to identify uncompressed representation of certs.
+  struct QUIC_EXPORT_PRIVATE UncompressedCerts {
+    UncompressedCerts();
+    UncompressedCerts(
+        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+        const std::string* client_cached_cert_hashes);
+    ~UncompressedCerts();
+
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain;
+    const std::string* client_cached_cert_hashes;
+  };
+
+  // Certs stored by QuicCompressedCertsCache where uncompressed certs data is
+  // used to identify the uncompressed representation of certs and
+  // |compressed_cert| is the cached compressed representation.
+  class QUIC_EXPORT_PRIVATE CachedCerts {
+   public:
+    CachedCerts();
+    CachedCerts(const UncompressedCerts& uncompressed_certs,
+                const std::string& compressed_cert);
+    CachedCerts(const CachedCerts& other);
+    ~CachedCerts();
+
+    // Returns true if the |uncompressed_certs| matches uncompressed
+    // representation of this cert.
+    bool MatchesUncompressedCerts(
+        const UncompressedCerts& uncompressed_certs) const;
+
+    const std::string* compressed_cert() const;
+
+   private:
+    // Uncompressed certs data.
+    quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain_;
+    const std::string client_cached_cert_hashes_;
+
+    // Cached compressed representation derived from uncompressed certs.
+    const std::string compressed_cert_;
+  };
+
+  // Computes a uint64_t hash for |uncompressed_certs|.
+  uint64_t ComputeUncompressedCertsHash(
+      const UncompressedCerts& uncompressed_certs);
+
+  // Key is a unit64_t hash for UncompressedCerts. Stored associated value is
+  // CachedCerts which has both original uncompressed certs data and the
+  // compressed representation of the certs.
+  QuicLRUCache<uint64_t, CachedCerts> certs_cache_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
diff --git a/quiche/quic/core/crypto/quic_compressed_certs_cache_test.cc b/quiche/quic/core/crypto/quic_compressed_certs_cache_test.cc
new file mode 100644
index 0000000..b98f9f2
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_compressed_certs_cache_test.cc
@@ -0,0 +1,91 @@
+// Copyright 2016 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 "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+class QuicCompressedCertsCacheTest : public QuicTest {
+ public:
+  QuicCompressedCertsCacheTest()
+      : certs_cache_(QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {}
+
+ protected:
+  QuicCompressedCertsCache certs_cache_;
+};
+
+TEST_F(QuicCompressedCertsCacheTest, CacheHit) {
+  std::vector<std::string> certs = {"leaf cert", "intermediate cert",
+                                    "root cert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+  std::string cached_certs = "cached certs";
+  std::string compressed = "compressed cert";
+
+  certs_cache_.Insert(chain, cached_certs, compressed);
+
+  const std::string* cached_value =
+      certs_cache_.GetCompressedCert(chain, cached_certs);
+  ASSERT_NE(nullptr, cached_value);
+  EXPECT_EQ(*cached_value, compressed);
+}
+
+TEST_F(QuicCompressedCertsCacheTest, CacheMiss) {
+  std::vector<std::string> certs = {"leaf cert", "intermediate cert",
+                                    "root cert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+
+  std::string cached_certs = "cached certs";
+  std::string compressed = "compressed cert";
+
+  certs_cache_.Insert(chain, cached_certs, compressed);
+
+  EXPECT_EQ(nullptr,
+            certs_cache_.GetCompressedCert(chain, "mismatched cached certs"));
+
+  // A different chain though with equivalent certs should get a cache miss.
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain2(
+      new ProofSource::Chain(certs));
+  EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(chain2, cached_certs));
+}
+
+TEST_F(QuicCompressedCertsCacheTest, CacheMissDueToEviction) {
+  // Test cache returns a miss when a queried uncompressed certs was cached but
+  // then evicted.
+  std::vector<std::string> certs = {"leaf cert", "intermediate cert",
+                                    "root cert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+
+  std::string cached_certs = "cached certs";
+  std::string compressed = "compressed cert";
+  certs_cache_.Insert(chain, cached_certs, compressed);
+
+  // Insert another kQuicCompressedCertsCacheSize certs to evict the first
+  // cached cert.
+  for (unsigned int i = 0;
+       i < QuicCompressedCertsCache::kQuicCompressedCertsCacheSize; i++) {
+    EXPECT_EQ(certs_cache_.Size(), i + 1);
+    certs_cache_.Insert(chain, absl::StrCat(i), absl::StrCat(i));
+  }
+  EXPECT_EQ(certs_cache_.MaxSize(), certs_cache_.Size());
+
+  EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(chain, cached_certs));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypter.cc b/quiche/quic/core/crypto/quic_crypter.cc
new file mode 100644
index 0000000..05c8e3a
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypter.cc
@@ -0,0 +1,18 @@
+// Copyright (c) 2019 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 "quiche/quic/core/crypto/quic_crypter.h"
+#include "absl/strings/string_view.h"
+
+namespace quic {
+
+bool QuicCrypter::SetNoncePrefixOrIV(const ParsedQuicVersion& version,
+                                     absl::string_view nonce_prefix_or_iv) {
+  if (version.UsesInitialObfuscators()) {
+    return SetIV(nonce_prefix_or_iv);
+  }
+  return SetNoncePrefix(nonce_prefix_or_iv);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypter.h b/quiche/quic/core/crypto/quic_crypter.h
new file mode 100644
index 0000000..d57a8e6
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypter.h
@@ -0,0 +1,94 @@
+// 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_CRYPTO_QUIC_CRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicCrypter is the parent class for QuicEncrypter and QuicDecrypter.
+// Its purpose is to provide an interface for using methods that are common to
+// both classes when operations are being done that apply to both encrypters and
+// decrypters.
+class QUIC_EXPORT_PRIVATE QuicCrypter {
+ public:
+  virtual ~QuicCrypter() {}
+
+  // Sets the symmetric encryption/decryption key. Returns true on success,
+  // false on failure.
+  //
+  // NOTE: The key is the client_write_key or server_write_key derived from
+  // the master secret.
+  virtual bool SetKey(absl::string_view key) = 0;
+
+  // Sets the fixed initial bytes of the nonce. Returns true on success,
+  // false on failure. This method must only be used with Google QUIC crypters.
+  //
+  // NOTE: The nonce prefix is the client_write_iv or server_write_iv
+  // derived from the master secret. A 64-bit packet number will
+  // be appended to form the nonce.
+  //
+  //                          <------------ 64 bits ----------->
+  //   +---------------------+----------------------------------+
+  //   |    Fixed prefix     |      packet number      |
+  //   +---------------------+----------------------------------+
+  //                          Nonce format
+  //
+  // The security of the nonce format requires that QUIC never reuse a
+  // packet number, even when retransmitting a lost packet.
+  virtual bool SetNoncePrefix(absl::string_view nonce_prefix) = 0;
+
+  // Sets |iv| as the initialization vector to use when constructing the nonce.
+  // Returns true on success, false on failure. This method must only be used
+  // with IETF QUIC crypters.
+  //
+  // Google QUIC and IETF QUIC use different nonce constructions. This method
+  // must be used when using IETF QUIC; SetNoncePrefix must be used when using
+  // Google QUIC.
+  //
+  // The nonce is constructed as follows (draft-ietf-quic-tls-14 section 5.2):
+  //
+  //    <---------------- max(8, N_MIN) bytes ----------------->
+  //   +--------------------------------------------------------+
+  //   |                 packet protection IV                   |
+  //   +--------------------------------------------------------+
+  //                             XOR
+  //                          <------------ 64 bits ----------->
+  //   +---------------------+----------------------------------+
+  //   |        zeroes       |   reconstructed packet number    |
+  //   +---------------------+----------------------------------+
+  //
+  // The nonce is the packet protection IV (|iv|) XOR'd with the left-padded
+  // reconstructed packet number.
+  //
+  // The security of the nonce format requires that QUIC never reuse a
+  // packet number, even when retransmitting a lost packet.
+  virtual bool SetIV(absl::string_view iv) = 0;
+
+  // Calls SetNoncePrefix or SetIV depending on whether |version| uses the
+  // Google QUIC crypto or IETF QUIC nonce construction.
+  virtual bool SetNoncePrefixOrIV(const ParsedQuicVersion& version,
+                                  absl::string_view nonce_prefix_or_iv);
+
+  // Sets the key to use for header protection.
+  virtual bool SetHeaderProtectionKey(absl::string_view key) = 0;
+
+  // GetKeySize, GetIVSize, and GetNoncePrefixSize are used to know how many
+  // bytes of key material needs to be derived from the master secret.
+
+  // Returns the size in bytes of a key for the algorithm.
+  virtual size_t GetKeySize() const = 0;
+  // Returns the size in bytes of an IV to use with the algorithm.
+  virtual size_t GetIVSize() const = 0;
+  // Returns the size in bytes of the fixed initial part of the nonce.
+  virtual size_t GetNoncePrefixSize() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
diff --git a/quiche/quic/core/crypto/quic_crypto_client_config.cc b/quiche/quic/core/crypto/quic_crypto_client_config.cc
new file mode 100644
index 0000000..e857591
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_client_config.cc
@@ -0,0 +1,857 @@
+// Copyright 2013 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 "quiche/quic/core/crypto/quic_crypto_client_config.h"
+
+#include <algorithm>
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/curve25519_key_exchange.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/core/crypto/p256_key_exchange.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/crypto/tls_client_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_client_stats.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Tracks the reason (the state of the server config) for sending inchoate
+// ClientHello to the server.
+void RecordInchoateClientHelloReason(
+    QuicCryptoClientConfig::CachedState::ServerConfigState state) {
+  QUIC_CLIENT_HISTOGRAM_ENUM(
+      "QuicInchoateClientHelloReason", state,
+      QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT, "");
+}
+
+// Tracks the state of the QUIC server information loaded from the disk cache.
+void RecordDiskCacheServerConfigState(
+    QuicCryptoClientConfig::CachedState::ServerConfigState state) {
+  QUIC_CLIENT_HISTOGRAM_ENUM(
+      "QuicServerInfo.DiskCacheState", state,
+      QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT, "");
+}
+
+}  // namespace
+
+QuicCryptoClientConfig::QuicCryptoClientConfig(
+    std::unique_ptr<ProofVerifier> proof_verifier)
+    : QuicCryptoClientConfig(std::move(proof_verifier), nullptr) {}
+
+QuicCryptoClientConfig::QuicCryptoClientConfig(
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
+    : proof_verifier_(std::move(proof_verifier)),
+      session_cache_(std::move(session_cache)),
+      ssl_ctx_(TlsClientConnection::CreateSslCtx(
+          !GetQuicFlag(FLAGS_quic_disable_client_tls_zero_rtt))) {
+  QUICHE_DCHECK(proof_verifier_.get());
+  SetDefaults();
+}
+
+QuicCryptoClientConfig::~QuicCryptoClientConfig() {}
+
+QuicCryptoClientConfig::CachedState::CachedState()
+    : server_config_valid_(false),
+      expiration_time_(QuicWallTime::Zero()),
+      generation_counter_(0) {}
+
+QuicCryptoClientConfig::CachedState::~CachedState() {}
+
+bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const {
+  if (server_config_.empty()) {
+    RecordInchoateClientHelloReason(SERVER_CONFIG_EMPTY);
+    return false;
+  }
+
+  if (!server_config_valid_) {
+    RecordInchoateClientHelloReason(SERVER_CONFIG_INVALID);
+    return false;
+  }
+
+  const CryptoHandshakeMessage* scfg = GetServerConfig();
+  if (!scfg) {
+    // Should be impossible short of cache corruption.
+    RecordInchoateClientHelloReason(SERVER_CONFIG_CORRUPTED);
+    QUICHE_DCHECK(false);
+    return false;
+  }
+
+  if (now.IsBefore(expiration_time_)) {
+    return true;
+  }
+
+  QUIC_CLIENT_HISTOGRAM_TIMES(
+      "QuicClientHelloServerConfig.InvalidDuration",
+      QuicTime::Delta::FromSeconds(now.ToUNIXSeconds() -
+                                   expiration_time_.ToUNIXSeconds()),
+      QuicTime::Delta::FromSeconds(60),              // 1 min.
+      QuicTime::Delta::FromSeconds(20 * 24 * 3600),  // 20 days.
+      50, "");
+  RecordInchoateClientHelloReason(SERVER_CONFIG_EXPIRED);
+  return false;
+}
+
+bool QuicCryptoClientConfig::CachedState::IsEmpty() const {
+  return server_config_.empty();
+}
+
+const CryptoHandshakeMessage*
+QuicCryptoClientConfig::CachedState::GetServerConfig() const {
+  if (server_config_.empty()) {
+    return nullptr;
+  }
+
+  if (!scfg_) {
+    scfg_ = CryptoFramer::ParseMessage(server_config_);
+    QUICHE_DCHECK(scfg_.get());
+  }
+  return scfg_.get();
+}
+
+QuicCryptoClientConfig::CachedState::ServerConfigState
+QuicCryptoClientConfig::CachedState::SetServerConfig(
+    absl::string_view server_config,
+    QuicWallTime now,
+    QuicWallTime expiry_time,
+    std::string* error_details) {
+  const bool matches_existing = server_config == server_config_;
+
+  // Even if the new server config matches the existing one, we still wish to
+  // reject it if it has expired.
+  std::unique_ptr<CryptoHandshakeMessage> new_scfg_storage;
+  const CryptoHandshakeMessage* new_scfg;
+
+  if (!matches_existing) {
+    new_scfg_storage = CryptoFramer::ParseMessage(server_config);
+    new_scfg = new_scfg_storage.get();
+  } else {
+    new_scfg = GetServerConfig();
+  }
+
+  if (!new_scfg) {
+    *error_details = "SCFG invalid";
+    return SERVER_CONFIG_INVALID;
+  }
+
+  if (expiry_time.IsZero()) {
+    uint64_t expiry_seconds;
+    if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
+      *error_details = "SCFG missing EXPY";
+      return SERVER_CONFIG_INVALID_EXPIRY;
+    }
+    expiration_time_ = QuicWallTime::FromUNIXSeconds(expiry_seconds);
+  } else {
+    expiration_time_ = expiry_time;
+  }
+
+  if (now.IsAfter(expiration_time_)) {
+    *error_details = "SCFG has expired";
+    return SERVER_CONFIG_EXPIRED;
+  }
+
+  if (!matches_existing) {
+    server_config_ = std::string(server_config);
+    SetProofInvalid();
+    scfg_ = std::move(new_scfg_storage);
+  }
+  return SERVER_CONFIG_VALID;
+}
+
+void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() {
+  server_config_.clear();
+  scfg_.reset();
+  SetProofInvalid();
+}
+
+void QuicCryptoClientConfig::CachedState::SetProof(
+    const std::vector<std::string>& certs,
+    absl::string_view cert_sct,
+    absl::string_view chlo_hash,
+    absl::string_view signature) {
+  bool has_changed = signature != server_config_sig_ ||
+                     chlo_hash != chlo_hash_ || certs_.size() != certs.size();
+
+  if (!has_changed) {
+    for (size_t i = 0; i < certs_.size(); i++) {
+      if (certs_[i] != certs[i]) {
+        has_changed = true;
+        break;
+      }
+    }
+  }
+
+  if (!has_changed) {
+    return;
+  }
+
+  // If the proof has changed then it needs to be revalidated.
+  SetProofInvalid();
+  certs_ = certs;
+  cert_sct_ = std::string(cert_sct);
+  chlo_hash_ = std::string(chlo_hash);
+  server_config_sig_ = std::string(signature);
+}
+
+void QuicCryptoClientConfig::CachedState::Clear() {
+  server_config_.clear();
+  source_address_token_.clear();
+  certs_.clear();
+  cert_sct_.clear();
+  chlo_hash_.clear();
+  server_config_sig_.clear();
+  server_config_valid_ = false;
+  proof_verify_details_.reset();
+  scfg_.reset();
+  ++generation_counter_;
+}
+
+void QuicCryptoClientConfig::CachedState::ClearProof() {
+  SetProofInvalid();
+  certs_.clear();
+  cert_sct_.clear();
+  chlo_hash_.clear();
+  server_config_sig_.clear();
+}
+
+void QuicCryptoClientConfig::CachedState::SetProofValid() {
+  server_config_valid_ = true;
+}
+
+void QuicCryptoClientConfig::CachedState::SetProofInvalid() {
+  server_config_valid_ = false;
+  ++generation_counter_;
+}
+
+bool QuicCryptoClientConfig::CachedState::Initialize(
+    absl::string_view server_config,
+    absl::string_view source_address_token,
+    const std::vector<std::string>& certs,
+    const std::string& cert_sct,
+    absl::string_view chlo_hash,
+    absl::string_view signature,
+    QuicWallTime now,
+    QuicWallTime expiration_time) {
+  QUICHE_DCHECK(server_config_.empty());
+
+  if (server_config.empty()) {
+    RecordDiskCacheServerConfigState(SERVER_CONFIG_EMPTY);
+    return false;
+  }
+
+  std::string error_details;
+  ServerConfigState state =
+      SetServerConfig(server_config, now, expiration_time, &error_details);
+  RecordDiskCacheServerConfigState(state);
+  if (state != SERVER_CONFIG_VALID) {
+    QUIC_DVLOG(1) << "SetServerConfig failed with " << error_details;
+    return false;
+  }
+
+  chlo_hash_.assign(chlo_hash.data(), chlo_hash.size());
+  server_config_sig_.assign(signature.data(), signature.size());
+  source_address_token_.assign(source_address_token.data(),
+                               source_address_token.size());
+  certs_ = certs;
+  cert_sct_ = cert_sct;
+  return true;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::server_config() const {
+  return server_config_;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::source_address_token()
+    const {
+  return source_address_token_;
+}
+
+const std::vector<std::string>& QuicCryptoClientConfig::CachedState::certs()
+    const {
+  return certs_;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::cert_sct() const {
+  return cert_sct_;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::chlo_hash() const {
+  return chlo_hash_;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::signature() const {
+  return server_config_sig_;
+}
+
+bool QuicCryptoClientConfig::CachedState::proof_valid() const {
+  return server_config_valid_;
+}
+
+uint64_t QuicCryptoClientConfig::CachedState::generation_counter() const {
+  return generation_counter_;
+}
+
+const ProofVerifyDetails*
+QuicCryptoClientConfig::CachedState::proof_verify_details() const {
+  return proof_verify_details_.get();
+}
+
+void QuicCryptoClientConfig::CachedState::set_source_address_token(
+    absl::string_view token) {
+  source_address_token_ = std::string(token);
+}
+
+void QuicCryptoClientConfig::CachedState::set_cert_sct(
+    absl::string_view cert_sct) {
+  cert_sct_ = std::string(cert_sct);
+}
+
+void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails(
+    ProofVerifyDetails* details) {
+  proof_verify_details_.reset(details);
+}
+
+void QuicCryptoClientConfig::CachedState::InitializeFrom(
+    const QuicCryptoClientConfig::CachedState& other) {
+  QUICHE_DCHECK(server_config_.empty());
+  QUICHE_DCHECK(!server_config_valid_);
+  server_config_ = other.server_config_;
+  source_address_token_ = other.source_address_token_;
+  certs_ = other.certs_;
+  cert_sct_ = other.cert_sct_;
+  chlo_hash_ = other.chlo_hash_;
+  server_config_sig_ = other.server_config_sig_;
+  server_config_valid_ = other.server_config_valid_;
+  expiration_time_ = other.expiration_time_;
+  if (other.proof_verify_details_ != nullptr) {
+    proof_verify_details_.reset(other.proof_verify_details_->Clone());
+  }
+  ++generation_counter_;
+}
+
+void QuicCryptoClientConfig::SetDefaults() {
+  // Key exchange methods.
+  kexs = {kC255, kP256};
+
+  // Authenticated encryption algorithms. Prefer AES-GCM if hardware-supported
+  // fast implementation is available.
+  if (EVP_has_aes_hardware() == 1) {
+    aead = {kAESG, kCC20};
+  } else {
+    aead = {kCC20, kAESG};
+  }
+}
+
+QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate(
+    const QuicServerId& server_id) {
+  auto it = cached_states_.find(server_id);
+  if (it != cached_states_.end()) {
+    return it->second.get();
+  }
+
+  CachedState* cached = new CachedState;
+  cached_states_.insert(std::make_pair(server_id, absl::WrapUnique(cached)));
+  bool cache_populated = PopulateFromCanonicalConfig(server_id, cached);
+  QUIC_CLIENT_HISTOGRAM_BOOL(
+      "QuicCryptoClientConfig.PopulatedFromCanonicalConfig", cache_populated,
+      "");
+  return cached;
+}
+
+void QuicCryptoClientConfig::ClearCachedStates(const ServerIdFilter& filter) {
+  for (auto it = cached_states_.begin(); it != cached_states_.end(); ++it) {
+    if (filter.Matches(it->first))
+      it->second->Clear();
+  }
+}
+
+void QuicCryptoClientConfig::FillInchoateClientHello(
+    const QuicServerId& server_id, const ParsedQuicVersion preferred_version,
+    const CachedState* cached, QuicRandom* rand, bool demand_x509_proof,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    CryptoHandshakeMessage* out) const {
+  out->set_tag(kCHLO);
+  out->set_minimum_size(1);
+
+  // Server name indication. We only send SNI if it's a valid domain name, as
+  // per the spec.
+  if (QuicHostnameUtils::IsValidSNI(server_id.host())) {
+    out->SetStringPiece(kSNI, server_id.host());
+  }
+  out->SetVersion(kVER, preferred_version);
+
+  if (!user_agent_id_.empty()) {
+    out->SetStringPiece(kUAID, user_agent_id_);
+  }
+
+  if (!alpn_.empty()) {
+    out->SetStringPiece(kALPN, alpn_);
+  }
+
+  // Even though this is an inchoate CHLO, send the SCID so that
+  // the STK can be validated by the server.
+  const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
+  if (scfg != nullptr) {
+    absl::string_view scid;
+    if (scfg->GetStringPiece(kSCID, &scid)) {
+      out->SetStringPiece(kSCID, scid);
+    }
+  }
+
+  if (!cached->source_address_token().empty()) {
+    out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token());
+  }
+
+  if (!demand_x509_proof) {
+    return;
+  }
+
+  char proof_nonce[32];
+  rand->RandBytes(proof_nonce, ABSL_ARRAYSIZE(proof_nonce));
+  out->SetStringPiece(
+      kNONP, absl::string_view(proof_nonce, ABSL_ARRAYSIZE(proof_nonce)));
+
+  out->SetVector(kPDMD, QuicTagVector{kX509});
+
+  out->SetStringPiece(kCertificateSCTTag, "");
+
+  const std::vector<std::string>& certs = cached->certs();
+  // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the
+  // client config is being used for multiple connections, another connection
+  // doesn't update the cached certificates and cause us to be unable to
+  // process the server's compressed certificate chain.
+  out_params->cached_certs = certs;
+  if (!certs.empty()) {
+    std::vector<uint64_t> hashes;
+    hashes.reserve(certs.size());
+    for (auto i = certs.begin(); i != certs.end(); ++i) {
+      hashes.push_back(QuicUtils::FNV1a_64_Hash(*i));
+    }
+    out->SetVector(kCCRT, hashes);
+  }
+}
+
+QuicErrorCode QuicCryptoClientConfig::FillClientHello(
+    const QuicServerId& server_id, QuicConnectionId connection_id,
+    const ParsedQuicVersion preferred_version,
+    const ParsedQuicVersion actual_version, const CachedState* cached,
+    QuicWallTime now, QuicRandom* rand,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    CryptoHandshakeMessage* out, std::string* error_details) const {
+  QUICHE_DCHECK(error_details != nullptr);
+  QUIC_BUG_IF(quic_bug_12943_2,
+              !QuicUtils::IsConnectionIdValidForVersion(
+                  connection_id, preferred_version.transport_version))
+      << "FillClientHello: attempted to use connection ID " << connection_id
+      << " which is invalid with version " << preferred_version;
+
+  FillInchoateClientHello(server_id, preferred_version, cached, rand,
+                          /* demand_x509_proof= */ true, out_params, out);
+
+  out->set_minimum_size(1);
+
+  const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
+  if (!scfg) {
+    // This should never happen as our caller should have checked
+    // cached->IsComplete() before calling this function.
+    *error_details = "Handshake not ready";
+    return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+
+  absl::string_view scid;
+  if (!scfg->GetStringPiece(kSCID, &scid)) {
+    *error_details = "SCFG missing SCID";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+  out->SetStringPiece(kSCID, scid);
+
+  out->SetStringPiece(kCertificateSCTTag, "");
+
+  QuicTagVector their_aeads;
+  QuicTagVector their_key_exchanges;
+  if (scfg->GetTaglist(kAEAD, &their_aeads) != QUIC_NO_ERROR ||
+      scfg->GetTaglist(kKEXS, &their_key_exchanges) != QUIC_NO_ERROR) {
+    *error_details = "Missing AEAD or KEXS";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  // AEAD: the work loads on the client and server are symmetric. Since the
+  // client is more likely to be CPU-constrained, break the tie by favoring
+  // the client's preference.
+  // Key exchange: the client does more work than the server, so favor the
+  // client's preference.
+  size_t key_exchange_index;
+  if (!FindMutualQuicTag(aead, their_aeads, &out_params->aead, nullptr) ||
+      !FindMutualQuicTag(kexs, their_key_exchanges, &out_params->key_exchange,
+                         &key_exchange_index)) {
+    *error_details = "Unsupported AEAD or KEXS";
+    return QUIC_CRYPTO_NO_SUPPORT;
+  }
+  out->SetVector(kAEAD, QuicTagVector{out_params->aead});
+  out->SetVector(kKEXS, QuicTagVector{out_params->key_exchange});
+
+  absl::string_view public_value;
+  if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) !=
+      QUIC_NO_ERROR) {
+    *error_details = "Missing public value";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  absl::string_view orbit;
+  if (!scfg->GetStringPiece(kORBT, &orbit) || orbit.size() != kOrbitSize) {
+    *error_details = "SCFG missing OBIT";
+    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  }
+
+  CryptoUtils::GenerateNonce(now, rand, orbit, &out_params->client_nonce);
+  out->SetStringPiece(kNONC, out_params->client_nonce);
+  if (!out_params->server_nonce.empty()) {
+    out->SetStringPiece(kServerNonceTag, out_params->server_nonce);
+  }
+
+  switch (out_params->key_exchange) {
+    case kC255:
+      out_params->client_key_exchange = Curve25519KeyExchange::New(
+          Curve25519KeyExchange::NewPrivateKey(rand));
+      break;
+    case kP256:
+      out_params->client_key_exchange =
+          P256KeyExchange::New(P256KeyExchange::NewPrivateKey());
+      break;
+    default:
+      QUICHE_DCHECK(false);
+      *error_details = "Configured to support an unknown key exchange";
+      return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+
+  if (!out_params->client_key_exchange->CalculateSharedKeySync(
+          public_value, &out_params->initial_premaster_secret)) {
+    *error_details = "Key exchange failure";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+  out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value());
+
+  const std::vector<std::string>& certs = cached->certs();
+  if (certs.empty()) {
+    *error_details = "No certs to calculate XLCT";
+    return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+  out->SetValue(kXLCT, CryptoUtils::ComputeLeafCertHash(certs[0]));
+
+  // Derive the symmetric keys and set up the encrypters and decrypters.
+  // Set the following members of out_params:
+  //   out_params->hkdf_input_suffix
+  //   out_params->initial_crypters
+  out_params->hkdf_input_suffix.clear();
+  out_params->hkdf_input_suffix.append(connection_id.data(),
+                                       connection_id.length());
+  const QuicData& client_hello_serialized = out->GetSerialized();
+  out_params->hkdf_input_suffix.append(client_hello_serialized.data(),
+                                       client_hello_serialized.length());
+  out_params->hkdf_input_suffix.append(cached->server_config());
+  if (certs.empty()) {
+    *error_details = "No certs found to include in KDF";
+    return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+  out_params->hkdf_input_suffix.append(certs[0]);
+
+  std::string hkdf_input;
+  const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
+  hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
+  hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
+  hkdf_input.append(out_params->hkdf_input_suffix);
+
+  std::string* subkey_secret = &out_params->initial_subkey_secret;
+
+  if (!CryptoUtils::DeriveKeys(
+          actual_version, out_params->initial_premaster_secret,
+          out_params->aead, out_params->client_nonce, out_params->server_nonce,
+          pre_shared_key_, hkdf_input, Perspective::IS_CLIENT,
+          CryptoUtils::Diversification::Pending(),
+          &out_params->initial_crypters, subkey_secret)) {
+    *error_details = "Symmetric key setup failed";
+    return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig(
+    const CryptoHandshakeMessage& message,
+    QuicWallTime now,
+    QuicTransportVersion /*version*/,
+    absl::string_view chlo_hash,
+    const std::vector<std::string>& cached_certs,
+    CachedState* cached,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  absl::string_view scfg;
+  if (!message.GetStringPiece(kSCFG, &scfg)) {
+    *error_details = "Missing SCFG";
+    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  }
+
+  QuicWallTime expiration_time = QuicWallTime::Zero();
+  uint64_t expiry_seconds;
+  if (message.GetUint64(kSTTL, &expiry_seconds) == QUIC_NO_ERROR) {
+    // Only cache configs for a maximum of 1 week.
+    expiration_time = now.Add(QuicTime::Delta::FromSeconds(
+        std::min(expiry_seconds, kNumSecondsPerWeek)));
+  }
+
+  CachedState::ServerConfigState state =
+      cached->SetServerConfig(scfg, now, expiration_time, error_details);
+  if (state == CachedState::SERVER_CONFIG_EXPIRED) {
+    return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED;
+  }
+  // TODO(rtenneti): Return more specific error code than returning
+  // QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER.
+  if (state != CachedState::SERVER_CONFIG_VALID) {
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  absl::string_view token;
+  if (message.GetStringPiece(kSourceAddressTokenTag, &token)) {
+    cached->set_source_address_token(token);
+  }
+
+  absl::string_view proof, cert_bytes, cert_sct;
+  bool has_proof = message.GetStringPiece(kPROF, &proof);
+  bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes);
+  if (has_proof && has_cert) {
+    std::vector<std::string> certs;
+    if (!CertCompressor::DecompressChain(cert_bytes, cached_certs, &certs)) {
+      *error_details = "Certificate data invalid";
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+
+    message.GetStringPiece(kCertificateSCTTag, &cert_sct);
+    cached->SetProof(certs, cert_sct, chlo_hash, proof);
+  } else {
+    // Secure QUIC: clear existing proof as we have been sent a new SCFG
+    // without matching proof/certs.
+    cached->ClearProof();
+
+    if (has_proof && !has_cert) {
+      *error_details = "Certificate missing";
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+
+    if (!has_proof && has_cert) {
+      *error_details = "Proof missing";
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
+    const CryptoHandshakeMessage& rej, QuicWallTime now,
+    const QuicTransportVersion version, absl::string_view chlo_hash,
+    CachedState* cached,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  if (rej.tag() != kREJ) {
+    *error_details = "Message is not REJ";
+    return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+
+  QuicErrorCode error =
+      CacheNewServerConfig(rej, now, version, chlo_hash,
+                           out_params->cached_certs, cached, error_details);
+  if (error != QUIC_NO_ERROR) {
+    return error;
+  }
+
+  absl::string_view nonce;
+  if (rej.GetStringPiece(kServerNonceTag, &nonce)) {
+    out_params->server_nonce = std::string(nonce);
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
+    const CryptoHandshakeMessage& server_hello,
+    QuicConnectionId /*connection_id*/, ParsedQuicVersion version,
+    const ParsedQuicVersionVector& negotiated_versions, CachedState* cached,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  QuicErrorCode valid = CryptoUtils::ValidateServerHello(
+      server_hello, negotiated_versions, error_details);
+  if (valid != QUIC_NO_ERROR) {
+    return valid;
+  }
+
+  // Learn about updated source address tokens.
+  absl::string_view token;
+  if (server_hello.GetStringPiece(kSourceAddressTokenTag, &token)) {
+    cached->set_source_address_token(token);
+  }
+
+  absl::string_view shlo_nonce;
+  if (!server_hello.GetStringPiece(kServerNonceTag, &shlo_nonce)) {
+    *error_details = "server hello missing server nonce";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  // TODO(agl):
+  //   learn about updated SCFGs.
+
+  absl::string_view public_value;
+  if (!server_hello.GetStringPiece(kPUBS, &public_value)) {
+    *error_details = "server hello missing forward secure public value";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  if (!out_params->client_key_exchange->CalculateSharedKeySync(
+          public_value, &out_params->forward_secure_premaster_secret)) {
+    *error_details = "Key exchange failure";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  std::string hkdf_input;
+  const size_t label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
+  hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
+  hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, label_len);
+  hkdf_input.append(out_params->hkdf_input_suffix);
+
+  if (!CryptoUtils::DeriveKeys(
+          version, out_params->forward_secure_premaster_secret,
+          out_params->aead, out_params->client_nonce,
+          shlo_nonce.empty() ? out_params->server_nonce : shlo_nonce,
+          pre_shared_key_, hkdf_input, Perspective::IS_CLIENT,
+          CryptoUtils::Diversification::Never(),
+          &out_params->forward_secure_crypters, &out_params->subkey_secret)) {
+    *error_details = "Symmetric key setup failed";
+    return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicCryptoClientConfig::ProcessServerConfigUpdate(
+    const CryptoHandshakeMessage& server_config_update, QuicWallTime now,
+    const QuicTransportVersion version, absl::string_view chlo_hash,
+    CachedState* cached,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  if (server_config_update.tag() != kSCUP) {
+    *error_details = "ServerConfigUpdate must have kSCUP tag.";
+    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+  }
+  return CacheNewServerConfig(server_config_update, now, version, chlo_hash,
+                              out_params->cached_certs, cached, error_details);
+}
+
+ProofVerifier* QuicCryptoClientConfig::proof_verifier() const {
+  return proof_verifier_.get();
+}
+
+SessionCache* QuicCryptoClientConfig::session_cache() const {
+  return session_cache_.get();
+}
+
+ClientProofSource* QuicCryptoClientConfig::proof_source() const {
+  return proof_source_.get();
+}
+
+void QuicCryptoClientConfig::set_proof_source(
+    std::unique_ptr<ClientProofSource> proof_source) {
+  proof_source_ = std::move(proof_source);
+}
+
+SSL_CTX* QuicCryptoClientConfig::ssl_ctx() const {
+  return ssl_ctx_.get();
+}
+
+void QuicCryptoClientConfig::InitializeFrom(
+    const QuicServerId& server_id,
+    const QuicServerId& canonical_server_id,
+    QuicCryptoClientConfig* canonical_crypto_config) {
+  CachedState* canonical_cached =
+      canonical_crypto_config->LookupOrCreate(canonical_server_id);
+  if (!canonical_cached->proof_valid()) {
+    return;
+  }
+  CachedState* cached = LookupOrCreate(server_id);
+  cached->InitializeFrom(*canonical_cached);
+}
+
+void QuicCryptoClientConfig::AddCanonicalSuffix(const std::string& suffix) {
+  canonical_suffixes_.push_back(suffix);
+}
+
+bool QuicCryptoClientConfig::PopulateFromCanonicalConfig(
+    const QuicServerId& server_id, CachedState* cached) {
+  QUICHE_DCHECK(cached->IsEmpty());
+  size_t i = 0;
+  for (; i < canonical_suffixes_.size(); ++i) {
+    if (absl::EndsWithIgnoreCase(server_id.host(), canonical_suffixes_[i])) {
+      break;
+    }
+  }
+  if (i == canonical_suffixes_.size()) {
+    return false;
+  }
+
+  QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(),
+                                server_id.privacy_mode_enabled());
+  auto it = canonical_server_map_.lower_bound(suffix_server_id);
+  if (it == canonical_server_map_.end() || it->first != suffix_server_id) {
+    // This is the first host we've seen which matches the suffix, so make it
+    // canonical.  Use |it| as position hint for faster insertion.
+    canonical_server_map_.insert(
+        it, std::make_pair(std::move(suffix_server_id), std::move(server_id)));
+    return false;
+  }
+
+  const QuicServerId& canonical_server_id = it->second;
+  CachedState* canonical_state = cached_states_[canonical_server_id].get();
+  if (!canonical_state->proof_valid()) {
+    return false;
+  }
+
+  // Update canonical version to point at the "most recent" entry.
+  it->second = server_id;
+
+  cached->InitializeFrom(*canonical_state);
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypto_client_config.h b/quiche/quic/core/crypto/quic_crypto_client_config.h
new file mode 100644
index 0000000..8b66ad5
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_client_config.h
@@ -0,0 +1,473 @@
+// Copyright 2013 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_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/client_proof_source.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+class CryptoHandshakeMessage;
+class ProofVerifier;
+class ProofVerifyDetails;
+class QuicRandom;
+
+// QuicResumptionState stores the state a client needs for performing connection
+// resumption.
+struct QUIC_EXPORT_PRIVATE QuicResumptionState {
+  // |tls_session| holds the cryptographic state necessary for a resumption. It
+  // includes the ALPN negotiated on the connection where the ticket was
+  // received.
+  bssl::UniquePtr<SSL_SESSION> tls_session;
+
+  // If the application using QUIC doesn't support 0-RTT handshakes or the
+  // client didn't receive a 0-RTT capable session ticket from the server,
+  // |transport_params| will be null. Otherwise, it will contain the transport
+  // parameters received from the server on the original connection.
+  std::unique_ptr<TransportParameters> transport_params = nullptr;
+
+  // If |transport_params| is null, then |application_state| is ignored and
+  // should be empty. |application_state| contains serialized state that the
+  // client received from the server at the application layer that the client
+  // needs to remember when performing a 0-RTT handshake.
+  std::unique_ptr<ApplicationState> application_state = nullptr;
+
+  // Opaque token received in NEW_TOKEN frame if any.
+  std::string token;
+};
+
+// SessionCache is an interface for managing storing and retrieving
+// QuicResumptionState structs.
+class QUIC_EXPORT_PRIVATE SessionCache {
+ public:
+  virtual ~SessionCache() {}
+
+  // Inserts |session|, |params|, and |application_states| into the cache, keyed
+  // by |server_id|. Insert is first called after all three values are present.
+  // The ownership of |session| is transferred to the cache, while other two are
+  // copied. Multiple sessions might need to be inserted for a connection.
+  // SessionCache implementations should support storing
+  // multiple entries per server ID.
+  virtual void Insert(const QuicServerId& server_id,
+                      bssl::UniquePtr<SSL_SESSION> session,
+                      const TransportParameters& params,
+                      const ApplicationState* application_state) = 0;
+
+  // Lookup is called once at the beginning of each TLS handshake to potentially
+  // provide the saved state both for the TLS handshake and for sending 0-RTT
+  // data (if supported). Lookup may return a nullptr. Implementations should
+  // delete cache entries after returning them in Lookup so that session tickets
+  // are used only once.
+  virtual std::unique_ptr<QuicResumptionState> Lookup(
+      const QuicServerId& server_id, QuicWallTime now, const SSL_CTX* ctx) = 0;
+
+  // Called when 0-RTT is rejected. Disables early data for all the TLS tickets
+  // associated with |server_id|.
+  virtual void ClearEarlyData(const QuicServerId& server_id) = 0;
+
+  // Called when NEW_TOKEN frame is received.
+  virtual void OnNewTokenReceived(const QuicServerId& server_id,
+                                  absl::string_view token) = 0;
+
+  // Called to remove expired entries.
+  virtual void RemoveExpiredEntries(QuicWallTime now) = 0;
+
+  // Clear the session cache.
+  virtual void Clear() = 0;
+};
+
+// QuicCryptoClientConfig contains crypto-related configuration settings for a
+// client. Note that this object isn't thread-safe. It's designed to be used on
+// a single thread at a time.
+class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
+ public:
+  // A CachedState contains the information that the client needs in order to
+  // perform a 0-RTT handshake with a server. This information can be reused
+  // over several connections to the same server.
+  class QUIC_EXPORT_PRIVATE CachedState {
+   public:
+    // Enum to track if the server config is valid or not. If it is not valid,
+    // it specifies why it is invalid.
+    enum ServerConfigState {
+      // WARNING: Do not change the numerical values of any of server config
+      // state. Do not remove deprecated server config states - just comment
+      // them as deprecated.
+      SERVER_CONFIG_EMPTY = 0,
+      SERVER_CONFIG_INVALID = 1,
+      SERVER_CONFIG_CORRUPTED = 2,
+      SERVER_CONFIG_EXPIRED = 3,
+      SERVER_CONFIG_INVALID_EXPIRY = 4,
+      SERVER_CONFIG_VALID = 5,
+      // NOTE: Add new server config states only immediately above this line.
+      // Make sure to update the QuicServerConfigState enum in
+      // tools/metrics/histograms/histograms.xml accordingly.
+      SERVER_CONFIG_COUNT
+    };
+
+    CachedState();
+    CachedState(const CachedState&) = delete;
+    CachedState& operator=(const CachedState&) = delete;
+    ~CachedState();
+
+    // IsComplete returns true if this object contains enough information to
+    // perform a handshake with the server. |now| is used to judge whether any
+    // cached server config has expired.
+    bool IsComplete(QuicWallTime now) const;
+
+    // IsEmpty returns true if |server_config_| is empty.
+    bool IsEmpty() const;
+
+    // GetServerConfig returns the parsed contents of |server_config|, or
+    // nullptr if |server_config| is empty. The return value is owned by this
+    // object and is destroyed when this object is.
+    const CryptoHandshakeMessage* GetServerConfig() const;
+
+    // SetServerConfig checks that |server_config| parses correctly and stores
+    // it in |server_config_|. |now| is used to judge whether |server_config|
+    // has expired.
+    ServerConfigState SetServerConfig(absl::string_view server_config,
+                                      QuicWallTime now,
+                                      QuicWallTime expiry_time,
+                                      std::string* error_details);
+
+    // InvalidateServerConfig clears the cached server config (if any).
+    void InvalidateServerConfig();
+
+    // SetProof stores a cert chain, cert signed timestamp and signature.
+    void SetProof(const std::vector<std::string>& certs,
+                  absl::string_view cert_sct,
+                  absl::string_view chlo_hash,
+                  absl::string_view signature);
+
+    // Clears all the data.
+    void Clear();
+
+    // Clears the certificate chain and signature and invalidates the proof.
+    void ClearProof();
+
+    // SetProofValid records that the certificate chain and signature have been
+    // validated and that it's safe to assume that the server is legitimate.
+    // (Note: this does not check the chain or signature.)
+    void SetProofValid();
+
+    // If the server config or the proof has changed then it needs to be
+    // revalidated. Helper function to keep server_config_valid_ and
+    // generation_counter_ in sync.
+    void SetProofInvalid();
+
+    const std::string& server_config() const;
+    const std::string& source_address_token() const;
+    const std::vector<std::string>& certs() const;
+    const std::string& cert_sct() const;
+    const std::string& chlo_hash() const;
+    const std::string& signature() const;
+    bool proof_valid() const;
+    uint64_t generation_counter() const;
+    const ProofVerifyDetails* proof_verify_details() const;
+
+    void set_source_address_token(absl::string_view token);
+
+    void set_cert_sct(absl::string_view cert_sct);
+
+    // SetProofVerifyDetails takes ownership of |details|.
+    void SetProofVerifyDetails(ProofVerifyDetails* details);
+
+    // Copy the |server_config_|, |source_address_token_|, |certs_|,
+    // |expiration_time_|, |cert_sct_|, |chlo_hash_| and |server_config_sig_|
+    // from the |other|.  The remaining fields, |generation_counter_|,
+    // |proof_verify_details_|, and |scfg_| remain unchanged.
+    void InitializeFrom(const CachedState& other);
+
+    // Initializes this cached state based on the arguments provided.
+    // Returns false if there is a problem parsing the server config.
+    bool Initialize(absl::string_view server_config,
+                    absl::string_view source_address_token,
+                    const std::vector<std::string>& certs,
+                    const std::string& cert_sct,
+                    absl::string_view chlo_hash,
+                    absl::string_view signature,
+                    QuicWallTime now,
+                    QuicWallTime expiration_time);
+
+   private:
+    std::string server_config_;         // A serialized handshake message.
+    std::string source_address_token_;  // An opaque proof of IP ownership.
+    std::vector<std::string> certs_;    // A list of certificates in leaf-first
+                                        // order.
+    std::string cert_sct_;              // Signed timestamp of the leaf cert.
+    std::string chlo_hash_;             // Hash of the CHLO message.
+    std::string server_config_sig_;     // A signature of |server_config_|.
+    bool server_config_valid_;          // True if |server_config_| is correctly
+                                // signed and |certs_| has been validated.
+    QuicWallTime expiration_time_;  // Time when the config is no longer valid.
+    // Generation counter associated with the |server_config_|, |certs_| and
+    // |server_config_sig_| combination. It is incremented whenever we set
+    // server_config_valid_ to false.
+    uint64_t generation_counter_;
+
+    std::unique_ptr<ProofVerifyDetails> proof_verify_details_;
+
+    // scfg contains the cached, parsed value of |server_config|.
+    mutable std::unique_ptr<CryptoHandshakeMessage> scfg_;
+  };
+
+  // Used to filter server ids for partial config deletion.
+  class QUIC_EXPORT_PRIVATE ServerIdFilter {
+   public:
+    virtual ~ServerIdFilter() {}
+
+    // Returns true if |server_id| matches the filter.
+    virtual bool Matches(const QuicServerId& server_id) const = 0;
+  };
+
+  // DEPRECATED: Use the constructor below instead.
+  explicit QuicCryptoClientConfig(
+      std::unique_ptr<ProofVerifier> proof_verifier);
+  QuicCryptoClientConfig(std::unique_ptr<ProofVerifier> proof_verifier,
+                         std::unique_ptr<SessionCache> session_cache);
+  QuicCryptoClientConfig(const QuicCryptoClientConfig&) = delete;
+  QuicCryptoClientConfig& operator=(const QuicCryptoClientConfig&) = delete;
+  ~QuicCryptoClientConfig();
+
+  // LookupOrCreate returns a CachedState for the given |server_id|. If no such
+  // CachedState currently exists, it will be created and cached.
+  CachedState* LookupOrCreate(const QuicServerId& server_id);
+
+  // Delete CachedState objects whose server ids match |filter| from
+  // cached_states.
+  void ClearCachedStates(const ServerIdFilter& filter);
+
+  // FillInchoateClientHello sets |out| to be a CHLO message that elicits a
+  // source-address token or SCFG from a server. If |cached| is non-nullptr, the
+  // source-address token will be taken from it. |out_params| is used in order
+  // to store the cached certs that were sent as hints to the server in
+  // |out_params->cached_certs|. |preferred_version| is the version of the
+  // QUIC protocol that this client chose to use initially. This allows the
+  // server to detect downgrade attacks.  If |demand_x509_proof| is true,
+  // then |out| will include an X509 proof demand, and the associated
+  // certificate related fields.
+  void FillInchoateClientHello(
+      const QuicServerId& server_id, const ParsedQuicVersion preferred_version,
+      const CachedState* cached, QuicRandom* rand, bool demand_x509_proof,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      CryptoHandshakeMessage* out) const;
+
+  // FillClientHello sets |out| to be a CHLO message based on the configuration
+  // of this object. This object must have cached enough information about
+  // the server's hostname in order to perform a handshake. This can be checked
+  // with the |IsComplete| member of |CachedState|.
+  //
+  // |now| and |rand| are used to generate the nonce and |out_params| is
+  // filled with the results of the handshake that the server is expected to
+  // accept. |preferred_version| is the version of the QUIC protocol that this
+  // client chose to use initially. This allows the server to detect downgrade
+  // attacks.
+  //
+  // If |channel_id_key| is not null, it is used to sign a secret value derived
+  // from the client and server's keys, and the Channel ID public key and the
+  // signature are placed in the CETV value of the CHLO.
+  QuicErrorCode FillClientHello(
+      const QuicServerId& server_id, QuicConnectionId connection_id,
+      const ParsedQuicVersion preferred_version,
+      const ParsedQuicVersion actual_version, const CachedState* cached,
+      QuicWallTime now, QuicRandom* rand,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      CryptoHandshakeMessage* out, std::string* error_details) const;
+
+  // ProcessRejection processes a REJ message from a server and updates the
+  // cached information about that server. After this, |IsComplete| may return
+  // true for that server's CachedState. If the rejection message contains state
+  // about a future handshake (i.e. an nonce value from the server), then it
+  // will be saved in |out_params|. |now| is used to judge whether the server
+  // config in the rejection message has expired.
+  QuicErrorCode ProcessRejection(
+      const CryptoHandshakeMessage& rej, QuicWallTime now,
+      QuicTransportVersion version, absl::string_view chlo_hash,
+      CachedState* cached,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      std::string* error_details);
+
+  // ProcessServerHello processes the message in |server_hello|, updates the
+  // cached information about that server, writes the negotiated parameters to
+  // |out_params| and returns QUIC_NO_ERROR. If |server_hello| is unacceptable
+  // then it puts an error message in |error_details| and returns an error
+  // code. |version| is the QUIC version for the current connection.
+  // |negotiated_versions| contains the list of version, if any, that were
+  // present in a version negotiation packet previously received from the
+  // server. The contents of this list will be compared against the list of
+  // versions provided in the VER tag of the server hello.
+  QuicErrorCode ProcessServerHello(
+      const CryptoHandshakeMessage& server_hello,
+      QuicConnectionId connection_id, ParsedQuicVersion version,
+      const ParsedQuicVersionVector& negotiated_versions, CachedState* cached,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      std::string* error_details);
+
+  // Processes the message in |server_config_update|, updating the cached source
+  // address token, and server config.
+  // If |server_config_update| is invalid then |error_details| will contain an
+  // error message, and an error code will be returned. If all has gone well
+  // QUIC_NO_ERROR is returned.
+  QuicErrorCode ProcessServerConfigUpdate(
+      const CryptoHandshakeMessage& server_config_update, QuicWallTime now,
+      const QuicTransportVersion version, absl::string_view chlo_hash,
+      CachedState* cached,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      std::string* error_details);
+
+  ProofVerifier* proof_verifier() const;
+  SessionCache* session_cache() const;
+  ClientProofSource* proof_source() const;
+  void set_proof_source(std::unique_ptr<ClientProofSource> proof_source);
+  SSL_CTX* ssl_ctx() const;
+
+  // Initialize the CachedState from |canonical_crypto_config| for the
+  // |canonical_server_id| as the initial CachedState for |server_id|. We will
+  // copy config data only if |canonical_crypto_config| has valid proof.
+  void InitializeFrom(const QuicServerId& server_id,
+                      const QuicServerId& canonical_server_id,
+                      QuicCryptoClientConfig* canonical_crypto_config);
+
+  // Adds |suffix| as a domain suffix for which the server's crypto config
+  // is expected to be shared among servers with the domain suffix. If a server
+  // matches this suffix, then the server config from another server with the
+  // suffix will be used to initialize the cached state for this server.
+  void AddCanonicalSuffix(const std::string& suffix);
+
+  // Saves the |user_agent_id| that will be passed in QUIC's CHLO message.
+  void set_user_agent_id(const std::string& user_agent_id) {
+    user_agent_id_ = user_agent_id;
+  }
+
+  // Returns the user_agent_id that will be provided in the client hello
+  // handshake message.
+  const std::string& user_agent_id() const { return user_agent_id_; }
+
+  void set_tls_signature_algorithms(std::string signature_algorithms) {
+    tls_signature_algorithms_ = std::move(signature_algorithms);
+  }
+
+  const absl::optional<std::string>& tls_signature_algorithms() const {
+    return tls_signature_algorithms_;
+  }
+
+  // Saves the |alpn| that will be passed in QUIC's CHLO message.
+  void set_alpn(const std::string& alpn) { alpn_ = alpn; }
+
+  // Saves the pre-shared key used during the handshake.
+  void set_pre_shared_key(absl::string_view psk) {
+    pre_shared_key_ = std::string(psk);
+  }
+
+  // Returns the pre-shared key used during the handshake.
+  const std::string& pre_shared_key() const { return pre_shared_key_; }
+
+  bool pad_inchoate_hello() const { return pad_inchoate_hello_; }
+  void set_pad_inchoate_hello(bool new_value) {
+    pad_inchoate_hello_ = new_value;
+  }
+
+  bool pad_full_hello() const { return pad_full_hello_; }
+  void set_pad_full_hello(bool new_value) { pad_full_hello_ = new_value; }
+
+  SessionCache* mutable_session_cache() { return session_cache_.get(); }
+
+ private:
+  // Sets the members to reasonable, default values.
+  void SetDefaults();
+
+  // CacheNewServerConfig checks for SCFG, STK, PROF, and CRT tags in |message|,
+  // verifies them, and stores them in the cached state if they validate.
+  // This is used on receipt of a REJ from a server, or when a server sends
+  // updated server config during a connection.
+  QuicErrorCode CacheNewServerConfig(
+      const CryptoHandshakeMessage& message,
+      QuicWallTime now,
+      QuicTransportVersion version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& cached_certs,
+      CachedState* cached,
+      std::string* error_details);
+
+  // If the suffix of the hostname in |server_id| is in |canonical_suffixes_|,
+  // then populate |cached| with the canonical cached state from
+  // |canonical_server_map_| for that suffix. Returns true if |cached| is
+  // initialized with canonical cached state.
+  bool PopulateFromCanonicalConfig(const QuicServerId& server_id,
+                                   CachedState* cached);
+
+  // cached_states_ maps from the server_id to the cached information about
+  // that server.
+  std::map<QuicServerId, std::unique_ptr<CachedState>> cached_states_;
+
+  // Contains a map of servers which could share the same server config. Map
+  // from a canonical host suffix/port/scheme to a representative server with
+  // the canonical suffix, which has a plausible set of initial certificates
+  // (or at least server public key).
+  std::map<QuicServerId, QuicServerId> canonical_server_map_;
+
+  // Contains list of suffixes (for exmaple ".c.youtube.com",
+  // ".googlevideo.com") of canonical hostnames.
+  std::vector<std::string> canonical_suffixes_;
+
+  std::unique_ptr<ProofVerifier> proof_verifier_;
+  std::unique_ptr<SessionCache> session_cache_;
+  std::unique_ptr<ClientProofSource> proof_source_;
+
+  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+
+  // The |user_agent_id_| passed in QUIC's CHLO message.
+  std::string user_agent_id_;
+
+  // The |alpn_| passed in QUIC's CHLO message.
+  std::string alpn_;
+
+  // If non-empty, the client will operate in the pre-shared key mode by
+  // incorporating |pre_shared_key_| into the key schedule.
+  std::string pre_shared_key_;
+
+  // If set, configure the client to use the specified signature algorithms, via
+  // SSL_set1_sigalgs_list. TLS only.
+  absl::optional<std::string> tls_signature_algorithms_;
+
+  // In QUIC, technically, client hello should be fully padded.
+  // However, fully padding on slow network connection (e.g. 50kbps) can add
+  // 150ms latency to one roundtrip. Therefore, you can disable padding of
+  // individual messages. It is recommend to leave at least one message in
+  // each direction fully padded (e.g. full CHLO and SHLO), but if you know
+  // the lower-bound MTU, you don't need to pad all of them (keep in mind that
+  // it's not OK to do it according to the standard).
+  //
+  // Also, if you disable padding, you must disable (change) the
+  // anti-amplification protection. You should only do so if you have some
+  // other means of verifying the client.
+  bool pad_inchoate_hello_ = true;
+  bool pad_full_hello_ = true;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
diff --git a/quiche/quic/core/crypto/quic_crypto_client_config_test.cc b/quiche/quic/core/crypto/quic_crypto_client_config_test.cc
new file mode 100644
index 0000000..7556592
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_client_config_test.cc
@@ -0,0 +1,550 @@
+// Copyright 2013 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 "quiche/quic/core/crypto/quic_crypto_client_config.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::StartsWith;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestProofVerifyDetails : public ProofVerifyDetails {
+  ~TestProofVerifyDetails() override {}
+
+  // ProofVerifyDetails implementation
+  ProofVerifyDetails* Clone() const override {
+    return new TestProofVerifyDetails;
+  }
+};
+
+class OneServerIdFilter : public QuicCryptoClientConfig::ServerIdFilter {
+ public:
+  explicit OneServerIdFilter(const QuicServerId* server_id)
+      : server_id_(*server_id) {}
+
+  bool Matches(const QuicServerId& server_id) const override {
+    return server_id == server_id_;
+  }
+
+ private:
+  const QuicServerId server_id_;
+};
+
+class AllServerIdsFilter : public QuicCryptoClientConfig::ServerIdFilter {
+ public:
+  bool Matches(const QuicServerId& /*server_id*/) const override {
+    return true;
+  }
+};
+
+}  // namespace
+
+class QuicCryptoClientConfigTest : public QuicTest {};
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_IsEmpty) {
+  QuicCryptoClientConfig::CachedState state;
+  EXPECT_TRUE(state.IsEmpty());
+}
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_IsComplete) {
+  QuicCryptoClientConfig::CachedState state;
+  EXPECT_FALSE(state.IsComplete(QuicWallTime::FromUNIXSeconds(0)));
+}
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_GenerationCounter) {
+  QuicCryptoClientConfig::CachedState state;
+  EXPECT_EQ(0u, state.generation_counter());
+  state.SetProofInvalid();
+  EXPECT_EQ(1u, state.generation_counter());
+}
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_SetProofVerifyDetails) {
+  QuicCryptoClientConfig::CachedState state;
+  EXPECT_TRUE(state.proof_verify_details() == nullptr);
+  ProofVerifyDetails* details = new TestProofVerifyDetails;
+  state.SetProofVerifyDetails(details);
+  EXPECT_EQ(details, state.proof_verify_details());
+}
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_InitializeFrom) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig::CachedState other;
+  state.set_source_address_token("TOKEN");
+  // TODO(rch): Populate other fields of |state|.
+  other.InitializeFrom(state);
+  EXPECT_EQ(state.server_config(), other.server_config());
+  EXPECT_EQ(state.source_address_token(), other.source_address_token());
+  EXPECT_EQ(state.certs(), other.certs());
+  EXPECT_EQ(1u, other.generation_counter());
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChlo) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.set_user_agent_id("quic-tester");
+  config.set_alpn("hq");
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  QuicVersionLabel cver;
+  EXPECT_THAT(msg.GetVersionLabel(kVER, &cver), IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
+  absl::string_view proof_nonce;
+  EXPECT_TRUE(msg.GetStringPiece(kNONP, &proof_nonce));
+  EXPECT_EQ(std::string(32, 'r'), proof_nonce);
+  absl::string_view user_agent_id;
+  EXPECT_TRUE(msg.GetStringPiece(kUAID, &user_agent_id));
+  EXPECT_EQ("quic-tester", user_agent_id);
+  absl::string_view alpn;
+  EXPECT_TRUE(msg.GetStringPiece(kALPN, &alpn));
+  EXPECT_EQ("hq", alpn);
+  EXPECT_EQ(msg.minimum_size(), 1u);
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChloIsNotPadded) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.set_pad_inchoate_hello(false);
+  config.set_user_agent_id("quic-tester");
+  config.set_alpn("hq");
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  EXPECT_EQ(msg.minimum_size(), 1u);
+}
+
+// Make sure AES-GCM is the preferred encryption algorithm if it has hardware
+// acceleration.
+TEST_F(QuicCryptoClientConfigTest, PreferAesGcm) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  if (EVP_has_aes_hardware() == 1) {
+    EXPECT_EQ(kAESG, config.aead[0]);
+  } else {
+    EXPECT_EQ(kCC20, config.aead[0]);
+  }
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChloSecure) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  QuicTag pdmd;
+  EXPECT_THAT(msg.GetUint32(kPDMD, &pdmd), IsQuicNoError());
+  EXPECT_EQ(kX509, pdmd);
+  absl::string_view scid;
+  EXPECT_FALSE(msg.GetStringPiece(kSCID, &scid));
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCIDNoEXPY) {
+  // Test that a config with no EXPY is still valid when a non-zero
+  // expiry time is passed in.
+  QuicCryptoClientConfig::CachedState state;
+  CryptoHandshakeMessage scfg;
+  scfg.set_tag(kSCFG);
+  scfg.SetStringPiece(kSCID, "12345678");
+  std::string details;
+  QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
+  QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
+  state.SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
+                        &details);
+  EXPECT_FALSE(state.IsEmpty());
+
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  absl::string_view scid;
+  EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
+  EXPECT_EQ("12345678", scid);
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) {
+  QuicCryptoClientConfig::CachedState state;
+  CryptoHandshakeMessage scfg;
+  scfg.set_tag(kSCFG);
+  uint64_t future = 1;
+  scfg.SetValue(kEXPY, future);
+  scfg.SetStringPiece(kSCID, "12345678");
+  std::string details;
+  state.SetServerConfig(scfg.GetSerialized().AsStringPiece(),
+                        QuicWallTime::FromUNIXSeconds(1),
+                        QuicWallTime::FromUNIXSeconds(0), &details);
+  EXPECT_FALSE(state.IsEmpty());
+
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  absl::string_view scid;
+  EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
+  EXPECT_EQ("12345678", scid);
+}
+
+TEST_F(QuicCryptoClientConfigTest, FillClientHello) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  QuicConnectionId kConnectionId = TestConnectionId(1234);
+  std::string error_details;
+  MockRandom rand;
+  CryptoHandshakeMessage chlo;
+  QuicServerId server_id("www.google.com", 443, false);
+  config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
+                         QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
+                         params, &chlo, &error_details);
+
+  // Verify that the version label has been set correctly in the CHLO.
+  QuicVersionLabel cver;
+  EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
+}
+
+TEST_F(QuicCryptoClientConfigTest, FillClientHelloNoPadding) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.set_pad_full_hello(false);
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  QuicConnectionId kConnectionId = TestConnectionId(1234);
+  std::string error_details;
+  MockRandom rand;
+  CryptoHandshakeMessage chlo;
+  QuicServerId server_id("www.google.com", 443, false);
+  config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
+                         QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
+                         params, &chlo, &error_details);
+
+  // Verify that the version label has been set correctly in the CHLO.
+  QuicVersionLabel cver;
+  EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
+  EXPECT_EQ(chlo.minimum_size(), 1u);
+}
+
+TEST_F(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) {
+  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  if (supported_versions.size() == 1) {
+    // No downgrade attack is possible if the client only supports one version.
+    return;
+  }
+
+  ParsedQuicVersionVector supported_version_vector;
+  for (size_t i = supported_versions.size(); i > 0; --i) {
+    supported_version_vector.push_back(supported_versions[i - 1]);
+  }
+
+  CryptoHandshakeMessage msg;
+  msg.set_tag(kSHLO);
+  msg.SetVersionVector(kVER, supported_version_vector);
+
+  QuicCryptoClientConfig::CachedState cached;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      out_params(new QuicCryptoNegotiatedParameters);
+  std::string error;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  EXPECT_THAT(config.ProcessServerHello(
+                  msg, EmptyQuicConnectionId(), supported_versions.front(),
+                  supported_versions, &cached, out_params, &error),
+              IsError(QUIC_VERSION_NEGOTIATION_MISMATCH));
+  EXPECT_THAT(error, StartsWith("Downgrade attack detected: ServerVersions"));
+}
+
+TEST_F(QuicCryptoClientConfigTest, InitializeFrom) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  QuicServerId canonical_server_id("www.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state =
+      config.LookupOrCreate(canonical_server_id);
+  // TODO(rch): Populate other fields of |state|.
+  state->set_source_address_token("TOKEN");
+  state->SetProofValid();
+
+  QuicServerId other_server_id("mail.google.com", 443, false);
+  config.InitializeFrom(other_server_id, canonical_server_id, &config);
+  QuicCryptoClientConfig::CachedState* other =
+      config.LookupOrCreate(other_server_id);
+
+  EXPECT_EQ(state->server_config(), other->server_config());
+  EXPECT_EQ(state->source_address_token(), other->source_address_token());
+  EXPECT_EQ(state->certs(), other->certs());
+  EXPECT_EQ(1u, other->generation_counter());
+}
+
+TEST_F(QuicCryptoClientConfigTest, Canonical) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.AddCanonicalSuffix(".google.com");
+  QuicServerId canonical_id1("www.google.com", 443, false);
+  QuicServerId canonical_id2("mail.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state =
+      config.LookupOrCreate(canonical_id1);
+  // TODO(rch): Populate other fields of |state|.
+  state->set_source_address_token("TOKEN");
+  state->SetProofValid();
+
+  QuicCryptoClientConfig::CachedState* other =
+      config.LookupOrCreate(canonical_id2);
+
+  EXPECT_TRUE(state->IsEmpty());
+  EXPECT_EQ(state->server_config(), other->server_config());
+  EXPECT_EQ(state->source_address_token(), other->source_address_token());
+  EXPECT_EQ(state->certs(), other->certs());
+  EXPECT_EQ(1u, other->generation_counter());
+
+  QuicServerId different_id("mail.google.org", 443, false);
+  EXPECT_TRUE(config.LookupOrCreate(different_id)->IsEmpty());
+}
+
+TEST_F(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.AddCanonicalSuffix(".google.com");
+  QuicServerId canonical_id1("www.google.com", 443, false);
+  QuicServerId canonical_id2("mail.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state =
+      config.LookupOrCreate(canonical_id1);
+  // TODO(rch): Populate other fields of |state|.
+  state->set_source_address_token("TOKEN");
+
+  // Do not set the proof as valid, and check that it is not used
+  // as a canonical entry.
+  EXPECT_TRUE(config.LookupOrCreate(canonical_id2)->IsEmpty());
+}
+
+TEST_F(QuicCryptoClientConfigTest, ClearCachedStates) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+
+  // Create two states on different origins.
+  struct TestCase {
+    TestCase(const std::string& host, QuicCryptoClientConfig* config)
+        : server_id(host, 443, false),
+          state(config->LookupOrCreate(server_id)) {
+      // TODO(rch): Populate other fields of |state|.
+      CryptoHandshakeMessage scfg;
+      scfg.set_tag(kSCFG);
+      uint64_t future = 1;
+      scfg.SetValue(kEXPY, future);
+      scfg.SetStringPiece(kSCID, "12345678");
+      std::string details;
+      state->SetServerConfig(scfg.GetSerialized().AsStringPiece(),
+                             QuicWallTime::FromUNIXSeconds(0),
+                             QuicWallTime::FromUNIXSeconds(future), &details);
+
+      std::vector<std::string> certs(1);
+      certs[0] = "Hello Cert for " + host;
+      state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
+      state->set_source_address_token("TOKEN");
+      state->SetProofValid();
+
+      // The generation counter starts at 2, because proof has been once
+      // invalidated in SetServerConfig().
+      EXPECT_EQ(2u, state->generation_counter());
+    }
+
+    QuicServerId server_id;
+    QuicCryptoClientConfig::CachedState* state;
+  } test_cases[] = {TestCase("www.google.com", &config),
+                    TestCase("www.example.com", &config)};
+
+  // Verify LookupOrCreate returns the same data.
+  for (const TestCase& test_case : test_cases) {
+    QuicCryptoClientConfig::CachedState* other =
+        config.LookupOrCreate(test_case.server_id);
+    EXPECT_EQ(test_case.state, other);
+    EXPECT_EQ(2u, other->generation_counter());
+  }
+
+  // Clear the cached state for www.google.com.
+  OneServerIdFilter google_com_filter(&test_cases[0].server_id);
+  config.ClearCachedStates(google_com_filter);
+
+  // Verify LookupOrCreate doesn't have any data for google.com.
+  QuicCryptoClientConfig::CachedState* cleared_cache =
+      config.LookupOrCreate(test_cases[0].server_id);
+
+  EXPECT_EQ(test_cases[0].state, cleared_cache);
+  EXPECT_FALSE(cleared_cache->proof_valid());
+  EXPECT_TRUE(cleared_cache->server_config().empty());
+  EXPECT_TRUE(cleared_cache->certs().empty());
+  EXPECT_TRUE(cleared_cache->cert_sct().empty());
+  EXPECT_TRUE(cleared_cache->signature().empty());
+  EXPECT_EQ(3u, cleared_cache->generation_counter());
+
+  // But it still does for www.example.com.
+  QuicCryptoClientConfig::CachedState* existing_cache =
+      config.LookupOrCreate(test_cases[1].server_id);
+
+  EXPECT_EQ(test_cases[1].state, existing_cache);
+  EXPECT_TRUE(existing_cache->proof_valid());
+  EXPECT_FALSE(existing_cache->server_config().empty());
+  EXPECT_FALSE(existing_cache->certs().empty());
+  EXPECT_FALSE(existing_cache->cert_sct().empty());
+  EXPECT_FALSE(existing_cache->signature().empty());
+  EXPECT_EQ(2u, existing_cache->generation_counter());
+
+  // Clear all cached states.
+  AllServerIdsFilter all_server_ids;
+  config.ClearCachedStates(all_server_ids);
+
+  // The data for www.example.com should now be cleared as well.
+  cleared_cache = config.LookupOrCreate(test_cases[1].server_id);
+
+  EXPECT_EQ(test_cases[1].state, cleared_cache);
+  EXPECT_FALSE(cleared_cache->proof_valid());
+  EXPECT_TRUE(cleared_cache->server_config().empty());
+  EXPECT_TRUE(cleared_cache->certs().empty());
+  EXPECT_TRUE(cleared_cache->cert_sct().empty());
+  EXPECT_TRUE(cleared_cache->signature().empty());
+  EXPECT_EQ(3u, cleared_cache->generation_counter());
+}
+
+TEST_F(QuicCryptoClientConfigTest, ProcessReject) {
+  CryptoHandshakeMessage rej;
+  crypto_test_utils::FillInDummyReject(&rej);
+
+  // Now process the rejection.
+  QuicCryptoClientConfig::CachedState cached;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      out_params(new QuicCryptoNegotiatedParameters);
+  std::string error;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  EXPECT_THAT(
+      config.ProcessRejection(
+          rej, QuicWallTime::FromUNIXSeconds(0),
+          AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
+          &cached, out_params, &error),
+      IsQuicNoError());
+}
+
+TEST_F(QuicCryptoClientConfigTest, ProcessRejectWithLongTTL) {
+  CryptoHandshakeMessage rej;
+  crypto_test_utils::FillInDummyReject(&rej);
+  QuicTime::Delta one_week = QuicTime::Delta::FromSeconds(kNumSecondsPerWeek);
+  int64_t long_ttl = 3 * one_week.ToSeconds();
+  rej.SetValue(kSTTL, long_ttl);
+
+  // Now process the rejection.
+  QuicCryptoClientConfig::CachedState cached;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      out_params(new QuicCryptoNegotiatedParameters);
+  std::string error;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  EXPECT_THAT(
+      config.ProcessRejection(
+          rej, QuicWallTime::FromUNIXSeconds(0),
+          AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
+          &cached, out_params, &error),
+      IsQuicNoError());
+  cached.SetProofValid();
+  EXPECT_FALSE(cached.IsComplete(QuicWallTime::FromUNIXSeconds(long_ttl)));
+  EXPECT_FALSE(
+      cached.IsComplete(QuicWallTime::FromUNIXSeconds(one_week.ToSeconds())));
+  EXPECT_TRUE(cached.IsComplete(
+      QuicWallTime::FromUNIXSeconds(one_week.ToSeconds() - 1)));
+}
+
+TEST_F(QuicCryptoClientConfigTest, ServerNonceinSHLO) {
+  // Test that the server must include a nonce in the SHLO.
+  CryptoHandshakeMessage msg;
+  msg.set_tag(kSHLO);
+  // Choose the latest version.
+  ParsedQuicVersionVector supported_versions;
+  ParsedQuicVersion version = AllSupportedVersions().front();
+  supported_versions.push_back(version);
+  msg.SetVersionVector(kVER, supported_versions);
+
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  QuicCryptoClientConfig::CachedState cached;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      out_params(new QuicCryptoNegotiatedParameters);
+  std::string error_details;
+  EXPECT_THAT(config.ProcessServerHello(msg, EmptyQuicConnectionId(), version,
+                                        supported_versions, &cached, out_params,
+                                        &error_details),
+              IsError(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER));
+  EXPECT_EQ("server hello missing server nonce", error_details);
+}
+
+// Test that PopulateFromCanonicalConfig() handles the case of multiple entries
+// in |canonical_server_map_|.
+TEST_F(QuicCryptoClientConfigTest, MultipleCanonicalEntries) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.AddCanonicalSuffix(".google.com");
+  QuicServerId canonical_server_id1("www.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state1 =
+      config.LookupOrCreate(canonical_server_id1);
+
+  CryptoHandshakeMessage scfg;
+  scfg.set_tag(kSCFG);
+  scfg.SetStringPiece(kSCID, "12345678");
+  std::string details;
+  QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
+  QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
+  state1->SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
+                          &details);
+  state1->set_source_address_token("TOKEN");
+  state1->SetProofValid();
+  EXPECT_FALSE(state1->IsEmpty());
+
+  // This will have the same |suffix_server_id| as |canonical_server_id1|,
+  // therefore |*state2| will be initialized from |*state1|.
+  QuicServerId canonical_server_id2("mail.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state2 =
+      config.LookupOrCreate(canonical_server_id2);
+  EXPECT_FALSE(state2->IsEmpty());
+  const CryptoHandshakeMessage* const scfg2 = state2->GetServerConfig();
+  ASSERT_TRUE(scfg2);
+  EXPECT_EQ(kSCFG, scfg2->tag());
+
+  // With a different |suffix_server_id|, this will return an empty CachedState.
+  config.AddCanonicalSuffix(".example.com");
+  QuicServerId canonical_server_id3("www.example.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state3 =
+      config.LookupOrCreate(canonical_server_id3);
+  EXPECT_TRUE(state3->IsEmpty());
+  const CryptoHandshakeMessage* const scfg3 = state3->GetServerConfig();
+  EXPECT_FALSE(scfg3);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypto_proof.cc b/quiche/quic/core/crypto/quic_crypto_proof.cc
new file mode 100644
index 0000000..a449c26
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_proof.cc
@@ -0,0 +1,12 @@
+// Copyright 2016 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 "quiche/quic/core/crypto/quic_crypto_proof.h"
+
+namespace quic {
+
+QuicCryptoProof::QuicCryptoProof()
+    : send_expect_ct_header(false), cert_matched_sni(false) {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypto_proof.h b/quiche/quic/core/crypto/quic_crypto_proof.h
new file mode 100644
index 0000000..579d264
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_proof.h
@@ -0,0 +1,32 @@
+// Copyright 2016 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_CRYPTO_QUIC_CRYPTO_PROOF_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Contains the crypto-related data provided by ProofSource
+struct QUIC_EXPORT_PRIVATE QuicCryptoProof {
+  QuicCryptoProof();
+
+  // Signature generated by ProofSource
+  std::string signature;
+  // SCTList (RFC6962) to be sent to the client, if it supports receiving it.
+  std::string leaf_cert_scts;
+  // Should the Expect-CT header be sent on the connection where the
+  // certificate is used.
+  bool send_expect_ct_header;
+  // Did the selected leaf certificate contain a SubjectAltName that included
+  // the requested SNI.
+  bool cert_matched_sni;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
diff --git a/quiche/quic/core/crypto/quic_crypto_server_config.cc b/quiche/quic/core/crypto/quic_crypto_server_config.cc
new file mode 100644
index 0000000..aa2d6e0
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_server_config.cc
@@ -0,0 +1,1918 @@
+// Copyright 2013 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 "quiche/quic/core/crypto/quic_crypto_server_config.h"
+
+#include <algorithm>
+#include <cstdlib>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+#include "quiche/quic/core/crypto/channel_id.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/curve25519_key_exchange.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/core/crypto/p256_key_exchange.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_hkdf.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/crypto/tls_server_connection.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/core/proto/source_address_token_proto.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_testvalue.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+namespace {
+
+// kMultiplier is the multiple of the CHLO message size that a REJ message
+// must stay under when the client doesn't present a valid source-address
+// token. This is used to protect QUIC from amplification attacks.
+// TODO(rch): Reduce this to 2 again once b/25933682 is fixed.
+const size_t kMultiplier = 3;
+
+const int kMaxTokenAddresses = 4;
+
+std::string DeriveSourceAddressTokenKey(
+    absl::string_view source_address_token_secret) {
+  QuicHKDF hkdf(source_address_token_secret, absl::string_view() /* no salt */,
+                "QUIC source address token key",
+                CryptoSecretBoxer::GetKeySize(), 0 /* no fixed IV needed */,
+                0 /* no subkey secret */);
+  return std::string(hkdf.server_write_key());
+}
+
+// Default source for creating KeyExchange objects.
+class DefaultKeyExchangeSource : public KeyExchangeSource {
+ public:
+  DefaultKeyExchangeSource() = default;
+  ~DefaultKeyExchangeSource() override = default;
+
+  std::unique_ptr<AsynchronousKeyExchange> Create(
+      std::string /*server_config_id*/,
+      bool /* is_fallback */,
+      QuicTag type,
+      absl::string_view private_key) override {
+    if (private_key.empty()) {
+      QUIC_LOG(WARNING) << "Server config contains key exchange method without "
+                           "corresponding private key of type "
+                        << QuicTagToString(type);
+      return nullptr;
+    }
+
+    std::unique_ptr<SynchronousKeyExchange> ka =
+        CreateLocalSynchronousKeyExchange(type, private_key);
+    if (!ka) {
+      QUIC_LOG(WARNING) << "Failed to create key exchange method of type "
+                        << QuicTagToString(type);
+    }
+    return ka;
+  }
+};
+
+// Returns true if the PDMD field from the client hello demands an X509
+// certificate.
+bool ClientDemandsX509Proof(const CryptoHandshakeMessage& client_hello) {
+  QuicTagVector their_proof_demands;
+
+  if (client_hello.GetTaglist(kPDMD, &their_proof_demands) != QUIC_NO_ERROR) {
+    return false;
+  }
+
+  for (const QuicTag tag : their_proof_demands) {
+    if (tag == kX509) {
+      return true;
+    }
+  }
+  return false;
+}
+
+std::string FormatCryptoHandshakeMessageForTrace(
+    const CryptoHandshakeMessage* message) {
+  if (message == nullptr) {
+    return "<null message>";
+  }
+
+  std::string s = QuicTagToString(message->tag());
+
+  // Append the reasons for REJ.
+  if (const auto it = message->tag_value_map().find(kRREJ);
+      it != message->tag_value_map().end()) {
+    const std::string& value = it->second;
+    // The value is a vector of uint32_t(s).
+    if (value.size() % sizeof(uint32_t) == 0) {
+      absl::StrAppend(&s, " RREJ:[");
+      // Append comma-separated list of reasons to |s|.
+      for (size_t j = 0; j < value.size(); j += sizeof(uint32_t)) {
+        uint32_t reason;
+        memcpy(&reason, value.data() + j, sizeof(reason));
+        if (j > 0) {
+          absl::StrAppend(&s, ",");
+        }
+        absl::StrAppend(&s, CryptoUtils::HandshakeFailureReasonToString(
+                                static_cast<HandshakeFailureReason>(reason)));
+      }
+      absl::StrAppend(&s, "]");
+    } else {
+      absl::StrAppendFormat(&s, " RREJ:[unexpected length:%u]", value.size());
+    }
+  }
+
+  return s;
+}
+
+}  // namespace
+
+// static
+std::unique_ptr<KeyExchangeSource> KeyExchangeSource::Default() {
+  return std::make_unique<DefaultKeyExchangeSource>();
+}
+
+class ValidateClientHelloHelper {
+ public:
+  // Note: stores a pointer to a unique_ptr, and std::moves the unique_ptr when
+  // ValidationComplete is called.
+  ValidateClientHelloHelper(
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          result,
+      std::unique_ptr<ValidateClientHelloResultCallback>* done_cb)
+      : result_(std::move(result)), done_cb_(done_cb) {}
+  ValidateClientHelloHelper(const ValidateClientHelloHelper&) = delete;
+  ValidateClientHelloHelper& operator=(const ValidateClientHelloHelper&) =
+      delete;
+
+  ~ValidateClientHelloHelper() {
+    QUIC_BUG_IF(quic_bug_12963_1, done_cb_ != nullptr)
+        << "Deleting ValidateClientHelloHelper with a pending callback.";
+  }
+
+  void ValidationComplete(
+      QuicErrorCode error_code,
+      const char* error_details,
+      std::unique_ptr<ProofSource::Details> proof_source_details) {
+    result_->error_code = error_code;
+    result_->error_details = error_details;
+    (*done_cb_)->Run(std::move(result_), std::move(proof_source_details));
+    DetachCallback();
+  }
+
+  void DetachCallback() {
+    QUIC_BUG_IF(quic_bug_10630_1, done_cb_ == nullptr)
+        << "Callback already detached.";
+    done_cb_ = nullptr;
+  }
+
+ private:
+  quiche::QuicheReferenceCountedPointer<
+      ValidateClientHelloResultCallback::Result>
+      result_;
+  std::unique_ptr<ValidateClientHelloResultCallback>* done_cb_;
+};
+
+// static
+const char QuicCryptoServerConfig::TESTING[] = "secret string for testing";
+
+ClientHelloInfo::ClientHelloInfo(const QuicIpAddress& in_client_ip,
+                                 QuicWallTime in_now)
+    : client_ip(in_client_ip), now(in_now), valid_source_address_token(false) {}
+
+ClientHelloInfo::ClientHelloInfo(const ClientHelloInfo& other) = default;
+
+ClientHelloInfo::~ClientHelloInfo() {}
+
+PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() {}
+
+PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() {}
+
+ValidateClientHelloResultCallback::Result::Result(
+    const CryptoHandshakeMessage& in_client_hello,
+    QuicIpAddress in_client_ip,
+    QuicWallTime in_now)
+    : client_hello(in_client_hello),
+      info(in_client_ip, in_now),
+      error_code(QUIC_NO_ERROR) {}
+
+ValidateClientHelloResultCallback::Result::~Result() {}
+
+ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {}
+
+ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {}
+
+ProcessClientHelloResultCallback::ProcessClientHelloResultCallback() {}
+
+ProcessClientHelloResultCallback::~ProcessClientHelloResultCallback() {}
+
+QuicCryptoServerConfig::ConfigOptions::ConfigOptions()
+    : expiry_time(QuicWallTime::Zero()),
+      channel_id_enabled(false),
+      p256(false) {}
+
+QuicCryptoServerConfig::ConfigOptions::ConfigOptions(
+    const ConfigOptions& other) = default;
+
+QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() {}
+
+QuicCryptoServerConfig::ProcessClientHelloContext::
+    ~ProcessClientHelloContext() {
+  if (done_cb_ != nullptr) {
+    QUIC_LOG(WARNING)
+        << "Deleting ProcessClientHelloContext with a pending callback.";
+  }
+}
+
+void QuicCryptoServerConfig::ProcessClientHelloContext::Fail(
+    QuicErrorCode error,
+    const std::string& error_details) {
+  QUIC_TRACEPRINTF("ProcessClientHello failed: error=%s, details=%s",
+                   QuicErrorCodeToString(error), error_details);
+  done_cb_->Run(error, error_details, nullptr, nullptr, nullptr);
+  done_cb_ = nullptr;
+}
+
+void QuicCryptoServerConfig::ProcessClientHelloContext::Succeed(
+    std::unique_ptr<CryptoHandshakeMessage> message,
+    std::unique_ptr<DiversificationNonce> diversification_nonce,
+    std::unique_ptr<ProofSource::Details> proof_source_details) {
+  QUIC_TRACEPRINTF("ProcessClientHello succeeded: %s",
+                   FormatCryptoHandshakeMessageForTrace(message.get()));
+
+  done_cb_->Run(QUIC_NO_ERROR, std::string(), std::move(message),
+                std::move(diversification_nonce),
+                std::move(proof_source_details));
+  done_cb_ = nullptr;
+}
+
+QuicCryptoServerConfig::QuicCryptoServerConfig(
+    absl::string_view source_address_token_secret,
+    QuicRandom* server_nonce_entropy,
+    std::unique_ptr<ProofSource> proof_source,
+    std::unique_ptr<KeyExchangeSource> key_exchange_source)
+    : replay_protection_(true),
+      chlo_multiplier_(kMultiplier),
+      configs_lock_(),
+      primary_config_(nullptr),
+      next_config_promotion_time_(QuicWallTime::Zero()),
+      proof_source_(std::move(proof_source)),
+      key_exchange_source_(std::move(key_exchange_source)),
+      ssl_ctx_(TlsServerConnection::CreateSslCtx(proof_source_.get())),
+      source_address_token_future_secs_(3600),
+      source_address_token_lifetime_secs_(86400),
+      enable_serving_sct_(false),
+      rejection_observer_(nullptr),
+      pad_rej_(true),
+      pad_shlo_(true),
+      validate_chlo_size_(true),
+      validate_source_address_token_(true) {
+  QUICHE_DCHECK(proof_source_.get());
+  source_address_token_boxer_.SetKeys(
+      {DeriveSourceAddressTokenKey(source_address_token_secret)});
+
+  // Generate a random key and orbit for server nonces.
+  server_nonce_entropy->RandBytes(server_nonce_orbit_,
+                                  sizeof(server_nonce_orbit_));
+  const size_t key_size = server_nonce_boxer_.GetKeySize();
+  std::unique_ptr<uint8_t[]> key_bytes(new uint8_t[key_size]);
+  server_nonce_entropy->RandBytes(key_bytes.get(), key_size);
+
+  server_nonce_boxer_.SetKeys(
+      {std::string(reinterpret_cast<char*>(key_bytes.get()), key_size)});
+}
+
+QuicCryptoServerConfig::~QuicCryptoServerConfig() {}
+
+// static
+QuicServerConfigProtobuf QuicCryptoServerConfig::GenerateConfig(
+    QuicRandom* rand,
+    const QuicClock* clock,
+    const ConfigOptions& options) {
+  CryptoHandshakeMessage msg;
+
+  const std::string curve25519_private_key =
+      Curve25519KeyExchange::NewPrivateKey(rand);
+  std::unique_ptr<Curve25519KeyExchange> curve25519 =
+      Curve25519KeyExchange::New(curve25519_private_key);
+  absl::string_view curve25519_public_value = curve25519->public_value();
+
+  std::string encoded_public_values;
+  // First three bytes encode the length of the public value.
+  QUICHE_DCHECK_LT(curve25519_public_value.size(), (1U << 24));
+  encoded_public_values.push_back(
+      static_cast<char>(curve25519_public_value.size()));
+  encoded_public_values.push_back(
+      static_cast<char>(curve25519_public_value.size() >> 8));
+  encoded_public_values.push_back(
+      static_cast<char>(curve25519_public_value.size() >> 16));
+  encoded_public_values.append(curve25519_public_value.data(),
+                               curve25519_public_value.size());
+
+  std::string p256_private_key;
+  if (options.p256) {
+    p256_private_key = P256KeyExchange::NewPrivateKey();
+    std::unique_ptr<P256KeyExchange> p256(
+        P256KeyExchange::New(p256_private_key));
+    absl::string_view p256_public_value = p256->public_value();
+
+    QUICHE_DCHECK_LT(p256_public_value.size(), (1U << 24));
+    encoded_public_values.push_back(
+        static_cast<char>(p256_public_value.size()));
+    encoded_public_values.push_back(
+        static_cast<char>(p256_public_value.size() >> 8));
+    encoded_public_values.push_back(
+        static_cast<char>(p256_public_value.size() >> 16));
+    encoded_public_values.append(p256_public_value.data(),
+                                 p256_public_value.size());
+  }
+
+  msg.set_tag(kSCFG);
+  if (options.p256) {
+    msg.SetVector(kKEXS, QuicTagVector{kC255, kP256});
+  } else {
+    msg.SetVector(kKEXS, QuicTagVector{kC255});
+  }
+  msg.SetVector(kAEAD, QuicTagVector{kAESG, kCC20});
+  msg.SetStringPiece(kPUBS, encoded_public_values);
+
+  if (options.expiry_time.IsZero()) {
+    const QuicWallTime now = clock->WallNow();
+    const QuicWallTime expiry = now.Add(QuicTime::Delta::FromSeconds(
+        60 * 60 * 24 * 180 /* 180 days, ~six months */));
+    const uint64_t expiry_seconds = expiry.ToUNIXSeconds();
+    msg.SetValue(kEXPY, expiry_seconds);
+  } else {
+    msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds());
+  }
+
+  char orbit_bytes[kOrbitSize];
+  if (options.orbit.size() == sizeof(orbit_bytes)) {
+    memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes));
+  } else {
+    QUICHE_DCHECK(options.orbit.empty());
+    rand->RandBytes(orbit_bytes, sizeof(orbit_bytes));
+  }
+  msg.SetStringPiece(kORBT,
+                     absl::string_view(orbit_bytes, sizeof(orbit_bytes)));
+
+  if (options.channel_id_enabled) {
+    msg.SetVector(kPDMD, QuicTagVector{kCHID});
+  }
+
+  if (options.id.empty()) {
+    // We need to ensure that the SCID changes whenever the server config does
+    // thus we make it a hash of the rest of the server config.
+    std::unique_ptr<QuicData> serialized =
+        CryptoFramer::ConstructHandshakeMessage(msg);
+
+    uint8_t scid_bytes[SHA256_DIGEST_LENGTH];
+    SHA256(reinterpret_cast<const uint8_t*>(serialized->data()),
+           serialized->length(), scid_bytes);
+    // The SCID is a truncated SHA-256 digest.
+    static_assert(16 <= SHA256_DIGEST_LENGTH, "SCID length too high.");
+    msg.SetStringPiece(
+        kSCID,
+        absl::string_view(reinterpret_cast<const char*>(scid_bytes), 16));
+  } else {
+    msg.SetStringPiece(kSCID, options.id);
+  }
+  // Don't put new tags below this point. The SCID generation should hash over
+  // everything but itself and so extra tags should be added prior to the
+  // preceding if block.
+
+  std::unique_ptr<QuicData> serialized =
+      CryptoFramer::ConstructHandshakeMessage(msg);
+
+  QuicServerConfigProtobuf config;
+  config.set_config(std::string(serialized->AsStringPiece()));
+  QuicServerConfigProtobuf::PrivateKey* curve25519_key = config.add_key();
+  curve25519_key->set_tag(kC255);
+  curve25519_key->set_private_key(curve25519_private_key);
+
+  if (options.p256) {
+    QuicServerConfigProtobuf::PrivateKey* p256_key = config.add_key();
+    p256_key->set_tag(kP256);
+    p256_key->set_private_key(p256_private_key);
+  }
+
+  return config;
+}
+
+std::unique_ptr<CryptoHandshakeMessage> QuicCryptoServerConfig::AddConfig(
+    const QuicServerConfigProtobuf& protobuf,
+    const QuicWallTime now) {
+  std::unique_ptr<CryptoHandshakeMessage> msg =
+      CryptoFramer::ParseMessage(protobuf.config());
+
+  if (!msg) {
+    QUIC_LOG(WARNING) << "Failed to parse server config message";
+    return nullptr;
+  }
+
+  quiche::QuicheReferenceCountedPointer<Config> config =
+      ParseConfigProtobuf(protobuf, /* is_fallback = */ false);
+  if (!config) {
+    QUIC_LOG(WARNING) << "Failed to parse server config message";
+    return nullptr;
+  }
+
+  {
+    QuicWriterMutexLock locked(&configs_lock_);
+    if (configs_.find(config->id) != configs_.end()) {
+      QUIC_LOG(WARNING) << "Failed to add config because another with the same "
+                           "server config id already exists: "
+                        << absl::BytesToHexString(config->id);
+      return nullptr;
+    }
+
+    configs_[config->id] = config;
+    SelectNewPrimaryConfig(now);
+    QUICHE_DCHECK(primary_config_.get());
+    QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
+                     primary_config_.get());
+  }
+
+  return msg;
+}
+
+std::unique_ptr<CryptoHandshakeMessage>
+QuicCryptoServerConfig::AddDefaultConfig(QuicRandom* rand,
+                                         const QuicClock* clock,
+                                         const ConfigOptions& options) {
+  return AddConfig(GenerateConfig(rand, clock, options), clock->WallNow());
+}
+
+bool QuicCryptoServerConfig::SetConfigs(
+    const std::vector<QuicServerConfigProtobuf>& protobufs,
+    const QuicServerConfigProtobuf* fallback_protobuf,
+    const QuicWallTime now) {
+  std::vector<quiche::QuicheReferenceCountedPointer<Config>> parsed_configs;
+  for (auto& protobuf : protobufs) {
+    quiche::QuicheReferenceCountedPointer<Config> config =
+        ParseConfigProtobuf(protobuf, /* is_fallback = */ false);
+    if (!config) {
+      QUIC_LOG(WARNING) << "Rejecting QUIC configs because of above errors";
+      return false;
+    }
+
+    parsed_configs.push_back(config);
+  }
+
+  quiche::QuicheReferenceCountedPointer<Config> fallback_config;
+  if (fallback_protobuf != nullptr) {
+    fallback_config =
+        ParseConfigProtobuf(*fallback_protobuf, /* is_fallback = */ true);
+    if (!fallback_config) {
+      QUIC_LOG(WARNING) << "Rejecting QUIC configs because of above errors";
+      return false;
+    }
+    QUIC_LOG(INFO) << "Fallback config has scid "
+                   << absl::BytesToHexString(fallback_config->id);
+    parsed_configs.push_back(fallback_config);
+  } else {
+    QUIC_LOG(INFO) << "No fallback config provided";
+  }
+
+  if (parsed_configs.empty()) {
+    QUIC_LOG(WARNING)
+        << "Rejecting QUIC configs because new config list is empty.";
+    return false;
+  }
+
+  QUIC_LOG(INFO) << "Updating configs:";
+
+  QuicWriterMutexLock locked(&configs_lock_);
+  ConfigMap new_configs;
+
+  for (const quiche::QuicheReferenceCountedPointer<Config>& config :
+       parsed_configs) {
+    auto it = configs_.find(config->id);
+    if (it != configs_.end()) {
+      QUIC_LOG(INFO) << "Keeping scid: " << absl::BytesToHexString(config->id)
+                     << " orbit: "
+                     << absl::BytesToHexString(absl::string_view(
+                            reinterpret_cast<const char*>(config->orbit),
+                            kOrbitSize))
+                     << " new primary_time "
+                     << config->primary_time.ToUNIXSeconds()
+                     << " old primary_time "
+                     << it->second->primary_time.ToUNIXSeconds()
+                     << " new priority " << config->priority << " old priority "
+                     << it->second->priority;
+      // Update primary_time and priority.
+      it->second->primary_time = config->primary_time;
+      it->second->priority = config->priority;
+      new_configs.insert(*it);
+    } else {
+      QUIC_LOG(INFO) << "Adding scid: " << absl::BytesToHexString(config->id)
+                     << " orbit: "
+                     << absl::BytesToHexString(absl::string_view(
+                            reinterpret_cast<const char*>(config->orbit),
+                            kOrbitSize))
+                     << " primary_time " << config->primary_time.ToUNIXSeconds()
+                     << " priority " << config->priority;
+      new_configs.emplace(config->id, config);
+    }
+  }
+
+  configs_ = std::move(new_configs);
+  fallback_config_ = fallback_config;
+  SelectNewPrimaryConfig(now);
+  QUICHE_DCHECK(primary_config_.get());
+  QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
+                   primary_config_.get());
+
+  return true;
+}
+
+void QuicCryptoServerConfig::SetSourceAddressTokenKeys(
+    const std::vector<std::string>& keys) {
+  // TODO(b/208866709)
+  source_address_token_boxer_.SetKeys(keys);
+}
+
+std::vector<std::string> QuicCryptoServerConfig::GetConfigIds() const {
+  QuicReaderMutexLock locked(&configs_lock_);
+  std::vector<std::string> scids;
+  for (auto it = configs_.begin(); it != configs_.end(); ++it) {
+    scids.push_back(it->first);
+  }
+  return scids;
+}
+
+void QuicCryptoServerConfig::ValidateClientHello(
+    const CryptoHandshakeMessage& client_hello,
+    const QuicSocketAddress& client_address,
+    const QuicSocketAddress& server_address, QuicTransportVersion version,
+    const QuicClock* clock,
+    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
+    std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const {
+  const QuicWallTime now(clock->WallNow());
+
+  quiche::QuicheReferenceCountedPointer<
+      ValidateClientHelloResultCallback::Result>
+      result(new ValidateClientHelloResultCallback::Result(
+          client_hello, client_address.host(), now));
+
+  absl::string_view requested_scid;
+  // We ignore here the return value from GetStringPiece. If there is no SCID
+  // tag, EvaluateClientHello will discover that because GetCurrentConfigs will
+  // not have found the requested config (i.e. because none of the configs will
+  // have an empty string as its id).
+  client_hello.GetStringPiece(kSCID, &requested_scid);
+  Configs configs;
+  if (!GetCurrentConfigs(now, requested_scid,
+                         /* old_primary_config = */ nullptr, &configs)) {
+    result->error_code = QUIC_CRYPTO_INTERNAL_ERROR;
+    result->error_details = "No configurations loaded";
+  }
+  signed_config->config = configs.primary;
+
+  if (result->error_code == QUIC_NO_ERROR) {
+    // QUIC requires a new proof for each CHLO so clear any existing proof.
+    signed_config->chain = nullptr;
+    signed_config->proof.signature = "";
+    signed_config->proof.leaf_cert_scts = "";
+    EvaluateClientHello(server_address, client_address, version, configs,
+                        result, std::move(done_cb));
+  } else {
+    done_cb->Run(result, /* details = */ nullptr);
+  }
+}
+
+class QuicCryptoServerConfig::ProcessClientHelloCallback
+    : public ProofSource::Callback {
+ public:
+  ProcessClientHelloCallback(const QuicCryptoServerConfig* config,
+                             std::unique_ptr<ProcessClientHelloContext> context,
+                             const Configs& configs)
+      : config_(config), context_(std::move(context)), configs_(configs) {}
+
+  void Run(
+      bool ok,
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const QuicCryptoProof& proof,
+      std::unique_ptr<ProofSource::Details> details) override {
+    if (ok) {
+      context_->signed_config()->chain = chain;
+      context_->signed_config()->proof = proof;
+    }
+    config_->ProcessClientHelloAfterGetProof(!ok, std::move(details),
+                                             std::move(context_), configs_);
+  }
+
+ private:
+  const QuicCryptoServerConfig* config_;
+  std::unique_ptr<ProcessClientHelloContext> context_;
+  const Configs configs_;
+};
+
+class QuicCryptoServerConfig::ProcessClientHelloAfterGetProofCallback
+    : public AsynchronousKeyExchange::Callback {
+ public:
+  ProcessClientHelloAfterGetProofCallback(
+      const QuicCryptoServerConfig* config,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      QuicTag key_exchange_type,
+      std::unique_ptr<CryptoHandshakeMessage> out,
+      absl::string_view public_value,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      const Configs& configs)
+      : config_(config),
+        proof_source_details_(std::move(proof_source_details)),
+        key_exchange_type_(key_exchange_type),
+        out_(std::move(out)),
+        public_value_(public_value),
+        context_(std::move(context)),
+        configs_(configs) {}
+
+  void Run(bool ok) override {
+    config_->ProcessClientHelloAfterCalculateSharedKeys(
+        !ok, std::move(proof_source_details_), key_exchange_type_,
+        std::move(out_), public_value_, std::move(context_), configs_);
+  }
+
+ private:
+  const QuicCryptoServerConfig* config_;
+  std::unique_ptr<ProofSource::Details> proof_source_details_;
+  const QuicTag key_exchange_type_;
+  std::unique_ptr<CryptoHandshakeMessage> out_;
+  const std::string public_value_;
+  std::unique_ptr<ProcessClientHelloContext> context_;
+  const Configs configs_;
+  std::unique_ptr<ProcessClientHelloResultCallback> done_cb_;
+};
+
+class QuicCryptoServerConfig::SendRejectWithFallbackConfigCallback
+    : public ProofSource::Callback {
+ public:
+  SendRejectWithFallbackConfigCallback(
+      const QuicCryptoServerConfig* config,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      quiche::QuicheReferenceCountedPointer<Config> fallback_config)
+      : config_(config),
+        context_(std::move(context)),
+        fallback_config_(fallback_config) {}
+
+  // Capture |chain| and |proof| into the signed config, and then invoke
+  // SendRejectWithFallbackConfigAfterGetProof.
+  void Run(
+      bool ok,
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const QuicCryptoProof& proof,
+      std::unique_ptr<ProofSource::Details> details) override {
+    if (ok) {
+      context_->signed_config()->chain = chain;
+      context_->signed_config()->proof = proof;
+    }
+    config_->SendRejectWithFallbackConfigAfterGetProof(
+        !ok, std::move(details), std::move(context_), fallback_config_);
+  }
+
+ private:
+  const QuicCryptoServerConfig* config_;
+  std::unique_ptr<ProcessClientHelloContext> context_;
+  quiche::QuicheReferenceCountedPointer<Config> fallback_config_;
+};
+
+void QuicCryptoServerConfig::ProcessClientHello(
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        validate_chlo_result,
+    bool reject_only, QuicConnectionId connection_id,
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address, ParsedQuicVersion version,
+    const ParsedQuicVersionVector& supported_versions, const QuicClock* clock,
+    QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        params,
+    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
+    QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
+    std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const {
+  QUICHE_DCHECK(done_cb);
+  auto context = std::make_unique<ProcessClientHelloContext>(
+      validate_chlo_result, reject_only, connection_id, server_address,
+      client_address, version, supported_versions, clock, rand,
+      compressed_certs_cache, params, signed_config, total_framing_overhead,
+      chlo_packet_size, std::move(done_cb));
+
+  // Verify that various parts of the CHLO are valid
+  std::string error_details;
+  QuicErrorCode valid = CryptoUtils::ValidateClientHello(
+      context->client_hello(), context->version(),
+      context->supported_versions(), &error_details);
+  if (valid != QUIC_NO_ERROR) {
+    context->Fail(valid, error_details);
+    return;
+  }
+
+  absl::string_view requested_scid;
+  context->client_hello().GetStringPiece(kSCID, &requested_scid);
+  Configs configs;
+  if (!GetCurrentConfigs(context->clock()->WallNow(), requested_scid,
+                         signed_config->config, &configs)) {
+    context->Fail(QUIC_CRYPTO_INTERNAL_ERROR, "No configurations loaded");
+    return;
+  }
+
+  if (context->validate_chlo_result()->error_code != QUIC_NO_ERROR) {
+    context->Fail(context->validate_chlo_result()->error_code,
+                  context->validate_chlo_result()->error_details);
+    return;
+  }
+
+  if (!ClientDemandsX509Proof(context->client_hello())) {
+    context->Fail(QUIC_UNSUPPORTED_PROOF_DEMAND, "Missing or invalid PDMD");
+    return;
+  }
+
+  // No need to get a new proof if one was already generated.
+  if (!context->signed_config()->chain) {
+    const std::string chlo_hash = CryptoUtils::HashHandshakeMessage(
+        context->client_hello(), Perspective::IS_SERVER);
+    const QuicSocketAddress server_address = context->server_address();
+    const std::string sni = std::string(context->info().sni);
+    const QuicTransportVersion transport_version = context->transport_version();
+
+    auto cb = std::make_unique<ProcessClientHelloCallback>(
+        this, std::move(context), configs);
+
+    QUICHE_DCHECK(proof_source_.get());
+    proof_source_->GetProof(server_address, client_address, sni,
+                            configs.primary->serialized, transport_version,
+                            chlo_hash, std::move(cb));
+    return;
+  }
+
+  ProcessClientHelloAfterGetProof(
+      /* found_error = */ false, /* proof_source_details = */ nullptr,
+      std::move(context), configs);
+}
+
+void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof(
+    bool found_error,
+    std::unique_ptr<ProofSource::Details> proof_source_details,
+    std::unique_ptr<ProcessClientHelloContext> context,
+    const Configs& configs) const {
+  QUIC_BUG_IF(quic_bug_12963_2,
+              !QuicUtils::IsConnectionIdValidForVersion(
+                  context->connection_id(), context->transport_version()))
+      << "ProcessClientHelloAfterGetProof: attempted to use connection ID "
+      << context->connection_id() << " which is invalid with version "
+      << context->version();
+
+  if (context->info().reject_reasons.empty()) {
+    if (!context->signed_config() || !context->signed_config()->chain) {
+      // No chain.
+      context->validate_chlo_result()->info.reject_reasons.push_back(
+          SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
+    } else if (!ValidateExpectedLeafCertificate(
+                   context->client_hello(),
+                   context->signed_config()->chain->certs)) {
+      // Has chain but leaf is invalid.
+      context->validate_chlo_result()->info.reject_reasons.push_back(
+          INVALID_EXPECTED_LEAF_CERTIFICATE);
+    }
+  }
+
+  if (found_error) {
+    context->Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof");
+    return;
+  }
+
+  auto out_diversification_nonce = std::make_unique<DiversificationNonce>();
+
+  absl::string_view cert_sct;
+  if (context->client_hello().GetStringPiece(kCertificateSCTTag, &cert_sct) &&
+      cert_sct.empty()) {
+    context->params()->sct_supported_by_client = true;
+  }
+
+  auto out = std::make_unique<CryptoHandshakeMessage>();
+  if (!context->info().reject_reasons.empty() || !configs.requested) {
+    BuildRejectionAndRecordStats(*context, *configs.primary,
+                                 context->info().reject_reasons, out.get());
+    context->Succeed(std::move(out), std::move(out_diversification_nonce),
+                     std::move(proof_source_details));
+    return;
+  }
+
+  if (context->reject_only()) {
+    context->Succeed(std::move(out), std::move(out_diversification_nonce),
+                     std::move(proof_source_details));
+    return;
+  }
+
+  QuicTagVector their_aeads;
+  QuicTagVector their_key_exchanges;
+  if (context->client_hello().GetTaglist(kAEAD, &their_aeads) !=
+          QUIC_NO_ERROR ||
+      context->client_hello().GetTaglist(kKEXS, &their_key_exchanges) !=
+          QUIC_NO_ERROR ||
+      their_aeads.size() != 1 || their_key_exchanges.size() != 1) {
+    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                  "Missing or invalid AEAD or KEXS");
+    return;
+  }
+
+  size_t key_exchange_index;
+  if (!FindMutualQuicTag(configs.requested->aead, their_aeads,
+                         &context->params()->aead, nullptr) ||
+      !FindMutualQuicTag(configs.requested->kexs, their_key_exchanges,
+                         &context->params()->key_exchange,
+                         &key_exchange_index)) {
+    context->Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS");
+    return;
+  }
+
+  absl::string_view public_value;
+  if (!context->client_hello().GetStringPiece(kPUBS, &public_value)) {
+    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                  "Missing public value");
+    return;
+  }
+
+  // Allow testing a specific adversarial case in which a client sends a public
+  // value of incorrect size.
+  AdjustTestValue("quic::QuicCryptoServerConfig::public_value_adjust",
+                  &public_value);
+
+  const AsynchronousKeyExchange* key_exchange =
+      configs.requested->key_exchanges[key_exchange_index].get();
+  std::string* initial_premaster_secret =
+      &context->params()->initial_premaster_secret;
+  auto cb = std::make_unique<ProcessClientHelloAfterGetProofCallback>(
+      this, std::move(proof_source_details), key_exchange->type(),
+      std::move(out), public_value, std::move(context), configs);
+  key_exchange->CalculateSharedKeyAsync(public_value, initial_premaster_secret,
+                                        std::move(cb));
+}
+
+void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys(
+    bool found_error,
+    std::unique_ptr<ProofSource::Details> proof_source_details,
+    QuicTag key_exchange_type,
+    std::unique_ptr<CryptoHandshakeMessage> out,
+    absl::string_view public_value,
+    std::unique_ptr<ProcessClientHelloContext> context,
+    const Configs& configs) const {
+  QUIC_BUG_IF(quic_bug_12963_3,
+              !QuicUtils::IsConnectionIdValidForVersion(
+                  context->connection_id(), context->transport_version()))
+      << "ProcessClientHelloAfterCalculateSharedKeys:"
+         " attempted to use connection ID "
+      << context->connection_id() << " which is invalid with version "
+      << context->version();
+
+  if (found_error) {
+    // If we are already using the fallback config, or there is no fallback
+    // config to use, just bail out of the handshake.
+    if (configs.fallback == nullptr ||
+        context->signed_config()->config == configs.fallback) {
+      context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                    "Failed to calculate shared key");
+    } else {
+      SendRejectWithFallbackConfig(std::move(context), configs.fallback);
+    }
+    return;
+  }
+
+  if (!context->info().sni.empty()) {
+    context->params()->sni =
+        QuicHostnameUtils::NormalizeHostname(context->info().sni);
+  }
+
+  std::string hkdf_suffix;
+  const QuicData& client_hello_serialized =
+      context->client_hello().GetSerialized();
+  hkdf_suffix.reserve(context->connection_id().length() +
+                      client_hello_serialized.length() +
+                      configs.requested->serialized.size());
+  hkdf_suffix.append(context->connection_id().data(),
+                     context->connection_id().length());
+  hkdf_suffix.append(client_hello_serialized.data(),
+                     client_hello_serialized.length());
+  hkdf_suffix.append(configs.requested->serialized);
+  QUICHE_DCHECK(proof_source_.get());
+  if (context->signed_config()->chain->certs.empty()) {
+    context->Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs");
+    return;
+  }
+  hkdf_suffix.append(context->signed_config()->chain->certs.at(0));
+
+  absl::string_view cetv_ciphertext;
+  if (configs.requested->channel_id_enabled &&
+      context->client_hello().GetStringPiece(kCETV, &cetv_ciphertext)) {
+    CryptoHandshakeMessage client_hello_copy(context->client_hello());
+    client_hello_copy.Erase(kCETV);
+    client_hello_copy.Erase(kPAD);
+
+    const QuicData& client_hello_copy_serialized =
+        client_hello_copy.GetSerialized();
+    std::string hkdf_input;
+    hkdf_input.append(QuicCryptoConfig::kCETVLabel,
+                      strlen(QuicCryptoConfig::kCETVLabel) + 1);
+    hkdf_input.append(context->connection_id().data(),
+                      context->connection_id().length());
+    hkdf_input.append(client_hello_copy_serialized.data(),
+                      client_hello_copy_serialized.length());
+    hkdf_input.append(configs.requested->serialized);
+
+    CrypterPair crypters;
+    if (!CryptoUtils::DeriveKeys(
+            context->version(), context->params()->initial_premaster_secret,
+            context->params()->aead, context->info().client_nonce,
+            context->info().server_nonce, pre_shared_key_, hkdf_input,
+            Perspective::IS_SERVER, CryptoUtils::Diversification::Never(),
+            &crypters, nullptr /* subkey secret */)) {
+      context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
+                    "Symmetric key setup failed");
+      return;
+    }
+
+    char plaintext[kMaxOutgoingPacketSize];
+    size_t plaintext_length = 0;
+    const bool success = crypters.decrypter->DecryptPacket(
+        0 /* packet number */, absl::string_view() /* associated data */,
+        cetv_ciphertext, plaintext, &plaintext_length, kMaxOutgoingPacketSize);
+    if (!success) {
+      context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                    "CETV decryption failure");
+      return;
+    }
+    std::unique_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage(
+        absl::string_view(plaintext, plaintext_length)));
+    if (!cetv) {
+      context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV parse error");
+      return;
+    }
+
+    absl::string_view key, signature;
+    if (cetv->GetStringPiece(kCIDK, &key) &&
+        cetv->GetStringPiece(kCIDS, &signature)) {
+      if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) {
+        context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                      "ChannelID signature failure");
+        return;
+      }
+
+      context->params()->channel_id = std::string(key);
+    }
+  }
+
+  std::string hkdf_input;
+  size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
+  hkdf_input.reserve(label_len + hkdf_suffix.size());
+  hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
+  hkdf_input.append(hkdf_suffix);
+
+  auto out_diversification_nonce = std::make_unique<DiversificationNonce>();
+  context->rand()->RandBytes(out_diversification_nonce->data(),
+                             out_diversification_nonce->size());
+  CryptoUtils::Diversification diversification =
+      CryptoUtils::Diversification::Now(out_diversification_nonce.get());
+  if (!CryptoUtils::DeriveKeys(
+          context->version(), context->params()->initial_premaster_secret,
+          context->params()->aead, context->info().client_nonce,
+          context->info().server_nonce, pre_shared_key_, hkdf_input,
+          Perspective::IS_SERVER, diversification,
+          &context->params()->initial_crypters,
+          &context->params()->initial_subkey_secret)) {
+    context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
+                  "Symmetric key setup failed");
+    return;
+  }
+
+  std::string forward_secure_public_value;
+  std::unique_ptr<SynchronousKeyExchange> forward_secure_key_exchange =
+      CreateLocalSynchronousKeyExchange(key_exchange_type, context->rand());
+  if (!forward_secure_key_exchange) {
+    QUIC_DLOG(WARNING) << "Failed to create keypair";
+    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                  "Failed to create keypair");
+    return;
+  }
+
+  forward_secure_public_value =
+      std::string(forward_secure_key_exchange->public_value());
+  if (!forward_secure_key_exchange->CalculateSharedKeySync(
+          public_value, &context->params()->forward_secure_premaster_secret)) {
+    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                  "Invalid public value");
+    return;
+  }
+
+  std::string forward_secure_hkdf_input;
+  label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
+  forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size());
+  forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel,
+                                   label_len);
+  forward_secure_hkdf_input.append(hkdf_suffix);
+
+  std::string shlo_nonce;
+  shlo_nonce = NewServerNonce(context->rand(), context->info().now);
+  out->SetStringPiece(kServerNonceTag, shlo_nonce);
+
+  if (!CryptoUtils::DeriveKeys(
+          context->version(),
+          context->params()->forward_secure_premaster_secret,
+          context->params()->aead, context->info().client_nonce,
+          shlo_nonce.empty() ? context->info().server_nonce : shlo_nonce,
+          pre_shared_key_, forward_secure_hkdf_input, Perspective::IS_SERVER,
+          CryptoUtils::Diversification::Never(),
+          &context->params()->forward_secure_crypters,
+          &context->params()->subkey_secret)) {
+    context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
+                  "Symmetric key setup failed");
+    return;
+  }
+
+  out->set_tag(kSHLO);
+  out->SetVersionVector(kVER, context->supported_versions());
+  out->SetStringPiece(
+      kSourceAddressTokenTag,
+      NewSourceAddressToken(*configs.requested->source_address_token_boxer,
+                            context->info().source_address_tokens,
+                            context->client_address().host(), context->rand(),
+                            context->info().now, nullptr));
+  QuicSocketAddressCoder address_coder(context->client_address());
+  out->SetStringPiece(kCADR, address_coder.Encode());
+  out->SetStringPiece(kPUBS, forward_secure_public_value);
+
+  context->Succeed(std::move(out), std::move(out_diversification_nonce),
+                   std::move(proof_source_details));
+}
+
+void QuicCryptoServerConfig::SendRejectWithFallbackConfig(
+    std::unique_ptr<ProcessClientHelloContext> context,
+    quiche::QuicheReferenceCountedPointer<Config> fallback_config) const {
+  // We failed to calculate a shared initial key, likely because we tried to use
+  // a remote key-exchange service which could not be reached.  We want to send
+  // a REJ which tells the client to use a different ServerConfig which
+  // corresponds to a local keypair.  To generate the REJ we need to request a
+  // new proof.
+  const std::string chlo_hash = CryptoUtils::HashHandshakeMessage(
+      context->client_hello(), Perspective::IS_SERVER);
+  const QuicSocketAddress server_address = context->server_address();
+  const std::string sni(context->info().sni);
+  const QuicTransportVersion transport_version = context->transport_version();
+
+  const QuicSocketAddress& client_address = context->client_address();
+  auto cb = std::make_unique<SendRejectWithFallbackConfigCallback>(
+      this, std::move(context), fallback_config);
+  proof_source_->GetProof(server_address, client_address, sni,
+                          fallback_config->serialized, transport_version,
+                          chlo_hash, std::move(cb));
+}
+
+void QuicCryptoServerConfig::SendRejectWithFallbackConfigAfterGetProof(
+    bool found_error,
+    std::unique_ptr<ProofSource::Details> proof_source_details,
+    std::unique_ptr<ProcessClientHelloContext> context,
+    quiche::QuicheReferenceCountedPointer<Config> fallback_config) const {
+  if (found_error) {
+    context->Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof");
+    return;
+  }
+
+  auto out = std::make_unique<CryptoHandshakeMessage>();
+  BuildRejectionAndRecordStats(*context, *fallback_config,
+                               {SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE},
+                               out.get());
+
+  context->Succeed(std::move(out), std::make_unique<DiversificationNonce>(),
+                   std::move(proof_source_details));
+}
+
+quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
+QuicCryptoServerConfig::GetConfigWithScid(
+    absl::string_view requested_scid) const {
+  configs_lock_.AssertReaderHeld();
+
+  if (!requested_scid.empty()) {
+    auto it = configs_.find((std::string(requested_scid)));
+    if (it != configs_.end()) {
+      // We'll use the config that the client requested in order to do
+      // key-agreement.
+      return quiche::QuicheReferenceCountedPointer<Config>(it->second);
+    }
+  }
+
+  return quiche::QuicheReferenceCountedPointer<Config>();
+}
+
+bool QuicCryptoServerConfig::GetCurrentConfigs(
+    const QuicWallTime& now, absl::string_view requested_scid,
+    quiche::QuicheReferenceCountedPointer<Config> old_primary_config,
+    Configs* configs) const {
+  QuicReaderMutexLock locked(&configs_lock_);
+
+  if (!primary_config_) {
+    return false;
+  }
+
+  if (IsNextConfigReady(now)) {
+    configs_lock_.ReaderUnlock();
+    configs_lock_.WriterLock();
+    SelectNewPrimaryConfig(now);
+    QUICHE_DCHECK(primary_config_.get());
+    QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
+                     primary_config_.get());
+    configs_lock_.WriterUnlock();
+    configs_lock_.ReaderLock();
+  }
+
+  if (old_primary_config != nullptr) {
+    configs->primary = old_primary_config;
+  } else {
+    configs->primary = primary_config_;
+  }
+  configs->requested = GetConfigWithScid(requested_scid);
+  configs->fallback = fallback_config_;
+
+  return true;
+}
+
+// ConfigPrimaryTimeLessThan is a comparator that implements "less than" for
+// Config's based on their primary_time.
+// static
+bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan(
+    const quiche::QuicheReferenceCountedPointer<Config>& a,
+    const quiche::QuicheReferenceCountedPointer<Config>& b) {
+  if (a->primary_time.IsBefore(b->primary_time) ||
+      b->primary_time.IsBefore(a->primary_time)) {
+    // Primary times differ.
+    return a->primary_time.IsBefore(b->primary_time);
+  } else if (a->priority != b->priority) {
+    // Primary times are equal, sort backwards by priority.
+    return a->priority < b->priority;
+  } else {
+    // Primary times and priorities are equal, sort by config id.
+    return a->id < b->id;
+  }
+}
+
+void QuicCryptoServerConfig::SelectNewPrimaryConfig(
+    const QuicWallTime now) const {
+  std::vector<quiche::QuicheReferenceCountedPointer<Config>> configs;
+  configs.reserve(configs_.size());
+
+  for (auto it = configs_.begin(); it != configs_.end(); ++it) {
+    // TODO(avd) Exclude expired configs?
+    configs.push_back(it->second);
+  }
+
+  if (configs.empty()) {
+    if (primary_config_ != nullptr) {
+      QUIC_BUG(quic_bug_10630_2)
+          << "No valid QUIC server config. Keeping the current config.";
+    } else {
+      QUIC_BUG(quic_bug_10630_3) << "No valid QUIC server config.";
+    }
+    return;
+  }
+
+  std::sort(configs.begin(), configs.end(), ConfigPrimaryTimeLessThan);
+
+  quiche::QuicheReferenceCountedPointer<Config> best_candidate = configs[0];
+
+  for (size_t i = 0; i < configs.size(); ++i) {
+    const quiche::QuicheReferenceCountedPointer<Config> config(configs[i]);
+    if (!config->primary_time.IsAfter(now)) {
+      if (config->primary_time.IsAfter(best_candidate->primary_time)) {
+        best_candidate = config;
+      }
+      continue;
+    }
+
+    // This is the first config with a primary_time in the future. Thus the
+    // previous Config should be the primary and this one should determine the
+    // next_config_promotion_time_.
+    quiche::QuicheReferenceCountedPointer<Config> new_primary = best_candidate;
+    if (i == 0) {
+      // We need the primary_time of the next config.
+      if (configs.size() > 1) {
+        next_config_promotion_time_ = configs[1]->primary_time;
+      } else {
+        next_config_promotion_time_ = QuicWallTime::Zero();
+      }
+    } else {
+      next_config_promotion_time_ = config->primary_time;
+    }
+
+    if (primary_config_) {
+      primary_config_->is_primary = false;
+    }
+    primary_config_ = new_primary;
+    new_primary->is_primary = true;
+    QUIC_DLOG(INFO) << "New primary config.  orbit: "
+                    << absl::BytesToHexString(
+                           absl::string_view(reinterpret_cast<const char*>(
+                                                 primary_config_->orbit),
+                                             kOrbitSize));
+    if (primary_config_changed_cb_ != nullptr) {
+      primary_config_changed_cb_->Run(primary_config_->id);
+    }
+
+    return;
+  }
+
+  // All config's primary times are in the past. We should make the most recent
+  // and highest priority candidate primary.
+  quiche::QuicheReferenceCountedPointer<Config> new_primary = best_candidate;
+  if (primary_config_) {
+    primary_config_->is_primary = false;
+  }
+  primary_config_ = new_primary;
+  new_primary->is_primary = true;
+  QUIC_DLOG(INFO) << "New primary config.  orbit: "
+                  << absl::BytesToHexString(absl::string_view(
+                         reinterpret_cast<const char*>(primary_config_->orbit),
+                         kOrbitSize))
+                  << " scid: " << absl::BytesToHexString(primary_config_->id);
+  next_config_promotion_time_ = QuicWallTime::Zero();
+  if (primary_config_changed_cb_ != nullptr) {
+    primary_config_changed_cb_->Run(primary_config_->id);
+  }
+}
+
+void QuicCryptoServerConfig::EvaluateClientHello(
+    const QuicSocketAddress& /*server_address*/,
+    const QuicSocketAddress& /*client_address*/,
+    QuicTransportVersion /*version*/, const Configs& configs,
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        client_hello_state,
+    std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const {
+  ValidateClientHelloHelper helper(client_hello_state, &done_cb);
+
+  const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello;
+  ClientHelloInfo* info = &(client_hello_state->info);
+
+  if (client_hello.GetStringPiece(kSNI, &info->sni) &&
+      !QuicHostnameUtils::IsValidSNI(info->sni)) {
+    helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                              "Invalid SNI name", nullptr);
+    return;
+  }
+
+  client_hello.GetStringPiece(kUAID, &info->user_agent_id);
+
+  HandshakeFailureReason source_address_token_error = MAX_FAILURE_REASON;
+  if (validate_source_address_token_) {
+    absl::string_view srct;
+    if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
+      Config& config =
+          configs.requested != nullptr ? *configs.requested : *configs.primary;
+      source_address_token_error =
+          ParseSourceAddressToken(*config.source_address_token_boxer, srct,
+                                  info->source_address_tokens);
+
+      if (source_address_token_error == HANDSHAKE_OK) {
+        source_address_token_error = ValidateSourceAddressTokens(
+            info->source_address_tokens, info->client_ip, info->now,
+            &client_hello_state->cached_network_params);
+      }
+      info->valid_source_address_token =
+          (source_address_token_error == HANDSHAKE_OK);
+    } else {
+      source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
+    }
+  } else {
+    source_address_token_error = HANDSHAKE_OK;
+    info->valid_source_address_token = true;
+  }
+
+  if (!configs.requested) {
+    absl::string_view requested_scid;
+    if (client_hello.GetStringPiece(kSCID, &requested_scid)) {
+      info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
+    } else {
+      info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
+    }
+    // No server config with the requested ID.
+    helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr);
+    return;
+  }
+
+  if (!client_hello.GetStringPiece(kNONC, &info->client_nonce)) {
+    info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
+    // Report no client nonce as INCHOATE_HELLO_FAILURE.
+    helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr);
+    return;
+  }
+
+  if (source_address_token_error != HANDSHAKE_OK) {
+    info->reject_reasons.push_back(source_address_token_error);
+    // No valid source address token.
+  }
+
+  if (info->client_nonce.size() != kNonceSize) {
+    info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
+    // Invalid client nonce.
+    QUIC_LOG_FIRST_N(ERROR, 2)
+        << "Invalid client nonce: " << client_hello.DebugString();
+    QUIC_DLOG(INFO) << "Invalid client nonce.";
+  }
+
+  // Server nonce is optional, and used for key derivation if present.
+  client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce);
+
+  // If the server nonce is empty and we're requiring handshake confirmation
+  // for DoS reasons then we must reject the CHLO.
+  if (GetQuicReloadableFlag(quic_require_handshake_confirmation) &&
+      info->server_nonce.empty()) {
+    info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE);
+  }
+  helper.ValidationComplete(QUIC_NO_ERROR, "",
+                            std::unique_ptr<ProofSource::Details>());
+}
+
+void QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
+    QuicTransportVersion version,
+    absl::string_view chlo_hash,
+    const SourceAddressTokens& previous_source_address_tokens,
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    const QuicClock* clock,
+    QuicRandom* rand,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    const QuicCryptoNegotiatedParameters& params,
+    const CachedNetworkParameters* cached_network_params,
+    std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const {
+  std::string serialized;
+  std::string source_address_token;
+  {
+    QuicReaderMutexLock locked(&configs_lock_);
+    serialized = primary_config_->serialized;
+    source_address_token = NewSourceAddressToken(
+        *primary_config_->source_address_token_boxer,
+        previous_source_address_tokens, client_address.host(), rand,
+        clock->WallNow(), cached_network_params);
+  }
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kSCUP);
+  message.SetStringPiece(kSCFG, serialized);
+  message.SetStringPiece(kSourceAddressTokenTag, source_address_token);
+
+  auto proof_source_cb =
+      std::make_unique<BuildServerConfigUpdateMessageProofSourceCallback>(
+          this, compressed_certs_cache, params, std::move(message),
+          std::move(cb));
+
+  proof_source_->GetProof(server_address, client_address, params.sni,
+                          serialized, version, chlo_hash,
+                          std::move(proof_source_cb));
+}
+
+QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
+    ~BuildServerConfigUpdateMessageProofSourceCallback() {}
+
+QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
+    BuildServerConfigUpdateMessageProofSourceCallback(
+        const QuicCryptoServerConfig* config,
+        QuicCompressedCertsCache* compressed_certs_cache,
+        const QuicCryptoNegotiatedParameters& params,
+        CryptoHandshakeMessage message,
+        std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb)
+    : config_(config),
+      compressed_certs_cache_(compressed_certs_cache),
+      client_cached_cert_hashes_(params.client_cached_cert_hashes),
+      sct_supported_by_client_(params.sct_supported_by_client),
+      sni_(params.sni),
+      message_(std::move(message)),
+      cb_(std::move(cb)) {}
+
+void QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
+    Run(bool ok,
+        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+        const QuicCryptoProof& proof,
+        std::unique_ptr<ProofSource::Details> details) {
+  config_->FinishBuildServerConfigUpdateMessage(
+      compressed_certs_cache_, client_cached_cert_hashes_,
+      sct_supported_by_client_, sni_, ok, chain, proof.signature,
+      proof.leaf_cert_scts, std::move(details), std::move(message_),
+      std::move(cb_));
+}
+
+void QuicCryptoServerConfig::FinishBuildServerConfigUpdateMessage(
+    QuicCompressedCertsCache* compressed_certs_cache,
+    const std::string& client_cached_cert_hashes, bool sct_supported_by_client,
+    const std::string& sni, bool ok,
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string& signature, const std::string& leaf_cert_sct,
+    std::unique_ptr<ProofSource::Details> /*details*/,
+    CryptoHandshakeMessage message,
+    std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const {
+  if (!ok) {
+    cb->Run(false, message);
+    return;
+  }
+
+  const std::string compressed =
+      CompressChain(compressed_certs_cache, chain, client_cached_cert_hashes);
+
+  message.SetStringPiece(kCertificateTag, compressed);
+  message.SetStringPiece(kPROF, signature);
+  if (sct_supported_by_client && enable_serving_sct_) {
+    if (leaf_cert_sct.empty()) {
+      QUIC_LOG_EVERY_N_SEC(WARNING, 60)
+          << "SCT is expected but it is empty. SNI: " << sni;
+    } else {
+      message.SetStringPiece(kCertificateSCTTag, leaf_cert_sct);
+    }
+  }
+
+  cb->Run(true, message);
+}
+
+void QuicCryptoServerConfig::BuildRejectionAndRecordStats(
+    const ProcessClientHelloContext& context,
+    const Config& config,
+    const std::vector<uint32_t>& reject_reasons,
+    CryptoHandshakeMessage* out) const {
+  BuildRejection(context, config, reject_reasons, out);
+  if (rejection_observer_ != nullptr) {
+    rejection_observer_->OnRejectionBuilt(reject_reasons, out);
+  }
+}
+
+void QuicCryptoServerConfig::BuildRejection(
+    const ProcessClientHelloContext& context,
+    const Config& config,
+    const std::vector<uint32_t>& reject_reasons,
+    CryptoHandshakeMessage* out) const {
+  const QuicWallTime now = context.clock()->WallNow();
+
+  out->set_tag(kREJ);
+  out->SetStringPiece(kSCFG, config.serialized);
+  out->SetStringPiece(
+      kSourceAddressTokenTag,
+      NewSourceAddressToken(
+          *config.source_address_token_boxer,
+          context.info().source_address_tokens, context.info().client_ip,
+          context.rand(), context.info().now,
+          &context.validate_chlo_result()->cached_network_params));
+  out->SetValue(kSTTL, config.expiry_time.AbsoluteDifference(now).ToSeconds());
+  if (replay_protection_) {
+    out->SetStringPiece(kServerNonceTag,
+                        NewServerNonce(context.rand(), context.info().now));
+  }
+
+  // Send client the reject reason for debugging purposes.
+  QUICHE_DCHECK_LT(0u, reject_reasons.size());
+  out->SetVector(kRREJ, reject_reasons);
+
+  // The client may have requested a certificate chain.
+  if (!ClientDemandsX509Proof(context.client_hello())) {
+    QUIC_BUG(quic_bug_10630_4)
+        << "x509 certificates not supported in proof demand";
+    return;
+  }
+
+  absl::string_view client_cached_cert_hashes;
+  if (context.client_hello().GetStringPiece(kCCRT,
+                                            &client_cached_cert_hashes)) {
+    context.params()->client_cached_cert_hashes =
+        std::string(client_cached_cert_hashes);
+  } else {
+    context.params()->client_cached_cert_hashes.clear();
+  }
+
+  const std::string compressed = CompressChain(
+      context.compressed_certs_cache(), context.signed_config()->chain,
+      context.params()->client_cached_cert_hashes);
+
+  QUICHE_DCHECK_GT(context.chlo_packet_size(), context.client_hello().size());
+  // kREJOverheadBytes is a very rough estimate of how much of a REJ
+  // message is taken up by things other than the certificates.
+  // STK: 56 bytes
+  // SNO: 56 bytes
+  // SCFG
+  //   SCID: 16 bytes
+  //   PUBS: 38 bytes
+  const size_t kREJOverheadBytes = 166;
+  // max_unverified_size is the number of bytes that the certificate chain,
+  // signature, and (optionally) signed certificate timestamp can consume before
+  // we will demand a valid source-address token.
+  const size_t max_unverified_size =
+      chlo_multiplier_ *
+          (context.chlo_packet_size() - context.total_framing_overhead()) -
+      kREJOverheadBytes;
+  static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes,
+                "overhead calculation may underflow");
+  bool should_return_sct =
+      context.params()->sct_supported_by_client && enable_serving_sct_;
+  const std::string& cert_sct = context.signed_config()->proof.leaf_cert_scts;
+  const size_t sct_size = should_return_sct ? cert_sct.size() : 0;
+  const size_t total_size = context.signed_config()->proof.signature.size() +
+                            compressed.size() + sct_size;
+  if (context.info().valid_source_address_token ||
+      total_size < max_unverified_size) {
+    out->SetStringPiece(kCertificateTag, compressed);
+    out->SetStringPiece(kPROF, context.signed_config()->proof.signature);
+    if (should_return_sct) {
+      if (cert_sct.empty()) {
+        // Log SNI and subject name for the leaf cert if its SCT is empty.
+        // This is for debugging b/28342827.
+        const std::vector<std::string>& certs =
+            context.signed_config()->chain->certs;
+        std::string ca_subject;
+        if (!certs.empty()) {
+            std::unique_ptr<CertificateView> view =
+                CertificateView::ParseSingleCertificate(certs[0]);
+            if (view != nullptr) {
+              absl::optional<std::string> maybe_ca_subject =
+                  view->GetHumanReadableSubject();
+              if (maybe_ca_subject.has_value()) {
+                ca_subject = *maybe_ca_subject;
+              }
+            }
+        }
+        QUIC_LOG_EVERY_N_SEC(WARNING, 60)
+            << "SCT is expected but it is empty. sni: '"
+            << context.params()->sni << "' cert subject: '" << ca_subject
+            << "'";
+      } else {
+        out->SetStringPiece(kCertificateSCTTag, cert_sct);
+      }
+    }
+  } else {
+    QUIC_LOG_EVERY_N_SEC(WARNING, 60)
+        << "Sending inchoate REJ for hostname: " << context.info().sni
+        << " signature: " << context.signed_config()->proof.signature.size()
+        << " cert: " << compressed.size() << " sct:" << sct_size
+        << " total: " << total_size << " max: " << max_unverified_size;
+  }
+}
+
+std::string QuicCryptoServerConfig::CompressChain(
+    QuicCompressedCertsCache* compressed_certs_cache,
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string& client_cached_cert_hashes) {
+  // Check whether the compressed certs is available in the cache.
+  QUICHE_DCHECK(compressed_certs_cache);
+  const std::string* cached_value = compressed_certs_cache->GetCompressedCert(
+      chain, client_cached_cert_hashes);
+  if (cached_value) {
+    return *cached_value;
+  }
+  std::string compressed =
+      CertCompressor::CompressChain(chain->certs, client_cached_cert_hashes);
+  // Insert the newly compressed cert to cache.
+  compressed_certs_cache->Insert(chain, client_cached_cert_hashes, compressed);
+  return compressed;
+}
+
+quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
+QuicCryptoServerConfig::ParseConfigProtobuf(
+    const QuicServerConfigProtobuf& protobuf, bool is_fallback) const {
+  std::unique_ptr<CryptoHandshakeMessage> msg =
+      CryptoFramer::ParseMessage(protobuf.config());
+
+  if (!msg) {
+    QUIC_LOG(WARNING) << "Failed to parse server config message";
+    return nullptr;
+  }
+
+  if (msg->tag() != kSCFG) {
+    QUIC_LOG(WARNING) << "Server config message has tag " << msg->tag()
+                      << ", but expected " << kSCFG;
+    return nullptr;
+  }
+
+  quiche::QuicheReferenceCountedPointer<Config> config(new Config);
+  config->serialized = protobuf.config();
+  config->source_address_token_boxer = &source_address_token_boxer_;
+
+  if (protobuf.has_primary_time()) {
+    config->primary_time =
+        QuicWallTime::FromUNIXSeconds(protobuf.primary_time());
+  }
+
+  config->priority = protobuf.priority();
+
+  absl::string_view scid;
+  if (!msg->GetStringPiece(kSCID, &scid)) {
+    QUIC_LOG(WARNING) << "Server config message is missing SCID";
+    return nullptr;
+  }
+  QUICHE_DCHECK(!scid.empty());
+  config->id = std::string(scid);
+
+  if (msg->GetTaglist(kAEAD, &config->aead) != QUIC_NO_ERROR) {
+    QUIC_LOG(WARNING) << "Server config message is missing AEAD";
+    return nullptr;
+  }
+
+  QuicTagVector kexs_tags;
+  if (msg->GetTaglist(kKEXS, &kexs_tags) != QUIC_NO_ERROR) {
+    QUIC_LOG(WARNING) << "Server config message is missing KEXS";
+    return nullptr;
+  }
+
+  absl::string_view orbit;
+  if (!msg->GetStringPiece(kORBT, &orbit)) {
+    QUIC_LOG(WARNING) << "Server config message is missing ORBT";
+    return nullptr;
+  }
+
+  if (orbit.size() != kOrbitSize) {
+    QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length."
+                         " Got "
+                      << orbit.size() << " want " << kOrbitSize;
+    return nullptr;
+  }
+  static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size");
+  memcpy(config->orbit, orbit.data(), sizeof(config->orbit));
+
+  QuicTagVector proof_demand_tags;
+  if (msg->GetTaglist(kPDMD, &proof_demand_tags) == QUIC_NO_ERROR) {
+    for (QuicTag tag : proof_demand_tags) {
+      if (tag == kCHID) {
+        config->channel_id_enabled = true;
+        break;
+      }
+    }
+  }
+
+  for (size_t i = 0; i < kexs_tags.size(); i++) {
+    const QuicTag tag = kexs_tags[i];
+    std::string private_key;
+
+    config->kexs.push_back(tag);
+
+    for (int j = 0; j < protobuf.key_size(); j++) {
+      const QuicServerConfigProtobuf::PrivateKey& key = protobuf.key(i);
+      if (key.tag() == tag) {
+        private_key = key.private_key();
+        break;
+      }
+    }
+
+    std::unique_ptr<AsynchronousKeyExchange> ka =
+        key_exchange_source_->Create(config->id, is_fallback, tag, private_key);
+    if (!ka) {
+      return nullptr;
+    }
+    for (const auto& key_exchange : config->key_exchanges) {
+      if (key_exchange->type() == tag) {
+        QUIC_LOG(WARNING) << "Duplicate key exchange in config: " << tag;
+        return nullptr;
+      }
+    }
+
+    config->key_exchanges.push_back(std::move(ka));
+  }
+
+  uint64_t expiry_seconds;
+  if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
+    QUIC_LOG(WARNING) << "Server config message is missing EXPY";
+    return nullptr;
+  }
+  config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds);
+
+  return config;
+}
+
+void QuicCryptoServerConfig::set_replay_protection(bool on) {
+  replay_protection_ = on;
+}
+
+void QuicCryptoServerConfig::set_chlo_multiplier(size_t multiplier) {
+  chlo_multiplier_ = multiplier;
+}
+
+void QuicCryptoServerConfig::set_source_address_token_future_secs(
+    uint32_t future_secs) {
+  source_address_token_future_secs_ = future_secs;
+}
+
+void QuicCryptoServerConfig::set_source_address_token_lifetime_secs(
+    uint32_t lifetime_secs) {
+  source_address_token_lifetime_secs_ = lifetime_secs;
+}
+
+void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) {
+  enable_serving_sct_ = enable_serving_sct;
+}
+
+void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
+    std::unique_ptr<PrimaryConfigChangedCallback> cb) {
+  QuicWriterMutexLock locked(&configs_lock_);
+  primary_config_changed_cb_ = std::move(cb);
+}
+
+std::string QuicCryptoServerConfig::NewSourceAddressToken(
+    const CryptoSecretBoxer& crypto_secret_boxer,
+    const SourceAddressTokens& previous_tokens,
+    const QuicIpAddress& ip,
+    QuicRandom* rand,
+    QuicWallTime now,
+    const CachedNetworkParameters* cached_network_params) const {
+  SourceAddressTokens source_address_tokens;
+  SourceAddressToken* source_address_token = source_address_tokens.add_tokens();
+  source_address_token->set_ip(ip.DualStacked().ToPackedString());
+  source_address_token->set_timestamp(now.ToUNIXSeconds());
+  if (cached_network_params != nullptr) {
+    *(source_address_token->mutable_cached_network_parameters()) =
+        *cached_network_params;
+  }
+
+  // Append previous tokens.
+  for (const SourceAddressToken& token : previous_tokens.tokens()) {
+    if (source_address_tokens.tokens_size() > kMaxTokenAddresses) {
+      break;
+    }
+
+    if (token.ip() == source_address_token->ip()) {
+      // It's for the same IP address.
+      continue;
+    }
+
+    if (ValidateSourceAddressTokenTimestamp(token, now) != HANDSHAKE_OK) {
+      continue;
+    }
+
+    *(source_address_tokens.add_tokens()) = token;
+  }
+
+  return crypto_secret_boxer.Box(rand,
+                                 source_address_tokens.SerializeAsString());
+}
+
+int QuicCryptoServerConfig::NumberOfConfigs() const {
+  QuicReaderMutexLock locked(&configs_lock_);
+  return configs_.size();
+}
+
+ProofSource* QuicCryptoServerConfig::proof_source() const {
+  return proof_source_.get();
+}
+
+SSL_CTX* QuicCryptoServerConfig::ssl_ctx() const {
+  return ssl_ctx_.get();
+}
+
+HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
+    const CryptoSecretBoxer& crypto_secret_boxer, absl::string_view token,
+    SourceAddressTokens& tokens) const {
+  std::string storage;
+  absl::string_view plaintext;
+  if (!crypto_secret_boxer.Unbox(token, &storage, &plaintext)) {
+    return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE;
+  }
+
+  if (!tokens.ParseFromArray(plaintext.data(), plaintext.size())) {
+    // Some clients might still be using the old source token format so
+    // attempt to parse that format.
+    // TODO(rch): remove this code once the new format is ubiquitous.
+    SourceAddressToken token;
+    if (!token.ParseFromArray(plaintext.data(), plaintext.size())) {
+      return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
+    }
+    *tokens.add_tokens() = token;
+  }
+
+  return HANDSHAKE_OK;
+}
+
+HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressTokens(
+    const SourceAddressTokens& source_address_tokens,
+    const QuicIpAddress& ip,
+    QuicWallTime now,
+    CachedNetworkParameters* cached_network_params) const {
+  HandshakeFailureReason reason =
+      SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
+  for (const SourceAddressToken& token : source_address_tokens.tokens()) {
+    reason = ValidateSingleSourceAddressToken(token, ip, now);
+    if (reason == HANDSHAKE_OK) {
+      if (cached_network_params != nullptr &&
+          token.has_cached_network_parameters()) {
+        *cached_network_params = token.cached_network_parameters();
+      }
+      break;
+    }
+  }
+  return reason;
+}
+
+HandshakeFailureReason QuicCryptoServerConfig::ValidateSingleSourceAddressToken(
+    const SourceAddressToken& source_address_token,
+    const QuicIpAddress& ip,
+    QuicWallTime now) const {
+  if (source_address_token.ip() != ip.DualStacked().ToPackedString()) {
+    // It's for a different IP address.
+    return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
+  }
+
+  return ValidateSourceAddressTokenTimestamp(source_address_token, now);
+}
+
+HandshakeFailureReason
+QuicCryptoServerConfig::ValidateSourceAddressTokenTimestamp(
+    const SourceAddressToken& source_address_token,
+    QuicWallTime now) const {
+  const QuicWallTime timestamp(
+      QuicWallTime::FromUNIXSeconds(source_address_token.timestamp()));
+  const QuicTime::Delta delta(now.AbsoluteDifference(timestamp));
+
+  if (now.IsBefore(timestamp) &&
+      delta.ToSeconds() > source_address_token_future_secs_) {
+    return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE;
+  }
+
+  if (now.IsAfter(timestamp) &&
+      delta.ToSeconds() > source_address_token_lifetime_secs_) {
+    return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE;
+  }
+
+  return HANDSHAKE_OK;
+}
+
+// kServerNoncePlaintextSize is the number of bytes in an unencrypted server
+// nonce.
+static const size_t kServerNoncePlaintextSize =
+    4 /* timestamp */ + 20 /* random bytes */;
+
+std::string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand,
+                                                   QuicWallTime now) const {
+  const uint32_t timestamp = static_cast<uint32_t>(now.ToUNIXSeconds());
+
+  uint8_t server_nonce[kServerNoncePlaintextSize];
+  static_assert(sizeof(server_nonce) > sizeof(timestamp), "nonce too small");
+  server_nonce[0] = static_cast<uint8_t>(timestamp >> 24);
+  server_nonce[1] = static_cast<uint8_t>(timestamp >> 16);
+  server_nonce[2] = static_cast<uint8_t>(timestamp >> 8);
+  server_nonce[3] = static_cast<uint8_t>(timestamp);
+  rand->RandBytes(&server_nonce[sizeof(timestamp)],
+                  sizeof(server_nonce) - sizeof(timestamp));
+
+  return server_nonce_boxer_.Box(
+      rand, absl::string_view(reinterpret_cast<char*>(server_nonce),
+                              sizeof(server_nonce)));
+}
+
+bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate(
+    const CryptoHandshakeMessage& client_hello,
+    const std::vector<std::string>& certs) const {
+  if (certs.empty()) {
+    return false;
+  }
+
+  uint64_t hash_from_client;
+  if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) {
+    return false;
+  }
+  return CryptoUtils::ComputeLeafCertHash(certs.at(0)) == hash_from_client;
+}
+
+bool QuicCryptoServerConfig::IsNextConfigReady(QuicWallTime now) const {
+  return !next_config_promotion_time_.IsZero() &&
+         !next_config_promotion_time_.IsAfter(now);
+}
+
+QuicCryptoServerConfig::Config::Config()
+    : channel_id_enabled(false),
+      is_primary(false),
+      primary_time(QuicWallTime::Zero()),
+      expiry_time(QuicWallTime::Zero()),
+      priority(0),
+      source_address_token_boxer(nullptr) {}
+
+QuicCryptoServerConfig::Config::~Config() {}
+
+QuicSignedServerConfig::QuicSignedServerConfig() {}
+QuicSignedServerConfig::~QuicSignedServerConfig() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypto_server_config.h b/quiche/quic/core/crypto/quic_crypto_server_config.h
new file mode 100644
index 0000000..3d79ad7
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_server_config.h
@@ -0,0 +1,965 @@
+// Copyright 2013 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_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_secret_boxer.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "quiche/quic/core/crypto/quic_crypto_proof.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/proto/source_address_token_proto.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+class CryptoHandshakeMessage;
+class ProofSource;
+class QuicClock;
+class QuicRandom;
+class QuicServerConfigProtobuf;
+struct QuicSignedServerConfig;
+
+// ClientHelloInfo contains information about a client hello message that is
+// only kept for as long as it's being processed.
+struct QUIC_EXPORT_PRIVATE ClientHelloInfo {
+  ClientHelloInfo(const QuicIpAddress& in_client_ip, QuicWallTime in_now);
+  ClientHelloInfo(const ClientHelloInfo& other);
+  ~ClientHelloInfo();
+
+  // Inputs to EvaluateClientHello.
+  const QuicIpAddress client_ip;
+  const QuicWallTime now;
+
+  // Outputs from EvaluateClientHello.
+  bool valid_source_address_token;
+  absl::string_view sni;
+  absl::string_view client_nonce;
+  absl::string_view server_nonce;
+  absl::string_view user_agent_id;
+  SourceAddressTokens source_address_tokens;
+
+  // Errors from EvaluateClientHello.
+  std::vector<uint32_t> reject_reasons;
+  static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
+};
+
+namespace test {
+class QuicCryptoServerConfigPeer;
+}  // namespace test
+
+// Hook that allows application code to subscribe to primary config changes.
+class QUIC_EXPORT_PRIVATE PrimaryConfigChangedCallback {
+ public:
+  PrimaryConfigChangedCallback();
+  PrimaryConfigChangedCallback(const PrimaryConfigChangedCallback&) = delete;
+  PrimaryConfigChangedCallback& operator=(const PrimaryConfigChangedCallback&) =
+      delete;
+  virtual ~PrimaryConfigChangedCallback();
+  virtual void Run(const std::string& scid) = 0;
+};
+
+// Callback used to accept the result of the |client_hello| validation step.
+class QUIC_EXPORT_PRIVATE ValidateClientHelloResultCallback {
+ public:
+  // Opaque token that holds information about the client_hello and
+  // its validity.  Can be interpreted by calling ProcessClientHello.
+  struct QUIC_EXPORT_PRIVATE Result : public quiche::QuicheReferenceCounted {
+    Result(const CryptoHandshakeMessage& in_client_hello,
+           QuicIpAddress in_client_ip,
+           QuicWallTime in_now);
+
+    CryptoHandshakeMessage client_hello;
+    ClientHelloInfo info;
+    QuicErrorCode error_code;
+    std::string error_details;
+
+    // Populated if the CHLO STK contained a CachedNetworkParameters proto.
+    CachedNetworkParameters cached_network_params;
+
+   protected:
+    ~Result() override;
+  };
+
+  ValidateClientHelloResultCallback();
+  ValidateClientHelloResultCallback(const ValidateClientHelloResultCallback&) =
+      delete;
+  ValidateClientHelloResultCallback& operator=(
+      const ValidateClientHelloResultCallback&) = delete;
+  virtual ~ValidateClientHelloResultCallback();
+  virtual void Run(quiche::QuicheReferenceCountedPointer<Result> result,
+                   std::unique_ptr<ProofSource::Details> details) = 0;
+};
+
+// Callback used to accept the result of the ProcessClientHello method.
+class QUIC_EXPORT_PRIVATE ProcessClientHelloResultCallback {
+ public:
+  ProcessClientHelloResultCallback();
+  ProcessClientHelloResultCallback(const ProcessClientHelloResultCallback&) =
+      delete;
+  ProcessClientHelloResultCallback& operator=(
+      const ProcessClientHelloResultCallback&) = delete;
+  virtual ~ProcessClientHelloResultCallback();
+  virtual void Run(QuicErrorCode error,
+                   const std::string& error_details,
+                   std::unique_ptr<CryptoHandshakeMessage> message,
+                   std::unique_ptr<DiversificationNonce> diversification_nonce,
+                   std::unique_ptr<ProofSource::Details> details) = 0;
+};
+
+// Callback used to receive the results of a call to
+// BuildServerConfigUpdateMessage.
+class QUIC_EXPORT_PRIVATE BuildServerConfigUpdateMessageResultCallback {
+ public:
+  BuildServerConfigUpdateMessageResultCallback() = default;
+  virtual ~BuildServerConfigUpdateMessageResultCallback() {}
+  BuildServerConfigUpdateMessageResultCallback(
+      const BuildServerConfigUpdateMessageResultCallback&) = delete;
+  BuildServerConfigUpdateMessageResultCallback& operator=(
+      const BuildServerConfigUpdateMessageResultCallback&) = delete;
+  virtual void Run(bool ok, const CryptoHandshakeMessage& message) = 0;
+};
+
+// Object that is interested in built rejections (which include REJ, SREJ and
+// cheap SREJ).
+class QUIC_EXPORT_PRIVATE RejectionObserver {
+ public:
+  RejectionObserver() = default;
+  virtual ~RejectionObserver() {}
+  RejectionObserver(const RejectionObserver&) = delete;
+  RejectionObserver& operator=(const RejectionObserver&) = delete;
+  // Called after a rejection is built.
+  virtual void OnRejectionBuilt(const std::vector<uint32_t>& reasons,
+                                CryptoHandshakeMessage* out) const = 0;
+};
+
+// Factory for creating KeyExchange objects.
+class QUIC_EXPORT_PRIVATE KeyExchangeSource {
+ public:
+  virtual ~KeyExchangeSource() = default;
+
+  // Returns the default KeyExchangeSource.
+  static std::unique_ptr<KeyExchangeSource> Default();
+
+  // Create a new KeyExchange using the curve specified by |type| using the
+  // specified private key.  |private_key| may be empty for key-exchange
+  // mechanisms which do not hold the private key in-process.  If |is_fallback|
+  // is set, |private_key| is required to be set, and a local key-exchange
+  // object should be returned.
+  virtual std::unique_ptr<AsynchronousKeyExchange> Create(
+      std::string server_config_id,
+      bool is_fallback,
+      QuicTag type,
+      absl::string_view private_key) = 0;
+};
+
+// QuicCryptoServerConfig contains the crypto configuration of a QUIC server.
+// Unlike a client, a QUIC server can have multiple configurations active in
+// order to support clients resuming with a previous configuration.
+// TODO(agl): when adding configurations at runtime is added, this object will
+// need to consider locking.
+class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
+ public:
+  // ConfigOptions contains options for generating server configs.
+  struct QUIC_EXPORT_PRIVATE ConfigOptions {
+    ConfigOptions();
+    ConfigOptions(const ConfigOptions& other);
+    ~ConfigOptions();
+
+    // expiry_time is the time, in UNIX seconds, when the server config will
+    // expire. If unset, it defaults to the current time plus six months.
+    QuicWallTime expiry_time;
+    // channel_id_enabled controls whether the server config will indicate
+    // support for ChannelIDs.
+    bool channel_id_enabled;
+    // id contains the server config id for the resulting config. If empty, a
+    // random id is generated.
+    std::string id;
+    // orbit contains the kOrbitSize bytes of the orbit value for the server
+    // config. If |orbit| is empty then a random orbit is generated.
+    std::string orbit;
+    // p256 determines whether a P-256 public key will be included in the
+    // server config. Note that this breaks deterministic server-config
+    // generation since P-256 key generation doesn't use the QuicRandom given
+    // to GenerateConfig().
+    bool p256;
+  };
+
+  // |source_address_token_secret|: secret key material used for encrypting and
+  //     decrypting source address tokens. It can be of any length as it is fed
+  //     into a KDF before use. In tests, use TESTING.
+  // |server_nonce_entropy|: an entropy source used to generate the orbit and
+  //     key for server nonces, which are always local to a given instance of a
+  //     server. Not owned.
+  // |proof_source|: provides certificate chains and signatures.
+  // |key_exchange_source|: provides key-exchange functionality.
+  QuicCryptoServerConfig(
+      absl::string_view source_address_token_secret,
+      QuicRandom* server_nonce_entropy,
+      std::unique_ptr<ProofSource> proof_source,
+      std::unique_ptr<KeyExchangeSource> key_exchange_source);
+  QuicCryptoServerConfig(const QuicCryptoServerConfig&) = delete;
+  QuicCryptoServerConfig& operator=(const QuicCryptoServerConfig&) = delete;
+  ~QuicCryptoServerConfig();
+
+  // TESTING is a magic parameter for passing to the constructor in tests.
+  static const char TESTING[];
+
+  // Generates a QuicServerConfigProtobuf protobuf suitable for
+  // AddConfig and SetConfigs.
+  static QuicServerConfigProtobuf GenerateConfig(QuicRandom* rand,
+                                                 const QuicClock* clock,
+                                                 const ConfigOptions& options);
+
+  // AddConfig adds a QuicServerConfigProtobuf to the available configurations.
+  // It returns the SCFG message from the config if successful. |now| is used in
+  // conjunction with |protobuf->primary_time()| to determine whether the
+  // config should be made primary.
+  std::unique_ptr<CryptoHandshakeMessage> AddConfig(
+      const QuicServerConfigProtobuf& protobuf,
+      QuicWallTime now);
+
+  // AddDefaultConfig calls GenerateConfig to create a config and then calls
+  // AddConfig to add it. See the comment for |GenerateConfig| for details of
+  // the arguments.
+  std::unique_ptr<CryptoHandshakeMessage> AddDefaultConfig(
+      QuicRandom* rand,
+      const QuicClock* clock,
+      const ConfigOptions& options);
+
+  // SetConfigs takes a vector of config protobufs and the current time.
+  // Configs are assumed to be uniquely identified by their server config ID.
+  // Previously unknown configs are added and possibly made the primary config
+  // depending on their |primary_time| and the value of |now|. Configs that are
+  // known, but are missing from the protobufs are deleted, unless they are
+  // currently the primary config. SetConfigs returns false if any errors were
+  // encountered and no changes to the QuicCryptoServerConfig will occur.
+  bool SetConfigs(const std::vector<QuicServerConfigProtobuf>& protobufs,
+                  const QuicServerConfigProtobuf* fallback_protobuf,
+                  QuicWallTime now);
+
+  // SetSourceAddressTokenKeys sets the keys to be tried, in order, when
+  // decrypting a source address token.  Note that these keys are used *without*
+  // passing them through a KDF, in contradistinction to the
+  // |source_address_token_secret| argument to the constructor.
+  void SetSourceAddressTokenKeys(const std::vector<std::string>& keys);
+
+  // Get the server config ids for all known configs.
+  std::vector<std::string> GetConfigIds() const;
+
+  // Checks |client_hello| for gross errors and determines whether it can be
+  // shown to be fresh (i.e. not a replay).  The result of the validation step
+  // must be interpreted by calling QuicCryptoServerConfig::ProcessClientHello
+  // from the done_cb.
+  //
+  // ValidateClientHello may invoke the done_cb before unrolling the
+  // stack if it is able to assess the validity of the client_nonce
+  // without asynchronous operations.
+  //
+  // client_hello: the incoming client hello message.
+  // client_ip: the IP address of the client, which is used to generate and
+  //     validate source-address tokens.
+  // server_address: the IP address and port of the server. The IP address and
+  //     port may be used for certificate selection.
+  // version: protocol version used for this connection.
+  // clock: used to validate client nonces and ephemeral keys.
+  // signed_config: in/out parameter to which will be written the crypto proof
+  //     used in reply to a proof demand.  The pointed-to-object must live until
+  //     the callback is invoked.
+  // done_cb: single-use callback that accepts an opaque
+  //     ValidatedClientHelloMsg token that holds information about
+  //     the client hello.  The callback will always be called exactly
+  //     once, either under the current call stack, or after the
+  //     completion of an asynchronous operation.
+  void ValidateClientHello(
+      const CryptoHandshakeMessage& client_hello,
+      const QuicSocketAddress& client_address,
+      const QuicSocketAddress& server_address, QuicTransportVersion version,
+      const QuicClock* clock,
+      quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+          signed_config,
+      std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const;
+
+  // ProcessClientHello processes |client_hello| and decides whether to accept
+  // or reject the connection. If the connection is to be accepted, |done_cb| is
+  // invoked with the contents of the ServerHello and QUIC_NO_ERROR. Otherwise
+  // |done_cb| is called with a REJ or SREJ message and QUIC_NO_ERROR.
+  //
+  // validate_chlo_result: Output from the asynchronous call to
+  //     ValidateClientHello.  Contains the client hello message and
+  //     information about it.
+  // reject_only: Only generate rejections, not server hello messages.
+  // connection_id: the ConnectionId for the connection, which is used in key
+  //     derivation.
+  // server_ip: the IP address of the server. The IP address may be used for
+  //     certificate selection.
+  // client_address: the IP address and port of the client. The IP address is
+  //     used to generate and validate source-address tokens.
+  // version: version of the QUIC protocol in use for this connection
+  // supported_versions: versions of the QUIC protocol that this server
+  //     supports.
+  // clock: used to validate client nonces and ephemeral keys.
+  // rand: an entropy source
+  // compressed_certs_cache: the cache that caches a set of most recently used
+  //     certs. Owned by QuicDispatcher.
+  // params: the state of the handshake. This may be updated with a server
+  //     nonce when we send a rejection.
+  // signed_config: output structure containing the crypto proof used in reply
+  //     to a proof demand.
+  // total_framing_overhead: the total per-packet overhead for a stream frame
+  // chlo_packet_size: the size, in bytes, of the CHLO packet
+  // done_cb: the callback invoked on completion
+  void ProcessClientHello(
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          validate_chlo_result,
+      bool reject_only, QuicConnectionId connection_id,
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, ParsedQuicVersion version,
+      const ParsedQuicVersionVector& supported_versions, const QuicClock* clock,
+      QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          params,
+      quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+          signed_config,
+      QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
+      std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const;
+
+  // BuildServerConfigUpdateMessage invokes |cb| with a SCUP message containing
+  // the current primary config, an up to date source-address token, and cert
+  // chain and proof in the case of secure QUIC. Passes true to |cb| if the
+  // message was generated successfully, and false otherwise.  This method
+  // assumes ownership of |cb|.
+  //
+  // |cached_network_params| is optional, and can be nullptr.
+  void BuildServerConfigUpdateMessage(
+      QuicTransportVersion version,
+      absl::string_view chlo_hash,
+      const SourceAddressTokens& previous_source_address_tokens,
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      const QuicClock* clock,
+      QuicRandom* rand,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      const QuicCryptoNegotiatedParameters& params,
+      const CachedNetworkParameters* cached_network_params,
+      std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const;
+
+  // set_replay_protection controls whether replay protection is enabled. If
+  // replay protection is disabled then no strike registers are needed and
+  // frontends can share an orbit value without a shared strike-register.
+  // However, an attacker can duplicate a handshake and cause a client's
+  // request to be processed twice.
+  void set_replay_protection(bool on);
+
+  // set_chlo_multiplier specifies the multiple of the CHLO message size
+  // that a REJ message must stay under when the client doesn't present a
+  // valid source-address token.
+  void set_chlo_multiplier(size_t multiplier);
+
+  // When sender is allowed to not pad client hello (not standards compliant),
+  // we need to disable the client hello check.
+  void set_validate_chlo_size(bool new_value) {
+    validate_chlo_size_ = new_value;
+  }
+
+  // Returns whether the sender is allowed to not pad the client hello.
+  bool validate_chlo_size() const { return validate_chlo_size_; }
+
+  // When QUIC is tunneled through some other mechanism, source token validation
+  // may be disabled. Do not disable it if you are not providing other
+  // protection. (|true| protects against UDP amplification attack.).
+  void set_validate_source_address_token(bool new_value) {
+    validate_source_address_token_ = new_value;
+  }
+
+  // set_source_address_token_future_secs sets the number of seconds into the
+  // future that source-address tokens will be accepted from. Since
+  // source-address tokens are authenticated, this should only happen if
+  // another, valid server has clock-skew.
+  void set_source_address_token_future_secs(uint32_t future_secs);
+
+  // set_source_address_token_lifetime_secs sets the number of seconds that a
+  // source-address token will be valid for.
+  void set_source_address_token_lifetime_secs(uint32_t lifetime_secs);
+
+  // set_enable_serving_sct enables or disables serving signed cert timestamp
+  // (RFC6962) in server hello.
+  void set_enable_serving_sct(bool enable_serving_sct);
+
+  // Set and take ownership of the callback to invoke on primary config changes.
+  void AcquirePrimaryConfigChangedCb(
+      std::unique_ptr<PrimaryConfigChangedCallback> cb);
+
+  // Returns the number of configs this object owns.
+  int NumberOfConfigs() const;
+
+  // NewSourceAddressToken returns a fresh source address token for the given
+  // IP address. |previous_tokens| is the received tokens, and can be empty.
+  // |cached_network_params| is optional, and can be nullptr.
+  std::string NewSourceAddressToken(
+      const CryptoSecretBoxer& crypto_secret_boxer,
+      const SourceAddressTokens& previous_tokens,
+      const QuicIpAddress& ip,
+      QuicRandom* rand,
+      QuicWallTime now,
+      const CachedNetworkParameters* cached_network_params) const;
+
+  // ParseSourceAddressToken parses the source address tokens contained in
+  // the encrypted |token|, and populates |tokens| with the parsed tokens.
+  // Returns HANDSHAKE_OK if |token| could be parsed, or the reason for the
+  // failure.
+  HandshakeFailureReason ParseSourceAddressToken(
+      const CryptoSecretBoxer& crypto_secret_boxer, absl::string_view token,
+      SourceAddressTokens& tokens) const;
+
+  // ValidateSourceAddressTokens returns HANDSHAKE_OK if the source address
+  // tokens in |tokens| contain a valid and timely token for the IP address
+  // |ip| given that the current time is |now|. Otherwise it returns the
+  // reason for failure. |cached_network_params| is populated if the valid
+  // token contains a CachedNetworkParameters proto.
+  HandshakeFailureReason ValidateSourceAddressTokens(
+      const SourceAddressTokens& tokens,
+      const QuicIpAddress& ip,
+      QuicWallTime now,
+      CachedNetworkParameters* cached_network_params) const;
+
+  // Callers retain the ownership of |rejection_observer| which must outlive the
+  // config.
+  void set_rejection_observer(RejectionObserver* rejection_observer) {
+    rejection_observer_ = rejection_observer;
+  }
+
+  ProofSource* proof_source() const;
+
+  SSL_CTX* ssl_ctx() const;
+
+  // Pre-shared key used during the handshake.
+  const std::string& pre_shared_key() const { return pre_shared_key_; }
+  void set_pre_shared_key(absl::string_view psk) {
+    pre_shared_key_ = std::string(psk);
+  }
+
+  bool pad_rej() const { return pad_rej_; }
+  void set_pad_rej(bool new_value) { pad_rej_ = new_value; }
+
+  bool pad_shlo() const { return pad_shlo_; }
+  void set_pad_shlo(bool new_value) { pad_shlo_ = new_value; }
+
+  const CryptoSecretBoxer& source_address_token_boxer() const {
+    return source_address_token_boxer_;
+  }
+
+ private:
+  friend class test::QuicCryptoServerConfigPeer;
+  friend struct QuicSignedServerConfig;
+
+  // Config represents a server config: a collection of preferences and
+  // Diffie-Hellman public values.
+  class QUIC_EXPORT_PRIVATE Config : public QuicCryptoConfig,
+                                     public quiche::QuicheReferenceCounted {
+   public:
+    Config();
+    Config(const Config&) = delete;
+    Config& operator=(const Config&) = delete;
+
+    // TODO(rtenneti): since this is a class, we should probably do
+    // getters/setters here.
+    // |serialized| contains the bytes of this server config, suitable for
+    // sending on the wire.
+    std::string serialized;
+    // id contains the SCID of this server config.
+    std::string id;
+    // orbit contains the orbit value for this config: an opaque identifier
+    // used to identify clusters of server frontends.
+    unsigned char orbit[kOrbitSize];
+
+    // key_exchanges contains key exchange objects. The values correspond,
+    // one-to-one, with the tags in |kexs| from the parent class.
+    std::vector<std::unique_ptr<AsynchronousKeyExchange>> key_exchanges;
+
+    // channel_id_enabled is true if the config in |serialized| specifies that
+    // ChannelIDs are supported.
+    bool channel_id_enabled;
+
+    // is_primary is true if this config is the one that we'll give out to
+    // clients as the current one.
+    bool is_primary;
+
+    // primary_time contains the timestamp when this config should become the
+    // primary config. A value of QuicWallTime::Zero() means that this config
+    // will not be promoted at a specific time.
+    QuicWallTime primary_time;
+
+    // expiry_time contains the timestamp when this config expires.
+    QuicWallTime expiry_time;
+
+    // Secondary sort key for use when selecting primary configs and
+    // there are multiple configs with the same primary time.
+    // Smaller numbers mean higher priority.
+    uint64_t priority;
+
+    // source_address_token_boxer_ is used to protect the
+    // source-address tokens that are given to clients.
+    // Points to either source_address_token_boxer_storage or the
+    // default boxer provided by QuicCryptoServerConfig.
+    const CryptoSecretBoxer* source_address_token_boxer;
+
+    // Holds the override source_address_token_boxer instance if the
+    // Config is not using the default source address token boxer
+    // instance provided by QuicCryptoServerConfig.
+    std::unique_ptr<CryptoSecretBoxer> source_address_token_boxer_storage;
+
+   private:
+    ~Config() override;
+  };
+
+  using ConfigMap =
+      std::map<ServerConfigID, quiche::QuicheReferenceCountedPointer<Config>>;
+
+  // Get a ref to the config with a given server config id.
+  quiche::QuicheReferenceCountedPointer<Config> GetConfigWithScid(
+      absl::string_view requested_scid) const
+      QUIC_SHARED_LOCKS_REQUIRED(configs_lock_);
+
+  // A snapshot of the configs associated with an in-progress handshake.
+  struct QUIC_EXPORT_PRIVATE Configs {
+    quiche::QuicheReferenceCountedPointer<Config> requested;
+    quiche::QuicheReferenceCountedPointer<Config> primary;
+    quiche::QuicheReferenceCountedPointer<Config> fallback;
+  };
+
+  // Get a snapshot of the current configs associated with a handshake.  If this
+  // method was called earlier in this handshake |old_primary_config| should be
+  // set to the primary config returned from that invocation, otherwise nullptr.
+  //
+  // Returns true if any configs are loaded.  If false is returned, |configs| is
+  // not modified.
+  bool GetCurrentConfigs(
+      const QuicWallTime& now, absl::string_view requested_scid,
+      quiche::QuicheReferenceCountedPointer<Config> old_primary_config,
+      Configs* configs) const;
+
+  // ConfigPrimaryTimeLessThan returns true if a->primary_time <
+  // b->primary_time.
+  static bool ConfigPrimaryTimeLessThan(
+      const quiche::QuicheReferenceCountedPointer<Config>& a,
+      const quiche::QuicheReferenceCountedPointer<Config>& b);
+
+  // SelectNewPrimaryConfig reevaluates the primary config based on the
+  // "primary_time" deadlines contained in each.
+  void SelectNewPrimaryConfig(QuicWallTime now) const
+      QUIC_EXCLUSIVE_LOCKS_REQUIRED(configs_lock_);
+
+  // EvaluateClientHello checks |client_hello_state->client_hello| for gross
+  // errors and determines whether it is fresh (i.e. not a replay). The results
+  // are written to |client_hello_state->info|.
+  void EvaluateClientHello(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, QuicTransportVersion version,
+      const Configs& configs,
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          client_hello_state,
+      std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const;
+
+  // Convenience class which carries the arguments passed to
+  // |ProcessClientHellp| along.
+  class QUIC_EXPORT_PRIVATE ProcessClientHelloContext {
+   public:
+    ProcessClientHelloContext(
+        quiche::QuicheReferenceCountedPointer<
+            ValidateClientHelloResultCallback::Result>
+            validate_chlo_result,
+        bool reject_only, QuicConnectionId connection_id,
+        const QuicSocketAddress& server_address,
+        const QuicSocketAddress& client_address, ParsedQuicVersion version,
+        const ParsedQuicVersionVector& supported_versions,
+        const QuicClock* clock, QuicRandom* rand,
+        QuicCompressedCertsCache* compressed_certs_cache,
+        quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+            params,
+        quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+            signed_config,
+        QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
+        std::unique_ptr<ProcessClientHelloResultCallback> done_cb)
+        : validate_chlo_result_(validate_chlo_result),
+          reject_only_(reject_only),
+          connection_id_(connection_id),
+          server_address_(server_address),
+          client_address_(client_address),
+          version_(version),
+          supported_versions_(supported_versions),
+          clock_(clock),
+          rand_(rand),
+          compressed_certs_cache_(compressed_certs_cache),
+          params_(params),
+          signed_config_(signed_config),
+          total_framing_overhead_(total_framing_overhead),
+          chlo_packet_size_(chlo_packet_size),
+          done_cb_(std::move(done_cb)) {}
+
+    ~ProcessClientHelloContext();
+
+    // Invoke |done_cb_| with an error status
+    void Fail(QuicErrorCode error, const std::string& error_details);
+
+    // Invoke |done_cb_| with a success status
+    void Succeed(std::unique_ptr<CryptoHandshakeMessage> message,
+                 std::unique_ptr<DiversificationNonce> diversification_nonce,
+                 std::unique_ptr<ProofSource::Details> proof_source_details);
+
+    // Member accessors
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+    validate_chlo_result() const {
+      return validate_chlo_result_;
+    }
+    bool reject_only() const { return reject_only_; }
+    QuicConnectionId connection_id() const { return connection_id_; }
+    QuicSocketAddress server_address() const { return server_address_; }
+    QuicSocketAddress client_address() const { return client_address_; }
+    ParsedQuicVersion version() const { return version_; }
+    ParsedQuicVersionVector supported_versions() const {
+      return supported_versions_;
+    }
+    const QuicClock* clock() const { return clock_; }
+    QuicRandom* rand() const { return rand_; }  // NOLINT
+    QuicCompressedCertsCache* compressed_certs_cache() const {
+      return compressed_certs_cache_;
+    }
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+    params() const {
+      return params_;
+    }
+    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+    signed_config() const {
+      return signed_config_;
+    }
+    QuicByteCount total_framing_overhead() const {
+      return total_framing_overhead_;
+    }
+    QuicByteCount chlo_packet_size() const { return chlo_packet_size_; }
+
+    // Derived value accessors
+    const CryptoHandshakeMessage& client_hello() const {
+      return validate_chlo_result()->client_hello;
+    }
+    const ClientHelloInfo& info() const { return validate_chlo_result()->info; }
+    QuicTransportVersion transport_version() const {
+      return version().transport_version;
+    }
+
+   private:
+    const quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        validate_chlo_result_;
+    const bool reject_only_;
+    const QuicConnectionId connection_id_;
+    const QuicSocketAddress server_address_;
+    const QuicSocketAddress client_address_;
+    const ParsedQuicVersion version_;
+    const ParsedQuicVersionVector supported_versions_;
+    const QuicClock* const clock_;
+    QuicRandom* const rand_;
+    QuicCompressedCertsCache* const compressed_certs_cache_;
+    const quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        params_;
+    const quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+        signed_config_;
+    const QuicByteCount total_framing_overhead_;
+    const QuicByteCount chlo_packet_size_;
+    std::unique_ptr<ProcessClientHelloResultCallback> done_cb_;
+  };
+
+  // Callback class for bridging between ProcessClientHello and
+  // ProcessClientHelloAfterGetProof.
+  class ProcessClientHelloCallback;
+  friend class ProcessClientHelloCallback;
+
+  // Portion of ProcessClientHello which executes after GetProof.
+  void ProcessClientHelloAfterGetProof(
+      bool found_error,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      const Configs& configs) const;
+
+  // Callback class for bridging between ProcessClientHelloAfterGetProof and
+  // ProcessClientHelloAfterCalculateSharedKeys.
+  class ProcessClientHelloAfterGetProofCallback;
+  friend class ProcessClientHelloAfterGetProofCallback;
+
+  // Portion of ProcessClientHello which executes after CalculateSharedKeys.
+  void ProcessClientHelloAfterCalculateSharedKeys(
+      bool found_error,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      QuicTag key_exchange_type,
+      std::unique_ptr<CryptoHandshakeMessage> out,
+      absl::string_view public_value,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      const Configs& configs) const;
+
+  // Send a REJ which contains a different ServerConfig than the one the client
+  // originally used.  This is necessary in cases where we discover in the
+  // middle of the handshake that the private key for the ServerConfig the
+  // client used is not accessible.
+  void SendRejectWithFallbackConfig(
+      std::unique_ptr<ProcessClientHelloContext> context,
+      quiche::QuicheReferenceCountedPointer<Config> fallback_config) const;
+
+  // Callback class for bridging between SendRejectWithFallbackConfig and
+  // SendRejectWithFallbackConfigAfterGetProof.
+  class SendRejectWithFallbackConfigCallback;
+  friend class SendRejectWithFallbackConfigCallback;
+
+  // Portion of ProcessClientHello which executes after GetProof in the case
+  // where we have received a CHLO but need to reject it due to the ServerConfig
+  // private keys being inaccessible.
+  void SendRejectWithFallbackConfigAfterGetProof(
+      bool found_error,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      quiche::QuicheReferenceCountedPointer<Config> fallback_config) const;
+
+  // BuildRejectionAndRecordStats calls |BuildRejection| below and also informs
+  // the RejectionObserver.
+  void BuildRejectionAndRecordStats(const ProcessClientHelloContext& context,
+                                    const Config& config,
+                                    const std::vector<uint32_t>& reject_reasons,
+                                    CryptoHandshakeMessage* out) const;
+
+  // BuildRejection sets |out| to be a REJ message in reply to |client_hello|.
+  void BuildRejection(const ProcessClientHelloContext& context,
+                      const Config& config,
+                      const std::vector<uint32_t>& reject_reasons,
+                      CryptoHandshakeMessage* out) const;
+
+  // CompressChain compresses the certificates in |chain->certs| and returns a
+  // compressed representation. |client_cached_cert_hashes| contains
+  // 64-bit, FNV-1a hashes of certificates that the peer already possesses.
+  static std::string CompressChain(
+      QuicCompressedCertsCache* compressed_certs_cache,
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const std::string& client_cached_cert_hashes);
+
+  // ParseConfigProtobuf parses the given config protobuf and returns a
+  // quiche::QuicheReferenceCountedPointer<Config> if successful. The caller
+  // adopts the reference to the Config. On error, ParseConfigProtobuf returns
+  // nullptr.
+  quiche::QuicheReferenceCountedPointer<Config> ParseConfigProtobuf(
+      const QuicServerConfigProtobuf& protobuf, bool is_fallback) const;
+
+  // ValidateSingleSourceAddressToken returns HANDSHAKE_OK if the source
+  // address token in |token| is a timely token for the IP address |ip|
+  // given that the current time is |now|. Otherwise it returns the reason
+  // for failure.
+  HandshakeFailureReason ValidateSingleSourceAddressToken(
+      const SourceAddressToken& token,
+      const QuicIpAddress& ip,
+      QuicWallTime now) const;
+
+  // Returns HANDSHAKE_OK if the source address token in |token| is a timely
+  // token given that the current time is |now|. Otherwise it returns the
+  // reason for failure.
+  HandshakeFailureReason ValidateSourceAddressTokenTimestamp(
+      const SourceAddressToken& token,
+      QuicWallTime now) const;
+
+  // NewServerNonce generates and encrypts a random nonce.
+  std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const;
+
+  // ValidateExpectedLeafCertificate checks the |client_hello| to see if it has
+  // an XLCT tag, and if so, verifies that its value matches the hash of the
+  // server's leaf certificate. |certs| is used to compare against the XLCT
+  // value.  This method returns true if the XLCT tag is not present, or if the
+  // XLCT tag is present and valid. It returns false otherwise.
+  bool ValidateExpectedLeafCertificate(
+      const CryptoHandshakeMessage& client_hello,
+      const std::vector<std::string>& certs) const;
+
+  // Callback to receive the results of ProofSource::GetProof.  Note: this
+  // callback has no cancellation support, since the lifetime of the ProofSource
+  // is controlled by this object via unique ownership.  If that ownership
+  // stricture changes, this decision may need to be revisited.
+  class BuildServerConfigUpdateMessageProofSourceCallback
+      : public ProofSource::Callback {
+   public:
+    BuildServerConfigUpdateMessageProofSourceCallback(
+        const BuildServerConfigUpdateMessageProofSourceCallback&) = delete;
+    ~BuildServerConfigUpdateMessageProofSourceCallback() override;
+    void operator=(const BuildServerConfigUpdateMessageProofSourceCallback&) =
+        delete;
+    BuildServerConfigUpdateMessageProofSourceCallback(
+        const QuicCryptoServerConfig* config,
+        QuicCompressedCertsCache* compressed_certs_cache,
+        const QuicCryptoNegotiatedParameters& params,
+        CryptoHandshakeMessage message,
+        std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb);
+
+    void Run(
+        bool ok,
+        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+        const QuicCryptoProof& proof,
+        std::unique_ptr<ProofSource::Details> details) override;
+
+   private:
+    const QuicCryptoServerConfig* config_;
+    QuicCompressedCertsCache* compressed_certs_cache_;
+    const std::string client_cached_cert_hashes_;
+    const bool sct_supported_by_client_;
+    const std::string sni_;
+    CryptoHandshakeMessage message_;
+    std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb_;
+  };
+
+  // Invoked by BuildServerConfigUpdateMessageProofSourceCallback::Run once
+  // the proof has been acquired.  Finishes building the server config update
+  // message and invokes |cb|.
+  void FinishBuildServerConfigUpdateMessage(
+      QuicCompressedCertsCache* compressed_certs_cache,
+      const std::string& client_cached_cert_hashes,
+      bool sct_supported_by_client, const std::string& sni, bool ok,
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const std::string& signature, const std::string& leaf_cert_sct,
+      std::unique_ptr<ProofSource::Details> details,
+      CryptoHandshakeMessage message,
+      std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const;
+
+  // Returns true if the next config promotion should happen now.
+  bool IsNextConfigReady(QuicWallTime now) const
+      QUIC_SHARED_LOCKS_REQUIRED(configs_lock_);
+
+  // replay_protection_ controls whether the server enforces that handshakes
+  // aren't replays.
+  bool replay_protection_;
+
+  // The multiple of the CHLO message size that a REJ message must stay under
+  // when the client doesn't present a valid source-address token. This is
+  // used to protect QUIC from amplification attacks.
+  size_t chlo_multiplier_;
+
+  // configs_ satisfies the following invariants:
+  //   1) configs_.empty() <-> primary_config_ == nullptr
+  //   2) primary_config_ != nullptr -> primary_config_->is_primary
+  //   3) ∀ c∈configs_, c->is_primary <-> c == primary_config_
+  mutable QuicMutex configs_lock_;
+
+  // configs_ contains all active server configs. It's expected that there are
+  // about half-a-dozen configs active at any one time.
+  ConfigMap configs_ QUIC_GUARDED_BY(configs_lock_);
+
+  // primary_config_ points to a Config (which is also in |configs_|) which is
+  // the primary config - i.e. the one that we'll give out to new clients.
+  mutable quiche::QuicheReferenceCountedPointer<Config> primary_config_
+      QUIC_GUARDED_BY(configs_lock_);
+
+  // fallback_config_ points to a Config (which is also in |configs_|) which is
+  // the fallback config, which will be used if the other configs are unuseable
+  // for some reason.
+  //
+  // TODO(b/112548056): This is currently always nullptr.
+  quiche::QuicheReferenceCountedPointer<Config> fallback_config_
+      QUIC_GUARDED_BY(configs_lock_);
+
+  // next_config_promotion_time_ contains the nearest, future time when an
+  // active config will be promoted to primary.
+  mutable QuicWallTime next_config_promotion_time_
+      QUIC_GUARDED_BY(configs_lock_);
+
+  // Callback to invoke when the primary config changes.
+  std::unique_ptr<PrimaryConfigChangedCallback> primary_config_changed_cb_
+      QUIC_GUARDED_BY(configs_lock_);
+
+  // Used to protect the source-address tokens that are given to clients.
+  CryptoSecretBoxer source_address_token_boxer_;
+
+  // server_nonce_boxer_ is used to encrypt and validate suggested server
+  // nonces.
+  CryptoSecretBoxer server_nonce_boxer_;
+
+  // server_nonce_orbit_ contains the random, per-server orbit values that this
+  // server will use to generate server nonces (the moral equivalent of a SYN
+  // cookies).
+  uint8_t server_nonce_orbit_[8];
+
+  // proof_source_ contains an object that can provide certificate chains and
+  // signatures.
+  std::unique_ptr<ProofSource> proof_source_;
+
+  // key_exchange_source_ contains an object that can provide key exchange
+  // objects.
+  std::unique_ptr<KeyExchangeSource> key_exchange_source_;
+
+  // ssl_ctx_ contains the server configuration for doing TLS handshakes.
+  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+
+  // These fields store configuration values. See the comments for their
+  // respective setter functions.
+  uint32_t source_address_token_future_secs_;
+  uint32_t source_address_token_lifetime_secs_;
+
+  // Enable serving SCT or not.
+  bool enable_serving_sct_;
+
+  // Does not own this observer.
+  RejectionObserver* rejection_observer_;
+
+  // If non-empty, the server will operate in the pre-shared key mode by
+  // incorporating |pre_shared_key_| into the key schedule.
+  std::string pre_shared_key_;
+
+  // Whether REJ message should be padded to max packet size.
+  bool pad_rej_;
+
+  // Whether SHLO message should be padded to max packet size.
+  bool pad_shlo_;
+
+  // If client is allowed to send a small client hello (by disabling padding),
+  // server MUST not check for the client hello size.
+  // DO NOT disable this unless you have some other way of validating client.
+  // (e.g. in realtime scenarios, where quic is tunneled through ICE, ICE will
+  // do its own peer validation using STUN pings with ufrag/upass).
+  bool validate_chlo_size_;
+
+  // When source address is validated by some other means (e.g. when using ICE),
+  // source address token validation may be disabled.
+  bool validate_source_address_token_;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicSignedServerConfig
+    : public quiche::QuicheReferenceCounted {
+  QuicSignedServerConfig();
+
+  QuicCryptoProof proof;
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain;
+  // The server config that is used for this proof (and the rest of the
+  // request).
+  quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config> config;
+  std::string primary_scid;
+
+ protected:
+  ~QuicSignedServerConfig() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
diff --git a/quiche/quic/core/crypto/quic_crypto_server_config_test.cc b/quiche/quic/core/crypto/quic_crypto_server_config_test.cc
new file mode 100644
index 0000000..5a24881
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_server_config_test.cc
@@ -0,0 +1,500 @@
+// Copyright 2013 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 "quiche/quic/core/crypto/quic_crypto_server_config.h"
+
+#include <stdarg.h>
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_secret_boxer.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+using ::testing::Not;
+
+// NOTE: This matcher depends on the wire format of serialzied protocol buffers,
+// which may change in the future.
+// Switch to ::testing::EqualsProto once it is available in Chromium.
+MATCHER_P(SerializedProtoEquals, message, "") {
+  std::string expected_serialized, actual_serialized;
+  message.SerializeToString(&expected_serialized);
+  arg.SerializeToString(&actual_serialized);
+  return expected_serialized == actual_serialized;
+}
+
+class QuicCryptoServerConfigTest : public QuicTest {};
+
+TEST_F(QuicCryptoServerConfigTest, ServerConfig) {
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+                                crypto_test_utils::ProofSourceForTesting(),
+                                KeyExchangeSource::Default());
+  MockClock clock;
+
+  std::unique_ptr<CryptoHandshakeMessage> message(server.AddDefaultConfig(
+      rand, &clock, QuicCryptoServerConfig::ConfigOptions()));
+
+  // The default configuration should have AES-GCM and at least one ChaCha20
+  // cipher.
+  QuicTagVector aead;
+  ASSERT_THAT(message->GetTaglist(kAEAD, &aead), IsQuicNoError());
+  EXPECT_THAT(aead, ::testing::Contains(kAESG));
+  EXPECT_LE(1u, aead.size());
+}
+
+TEST_F(QuicCryptoServerConfigTest, CompressCerts) {
+  QuicCompressedCertsCache compressed_certs_cache(
+      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
+
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+                                crypto_test_utils::ProofSourceForTesting(),
+                                KeyExchangeSource::Default());
+  QuicCryptoServerConfigPeer peer(&server);
+
+  std::vector<std::string> certs = {"testcert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+
+  std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain, "");
+
+  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
+}
+
+TEST_F(QuicCryptoServerConfigTest, CompressSameCertsTwice) {
+  QuicCompressedCertsCache compressed_certs_cache(
+      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
+
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+                                crypto_test_utils::ProofSourceForTesting(),
+                                KeyExchangeSource::Default());
+  QuicCryptoServerConfigPeer peer(&server);
+
+  // Compress the certs for the first time.
+  std::vector<std::string> certs = {"testcert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+  std::string cached_certs = "";
+
+  std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain, cached_certs);
+  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
+
+  // Compress the same certs, should use cache if available.
+  std::string compressed2 = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain, cached_certs);
+  EXPECT_EQ(compressed, compressed2);
+  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
+}
+
+TEST_F(QuicCryptoServerConfigTest, CompressDifferentCerts) {
+  // This test compresses a set of similar but not identical certs. Cache if
+  // used should return cache miss and add all the compressed certs.
+  QuicCompressedCertsCache compressed_certs_cache(
+      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
+
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+                                crypto_test_utils::ProofSourceForTesting(),
+                                KeyExchangeSource::Default());
+  QuicCryptoServerConfigPeer peer(&server);
+
+  std::vector<std::string> certs = {"testcert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+  std::string cached_certs = "";
+
+  std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain, cached_certs);
+  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
+
+  // Compress a similar certs which only differs in the chain.
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain2(
+      new ProofSource::Chain(certs));
+
+  std::string compressed2 = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain2, cached_certs);
+  EXPECT_EQ(compressed_certs_cache.Size(), 2u);
+}
+
+class SourceAddressTokenTest : public QuicTest {
+ public:
+  SourceAddressTokenTest()
+      : ip4_(QuicIpAddress::Loopback4()),
+        ip4_dual_(ip4_.DualStacked()),
+        ip6_(QuicIpAddress::Loopback6()),
+        original_time_(QuicWallTime::Zero()),
+        rand_(QuicRandom::GetInstance()),
+        server_(QuicCryptoServerConfig::TESTING,
+                rand_,
+                crypto_test_utils::ProofSourceForTesting(),
+                KeyExchangeSource::Default()),
+        peer_(&server_) {
+    // Advance the clock to some non-zero time.
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
+    original_time_ = clock_.WallNow();
+
+    primary_config_ = server_.AddDefaultConfig(
+        rand_, &clock_, QuicCryptoServerConfig::ConfigOptions());
+  }
+
+  std::string NewSourceAddressToken(std::string config_id,
+                                    const QuicIpAddress& ip) {
+    return NewSourceAddressToken(config_id, ip, nullptr);
+  }
+
+  std::string NewSourceAddressToken(
+      std::string config_id,
+      const QuicIpAddress& ip,
+      const SourceAddressTokens& previous_tokens) {
+    return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
+                                       clock_.WallNow(), nullptr);
+  }
+
+  std::string NewSourceAddressToken(
+      std::string config_id,
+      const QuicIpAddress& ip,
+      CachedNetworkParameters* cached_network_params) {
+    SourceAddressTokens previous_tokens;
+    return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
+                                       clock_.WallNow(), cached_network_params);
+  }
+
+  HandshakeFailureReason ValidateSourceAddressTokens(std::string config_id,
+                                                     absl::string_view srct,
+                                                     const QuicIpAddress& ip) {
+    return ValidateSourceAddressTokens(config_id, srct, ip, nullptr);
+  }
+
+  HandshakeFailureReason ValidateSourceAddressTokens(
+      std::string config_id,
+      absl::string_view srct,
+      const QuicIpAddress& ip,
+      CachedNetworkParameters* cached_network_params) {
+    return peer_.ValidateSourceAddressTokens(
+        config_id, srct, ip, clock_.WallNow(), cached_network_params);
+  }
+
+  const std::string kPrimary = "<primary>";
+  const std::string kOverride = "Config with custom source address token key";
+
+  QuicIpAddress ip4_;
+  QuicIpAddress ip4_dual_;
+  QuicIpAddress ip6_;
+
+  MockClock clock_;
+  QuicWallTime original_time_;
+  QuicRandom* rand_ = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server_;
+  QuicCryptoServerConfigPeer peer_;
+  // Stores the primary config.
+  std::unique_ptr<CryptoHandshakeMessage> primary_config_;
+  std::unique_ptr<QuicServerConfigProtobuf> override_config_protobuf_;
+};
+
+// Test basic behavior of source address tokens including being specific
+// to a single IP address and server config.
+TEST_F(SourceAddressTokenTest, SourceAddressToken) {
+  // Primary config generates configs that validate successfully.
+  const std::string token4 = NewSourceAddressToken(kPrimary, ip4_);
+  const std::string token4d = NewSourceAddressToken(kPrimary, ip4_dual_);
+  const std::string token6 = NewSourceAddressToken(kPrimary, ip6_);
+  EXPECT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4, ip4_));
+  ASSERT_EQ(HANDSHAKE_OK,
+            ValidateSourceAddressTokens(kPrimary, token4, ip4_dual_));
+  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+            ValidateSourceAddressTokens(kPrimary, token4, ip6_));
+  ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4d, ip4_));
+  ASSERT_EQ(HANDSHAKE_OK,
+            ValidateSourceAddressTokens(kPrimary, token4d, ip4_dual_));
+  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+            ValidateSourceAddressTokens(kPrimary, token4d, ip6_));
+  ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token6, ip6_));
+}
+
+TEST_F(SourceAddressTokenTest, SourceAddressTokenExpiration) {
+  const std::string token = NewSourceAddressToken(kPrimary, ip4_);
+
+  // Validation fails if the token is from the future.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(-3600 * 2));
+  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE,
+            ValidateSourceAddressTokens(kPrimary, token, ip4_));
+
+  // Validation fails after tokens expire.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400 * 7));
+  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE,
+            ValidateSourceAddressTokens(kPrimary, token, ip4_));
+}
+
+TEST_F(SourceAddressTokenTest, SourceAddressTokenWithNetworkParams) {
+  // Make sure that if the source address token contains CachedNetworkParameters
+  // that this gets written to ValidateSourceAddressToken output argument.
+  CachedNetworkParameters cached_network_params_input;
+  cached_network_params_input.set_bandwidth_estimate_bytes_per_second(1234);
+  const std::string token4_with_cached_network_params =
+      NewSourceAddressToken(kPrimary, ip4_, &cached_network_params_input);
+
+  CachedNetworkParameters cached_network_params_output;
+  EXPECT_THAT(cached_network_params_output,
+              Not(SerializedProtoEquals(cached_network_params_input)));
+  ValidateSourceAddressTokens(kPrimary, token4_with_cached_network_params, ip4_,
+                              &cached_network_params_output);
+  EXPECT_THAT(cached_network_params_output,
+              SerializedProtoEquals(cached_network_params_input));
+}
+
+// Test the ability for a source address token to be valid for multiple
+// addresses.
+TEST_F(SourceAddressTokenTest, SourceAddressTokenMultipleAddresses) {
+  QuicWallTime now = clock_.WallNow();
+
+  // Now create a token which is usable for both addresses.
+  SourceAddressToken previous_token;
+  previous_token.set_ip(ip6_.DualStacked().ToPackedString());
+  previous_token.set_timestamp(now.ToUNIXSeconds());
+  SourceAddressTokens previous_tokens;
+  (*previous_tokens.add_tokens()) = previous_token;
+  const std::string token4or6 =
+      NewSourceAddressToken(kPrimary, ip4_, previous_tokens);
+
+  EXPECT_EQ(HANDSHAKE_OK,
+            ValidateSourceAddressTokens(kPrimary, token4or6, ip4_));
+  ASSERT_EQ(HANDSHAKE_OK,
+            ValidateSourceAddressTokens(kPrimary, token4or6, ip6_));
+}
+
+class CryptoServerConfigsTest : public QuicTest {
+ public:
+  CryptoServerConfigsTest()
+      : rand_(QuicRandom::GetInstance()),
+        config_(QuicCryptoServerConfig::TESTING,
+                rand_,
+                crypto_test_utils::ProofSourceForTesting(),
+                KeyExchangeSource::Default()),
+        test_peer_(&config_) {}
+
+  void SetUp() override {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000));
+  }
+
+  // SetConfigs constructs suitable config protobufs and calls SetConfigs on
+  // |config_|.
+  // Each struct in the input vector contains 3 elements.
+  // The first is the server config ID of a Config. The second is
+  // the |primary_time| of that Config, given in epoch seconds. (Although note
+  // that, in these tests, time is set to 1000 seconds since the epoch.).
+  // The third is the priority.
+  //
+  // For example:
+  //   SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>());  // calls
+  //   |config_.SetConfigs| with no protobufs.
+  //
+  //   // Calls |config_.SetConfigs| with two protobufs: one for a Config with
+  //   // a |primary_time| of 900 and priority 1, and another with
+  //   // a |primary_time| of 1000 and priority 2.
+
+  //   CheckConfigs(
+  //     {{"id1", 900,  1},
+  //      {"id2", 1000, 2}});
+  //
+  // If the server config id starts with "INVALID" then the generated protobuf
+  // will be invalid.
+  struct ServerConfigIDWithTimeAndPriority {
+    ServerConfigID server_config_id;
+    int primary_time;
+    int priority;
+  };
+  void SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority> configs) {
+    const char kOrbit[] = "12345678";
+
+    bool has_invalid = false;
+
+    std::vector<QuicServerConfigProtobuf> protobufs;
+    for (const auto& config : configs) {
+      const ServerConfigID& server_config_id = config.server_config_id;
+      const int primary_time = config.primary_time;
+      const int priority = config.priority;
+
+      QuicCryptoServerConfig::ConfigOptions options;
+      options.id = server_config_id;
+      options.orbit = kOrbit;
+      QuicServerConfigProtobuf protobuf =
+          QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options);
+      protobuf.set_primary_time(primary_time);
+      protobuf.set_priority(priority);
+      if (absl::StartsWith(std::string(server_config_id), "INVALID")) {
+        protobuf.clear_key();
+        has_invalid = true;
+      }
+      protobufs.push_back(std::move(protobuf));
+    }
+
+    ASSERT_EQ(!has_invalid && !configs.empty(),
+              config_.SetConfigs(protobufs, /* fallback_protobuf = */ nullptr,
+                                 clock_.WallNow()));
+  }
+
+ protected:
+  QuicRandom* const rand_;
+  MockClock clock_;
+  QuicCryptoServerConfig config_;
+  QuicCryptoServerConfigPeer test_peer_;
+};
+
+TEST_F(CryptoServerConfigsTest, NoConfigs) {
+  test_peer_.CheckConfigs(std::vector<std::pair<std::string, bool>>());
+}
+
+TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) {
+  // Make sure that "b" is primary even though "a" comes first.
+  SetConfigs({{"a", 1100, 1}, {"b", 900, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, MakePrimarySecond) {
+  // Make sure that a remains primary after b is added.
+  SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}});
+}
+
+TEST_F(CryptoServerConfigsTest, Delete) {
+  // Ensure that configs get deleted when removed.
+  SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
+  SetConfigs({{"b", 900, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"b", true}, {"c", false}});
+}
+
+TEST_F(CryptoServerConfigsTest, DeletePrimary) {
+  // Ensure that deleting the primary config works.
+  SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
+  SetConfigs({{"a", 800, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", true}, {"c", false}});
+}
+
+TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) {
+  // Ensure that configs get deleted when removed.
+  SetConfigs({{"a", 800, 1}, {"b", 900, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+  SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>());
+  // Config change is rejected, still using old configs.
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
+  // Check that updates to primary time get picked up.
+  SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
+  test_peer_.SelectNewPrimaryConfig(500);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+  SetConfigs({{"a", 1200, 1}, {"b", 800, 1}, {"c", 400, 1}});
+  test_peer_.SelectNewPrimaryConfig(500);
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
+  // Check that the most recent config is selected.
+  SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
+  test_peer_.SelectNewPrimaryConfig(1500);
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
+  // Check that the first config is selected.
+  SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
+  test_peer_.SelectNewPrimaryConfig(100);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+}
+
+TEST_F(CryptoServerConfigsTest, SortByPriority) {
+  // Check that priority is used to decide on a primary config when
+  // configs have the same primary time.
+  SetConfigs({{"a", 900, 1}, {"b", 900, 2}, {"c", 900, 3}});
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+  test_peer_.SelectNewPrimaryConfig(800);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+  test_peer_.SelectNewPrimaryConfig(1000);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+
+  // Change priorities and expect sort order to change.
+  SetConfigs({{"a", 900, 2}, {"b", 900, 1}, {"c", 900, 0}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+  test_peer_.SelectNewPrimaryConfig(800);
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+  test_peer_.SelectNewPrimaryConfig(1000);
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, AdvancePrimary) {
+  // Check that a new primary config is enabled at the right time.
+  SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
+  test_peer_.SelectNewPrimaryConfig(1000);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}});
+  test_peer_.SelectNewPrimaryConfig(1101);
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+}
+
+class ValidateCallback : public ValidateClientHelloResultCallback {
+ public:
+  void Run(quiche::QuicheReferenceCountedPointer<Result> /*result*/,
+           std::unique_ptr<ProofSource::Details> /*details*/) override {}
+};
+
+TEST_F(CryptoServerConfigsTest, AdvancePrimaryViaValidate) {
+  // Check that a new primary config is enabled at the right time.
+  SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
+  test_peer_.SelectNewPrimaryConfig(1000);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}});
+  CryptoHandshakeMessage client_hello;
+  QuicSocketAddress client_address;
+  QuicSocketAddress server_address;
+  QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      transport_version = version.transport_version;
+      break;
+    }
+  }
+  ASSERT_NE(transport_version, QUIC_VERSION_UNSUPPORTED);
+  MockClock clock;
+  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config(
+      new QuicSignedServerConfig);
+  std::unique_ptr<ValidateClientHelloResultCallback> done_cb(
+      new ValidateCallback);
+  clock.AdvanceTime(QuicTime::Delta::FromSeconds(1100));
+  config_.ValidateClientHello(client_hello, client_address, server_address,
+                              transport_version, &clock, signed_config,
+                              std::move(done_cb));
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
+  // Ensure that invalid configs don't change anything.
+  SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
+  SetConfigs({{"a", 800, 1}, {"c", 1100, 1}, {"INVALID1", 1000, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_decrypter.cc b/quiche/quic/core/crypto/quic_decrypter.cc
new file mode 100644
index 0000000..f91a786
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_decrypter.cc
@@ -0,0 +1,80 @@
+// 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 "quiche/quic/core/crypto/quic_decrypter.h"
+
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_decrypter.h"
+#include "quiche/quic/core/crypto/aes_256_gcm_decrypter.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_decrypter.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/quic_hkdf.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// static
+std::unique_ptr<QuicDecrypter> QuicDecrypter::Create(
+    const ParsedQuicVersion& version,
+    QuicTag algorithm) {
+  switch (algorithm) {
+    case kAESG:
+      if (version.UsesInitialObfuscators()) {
+        return std::make_unique<Aes128GcmDecrypter>();
+      } else {
+        return std::make_unique<Aes128Gcm12Decrypter>();
+      }
+    case kCC20:
+      if (version.UsesInitialObfuscators()) {
+        return std::make_unique<ChaCha20Poly1305TlsDecrypter>();
+      } else {
+        return std::make_unique<ChaCha20Poly1305Decrypter>();
+      }
+    default:
+      QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
+      return nullptr;
+  }
+}
+
+// static
+std::unique_ptr<QuicDecrypter> QuicDecrypter::CreateFromCipherSuite(
+    uint32_t cipher_suite) {
+  switch (cipher_suite) {
+    case TLS1_CK_AES_128_GCM_SHA256:
+      return std::make_unique<Aes128GcmDecrypter>();
+    case TLS1_CK_AES_256_GCM_SHA384:
+      return std::make_unique<Aes256GcmDecrypter>();
+    case TLS1_CK_CHACHA20_POLY1305_SHA256:
+      return std::make_unique<ChaCha20Poly1305TlsDecrypter>();
+    default:
+      QUIC_BUG(quic_bug_10660_1) << "TLS cipher suite is unknown to QUIC";
+      return nullptr;
+  }
+}
+
+// static
+void QuicDecrypter::DiversifyPreliminaryKey(absl::string_view preliminary_key,
+                                            absl::string_view nonce_prefix,
+                                            const DiversificationNonce& nonce,
+                                            size_t key_size,
+                                            size_t nonce_prefix_size,
+                                            std::string* out_key,
+                                            std::string* out_nonce_prefix) {
+  QuicHKDF hkdf((std::string(preliminary_key)) + (std::string(nonce_prefix)),
+                absl::string_view(nonce.data(), nonce.size()),
+                "QUIC key diversification", 0, key_size, 0, nonce_prefix_size,
+                0);
+  *out_key = std::string(hkdf.server_write_key());
+  *out_nonce_prefix = std::string(hkdf.server_write_iv());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_decrypter.h b/quiche/quic/core/crypto/quic_decrypter.h
new file mode 100644
index 0000000..2cd799c
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_decrypter.h
@@ -0,0 +1,95 @@
+// 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_CRYPTO_QUIC_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_crypter.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicDecrypter : public QuicCrypter {
+ public:
+  virtual ~QuicDecrypter() {}
+
+  static std::unique_ptr<QuicDecrypter> Create(const ParsedQuicVersion& version,
+                                               QuicTag algorithm);
+
+  // Creates an IETF QuicDecrypter based on |cipher_suite| which must be an id
+  // returned by SSL_CIPHER_get_id. The caller is responsible for taking
+  // ownership of the new QuicDecrypter.
+  static std::unique_ptr<QuicDecrypter> CreateFromCipherSuite(
+      uint32_t cipher_suite);
+
+  // Sets the encryption key. Returns true on success, false on failure.
+  // |DecryptPacket| may not be called until |SetDiversificationNonce| is
+  // called and the preliminary keying material will be combined with that
+  // nonce in order to create the actual key and nonce-prefix.
+  //
+  // If this function is called, neither |SetKey| nor |SetNoncePrefix| may be
+  // called.
+  virtual bool SetPreliminaryKey(absl::string_view key) = 0;
+
+  // SetDiversificationNonce uses |nonce| to derive final keys based on the
+  // input keying material given by calling |SetPreliminaryKey|.
+  //
+  // Calling this function is a no-op if |SetPreliminaryKey| hasn't been
+  // called.
+  virtual bool SetDiversificationNonce(const DiversificationNonce& nonce) = 0;
+
+  // Populates |output| with the decrypted |ciphertext| and populates
+  // |output_length| with the length.  Returns 0 if there is an error.
+  // |output| size is specified by |max_output_length| and must be
+  // at least as large as the ciphertext.  |packet_number| is
+  // appended to the |nonce_prefix| value provided in SetNoncePrefix()
+  // to form the nonce.
+  // TODO(wtc): add a way for DecryptPacket to report decryption failure due
+  // to non-authentic inputs, as opposed to other reasons for failure.
+  virtual bool DecryptPacket(uint64_t packet_number,
+                             absl::string_view associated_data,
+                             absl::string_view ciphertext,
+                             char* output,
+                             size_t* output_length,
+                             size_t max_output_length) = 0;
+
+  // Reads a sample of ciphertext from |sample_reader| and uses the header
+  // protection key to generate a mask to use for header protection. If
+  // successful, this function returns this mask, which is at least 5 bytes
+  // long. Callers can detect failure by checking if the output string is empty.
+  virtual std::string GenerateHeaderProtectionMask(
+      QuicDataReader* sample_reader) = 0;
+
+  // The ID of the cipher. Return 0x03000000 ORed with the 'cryptographic suite
+  // selector'.
+  virtual uint32_t cipher_id() const = 0;
+
+  // Returns the maximum number of packets that can safely fail decryption with
+  // this decrypter.
+  virtual QuicPacketCount GetIntegrityLimit() const = 0;
+
+  // For use by unit tests only.
+  virtual absl::string_view GetKey() const = 0;
+  virtual absl::string_view GetNoncePrefix() const = 0;
+
+  static void DiversifyPreliminaryKey(absl::string_view preliminary_key,
+                                      absl::string_view nonce_prefix,
+                                      const DiversificationNonce& nonce,
+                                      size_t key_size,
+                                      size_t nonce_prefix_size,
+                                      std::string* out_key,
+                                      std::string* out_nonce_prefix);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/quic_encrypter.cc b/quiche/quic/core/crypto/quic_encrypter.cc
new file mode 100644
index 0000000..4ae5232
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_encrypter.cc
@@ -0,0 +1,61 @@
+// 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 "quiche/quic/core/crypto/quic_encrypter.h"
+
+#include <utility>
+
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_encrypter.h"
+#include "quiche/quic/core/crypto/aes_256_gcm_encrypter.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// static
+std::unique_ptr<QuicEncrypter> QuicEncrypter::Create(
+    const ParsedQuicVersion& version,
+    QuicTag algorithm) {
+  switch (algorithm) {
+    case kAESG:
+      if (version.UsesInitialObfuscators()) {
+        return std::make_unique<Aes128GcmEncrypter>();
+      } else {
+        return std::make_unique<Aes128Gcm12Encrypter>();
+      }
+    case kCC20:
+      if (version.UsesInitialObfuscators()) {
+        return std::make_unique<ChaCha20Poly1305TlsEncrypter>();
+      } else {
+        return std::make_unique<ChaCha20Poly1305Encrypter>();
+      }
+    default:
+      QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
+      return nullptr;
+  }
+}
+
+// static
+std::unique_ptr<QuicEncrypter> QuicEncrypter::CreateFromCipherSuite(
+    uint32_t cipher_suite) {
+  switch (cipher_suite) {
+    case TLS1_CK_AES_128_GCM_SHA256:
+      return std::make_unique<Aes128GcmEncrypter>();
+    case TLS1_CK_AES_256_GCM_SHA384:
+      return std::make_unique<Aes256GcmEncrypter>();
+    case TLS1_CK_CHACHA20_POLY1305_SHA256:
+      return std::make_unique<ChaCha20Poly1305TlsEncrypter>();
+    default:
+      QUIC_BUG(quic_bug_10711_1) << "TLS cipher suite is unknown to QUIC";
+      return nullptr;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_encrypter.h b/quiche/quic/core/crypto/quic_encrypter.h
new file mode 100644
index 0000000..6caf51b
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_encrypter.h
@@ -0,0 +1,71 @@
+// 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_CRYPTO_QUIC_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_crypter.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicEncrypter : public QuicCrypter {
+ public:
+  virtual ~QuicEncrypter() {}
+
+  static std::unique_ptr<QuicEncrypter> Create(const ParsedQuicVersion& version,
+                                               QuicTag algorithm);
+
+  // Creates an IETF QuicEncrypter based on |cipher_suite| which must be an id
+  // returned by SSL_CIPHER_get_id. The caller is responsible for taking
+  // ownership of the new QuicEncrypter.
+  static std::unique_ptr<QuicEncrypter> CreateFromCipherSuite(
+      uint32_t cipher_suite);
+
+  // Writes encrypted |plaintext| and a MAC over |plaintext| and
+  // |associated_data| into output. Sets |output_length| to the number of
+  // bytes written. Returns true on success or false if there was an error.
+  // |packet_number| is appended to the |nonce_prefix| value provided in
+  // SetNoncePrefix() to form the nonce. |output| must not overlap with
+  // |associated_data|. If |output| overlaps with |plaintext| then
+  // |plaintext| must be <= |output|.
+  virtual bool EncryptPacket(uint64_t packet_number,
+                             absl::string_view associated_data,
+                             absl::string_view plaintext,
+                             char* output,
+                             size_t* output_length,
+                             size_t max_output_length) = 0;
+
+  // Takes a |sample| of ciphertext and uses the header protection key to
+  // generate a mask to use for header protection, and returns that mask. On
+  // success, the mask will be at least 5 bytes long; on failure the string will
+  // be empty.
+  virtual std::string GenerateHeaderProtectionMask(
+      absl::string_view sample) = 0;
+
+  // Returns the maximum length of plaintext that can be encrypted
+  // to ciphertext no larger than |ciphertext_size|.
+  virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) const = 0;
+
+  // Returns the length of the ciphertext that would be generated by encrypting
+  // to plaintext of size |plaintext_size|.
+  virtual size_t GetCiphertextSize(size_t plaintext_size) const = 0;
+
+  // Returns the maximum number of packets that can be safely encrypted with
+  // this encrypter.
+  virtual QuicPacketCount GetConfidentialityLimit() const = 0;
+
+  // For use by unit tests only.
+  virtual absl::string_view GetKey() const = 0;
+  virtual absl::string_view GetNoncePrefix() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/quic_hkdf.cc b/quiche/quic/core/crypto/quic_hkdf.cc
new file mode 100644
index 0000000..2ad00f2
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_hkdf.cc
@@ -0,0 +1,107 @@
+// Copyright (c) 2018 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 "quiche/quic/core/crypto/quic_hkdf.h"
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/hkdf.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+const size_t kSHA256HashLength = 32;
+const size_t kMaxKeyMaterialSize = kSHA256HashLength * 256;
+
+QuicHKDF::QuicHKDF(absl::string_view secret,
+                   absl::string_view salt,
+                   absl::string_view info,
+                   size_t key_bytes_to_generate,
+                   size_t iv_bytes_to_generate,
+                   size_t subkey_secret_bytes_to_generate)
+    : QuicHKDF(secret,
+               salt,
+               info,
+               key_bytes_to_generate,
+               key_bytes_to_generate,
+               iv_bytes_to_generate,
+               iv_bytes_to_generate,
+               subkey_secret_bytes_to_generate) {}
+
+QuicHKDF::QuicHKDF(absl::string_view secret,
+                   absl::string_view salt,
+                   absl::string_view info,
+                   size_t client_key_bytes_to_generate,
+                   size_t server_key_bytes_to_generate,
+                   size_t client_iv_bytes_to_generate,
+                   size_t server_iv_bytes_to_generate,
+                   size_t subkey_secret_bytes_to_generate) {
+  const size_t material_length =
+      2 * client_key_bytes_to_generate + client_iv_bytes_to_generate +
+      2 * server_key_bytes_to_generate + server_iv_bytes_to_generate +
+      subkey_secret_bytes_to_generate;
+  QUICHE_DCHECK_LT(material_length, kMaxKeyMaterialSize);
+
+  output_.resize(material_length);
+  // On Windows, when the size of output_ is zero, dereference of 0'th element
+  // results in a crash. C++11 solves this problem by adding a data() getter
+  // method to std::vector.
+  if (output_.empty()) {
+    return;
+  }
+
+  ::HKDF(&output_[0], output_.size(), ::EVP_sha256(),
+         reinterpret_cast<const uint8_t*>(secret.data()), secret.size(),
+         reinterpret_cast<const uint8_t*>(salt.data()), salt.size(),
+         reinterpret_cast<const uint8_t*>(info.data()), info.size());
+
+  size_t j = 0;
+  if (client_key_bytes_to_generate) {
+    client_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                          client_key_bytes_to_generate);
+    j += client_key_bytes_to_generate;
+  }
+
+  if (server_key_bytes_to_generate) {
+    server_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                          server_key_bytes_to_generate);
+    j += server_key_bytes_to_generate;
+  }
+
+  if (client_iv_bytes_to_generate) {
+    client_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                         client_iv_bytes_to_generate);
+    j += client_iv_bytes_to_generate;
+  }
+
+  if (server_iv_bytes_to_generate) {
+    server_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                         server_iv_bytes_to_generate);
+    j += server_iv_bytes_to_generate;
+  }
+
+  if (subkey_secret_bytes_to_generate) {
+    subkey_secret_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                       subkey_secret_bytes_to_generate);
+    j += subkey_secret_bytes_to_generate;
+  }
+  // Repeat client and server key bytes for header protection keys.
+  if (client_key_bytes_to_generate) {
+    client_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                       client_key_bytes_to_generate);
+    j += client_key_bytes_to_generate;
+  }
+
+  if (server_key_bytes_to_generate) {
+    server_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                       server_key_bytes_to_generate);
+    j += server_key_bytes_to_generate;
+  }
+}
+
+QuicHKDF::~QuicHKDF() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_hkdf.h b/quiche/quic/core/crypto/quic_hkdf.h
new file mode 100644
index 0000000..0040447
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_hkdf.h
@@ -0,0 +1,76 @@
+// Copyright 2018 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_CRYPTO_QUIC_HKDF_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
+
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicHKDF implements the key derivation function specified in RFC 5869
+// (using SHA-256) and outputs key material, as needed by QUIC.
+// See https://tools.ietf.org/html/rfc5869 for details.
+class QUIC_EXPORT_PRIVATE QuicHKDF {
+ public:
+  // |secret|: the input shared secret (or, from RFC 5869, the IKM).
+  // |salt|: an (optional) public salt / non-secret random value. While
+  // optional, callers are strongly recommended to provide a salt. There is no
+  // added security value in making this larger than the SHA-256 block size of
+  // 64 bytes.
+  // |info|: an (optional) label to distinguish different uses of HKDF. It is
+  // optional context and application specific information (can be a zero-length
+  // string).
+  // |key_bytes_to_generate|: the number of bytes of key material to generate
+  // for both client and server.
+  // |iv_bytes_to_generate|: the number of bytes of IV to generate for both
+  // client and server.
+  // |subkey_secret_bytes_to_generate|: the number of bytes of subkey secret to
+  // generate, shared between client and server.
+  QuicHKDF(absl::string_view secret,
+           absl::string_view salt,
+           absl::string_view info,
+           size_t key_bytes_to_generate,
+           size_t iv_bytes_to_generate,
+           size_t subkey_secret_bytes_to_generate);
+
+  // An alternative constructor that allows the client and server key/IV
+  // lengths to be different.
+  QuicHKDF(absl::string_view secret,
+           absl::string_view salt,
+           absl::string_view info,
+           size_t client_key_bytes_to_generate,
+           size_t server_key_bytes_to_generate,
+           size_t client_iv_bytes_to_generate,
+           size_t server_iv_bytes_to_generate,
+           size_t subkey_secret_bytes_to_generate);
+
+  ~QuicHKDF();
+
+  absl::string_view client_write_key() const { return client_write_key_; }
+  absl::string_view client_write_iv() const { return client_write_iv_; }
+  absl::string_view server_write_key() const { return server_write_key_; }
+  absl::string_view server_write_iv() const { return server_write_iv_; }
+  absl::string_view subkey_secret() const { return subkey_secret_; }
+  absl::string_view client_hp_key() const { return client_hp_key_; }
+  absl::string_view server_hp_key() const { return server_hp_key_; }
+
+ private:
+  std::vector<uint8_t> output_;
+
+  absl::string_view client_write_key_;
+  absl::string_view server_write_key_;
+  absl::string_view client_write_iv_;
+  absl::string_view server_write_iv_;
+  absl::string_view subkey_secret_;
+  absl::string_view client_hp_key_;
+  absl::string_view server_hp_key_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
diff --git a/quiche/quic/core/crypto/quic_hkdf_test.cc b/quiche/quic/core/crypto/quic_hkdf_test.cc
new file mode 100644
index 0000000..48f041f
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_hkdf_test.cc
@@ -0,0 +1,91 @@
+// Copyright 2018 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 "quiche/quic/core/crypto/quic_hkdf.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+struct HKDFInput {
+  const char* key_hex;
+  const char* salt_hex;
+  const char* info_hex;
+  const char* output_hex;
+};
+
+// These test cases are taken from
+// https://tools.ietf.org/html/rfc5869#appendix-A.
+static const HKDFInput kHKDFInputs[] = {
+    {
+        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+        "000102030405060708090a0b0c",
+        "f0f1f2f3f4f5f6f7f8f9",
+        "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf340072"
+        "08d5"
+        "b887185865",
+    },
+    {
+        "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122"
+        "2324"
+        "25262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647"
+        "4849"
+        "4a4b4c4d4e4f",
+        "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182"
+        "8384"
+        "85868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7"
+        "a8a9"
+        "aaabacadaeaf",
+        "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2"
+        "d3d4"
+        "d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7"
+        "f8f9"
+        "fafbfcfdfeff",
+        "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a"
+        "99ca"
+        "c7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87"
+        "c14c"
+        "01d5c1f3434f1d87",
+    },
+    {
+        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+        "",
+        "",
+        "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d2013"
+        "95fa"
+        "a4b61a96c8",
+    },
+};
+
+class QuicHKDFTest : public QuicTest {};
+
+TEST_F(QuicHKDFTest, HKDF) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kHKDFInputs); i++) {
+    const HKDFInput& test(kHKDFInputs[i]);
+    SCOPED_TRACE(i);
+
+    const std::string key = absl::HexStringToBytes(test.key_hex);
+    const std::string salt = absl::HexStringToBytes(test.salt_hex);
+    const std::string info = absl::HexStringToBytes(test.info_hex);
+    const std::string expected = absl::HexStringToBytes(test.output_hex);
+
+    // We set the key_length to the length of the expected output and then take
+    // the result from the first key, which is the client write key.
+    QuicHKDF hkdf(key, salt, info, expected.size(), 0, 0);
+
+    ASSERT_EQ(expected.size(), hkdf.client_write_key().size());
+    EXPECT_EQ(0, memcmp(expected.data(), hkdf.client_write_key().data(),
+                        expected.size()));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_random.cc b/quiche/quic/core/crypto/quic_random.cc
new file mode 100644
index 0000000..22eed48
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_random.cc
@@ -0,0 +1,100 @@
+// 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 "quiche/quic/core/crypto/quic_random.h"
+#include <cstdint>
+#include <cstring>
+
+#include "third_party/boringssl/src/include/openssl/rand.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Insecure randomness in DefaultRandom uses an implementation of
+// xoshiro256++ 1.0 based on code in the public domain from
+// <http://prng.di.unimi.it/xoshiro256plusplus.c>.
+
+inline uint64_t Xoshiro256InitializeRngStateMember() {
+  uint64_t result;
+  RAND_bytes(reinterpret_cast<uint8_t*>(&result), sizeof(result));
+  return result;
+}
+
+inline uint64_t Xoshiro256PlusPlusRotLeft(uint64_t x, int k) {
+  return (x << k) | (x >> (64 - k));
+}
+
+uint64_t Xoshiro256PlusPlus() {
+  static thread_local uint64_t rng_state[4] = {
+      Xoshiro256InitializeRngStateMember(),
+      Xoshiro256InitializeRngStateMember(),
+      Xoshiro256InitializeRngStateMember(),
+      Xoshiro256InitializeRngStateMember()};
+  const uint64_t result =
+      Xoshiro256PlusPlusRotLeft(rng_state[0] + rng_state[3], 23) + rng_state[0];
+  const uint64_t t = rng_state[1] << 17;
+  rng_state[2] ^= rng_state[0];
+  rng_state[3] ^= rng_state[1];
+  rng_state[1] ^= rng_state[2];
+  rng_state[0] ^= rng_state[3];
+  rng_state[2] ^= t;
+  rng_state[3] = Xoshiro256PlusPlusRotLeft(rng_state[3], 45);
+  return result;
+}
+
+class DefaultRandom : public QuicRandom {
+ public:
+  DefaultRandom() {}
+  DefaultRandom(const DefaultRandom&) = delete;
+  DefaultRandom& operator=(const DefaultRandom&) = delete;
+  ~DefaultRandom() override {}
+
+  // QuicRandom implementation
+  void RandBytes(void* data, size_t len) override;
+  uint64_t RandUint64() override;
+  void InsecureRandBytes(void* data, size_t len) override;
+  uint64_t InsecureRandUint64() override;
+};
+
+void DefaultRandom::RandBytes(void* data, size_t len) {
+  RAND_bytes(reinterpret_cast<uint8_t*>(data), len);
+}
+
+uint64_t DefaultRandom::RandUint64() {
+  uint64_t value;
+  RandBytes(&value, sizeof(value));
+  return value;
+}
+
+void DefaultRandom::InsecureRandBytes(void* data, size_t len) {
+  while (len >= sizeof(uint64_t)) {
+    uint64_t random_bytes64 = Xoshiro256PlusPlus();
+    memcpy(data, &random_bytes64, sizeof(uint64_t));
+    data = reinterpret_cast<char*>(data) + sizeof(uint64_t);
+    len -= sizeof(uint64_t);
+  }
+  if (len > 0) {
+    QUICHE_DCHECK_LT(len, sizeof(uint64_t));
+    uint64_t random_bytes64 = Xoshiro256PlusPlus();
+    memcpy(data, &random_bytes64, len);
+  }
+}
+
+uint64_t DefaultRandom::InsecureRandUint64() {
+  return Xoshiro256PlusPlus();
+}
+
+}  // namespace
+
+// static
+QuicRandom* QuicRandom::GetInstance() {
+  static DefaultRandom* random = new DefaultRandom();
+  return random;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_random.h b/quiche/quic/core/crypto/quic_random.h
new file mode 100644
index 0000000..47722cb
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_random.h
@@ -0,0 +1,41 @@
+// 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_CRYPTO_QUIC_RANDOM_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// The interface for a random number generator.
+class QUIC_EXPORT_PRIVATE QuicRandom {
+ public:
+  virtual ~QuicRandom() {}
+
+  // Returns the default random number generator, which is cryptographically
+  // secure and thread-safe.
+  static QuicRandom* GetInstance();
+
+  // Generates |len| random bytes in the |data| buffer.
+  virtual void RandBytes(void* data, size_t len) = 0;
+
+  // Returns a random number in the range [0, kuint64max].
+  virtual uint64_t RandUint64() = 0;
+
+  // Generates |len| random bytes in the |data| buffer. This MUST NOT be used
+  // for any application that requires cryptographically-secure randomness.
+  virtual void InsecureRandBytes(void* data, size_t len) = 0;
+
+  // Returns a random number in the range [0, kuint64max]. This MUST NOT be used
+  // for any application that requires cryptographically-secure randomness.
+  virtual uint64_t InsecureRandUint64() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
diff --git a/quiche/quic/core/crypto/quic_random_test.cc b/quiche/quic/core/crypto/quic_random_test.cc
new file mode 100644
index 0000000..2a43c29
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_random_test.cc
@@ -0,0 +1,53 @@
+// 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 "quiche/quic/core/crypto/quic_random.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QuicRandomTest : public QuicTest {};
+
+TEST_F(QuicRandomTest, RandBytes) {
+  unsigned char buf1[16];
+  unsigned char buf2[16];
+  memset(buf1, 0xaf, sizeof(buf1));
+  memset(buf2, 0xaf, sizeof(buf2));
+  ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
+
+  QuicRandom* rng = QuicRandom::GetInstance();
+  rng->RandBytes(buf1, sizeof(buf1));
+  EXPECT_NE(0, memcmp(buf1, buf2, sizeof(buf1)));
+}
+
+TEST_F(QuicRandomTest, RandUint64) {
+  QuicRandom* rng = QuicRandom::GetInstance();
+  uint64_t value1 = rng->RandUint64();
+  uint64_t value2 = rng->RandUint64();
+  EXPECT_NE(value1, value2);
+}
+
+TEST_F(QuicRandomTest, InsecureRandBytes) {
+  unsigned char buf1[16];
+  unsigned char buf2[16];
+  memset(buf1, 0xaf, sizeof(buf1));
+  memset(buf2, 0xaf, sizeof(buf2));
+  ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
+
+  QuicRandom* rng = QuicRandom::GetInstance();
+  rng->InsecureRandBytes(buf1, sizeof(buf1));
+  EXPECT_NE(0, memcmp(buf1, buf2, sizeof(buf1)));
+}
+
+TEST_F(QuicRandomTest, InsecureRandUint64) {
+  QuicRandom* rng = QuicRandom::GetInstance();
+  uint64_t value1 = rng->InsecureRandUint64();
+  uint64_t value2 = rng->InsecureRandUint64();
+  EXPECT_NE(value1, value2);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/tls_client_connection.cc b/quiche/quic/core/crypto/tls_client_connection.cc
new file mode 100644
index 0000000..9140527
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_client_connection.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2019 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 "quiche/quic/core/crypto/tls_client_connection.h"
+
+namespace quic {
+
+TlsClientConnection::TlsClientConnection(SSL_CTX* ssl_ctx,
+                                         Delegate* delegate,
+                                         QuicSSLConfig ssl_config)
+    : TlsConnection(ssl_ctx,
+                    delegate->ConnectionDelegate(),
+                    std::move(ssl_config)),
+      delegate_(delegate) {}
+
+// static
+bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx(
+    bool enable_early_data) {
+  bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
+  // Configure certificate verification.
+  SSL_CTX_set_custom_verify(ssl_ctx.get(), SSL_VERIFY_PEER, &VerifyCallback);
+  int reverify_on_resume_enabled = 1;
+  SSL_CTX_set_reverify_on_resume(ssl_ctx.get(), reverify_on_resume_enabled);
+
+  // Configure session caching.
+  SSL_CTX_set_session_cache_mode(
+      ssl_ctx.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
+  SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
+
+  // TODO(wub): Always enable early data on the SSL_CTX, but allow it to be
+  // overridden on the SSL object, via QuicSSLConfig.
+  SSL_CTX_set_early_data_enabled(ssl_ctx.get(), enable_early_data);
+  return ssl_ctx;
+}
+
+void TlsClientConnection::SetCertChain(
+    const std::vector<CRYPTO_BUFFER*>& cert_chain, EVP_PKEY* privkey) {
+  SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), privkey,
+                        /*privkey_method=*/nullptr);
+}
+
+// static
+int TlsClientConnection::NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
+  static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl))
+      ->delegate_->InsertSession(bssl::UniquePtr<SSL_SESSION>(session));
+  return 1;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/tls_client_connection.h b/quiche/quic/core/crypto/tls_client_connection.h
new file mode 100644
index 0000000..1c98a70
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_client_connection.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2019 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_CRYPTO_TLS_CLIENT_CONNECTION_H_
+#define QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
+
+#include "quiche/quic/core/crypto/tls_connection.h"
+
+namespace quic {
+
+// TlsClientConnection receives calls for client-specific BoringSSL callbacks
+// and calls its Delegate for the implementation of those callbacks.
+class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection {
+ public:
+  // A TlsClientConnection::Delegate implements the client-specific methods that
+  // are set as callbacks for an SSL object.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+   protected:
+    // Called when a NewSessionTicket is received from the server.
+    virtual void InsertSession(bssl::UniquePtr<SSL_SESSION> session) = 0;
+
+    // Provides the delegate for callbacks that are shared between client and
+    // server.
+    virtual TlsConnection::Delegate* ConnectionDelegate() = 0;
+
+    friend class TlsClientConnection;
+  };
+
+  TlsClientConnection(SSL_CTX* ssl_ctx,
+                      Delegate* delegate,
+                      QuicSSLConfig ssl_config);
+
+  // Creates and configures an SSL_CTX that is appropriate for clients to use.
+  static bssl::UniquePtr<SSL_CTX> CreateSslCtx(bool enable_early_data);
+
+  // Set the client cert and private key to be used on this connection, if
+  // requested by the server.
+  void SetCertChain(const std::vector<CRYPTO_BUFFER*>& cert_chain,
+                    EVP_PKEY* privkey);
+
+ private:
+  // Registered as the callback for SSL_CTX_sess_set_new_cb, which calls
+  // Delegate::InsertSession.
+  static int NewSessionCallback(SSL* ssl, SSL_SESSION* session);
+
+  Delegate* delegate_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
diff --git a/quiche/quic/core/crypto/tls_connection.cc b/quiche/quic/core/crypto/tls_connection.cc
new file mode 100644
index 0000000..d1be900
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_connection.cc
@@ -0,0 +1,212 @@
+// Copyright (c) 2019 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 "quiche/quic/core/crypto/tls_connection.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+namespace {
+
+// BoringSSL allows storing extra data off of some of its data structures,
+// including the SSL struct. To allow for multiple callers to store data, each
+// caller can use a different index for setting and getting data. These indices
+// are globals handed out by calling SSL_get_ex_new_index.
+//
+// SslIndexSingleton calls SSL_get_ex_new_index on its construction, and then
+// provides this index to be used in calls to SSL_get_ex_data/SSL_set_ex_data.
+// This is used to store in the SSL struct a pointer to the TlsConnection which
+// owns it.
+class SslIndexSingleton {
+ public:
+  static SslIndexSingleton* GetInstance() {
+    static SslIndexSingleton* instance = new SslIndexSingleton();
+    return instance;
+  }
+
+  int ssl_ex_data_index_connection() const {
+    return ssl_ex_data_index_connection_;
+  }
+
+ private:
+  SslIndexSingleton() {
+    CRYPTO_library_init();
+    ssl_ex_data_index_connection_ =
+        SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
+    QUICHE_CHECK_LE(0, ssl_ex_data_index_connection_);
+  }
+
+  SslIndexSingleton(const SslIndexSingleton&) = delete;
+  SslIndexSingleton& operator=(const SslIndexSingleton&) = delete;
+
+  // The index to supply to SSL_get_ex_data/SSL_set_ex_data for getting/setting
+  // the TlsConnection pointer.
+  int ssl_ex_data_index_connection_;
+};
+
+}  // namespace
+
+// static
+EncryptionLevel TlsConnection::QuicEncryptionLevel(
+    enum ssl_encryption_level_t level) {
+  switch (level) {
+    case ssl_encryption_initial:
+      return ENCRYPTION_INITIAL;
+    case ssl_encryption_early_data:
+      return ENCRYPTION_ZERO_RTT;
+    case ssl_encryption_handshake:
+      return ENCRYPTION_HANDSHAKE;
+    case ssl_encryption_application:
+      return ENCRYPTION_FORWARD_SECURE;
+    default:
+      QUIC_BUG(quic_bug_10698_1)
+          << "Invalid ssl_encryption_level_t " << static_cast<int>(level);
+      return ENCRYPTION_INITIAL;
+  }
+}
+
+// static
+enum ssl_encryption_level_t TlsConnection::BoringEncryptionLevel(
+    EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      return ssl_encryption_initial;
+    case ENCRYPTION_HANDSHAKE:
+      return ssl_encryption_handshake;
+    case ENCRYPTION_ZERO_RTT:
+      return ssl_encryption_early_data;
+    case ENCRYPTION_FORWARD_SECURE:
+      return ssl_encryption_application;
+    default:
+      QUIC_BUG(quic_bug_10698_2)
+          << "Invalid encryption level " << static_cast<int>(level);
+      return ssl_encryption_initial;
+  }
+}
+
+TlsConnection::TlsConnection(SSL_CTX* ssl_ctx,
+                             TlsConnection::Delegate* delegate,
+                             QuicSSLConfig ssl_config)
+    : delegate_(delegate),
+      ssl_(SSL_new(ssl_ctx)),
+      ssl_config_(std::move(ssl_config)) {
+  SSL_set_ex_data(
+      ssl(), SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection(),
+      this);
+  if (ssl_config_.early_data_enabled.has_value()) {
+    const int early_data_enabled = *ssl_config_.early_data_enabled ? 1 : 0;
+    SSL_set_early_data_enabled(ssl(), early_data_enabled);
+  }
+  if (ssl_config_.signing_algorithm_prefs.has_value()) {
+    SSL_set_signing_algorithm_prefs(
+        ssl(), ssl_config_.signing_algorithm_prefs->data(),
+        ssl_config_.signing_algorithm_prefs->size());
+  }
+  if (ssl_config_.disable_ticket_support.has_value()) {
+    if (*ssl_config_.disable_ticket_support) {
+      SSL_set_options(ssl(), SSL_OP_NO_TICKET);
+    }
+  }
+}
+
+void TlsConnection::EnableInfoCallback() {
+  SSL_set_info_callback(
+      ssl(), +[](const SSL* ssl, int type, int value) {
+        ConnectionFromSsl(ssl)->delegate_->InfoCallback(type, value);
+      });
+}
+
+void TlsConnection::DisableTicketSupport() {
+  ssl_config_.disable_ticket_support = true;
+  SSL_set_options(ssl(), SSL_OP_NO_TICKET);
+}
+
+// static
+bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx() {
+  CRYPTO_library_init();
+  bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_with_buffers_method()));
+  SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
+  SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
+  SSL_CTX_set_quic_method(ssl_ctx.get(), &kSslQuicMethod);
+  return ssl_ctx;
+}
+
+// static
+TlsConnection* TlsConnection::ConnectionFromSsl(const SSL* ssl) {
+  return reinterpret_cast<TlsConnection*>(SSL_get_ex_data(
+      ssl, SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection()));
+}
+
+// static
+enum ssl_verify_result_t TlsConnection::VerifyCallback(SSL* ssl,
+                                                       uint8_t* out_alert) {
+  return ConnectionFromSsl(ssl)->delegate_->VerifyCert(out_alert);
+}
+
+const SSL_QUIC_METHOD TlsConnection::kSslQuicMethod{
+    TlsConnection::SetReadSecretCallback, TlsConnection::SetWriteSecretCallback,
+    TlsConnection::WriteMessageCallback, TlsConnection::FlushFlightCallback,
+    TlsConnection::SendAlertCallback};
+
+// static
+int TlsConnection::SetReadSecretCallback(SSL* ssl,
+                                         enum ssl_encryption_level_t level,
+                                         const SSL_CIPHER* cipher,
+                                         const uint8_t* secret,
+                                         size_t secret_length) {
+  // TODO(nharper): replace this vector with a span (which unfortunately doesn't
+  // yet exist in quic/platform/api).
+  std::vector<uint8_t> secret_vec(secret, secret + secret_length);
+  TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
+  if (!delegate->SetReadSecret(QuicEncryptionLevel(level), cipher,
+                               secret_vec)) {
+    return 0;
+  }
+  return 1;
+}
+
+// static
+int TlsConnection::SetWriteSecretCallback(SSL* ssl,
+                                          enum ssl_encryption_level_t level,
+                                          const SSL_CIPHER* cipher,
+                                          const uint8_t* secret,
+                                          size_t secret_length) {
+  // TODO(nharper): replace this vector with a span (which unfortunately doesn't
+  // yet exist in quic/platform/api).
+  std::vector<uint8_t> secret_vec(secret, secret + secret_length);
+  TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
+  delegate->SetWriteSecret(QuicEncryptionLevel(level), cipher, secret_vec);
+  return 1;
+}
+
+// static
+int TlsConnection::WriteMessageCallback(SSL* ssl,
+                                        enum ssl_encryption_level_t level,
+                                        const uint8_t* data,
+                                        size_t len) {
+  ConnectionFromSsl(ssl)->delegate_->WriteMessage(
+      QuicEncryptionLevel(level),
+      absl::string_view(reinterpret_cast<const char*>(data), len));
+  return 1;
+}
+
+// static
+int TlsConnection::FlushFlightCallback(SSL* ssl) {
+  ConnectionFromSsl(ssl)->delegate_->FlushFlight();
+  return 1;
+}
+
+// static
+int TlsConnection::SendAlertCallback(SSL* ssl,
+                                     enum ssl_encryption_level_t level,
+                                     uint8_t desc) {
+  ConnectionFromSsl(ssl)->delegate_->SendAlert(QuicEncryptionLevel(level),
+                                               desc);
+  return 1;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/tls_connection.h b/quiche/quic/core/crypto/tls_connection.h
new file mode 100644
index 0000000..c7f7758
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_connection.h
@@ -0,0 +1,162 @@
+// Copyright (c) 2019 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_CRYPTO_TLS_CONNECTION_H_
+#define QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
+
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+// TlsConnection wraps BoringSSL's SSL object which represents a single TLS
+// connection. Callbacks set in BoringSSL which are called with an SSL* argument
+// will get dispatched to the TlsConnection object owning that SSL. In turn, the
+// TlsConnection will delegate the implementation of that callback to its
+// Delegate.
+//
+// The owner of the TlsConnection is responsible for driving the TLS handshake
+// (and other interactions with the SSL*). This class only handles mapping
+// callbacks to the correct instance.
+class QUIC_EXPORT_PRIVATE TlsConnection {
+ public:
+  // A TlsConnection::Delegate implements the methods that are set as callbacks
+  // of TlsConnection.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+   protected:
+    // Certificate management functions:
+
+    // Verifies the peer's certificate chain. It may use
+    // SSL_get0_peer_certificates to get the cert chain. This method returns
+    // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid,
+    // or ssl_verify_retry if verification is happening asynchronously.
+    virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0;
+
+    // QUIC-TLS interface functions:
+
+    // SetWriteSecret provides the encryption secret used to encrypt messages at
+    // encryption level |level|. The secret provided here is the one from the
+    // TLS 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
+    // traffic secrets and application traffic secrets. The provided write
+    // secret must be used with the provided cipher suite |cipher|.
+    virtual void SetWriteSecret(EncryptionLevel level,
+                                const SSL_CIPHER* cipher,
+                                const std::vector<uint8_t>& write_secret) = 0;
+
+    // SetReadSecret is similar to SetWriteSecret, except that it is used for
+    // decrypting messages. SetReadSecret at a particular level is always called
+    // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT,
+    // where the EncryptionLevel for SetWriteSecret is
+    // ENCRYPTION_FORWARD_SECURE.
+    virtual bool SetReadSecret(EncryptionLevel level,
+                               const SSL_CIPHER* cipher,
+                               const std::vector<uint8_t>& read_secret) = 0;
+
+    // WriteMessage is called when there is |data| from the TLS stack ready for
+    // the QUIC stack to write in a crypto frame. The data must be transmitted
+    // at encryption level |level|.
+    virtual void WriteMessage(EncryptionLevel level,
+                              absl::string_view data) = 0;
+
+    // FlushFlight is called to signal that the current flight of messages have
+    // all been written (via calls to WriteMessage) and can be flushed to the
+    // underlying transport.
+    virtual void FlushFlight() = 0;
+
+    // SendAlert causes this TlsConnection to close the QUIC connection with an
+    // error code corersponding to the TLS alert description |desc| sent at
+    // level |level|.
+    virtual void SendAlert(EncryptionLevel level, uint8_t desc) = 0;
+
+    // Informational callback from BoringSSL. This callback is disabled by
+    // default, but can be enabled by TlsConnection::EnableInfoCallback.
+    //
+    // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
+    virtual void InfoCallback(int type, int value) = 0;
+
+    friend class TlsConnection;
+  };
+
+  TlsConnection(const TlsConnection&) = delete;
+  TlsConnection& operator=(const TlsConnection&) = delete;
+
+  // Configure the SSL such that delegate_->InfoCallback will be called.
+  void EnableInfoCallback();
+
+  // Configure the SSL to disable session ticket support. Note that, this
+  // function simply sets the |SSL_OP_NO_TICKET| option on the SSL object, it
+  // does not check whether it is too late to do so.
+  void DisableTicketSupport();
+
+  // Functions to convert between BoringSSL's enum ssl_encryption_level_t and
+  // QUIC's EncryptionLevel.
+  static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
+  static enum ssl_encryption_level_t BoringEncryptionLevel(
+      EncryptionLevel level);
+
+  SSL* ssl() const { return ssl_.get(); }
+
+  const QuicSSLConfig& ssl_config() const { return ssl_config_; }
+
+ protected:
+  // TlsConnection does not take ownership of |ssl_ctx| or |delegate|; they must
+  // outlive the TlsConnection object.
+  TlsConnection(SSL_CTX* ssl_ctx, Delegate* delegate, QuicSSLConfig ssl_config);
+
+  // Creates an SSL_CTX and configures it with the options that are appropriate
+  // for both client and server. The caller is responsible for ownership of the
+  // newly created struct.
+  static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
+
+  // From a given SSL* |ssl|, returns a pointer to the TlsConnection that it
+  // belongs to. This helper method allows the callbacks set in BoringSSL to be
+  // dispatched to the correct TlsConnection from the SSL* passed into the
+  // callback.
+  static TlsConnection* ConnectionFromSsl(const SSL* ssl);
+
+  // Registered as the callback for SSL(_CTX)_set_custom_verify. The
+  // implementation is delegated to Delegate::VerifyCert.
+  static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert);
+
+  QuicSSLConfig& mutable_ssl_config() { return ssl_config_; }
+
+ private:
+  // TlsConnection implements SSL_QUIC_METHOD, which provides the interface
+  // between BoringSSL's TLS stack and a QUIC implementation.
+  static const SSL_QUIC_METHOD kSslQuicMethod;
+
+  // The following static functions make up the members of kSslQuicMethod:
+  static int SetReadSecretCallback(SSL* ssl,
+                                   enum ssl_encryption_level_t level,
+                                   const SSL_CIPHER* cipher,
+                                   const uint8_t* secret,
+                                   size_t secret_len);
+  static int SetWriteSecretCallback(SSL* ssl,
+                                    enum ssl_encryption_level_t level,
+                                    const SSL_CIPHER* cipher,
+                                    const uint8_t* secret,
+                                    size_t secret_len);
+  static int WriteMessageCallback(SSL* ssl,
+                                  enum ssl_encryption_level_t level,
+                                  const uint8_t* data,
+                                  size_t len);
+  static int FlushFlightCallback(SSL* ssl);
+  static int SendAlertCallback(SSL* ssl,
+                               enum ssl_encryption_level_t level,
+                               uint8_t desc);
+
+  Delegate* delegate_;
+  bssl::UniquePtr<SSL> ssl_;
+  QuicSSLConfig ssl_config_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
diff --git a/quiche/quic/core/crypto/tls_server_connection.cc b/quiche/quic/core/crypto/tls_server_connection.cc
new file mode 100644
index 0000000..1e63d3f
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_server_connection.cc
@@ -0,0 +1,186 @@
+// Copyright (c) 2019 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 "quiche/quic/core/crypto/tls_server_connection.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+TlsServerConnection::TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate,
+                                         QuicSSLConfig ssl_config)
+    : TlsConnection(ssl_ctx, delegate->ConnectionDelegate(),
+                    std::move(ssl_config)),
+      delegate_(delegate) {
+  // By default, cert verify callback is not installed on ssl(), so only need to
+  // UpdateCertVerifyCallback() if client_cert_mode is not kNone.
+  if (TlsConnection::ssl_config().client_cert_mode != ClientCertMode::kNone) {
+    UpdateCertVerifyCallback();
+  }
+}
+
+// static
+bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx(
+    ProofSource* proof_source) {
+  bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
+
+  // Server does not request/verify client certs by default. Individual server
+  // connections may call SSL_set_custom_verify on their SSL object to request
+  // client certs.
+
+  SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(),
+                                         &TlsExtServernameCallback);
+  SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr);
+  // We don't actually need the TicketCrypter here, but we need to know
+  // whether it's set.
+  if (proof_source->GetTicketCrypter()) {
+    QUIC_CODE_COUNT(quic_session_tickets_enabled);
+    SSL_CTX_set_ticket_aead_method(ssl_ctx.get(),
+                                   &TlsServerConnection::kSessionTicketMethod);
+  } else {
+    QUIC_CODE_COUNT(quic_session_tickets_disabled);
+  }
+
+  SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
+
+  SSL_CTX_set_select_certificate_cb(
+      ssl_ctx.get(), &TlsServerConnection::EarlySelectCertCallback);
+  SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
+  return ssl_ctx;
+}
+
+void TlsServerConnection::SetCertChain(
+    const std::vector<CRYPTO_BUFFER*>& cert_chain) {
+  SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), nullptr,
+                        &TlsServerConnection::kPrivateKeyMethod);
+}
+
+void TlsServerConnection::SetClientCertMode(ClientCertMode client_cert_mode) {
+  if (ssl_config().client_cert_mode == client_cert_mode) {
+    return;
+  }
+
+  mutable_ssl_config().client_cert_mode = client_cert_mode;
+  UpdateCertVerifyCallback();
+}
+
+void TlsServerConnection::UpdateCertVerifyCallback() {
+  const ClientCertMode client_cert_mode = ssl_config().client_cert_mode;
+  if (client_cert_mode == ClientCertMode::kNone) {
+    SSL_set_custom_verify(ssl(), SSL_VERIFY_NONE, nullptr);
+    return;
+  }
+
+  int mode = SSL_VERIFY_PEER;
+  if (client_cert_mode == ClientCertMode::kRequire) {
+    mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+  } else {
+    QUICHE_DCHECK_EQ(client_cert_mode, ClientCertMode::kRequest);
+  }
+  SSL_set_custom_verify(ssl(), mode, &VerifyCallback);
+}
+
+const SSL_PRIVATE_KEY_METHOD TlsServerConnection::kPrivateKeyMethod{
+    &TlsServerConnection::PrivateKeySign,
+    nullptr,  // decrypt
+    &TlsServerConnection::PrivateKeyComplete,
+};
+
+// static
+TlsServerConnection* TlsServerConnection::ConnectionFromSsl(SSL* ssl) {
+  return static_cast<TlsServerConnection*>(
+      TlsConnection::ConnectionFromSsl(ssl));
+}
+
+// static
+ssl_select_cert_result_t TlsServerConnection::EarlySelectCertCallback(
+    const SSL_CLIENT_HELLO* client_hello) {
+  return ConnectionFromSsl(client_hello->ssl)
+      ->delegate_->EarlySelectCertCallback(client_hello);
+}
+
+// static
+int TlsServerConnection::TlsExtServernameCallback(SSL* ssl,
+                                                  int* out_alert,
+                                                  void* /*arg*/) {
+  return ConnectionFromSsl(ssl)->delegate_->TlsExtServernameCallback(out_alert);
+}
+
+// static
+int TlsServerConnection::SelectAlpnCallback(SSL* ssl,
+                                            const uint8_t** out,
+                                            uint8_t* out_len,
+                                            const uint8_t* in,
+                                            unsigned in_len,
+                                            void* /*arg*/) {
+  return ConnectionFromSsl(ssl)->delegate_->SelectAlpn(out, out_len, in,
+                                                       in_len);
+}
+
+// static
+ssl_private_key_result_t TlsServerConnection::PrivateKeySign(SSL* ssl,
+                                                             uint8_t* out,
+                                                             size_t* out_len,
+                                                             size_t max_out,
+                                                             uint16_t sig_alg,
+                                                             const uint8_t* in,
+                                                             size_t in_len) {
+  return ConnectionFromSsl(ssl)->delegate_->PrivateKeySign(
+      out, out_len, max_out, sig_alg,
+      absl::string_view(reinterpret_cast<const char*>(in), in_len));
+}
+
+// static
+ssl_private_key_result_t TlsServerConnection::PrivateKeyComplete(
+    SSL* ssl,
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out) {
+  return ConnectionFromSsl(ssl)->delegate_->PrivateKeyComplete(out, out_len,
+                                                               max_out);
+}
+
+// static
+const SSL_TICKET_AEAD_METHOD TlsServerConnection::kSessionTicketMethod{
+    TlsServerConnection::SessionTicketMaxOverhead,
+    TlsServerConnection::SessionTicketSeal,
+    TlsServerConnection::SessionTicketOpen,
+};
+
+// static
+size_t TlsServerConnection::SessionTicketMaxOverhead(SSL* ssl) {
+  return ConnectionFromSsl(ssl)->delegate_->SessionTicketMaxOverhead();
+}
+
+// static
+int TlsServerConnection::SessionTicketSeal(SSL* ssl,
+                                           uint8_t* out,
+                                           size_t* out_len,
+                                           size_t max_out_len,
+                                           const uint8_t* in,
+                                           size_t in_len) {
+  return ConnectionFromSsl(ssl)->delegate_->SessionTicketSeal(
+      out, out_len, max_out_len,
+      absl::string_view(reinterpret_cast<const char*>(in), in_len));
+}
+
+// static
+enum ssl_ticket_aead_result_t TlsServerConnection::SessionTicketOpen(
+    SSL* ssl,
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out_len,
+    const uint8_t* in,
+    size_t in_len) {
+  return ConnectionFromSsl(ssl)->delegate_->SessionTicketOpen(
+      out, out_len, max_out_len,
+      absl::string_view(reinterpret_cast<const char*>(in), in_len));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/tls_server_connection.h b/quiche/quic/core/crypto/tls_server_connection.h
new file mode 100644
index 0000000..85dddd0
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_server_connection.h
@@ -0,0 +1,200 @@
+// Copyright (c) 2019 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_CRYPTO_TLS_SERVER_CONNECTION_H_
+#define QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/tls_connection.h"
+
+namespace quic {
+
+// TlsServerConnection receives calls for client-specific BoringSSL callbacks
+// and calls its Delegate for the implementation of those callbacks.
+class QUIC_EXPORT_PRIVATE TlsServerConnection : public TlsConnection {
+ public:
+  // A TlsServerConnection::Delegate implement the server-specific methods that
+  // are set as callbacks for an SSL object.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+   protected:
+    // Called from BoringSSL right after SNI is extracted, which is very early
+    // in the handshake process.
+    virtual ssl_select_cert_result_t EarlySelectCertCallback(
+        const SSL_CLIENT_HELLO* client_hello) = 0;
+
+    // Called after the ClientHello extensions have been successfully parsed.
+    // Returns an SSL_TLSEXT_ERR_* value (see
+    // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_tlsext_servername_callback).
+    //
+    // On success, return SSL_TLSEXT_ERR_OK causes the server_name extension to
+    // be acknowledged in the ServerHello, or return SSL_TLSEXT_ERR_NOACK which
+    // causes it to be not acknowledged.
+    //
+    // If the function returns SSL_TLSEXT_ERR_ALERT_FATAL, then it puts in
+    // |*out_alert| the TLS alert value that the server will send.
+    //
+    virtual int TlsExtServernameCallback(int* out_alert) = 0;
+
+    // Selects which ALPN to use based on the list sent by the client.
+    virtual int SelectAlpn(const uint8_t** out,
+                           uint8_t* out_len,
+                           const uint8_t* in,
+                           unsigned in_len) = 0;
+
+    // Signs |in| using the signature algorithm specified by |sig_alg| (an
+    // SSL_SIGN_* value). If the signing operation cannot be completed
+    // synchronously, ssl_private_key_retry is returned. If there is an error
+    // signing, or if the signature is longer than |max_out|, then
+    // ssl_private_key_failure is returned. Otherwise, ssl_private_key_success
+    // is returned with the signature put in |*out| and the length in
+    // |*out_len|.
+    virtual ssl_private_key_result_t PrivateKeySign(uint8_t* out,
+                                                    size_t* out_len,
+                                                    size_t max_out,
+                                                    uint16_t sig_alg,
+                                                    absl::string_view in) = 0;
+
+    // When PrivateKeySign returns ssl_private_key_retry, PrivateKeyComplete
+    // will be called after the async sign operation has completed.
+    // PrivateKeyComplete puts the resulting signature in |*out| and length in
+    // |*out_len|. If the length is greater than |max_out| or if there was an
+    // error in signing, then ssl_private_key_failure is returned. Otherwise,
+    // ssl_private_key_success is returned.
+    virtual ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
+                                                        size_t* out_len,
+                                                        size_t max_out) = 0;
+
+    // The following functions are used to implement an SSL_TICKET_AEAD_METHOD.
+    // See
+    // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#ssl_ticket_aead_result_t
+    // for details on the BoringSSL API.
+
+    // SessionTicketMaxOverhead returns the maximum number of bytes of overhead
+    // that SessionTicketSeal may add when encrypting a session ticket.
+    virtual size_t SessionTicketMaxOverhead() = 0;
+
+    // SessionTicketSeal encrypts the session ticket in |in|, putting the
+    // resulting encrypted ticket in |out|, writing the length of the bytes
+    // written to |*out_len|, which is no larger than |max_out_len|. It returns
+    // 1 on success and 0 on error.
+    virtual int SessionTicketSeal(uint8_t* out,
+                                  size_t* out_len,
+                                  size_t max_out_len,
+                                  absl::string_view in) = 0;
+
+    // SessionTicketOpen is called when BoringSSL has an encrypted session
+    // ticket |in| and wants the ticket decrypted. This decryption operation can
+    // happen synchronously or asynchronously.
+    //
+    // If the decrypted ticket is not available at the time of the function
+    // call, this function returns ssl_ticket_aead_retry. If this function
+    // returns ssl_ticket_aead_retry, then SSL_do_handshake will return
+    // SSL_ERROR_PENDING_TICKET. Once the pending ticket decryption has
+    // completed, SSL_do_handshake needs to be called again.
+    //
+    // When this function is called and the decrypted ticket is available
+    // (either the ticket was decrypted synchronously, or an asynchronous
+    // operation has completed and SSL_do_handshake has been called again), the
+    // decrypted ticket is put in |out|, and the length of that output is
+    // written to |*out_len|, not to exceed |max_out_len|, and
+    // ssl_ticket_aead_success is returned. If the ticket cannot be decrypted
+    // and should be ignored, this function returns
+    // ssl_ticket_aead_ignore_ticket and a full handshake will be performed
+    // instead. If a fatal error occurs, ssl_ticket_aead_error can be returned
+    // which will terminate the handshake.
+    virtual enum ssl_ticket_aead_result_t SessionTicketOpen(
+        uint8_t* out,
+        size_t* out_len,
+        size_t max_out_len,
+        absl::string_view in) = 0;
+
+    // Provides the delegate for callbacks that are shared between client and
+    // server.
+    virtual TlsConnection::Delegate* ConnectionDelegate() = 0;
+
+    friend class TlsServerConnection;
+  };
+
+  TlsServerConnection(SSL_CTX* ssl_ctx,
+                      Delegate* delegate,
+                      QuicSSLConfig ssl_config);
+
+  // Creates and configures an SSL_CTX that is appropriate for servers to use.
+  static bssl::UniquePtr<SSL_CTX> CreateSslCtx(ProofSource* proof_source);
+
+  void SetCertChain(const std::vector<CRYPTO_BUFFER*>& cert_chain);
+
+  // Set the client cert mode to be used on this connection. This should be
+  // called right after cert selection at the latest, otherwise it is too late
+  // to has an effect.
+  void SetClientCertMode(ClientCertMode client_cert_mode);
+
+ private:
+  // Specialization of TlsConnection::ConnectionFromSsl.
+  static TlsServerConnection* ConnectionFromSsl(SSL* ssl);
+
+  static ssl_select_cert_result_t EarlySelectCertCallback(
+      const SSL_CLIENT_HELLO* client_hello);
+
+  // These functions are registered as callbacks in BoringSSL and delegate their
+  // implementation to the matching methods in Delegate above.
+  static int TlsExtServernameCallback(SSL* ssl, int* out_alert, void* arg);
+  static int SelectAlpnCallback(SSL* ssl,
+                                const uint8_t** out,
+                                uint8_t* out_len,
+                                const uint8_t* in,
+                                unsigned in_len,
+                                void* arg);
+
+  // |kPrivateKeyMethod| is a vtable pointing to PrivateKeySign and
+  // PrivateKeyComplete used by the TLS stack to compute the signature for the
+  // CertificateVerify message (using the server's private key).
+  static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
+
+  // The following functions make up the contents of |kPrivateKeyMethod|.
+  static ssl_private_key_result_t PrivateKeySign(SSL* ssl,
+                                                 uint8_t* out,
+                                                 size_t* out_len,
+                                                 size_t max_out,
+                                                 uint16_t sig_alg,
+                                                 const uint8_t* in,
+                                                 size_t in_len);
+  static ssl_private_key_result_t PrivateKeyComplete(SSL* ssl,
+                                                     uint8_t* out,
+                                                     size_t* out_len,
+                                                     size_t max_out);
+
+  // Implementation of SSL_TICKET_AEAD_METHOD which delegates to corresponding
+  // methods in TlsServerConnection::Delegate (a.k.a. TlsServerHandshaker).
+  static const SSL_TICKET_AEAD_METHOD kSessionTicketMethod;
+
+  // The following functions make up the contents of |kSessionTicketMethod|.
+  static size_t SessionTicketMaxOverhead(SSL* ssl);
+  static int SessionTicketSeal(SSL* ssl,
+                               uint8_t* out,
+                               size_t* out_len,
+                               size_t max_out_len,
+                               const uint8_t* in,
+                               size_t in_len);
+  static enum ssl_ticket_aead_result_t SessionTicketOpen(SSL* ssl,
+                                                         uint8_t* out,
+                                                         size_t* out_len,
+                                                         size_t max_out_len,
+                                                         const uint8_t* in,
+                                                         size_t in_len);
+
+  // Install custom verify callback on ssl() if |ssl_config().client_cert_mode|
+  // is not ClientCertMode::kNone. Uninstall otherwise.
+  void UpdateCertVerifyCallback();
+
+  Delegate* delegate_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
diff --git a/quiche/quic/core/crypto/transport_parameters.cc b/quiche/quic/core/crypto/transport_parameters.cc
new file mode 100644
index 0000000..04db561
--- /dev/null
+++ b/quiche/quic/core/crypto/transport_parameters.cc
@@ -0,0 +1,1590 @@
+// Copyright (c) 2018 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 "quiche/quic/core/crypto/transport_parameters.h"
+
+#include <cstdint>
+#include <cstring>
+#include <forward_list>
+#include <memory>
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+namespace quic {
+
+// Values of the TransportParameterId enum as defined in the
+// "Transport Parameter Encoding" section of draft-ietf-quic-transport.
+// When parameters are encoded, one of these enum values is used to indicate
+// which parameter is encoded. The supported draft version is noted in
+// transport_parameters.h.
+enum TransportParameters::TransportParameterId : uint64_t {
+  kOriginalDestinationConnectionId = 0,
+  kMaxIdleTimeout = 1,
+  kStatelessResetToken = 2,
+  kMaxPacketSize = 3,
+  kInitialMaxData = 4,
+  kInitialMaxStreamDataBidiLocal = 5,
+  kInitialMaxStreamDataBidiRemote = 6,
+  kInitialMaxStreamDataUni = 7,
+  kInitialMaxStreamsBidi = 8,
+  kInitialMaxStreamsUni = 9,
+  kAckDelayExponent = 0xa,
+  kMaxAckDelay = 0xb,
+  kDisableActiveMigration = 0xc,
+  kPreferredAddress = 0xd,
+  kActiveConnectionIdLimit = 0xe,
+  kInitialSourceConnectionId = 0xf,
+  kRetrySourceConnectionId = 0x10,
+
+  kMaxDatagramFrameSize = 0x20,
+
+  kInitialRoundTripTime = 0x3127,
+  kGoogleConnectionOptions = 0x3128,
+  // 0x3129 was used to convey the user agent string.
+  // 0x312A was used only in T050 to indicate support for HANDSHAKE_DONE.
+  // 0x312B was used to indicate that QUIC+TLS key updates were not supported.
+  // 0x4751 was used for non-standard Google-specific parameters encoded as a
+  // Google QUIC_CRYPTO CHLO, it has been replaced by individual parameters.
+  kGoogleQuicVersion =
+      0x4752,  // Used to transmit version and supported_versions.
+
+  kMinAckDelay = 0xDE1A,           // draft-iyengar-quic-delayed-ack.
+  kVersionInformation = 0xFF73DB,  // draft-ietf-quic-version-negotiation.
+};
+
+namespace {
+
+// The following constants define minimum and maximum allowed values for some of
+// the parameters. These come from the "Transport Parameter Definitions"
+// section of draft-ietf-quic-transport.
+constexpr uint64_t kMinMaxPacketSizeTransportParam = 1200;
+constexpr uint64_t kMaxAckDelayExponentTransportParam = 20;
+constexpr uint64_t kDefaultAckDelayExponentTransportParam = 3;
+constexpr uint64_t kMaxMaxAckDelayTransportParam = 16383;
+constexpr uint64_t kDefaultMaxAckDelayTransportParam = 25;
+constexpr uint64_t kMinActiveConnectionIdLimitTransportParam = 2;
+constexpr uint64_t kDefaultActiveConnectionIdLimitTransportParam = 2;
+
+std::string TransportParameterIdToString(
+    TransportParameters::TransportParameterId param_id) {
+  switch (param_id) {
+    case TransportParameters::kOriginalDestinationConnectionId:
+      return "original_destination_connection_id";
+    case TransportParameters::kMaxIdleTimeout:
+      return "max_idle_timeout";
+    case TransportParameters::kStatelessResetToken:
+      return "stateless_reset_token";
+    case TransportParameters::kMaxPacketSize:
+      return "max_udp_payload_size";
+    case TransportParameters::kInitialMaxData:
+      return "initial_max_data";
+    case TransportParameters::kInitialMaxStreamDataBidiLocal:
+      return "initial_max_stream_data_bidi_local";
+    case TransportParameters::kInitialMaxStreamDataBidiRemote:
+      return "initial_max_stream_data_bidi_remote";
+    case TransportParameters::kInitialMaxStreamDataUni:
+      return "initial_max_stream_data_uni";
+    case TransportParameters::kInitialMaxStreamsBidi:
+      return "initial_max_streams_bidi";
+    case TransportParameters::kInitialMaxStreamsUni:
+      return "initial_max_streams_uni";
+    case TransportParameters::kAckDelayExponent:
+      return "ack_delay_exponent";
+    case TransportParameters::kMaxAckDelay:
+      return "max_ack_delay";
+    case TransportParameters::kDisableActiveMigration:
+      return "disable_active_migration";
+    case TransportParameters::kPreferredAddress:
+      return "preferred_address";
+    case TransportParameters::kActiveConnectionIdLimit:
+      return "active_connection_id_limit";
+    case TransportParameters::kInitialSourceConnectionId:
+      return "initial_source_connection_id";
+    case TransportParameters::kRetrySourceConnectionId:
+      return "retry_source_connection_id";
+    case TransportParameters::kMaxDatagramFrameSize:
+      return "max_datagram_frame_size";
+    case TransportParameters::kInitialRoundTripTime:
+      return "initial_round_trip_time";
+    case TransportParameters::kGoogleConnectionOptions:
+      return "google_connection_options";
+    case TransportParameters::kGoogleQuicVersion:
+      return "google-version";
+    case TransportParameters::kMinAckDelay:
+      return "min_ack_delay_us";
+    case TransportParameters::kVersionInformation:
+      return "version_information";
+  }
+  return absl::StrCat("Unknown(", param_id, ")");
+}
+
+bool TransportParameterIdIsKnown(
+    TransportParameters::TransportParameterId param_id) {
+  switch (param_id) {
+    case TransportParameters::kOriginalDestinationConnectionId:
+    case TransportParameters::kMaxIdleTimeout:
+    case TransportParameters::kStatelessResetToken:
+    case TransportParameters::kMaxPacketSize:
+    case TransportParameters::kInitialMaxData:
+    case TransportParameters::kInitialMaxStreamDataBidiLocal:
+    case TransportParameters::kInitialMaxStreamDataBidiRemote:
+    case TransportParameters::kInitialMaxStreamDataUni:
+    case TransportParameters::kInitialMaxStreamsBidi:
+    case TransportParameters::kInitialMaxStreamsUni:
+    case TransportParameters::kAckDelayExponent:
+    case TransportParameters::kMaxAckDelay:
+    case TransportParameters::kDisableActiveMigration:
+    case TransportParameters::kPreferredAddress:
+    case TransportParameters::kActiveConnectionIdLimit:
+    case TransportParameters::kInitialSourceConnectionId:
+    case TransportParameters::kRetrySourceConnectionId:
+    case TransportParameters::kMaxDatagramFrameSize:
+    case TransportParameters::kInitialRoundTripTime:
+    case TransportParameters::kGoogleConnectionOptions:
+    case TransportParameters::kGoogleQuicVersion:
+    case TransportParameters::kMinAckDelay:
+    case TransportParameters::kVersionInformation:
+      return true;
+  }
+  return false;
+}
+
+}  // namespace
+
+TransportParameters::IntegerParameter::IntegerParameter(
+    TransportParameters::TransportParameterId param_id,
+    uint64_t default_value,
+    uint64_t min_value,
+    uint64_t max_value)
+    : param_id_(param_id),
+      value_(default_value),
+      default_value_(default_value),
+      min_value_(min_value),
+      max_value_(max_value),
+      has_been_read_(false) {
+  QUICHE_DCHECK_LE(min_value, default_value);
+  QUICHE_DCHECK_LE(default_value, max_value);
+  QUICHE_DCHECK_LE(max_value, kVarInt62MaxValue);
+}
+
+TransportParameters::IntegerParameter::IntegerParameter(
+    TransportParameters::TransportParameterId param_id)
+    : TransportParameters::IntegerParameter::IntegerParameter(
+          param_id,
+          0,
+          0,
+          kVarInt62MaxValue) {}
+
+void TransportParameters::IntegerParameter::set_value(uint64_t value) {
+  value_ = value;
+}
+
+uint64_t TransportParameters::IntegerParameter::value() const {
+  return value_;
+}
+
+bool TransportParameters::IntegerParameter::IsValid() const {
+  return min_value_ <= value_ && value_ <= max_value_;
+}
+
+bool TransportParameters::IntegerParameter::Write(
+    QuicDataWriter* writer) const {
+  QUICHE_DCHECK(IsValid());
+  if (value_ == default_value_) {
+    // Do not write if the value is default.
+    return true;
+  }
+  if (!writer->WriteVarInt62(param_id_)) {
+    QUIC_BUG(quic_bug_10743_1) << "Failed to write param_id for " << *this;
+    return false;
+  }
+  const QuicVariableLengthIntegerLength value_length =
+      QuicDataWriter::GetVarInt62Len(value_);
+  if (!writer->WriteVarInt62(value_length)) {
+    QUIC_BUG(quic_bug_10743_2) << "Failed to write value_length for " << *this;
+    return false;
+  }
+  if (!writer->WriteVarInt62(value_, value_length)) {
+    QUIC_BUG(quic_bug_10743_3) << "Failed to write value for " << *this;
+    return false;
+  }
+  return true;
+}
+
+bool TransportParameters::IntegerParameter::Read(QuicDataReader* reader,
+                                                 std::string* error_details) {
+  if (has_been_read_) {
+    *error_details =
+        "Received a second " + TransportParameterIdToString(param_id_);
+    return false;
+  }
+  has_been_read_ = true;
+
+  if (!reader->ReadVarInt62(&value_)) {
+    *error_details =
+        "Failed to parse value for " + TransportParameterIdToString(param_id_);
+    return false;
+  }
+  if (!reader->IsDoneReading()) {
+    *error_details =
+        absl::StrCat("Received unexpected ", reader->BytesRemaining(),
+                     " bytes after parsing ", this->ToString(false));
+    return false;
+  }
+  return true;
+}
+
+std::string TransportParameters::IntegerParameter::ToString(
+    bool for_use_in_list) const {
+  if (for_use_in_list && value_ == default_value_) {
+    return "";
+  }
+  std::string rv = for_use_in_list ? " " : "";
+  absl::StrAppend(&rv, TransportParameterIdToString(param_id_), " ", value_);
+  if (!IsValid()) {
+    rv += " (Invalid)";
+  }
+  return rv;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const TransportParameters::IntegerParameter& param) {
+  os << param.ToString(/*for_use_in_list=*/false);
+  return os;
+}
+
+TransportParameters::PreferredAddress::PreferredAddress()
+    : ipv4_socket_address(QuicIpAddress::Any4(), 0),
+      ipv6_socket_address(QuicIpAddress::Any6(), 0),
+      connection_id(EmptyQuicConnectionId()),
+      stateless_reset_token(kStatelessResetTokenLength, 0) {}
+
+TransportParameters::PreferredAddress::~PreferredAddress() {}
+
+bool TransportParameters::PreferredAddress::operator==(
+    const PreferredAddress& rhs) const {
+  return ipv4_socket_address == rhs.ipv4_socket_address &&
+         ipv6_socket_address == rhs.ipv6_socket_address &&
+         connection_id == rhs.connection_id &&
+         stateless_reset_token == rhs.stateless_reset_token;
+}
+
+bool TransportParameters::PreferredAddress::operator!=(
+    const PreferredAddress& rhs) const {
+  return !(*this == rhs);
+}
+
+std::ostream& operator<<(
+    std::ostream& os,
+    const TransportParameters::PreferredAddress& preferred_address) {
+  os << preferred_address.ToString();
+  return os;
+}
+
+std::string TransportParameters::PreferredAddress::ToString() const {
+  return "[" + ipv4_socket_address.ToString() + " " +
+         ipv6_socket_address.ToString() + " connection_id " +
+         connection_id.ToString() + " stateless_reset_token " +
+         absl::BytesToHexString(absl::string_view(
+             reinterpret_cast<const char*>(stateless_reset_token.data()),
+             stateless_reset_token.size())) +
+         "]";
+}
+
+TransportParameters::LegacyVersionInformation::LegacyVersionInformation()
+    : version(0) {}
+
+bool TransportParameters::LegacyVersionInformation::operator==(
+    const LegacyVersionInformation& rhs) const {
+  return version == rhs.version && supported_versions == rhs.supported_versions;
+}
+
+bool TransportParameters::LegacyVersionInformation::operator!=(
+    const LegacyVersionInformation& rhs) const {
+  return !(*this == rhs);
+}
+
+std::string TransportParameters::LegacyVersionInformation::ToString() const {
+  std::string rv =
+      absl::StrCat("legacy[version ", QuicVersionLabelToString(version));
+  if (!supported_versions.empty()) {
+    absl::StrAppend(&rv,
+                    " supported_versions " +
+                        QuicVersionLabelVectorToString(supported_versions));
+  }
+  absl::StrAppend(&rv, "]");
+  return rv;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const TransportParameters::LegacyVersionInformation&
+                             legacy_version_information) {
+  os << legacy_version_information.ToString();
+  return os;
+}
+
+TransportParameters::VersionInformation::VersionInformation()
+    : chosen_version(0) {}
+
+bool TransportParameters::VersionInformation::operator==(
+    const VersionInformation& rhs) const {
+  return chosen_version == rhs.chosen_version &&
+         other_versions == rhs.other_versions;
+}
+
+bool TransportParameters::VersionInformation::operator!=(
+    const VersionInformation& rhs) const {
+  return !(*this == rhs);
+}
+
+std::string TransportParameters::VersionInformation::ToString() const {
+  std::string rv = absl::StrCat("[chosen_version ",
+                                QuicVersionLabelToString(chosen_version));
+  if (!other_versions.empty()) {
+    absl::StrAppend(&rv, " other_versions " +
+                             QuicVersionLabelVectorToString(other_versions));
+  }
+  absl::StrAppend(&rv, "]");
+  return rv;
+}
+
+std::ostream& operator<<(
+    std::ostream& os,
+    const TransportParameters::VersionInformation& version_information) {
+  os << version_information.ToString();
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const TransportParameters& params) {
+  os << params.ToString();
+  return os;
+}
+
+std::string TransportParameters::ToString() const {
+  std::string rv = "[";
+  if (perspective == Perspective::IS_SERVER) {
+    rv += "Server";
+  } else {
+    rv += "Client";
+  }
+  if (legacy_version_information.has_value()) {
+    rv += " " + legacy_version_information.value().ToString();
+  }
+  if (version_information.has_value()) {
+    rv += " " + version_information.value().ToString();
+  }
+  if (original_destination_connection_id.has_value()) {
+    rv += " " + TransportParameterIdToString(kOriginalDestinationConnectionId) +
+          " " + original_destination_connection_id.value().ToString();
+  }
+  rv += max_idle_timeout_ms.ToString(/*for_use_in_list=*/true);
+  if (!stateless_reset_token.empty()) {
+    rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " +
+          absl::BytesToHexString(absl::string_view(
+              reinterpret_cast<const char*>(stateless_reset_token.data()),
+              stateless_reset_token.size()));
+  }
+  rv += max_udp_payload_size.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_data.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_stream_data_bidi_local.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_stream_data_bidi_remote.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_stream_data_uni.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_streams_bidi.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_streams_uni.ToString(/*for_use_in_list=*/true);
+  rv += ack_delay_exponent.ToString(/*for_use_in_list=*/true);
+  rv += max_ack_delay.ToString(/*for_use_in_list=*/true);
+  rv += min_ack_delay_us.ToString(/*for_use_in_list=*/true);
+  if (disable_active_migration) {
+    rv += " " + TransportParameterIdToString(kDisableActiveMigration);
+  }
+  if (preferred_address) {
+    rv += " " + TransportParameterIdToString(kPreferredAddress) + " " +
+          preferred_address->ToString();
+  }
+  rv += active_connection_id_limit.ToString(/*for_use_in_list=*/true);
+  if (initial_source_connection_id.has_value()) {
+    rv += " " + TransportParameterIdToString(kInitialSourceConnectionId) + " " +
+          initial_source_connection_id.value().ToString();
+  }
+  if (retry_source_connection_id.has_value()) {
+    rv += " " + TransportParameterIdToString(kRetrySourceConnectionId) + " " +
+          retry_source_connection_id.value().ToString();
+  }
+  rv += max_datagram_frame_size.ToString(/*for_use_in_list=*/true);
+  rv += initial_round_trip_time_us.ToString(/*for_use_in_list=*/true);
+  if (google_connection_options.has_value()) {
+    rv += " " + TransportParameterIdToString(kGoogleConnectionOptions) + " ";
+    bool first = true;
+    for (const QuicTag& connection_option : google_connection_options.value()) {
+      if (first) {
+        first = false;
+      } else {
+        rv += ",";
+      }
+      rv += QuicTagToString(connection_option);
+    }
+  }
+  for (const auto& kv : custom_parameters) {
+    absl::StrAppend(&rv, " 0x", absl::Hex(static_cast<uint32_t>(kv.first)),
+                    "=");
+    static constexpr size_t kMaxPrintableLength = 32;
+    if (kv.second.length() <= kMaxPrintableLength) {
+      rv += absl::BytesToHexString(kv.second);
+    } else {
+      absl::string_view truncated(kv.second.data(), kMaxPrintableLength);
+      rv += absl::StrCat(absl::BytesToHexString(truncated), "...(length ",
+                         kv.second.length(), ")");
+    }
+  }
+  rv += "]";
+  return rv;
+}
+
+TransportParameters::TransportParameters()
+    : max_idle_timeout_ms(kMaxIdleTimeout),
+      max_udp_payload_size(kMaxPacketSize, kDefaultMaxPacketSizeTransportParam,
+                           kMinMaxPacketSizeTransportParam, kVarInt62MaxValue),
+      initial_max_data(kInitialMaxData),
+      initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
+      initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
+      initial_max_stream_data_uni(kInitialMaxStreamDataUni),
+      initial_max_streams_bidi(kInitialMaxStreamsBidi),
+      initial_max_streams_uni(kInitialMaxStreamsUni),
+      ack_delay_exponent(kAckDelayExponent,
+                         kDefaultAckDelayExponentTransportParam, 0,
+                         kMaxAckDelayExponentTransportParam),
+      max_ack_delay(kMaxAckDelay, kDefaultMaxAckDelayTransportParam, 0,
+                    kMaxMaxAckDelayTransportParam),
+      min_ack_delay_us(kMinAckDelay, 0, 0,
+                       kMaxMaxAckDelayTransportParam * kNumMicrosPerMilli),
+      disable_active_migration(false),
+      active_connection_id_limit(kActiveConnectionIdLimit,
+                                 kDefaultActiveConnectionIdLimitTransportParam,
+                                 kMinActiveConnectionIdLimitTransportParam,
+                                 kVarInt62MaxValue),
+      max_datagram_frame_size(kMaxDatagramFrameSize),
+      initial_round_trip_time_us(kInitialRoundTripTime)
+// Important note: any new transport parameters must be added
+// to TransportParameters::AreValid, SerializeTransportParameters and
+// ParseTransportParameters, TransportParameters's custom copy constructor, the
+// operator==, and TransportParametersTest.Comparator.
+{}
+
+TransportParameters::TransportParameters(const TransportParameters& other)
+    : perspective(other.perspective),
+      legacy_version_information(other.legacy_version_information),
+      version_information(other.version_information),
+      original_destination_connection_id(
+          other.original_destination_connection_id),
+      max_idle_timeout_ms(other.max_idle_timeout_ms),
+      stateless_reset_token(other.stateless_reset_token),
+      max_udp_payload_size(other.max_udp_payload_size),
+      initial_max_data(other.initial_max_data),
+      initial_max_stream_data_bidi_local(
+          other.initial_max_stream_data_bidi_local),
+      initial_max_stream_data_bidi_remote(
+          other.initial_max_stream_data_bidi_remote),
+      initial_max_stream_data_uni(other.initial_max_stream_data_uni),
+      initial_max_streams_bidi(other.initial_max_streams_bidi),
+      initial_max_streams_uni(other.initial_max_streams_uni),
+      ack_delay_exponent(other.ack_delay_exponent),
+      max_ack_delay(other.max_ack_delay),
+      min_ack_delay_us(other.min_ack_delay_us),
+      disable_active_migration(other.disable_active_migration),
+      active_connection_id_limit(other.active_connection_id_limit),
+      initial_source_connection_id(other.initial_source_connection_id),
+      retry_source_connection_id(other.retry_source_connection_id),
+      max_datagram_frame_size(other.max_datagram_frame_size),
+      initial_round_trip_time_us(other.initial_round_trip_time_us),
+      google_connection_options(other.google_connection_options),
+      custom_parameters(other.custom_parameters) {
+  if (other.preferred_address) {
+    preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
+        *other.preferred_address);
+  }
+}
+
+bool TransportParameters::operator==(const TransportParameters& rhs) const {
+  if (!(perspective == rhs.perspective &&
+        legacy_version_information == rhs.legacy_version_information &&
+        version_information == rhs.version_information &&
+        original_destination_connection_id ==
+            rhs.original_destination_connection_id &&
+        max_idle_timeout_ms.value() == rhs.max_idle_timeout_ms.value() &&
+        stateless_reset_token == rhs.stateless_reset_token &&
+        max_udp_payload_size.value() == rhs.max_udp_payload_size.value() &&
+        initial_max_data.value() == rhs.initial_max_data.value() &&
+        initial_max_stream_data_bidi_local.value() ==
+            rhs.initial_max_stream_data_bidi_local.value() &&
+        initial_max_stream_data_bidi_remote.value() ==
+            rhs.initial_max_stream_data_bidi_remote.value() &&
+        initial_max_stream_data_uni.value() ==
+            rhs.initial_max_stream_data_uni.value() &&
+        initial_max_streams_bidi.value() ==
+            rhs.initial_max_streams_bidi.value() &&
+        initial_max_streams_uni.value() ==
+            rhs.initial_max_streams_uni.value() &&
+        ack_delay_exponent.value() == rhs.ack_delay_exponent.value() &&
+        max_ack_delay.value() == rhs.max_ack_delay.value() &&
+        min_ack_delay_us.value() == rhs.min_ack_delay_us.value() &&
+        disable_active_migration == rhs.disable_active_migration &&
+        active_connection_id_limit.value() ==
+            rhs.active_connection_id_limit.value() &&
+        initial_source_connection_id == rhs.initial_source_connection_id &&
+        retry_source_connection_id == rhs.retry_source_connection_id &&
+        max_datagram_frame_size.value() ==
+            rhs.max_datagram_frame_size.value() &&
+        initial_round_trip_time_us.value() ==
+            rhs.initial_round_trip_time_us.value() &&
+        google_connection_options == rhs.google_connection_options &&
+        custom_parameters == rhs.custom_parameters)) {
+    return false;
+  }
+
+  if ((!preferred_address && rhs.preferred_address) ||
+      (preferred_address && !rhs.preferred_address)) {
+    return false;
+  }
+  if (preferred_address && rhs.preferred_address &&
+      *preferred_address != *rhs.preferred_address) {
+    return false;
+  }
+
+  return true;
+}
+
+bool TransportParameters::operator!=(const TransportParameters& rhs) const {
+  return !(*this == rhs);
+}
+
+bool TransportParameters::AreValid(std::string* error_details) const {
+  QUICHE_DCHECK(perspective == Perspective::IS_CLIENT ||
+                perspective == Perspective::IS_SERVER);
+  if (perspective == Perspective::IS_CLIENT && !stateless_reset_token.empty()) {
+    *error_details = "Client cannot send stateless reset token";
+    return false;
+  }
+  if (perspective == Perspective::IS_CLIENT &&
+      original_destination_connection_id.has_value()) {
+    *error_details = "Client cannot send original_destination_connection_id";
+    return false;
+  }
+  if (!stateless_reset_token.empty() &&
+      stateless_reset_token.size() != kStatelessResetTokenLength) {
+    *error_details = absl::StrCat("Stateless reset token has bad length ",
+                                  stateless_reset_token.size());
+    return false;
+  }
+  if (perspective == Perspective::IS_CLIENT && preferred_address) {
+    *error_details = "Client cannot send preferred address";
+    return false;
+  }
+  if (preferred_address && preferred_address->stateless_reset_token.size() !=
+                               kStatelessResetTokenLength) {
+    *error_details =
+        absl::StrCat("Preferred address stateless reset token has bad length ",
+                     preferred_address->stateless_reset_token.size());
+    return false;
+  }
+  if (preferred_address &&
+      (!preferred_address->ipv4_socket_address.host().IsIPv4() ||
+       !preferred_address->ipv6_socket_address.host().IsIPv6())) {
+    QUIC_BUG(quic_bug_10743_4) << "Preferred address family failure";
+    *error_details = "Internal preferred address family failure";
+    return false;
+  }
+  if (perspective == Perspective::IS_CLIENT &&
+      retry_source_connection_id.has_value()) {
+    *error_details = "Client cannot send retry_source_connection_id";
+    return false;
+  }
+  for (const auto& kv : custom_parameters) {
+    if (TransportParameterIdIsKnown(kv.first)) {
+      *error_details = absl::StrCat("Using custom_parameters with known ID ",
+                                    TransportParameterIdToString(kv.first),
+                                    " is not allowed");
+      return false;
+    }
+  }
+  if (perspective == Perspective::IS_SERVER &&
+      initial_round_trip_time_us.value() > 0) {
+    *error_details = "Server cannot send initial round trip time";
+    return false;
+  }
+  if (version_information.has_value()) {
+    const QuicVersionLabel& chosen_version =
+        version_information.value().chosen_version;
+    const QuicVersionLabelVector& other_versions =
+        version_information.value().other_versions;
+    if (chosen_version == 0) {
+      *error_details = "Invalid chosen version";
+      return false;
+    }
+    if (perspective == Perspective::IS_CLIENT &&
+        std::find(other_versions.begin(), other_versions.end(),
+                  chosen_version) == other_versions.end()) {
+      // When sent by the client, chosen_version needs to be present in
+      // other_versions because other_versions lists the compatible versions and
+      // the chosen version is part of that list. When sent by the server,
+      // other_version contains the list of fully-deployed versions which is
+      // generally equal to the list of supported versions but can slightly
+      // differ during removal of versions across a server fleet. See
+      // draft-ietf-quic-version-negotiation for details.
+      *error_details = "Client chosen version not in other versions";
+      return false;
+    }
+  }
+  const bool ok =
+      max_idle_timeout_ms.IsValid() && max_udp_payload_size.IsValid() &&
+      initial_max_data.IsValid() &&
+      initial_max_stream_data_bidi_local.IsValid() &&
+      initial_max_stream_data_bidi_remote.IsValid() &&
+      initial_max_stream_data_uni.IsValid() &&
+      initial_max_streams_bidi.IsValid() && initial_max_streams_uni.IsValid() &&
+      ack_delay_exponent.IsValid() && max_ack_delay.IsValid() &&
+      min_ack_delay_us.IsValid() && active_connection_id_limit.IsValid() &&
+      max_datagram_frame_size.IsValid() && initial_round_trip_time_us.IsValid();
+  if (!ok) {
+    *error_details = "Invalid transport parameters " + this->ToString();
+  }
+  return ok;
+}
+
+TransportParameters::~TransportParameters() = default;
+
+bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
+                                  const TransportParameters& in,
+                                  std::vector<uint8_t>* out) {
+  std::string error_details;
+  if (!in.AreValid(&error_details)) {
+    QUIC_BUG(invalid transport parameters)
+        << "Not serializing invalid transport parameters: " << error_details;
+    return false;
+  }
+  if (!in.legacy_version_information.has_value() ||
+      in.legacy_version_information.value().version == 0 ||
+      (in.perspective == Perspective::IS_SERVER &&
+       in.legacy_version_information.value().supported_versions.empty())) {
+    QUIC_BUG(missing versions) << "Refusing to serialize without versions";
+    return false;
+  }
+  TransportParameters::ParameterMap custom_parameters = in.custom_parameters;
+  for (const auto& kv : custom_parameters) {
+    if (kv.first % 31 == 27) {
+      // See the "Reserved Transport Parameters" section of RFC 9000.
+      QUIC_BUG(custom_parameters with GREASE)
+          << "Serializing custom_parameters with GREASE ID " << kv.first
+          << " is not allowed";
+      return false;
+    }
+  }
+
+  // Maximum length of the GREASE transport parameter (see below).
+  static constexpr size_t kMaxGreaseLength = 16;
+
+  // Empirically transport parameters generally fit within 128 bytes, but we
+  // need to allocate the size up front. Integer transport parameters
+  // have a maximum encoded length of 24 bytes (3 variable length integers),
+  // other transport parameters have a length of 16 + the maximum value length.
+  static constexpr size_t kTypeAndValueLength = 2 * sizeof(uint64_t);
+  static constexpr size_t kIntegerParameterLength =
+      kTypeAndValueLength + sizeof(uint64_t);
+  static constexpr size_t kStatelessResetParameterLength =
+      kTypeAndValueLength + 16 /* stateless reset token length */;
+  static constexpr size_t kConnectionIdParameterLength =
+      kTypeAndValueLength + 255 /* maximum connection ID length */;
+  static constexpr size_t kPreferredAddressParameterLength =
+      kTypeAndValueLength + 4 /*IPv4 address */ + 2 /* IPv4 port */ +
+      16 /* IPv6 address */ + 1 /* Connection ID length */ +
+      255 /* maximum connection ID length */ + 16 /* stateless reset token */;
+  static constexpr size_t kKnownTransportParamLength =
+      kConnectionIdParameterLength +      // original_destination_connection_id
+      kIntegerParameterLength +           // max_idle_timeout
+      kStatelessResetParameterLength +    // stateless_reset_token
+      kIntegerParameterLength +           // max_udp_payload_size
+      kIntegerParameterLength +           // initial_max_data
+      kIntegerParameterLength +           // initial_max_stream_data_bidi_local
+      kIntegerParameterLength +           // initial_max_stream_data_bidi_remote
+      kIntegerParameterLength +           // initial_max_stream_data_uni
+      kIntegerParameterLength +           // initial_max_streams_bidi
+      kIntegerParameterLength +           // initial_max_streams_uni
+      kIntegerParameterLength +           // ack_delay_exponent
+      kIntegerParameterLength +           // max_ack_delay
+      kIntegerParameterLength +           // min_ack_delay_us
+      kTypeAndValueLength +               // disable_active_migration
+      kPreferredAddressParameterLength +  // preferred_address
+      kIntegerParameterLength +           // active_connection_id_limit
+      kConnectionIdParameterLength +      // initial_source_connection_id
+      kConnectionIdParameterLength +      // retry_source_connection_id
+      kIntegerParameterLength +           // max_datagram_frame_size
+      kIntegerParameterLength +           // initial_round_trip_time_us
+      kTypeAndValueLength +               // google_connection_options
+      kTypeAndValueLength;                // google-version
+
+  std::vector<TransportParameters::TransportParameterId> parameter_ids = {
+      TransportParameters::kOriginalDestinationConnectionId,
+      TransportParameters::kMaxIdleTimeout,
+      TransportParameters::kStatelessResetToken,
+      TransportParameters::kMaxPacketSize,
+      TransportParameters::kInitialMaxData,
+      TransportParameters::kInitialMaxStreamDataBidiLocal,
+      TransportParameters::kInitialMaxStreamDataBidiRemote,
+      TransportParameters::kInitialMaxStreamDataUni,
+      TransportParameters::kInitialMaxStreamsBidi,
+      TransportParameters::kInitialMaxStreamsUni,
+      TransportParameters::kAckDelayExponent,
+      TransportParameters::kMaxAckDelay,
+      TransportParameters::kMinAckDelay,
+      TransportParameters::kActiveConnectionIdLimit,
+      TransportParameters::kMaxDatagramFrameSize,
+      TransportParameters::kInitialRoundTripTime,
+      TransportParameters::kDisableActiveMigration,
+      TransportParameters::kPreferredAddress,
+      TransportParameters::kInitialSourceConnectionId,
+      TransportParameters::kRetrySourceConnectionId,
+      TransportParameters::kGoogleConnectionOptions,
+      TransportParameters::kGoogleQuicVersion,
+      TransportParameters::kVersionInformation,
+  };
+
+  size_t max_transport_param_length = kKnownTransportParamLength;
+  // google_connection_options.
+  if (in.google_connection_options.has_value()) {
+    max_transport_param_length +=
+        in.google_connection_options.value().size() * sizeof(QuicTag);
+  }
+  // Google-specific version extension.
+  if (in.legacy_version_information.has_value()) {
+    max_transport_param_length +=
+        sizeof(in.legacy_version_information.value().version) +
+        1 /* versions length */ +
+        in.legacy_version_information.value().supported_versions.size() *
+            sizeof(QuicVersionLabel);
+  }
+  // version_information.
+  if (in.version_information.has_value()) {
+    max_transport_param_length +=
+        sizeof(in.version_information.value().chosen_version) +
+        // Add one for the added GREASE version.
+        (in.version_information.value().other_versions.size() + 1) *
+            sizeof(QuicVersionLabel);
+  }
+
+  // Add a random GREASE transport parameter, as defined in the
+  // "Reserved Transport Parameters" section of RFC 9000.
+  // This forces receivers to support unexpected input.
+  QuicRandom* random = QuicRandom::GetInstance();
+  // Transport parameter identifiers are 62 bits long so we need to
+  // ensure that the output of the computation below fits in 62 bits.
+  uint64_t grease_id64 = random->RandUint64() % ((1ULL << 62) - 31);
+  // Make sure grease_id % 31 == 27. Note that this is not uniformely
+  // distributed but is acceptable since no security depends on this
+  // randomness.
+  grease_id64 = (grease_id64 / 31) * 31 + 27;
+  TransportParameters::TransportParameterId grease_id =
+      static_cast<TransportParameters::TransportParameterId>(grease_id64);
+  const size_t grease_length = random->RandUint64() % kMaxGreaseLength;
+  QUICHE_DCHECK_GE(kMaxGreaseLength, grease_length);
+  char grease_contents[kMaxGreaseLength];
+  random->RandBytes(grease_contents, grease_length);
+  custom_parameters[grease_id] = std::string(grease_contents, grease_length);
+
+  // Custom parameters.
+  for (const auto& kv : custom_parameters) {
+    max_transport_param_length += kTypeAndValueLength + kv.second.length();
+    parameter_ids.push_back(kv.first);
+  }
+
+  // Randomize order of sent transport parameters by walking the array
+  // backwards and swapping each element with a random earlier one.
+  for (size_t i = parameter_ids.size() - 1; i > 0; i--) {
+    std::swap(parameter_ids[i],
+              parameter_ids[random->InsecureRandUint64() % (i + 1)]);
+  }
+
+  out->resize(max_transport_param_length);
+  QuicDataWriter writer(out->size(), reinterpret_cast<char*>(out->data()));
+
+  for (TransportParameters::TransportParameterId parameter_id : parameter_ids) {
+    switch (parameter_id) {
+      // original_destination_connection_id
+      case TransportParameters::kOriginalDestinationConnectionId: {
+        if (in.original_destination_connection_id.has_value()) {
+          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
+          QuicConnectionId original_destination_connection_id =
+              in.original_destination_connection_id.value();
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kOriginalDestinationConnectionId) ||
+              !writer.WriteStringPieceVarInt62(absl::string_view(
+                  original_destination_connection_id.data(),
+                  original_destination_connection_id.length()))) {
+            QUIC_BUG(Failed to write original_destination_connection_id)
+                << "Failed to write original_destination_connection_id "
+                << original_destination_connection_id << " for " << in;
+            return false;
+          }
+        }
+      } break;
+      // max_idle_timeout
+      case TransportParameters::kMaxIdleTimeout: {
+        if (!in.max_idle_timeout_ms.Write(&writer)) {
+          QUIC_BUG(Failed to write idle_timeout)
+              << "Failed to write idle_timeout for " << in;
+          return false;
+        }
+      } break;
+      // stateless_reset_token
+      case TransportParameters::kStatelessResetToken: {
+        if (!in.stateless_reset_token.empty()) {
+          QUICHE_DCHECK_EQ(kStatelessResetTokenLength,
+                           in.stateless_reset_token.size());
+          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kStatelessResetToken) ||
+              !writer.WriteStringPieceVarInt62(
+                  absl::string_view(reinterpret_cast<const char*>(
+                                        in.stateless_reset_token.data()),
+                                    in.stateless_reset_token.size()))) {
+            QUIC_BUG(Failed to write stateless_reset_token)
+                << "Failed to write stateless_reset_token of length "
+                << in.stateless_reset_token.size() << " for " << in;
+            return false;
+          }
+        }
+      } break;
+      // max_udp_payload_size
+      case TransportParameters::kMaxPacketSize: {
+        if (!in.max_udp_payload_size.Write(&writer)) {
+          QUIC_BUG(Failed to write max_udp_payload_size)
+              << "Failed to write max_udp_payload_size for " << in;
+          return false;
+        }
+      } break;
+      // initial_max_data
+      case TransportParameters::kInitialMaxData: {
+        if (!in.initial_max_data.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_data)
+              << "Failed to write initial_max_data for " << in;
+          return false;
+        }
+      } break;
+      // initial_max_stream_data_bidi_local
+      case TransportParameters::kInitialMaxStreamDataBidiLocal: {
+        if (!in.initial_max_stream_data_bidi_local.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_stream_data_bidi_local)
+              << "Failed to write initial_max_stream_data_bidi_local for "
+              << in;
+          return false;
+        }
+      } break;
+      // initial_max_stream_data_bidi_remote
+      case TransportParameters::kInitialMaxStreamDataBidiRemote: {
+        if (!in.initial_max_stream_data_bidi_remote.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_stream_data_bidi_remote)
+              << "Failed to write initial_max_stream_data_bidi_remote for "
+              << in;
+          return false;
+        }
+      } break;
+      // initial_max_stream_data_uni
+      case TransportParameters::kInitialMaxStreamDataUni: {
+        if (!in.initial_max_stream_data_uni.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_stream_data_uni)
+              << "Failed to write initial_max_stream_data_uni for " << in;
+          return false;
+        }
+      } break;
+      // initial_max_streams_bidi
+      case TransportParameters::kInitialMaxStreamsBidi: {
+        if (!in.initial_max_streams_bidi.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_streams_bidi)
+              << "Failed to write initial_max_streams_bidi for " << in;
+          return false;
+        }
+      } break;
+      // initial_max_streams_uni
+      case TransportParameters::kInitialMaxStreamsUni: {
+        if (!in.initial_max_streams_uni.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_streams_uni)
+              << "Failed to write initial_max_streams_uni for " << in;
+          return false;
+        }
+      } break;
+      // ack_delay_exponent
+      case TransportParameters::kAckDelayExponent: {
+        if (!in.ack_delay_exponent.Write(&writer)) {
+          QUIC_BUG(Failed to write ack_delay_exponent)
+              << "Failed to write ack_delay_exponent for " << in;
+          return false;
+        }
+      } break;
+      // max_ack_delay
+      case TransportParameters::kMaxAckDelay: {
+        if (!in.max_ack_delay.Write(&writer)) {
+          QUIC_BUG(Failed to write max_ack_delay)
+              << "Failed to write max_ack_delay for " << in;
+          return false;
+        }
+      } break;
+      // min_ack_delay_us
+      case TransportParameters::kMinAckDelay: {
+        if (!in.min_ack_delay_us.Write(&writer)) {
+          QUIC_BUG(Failed to write min_ack_delay_us)
+              << "Failed to write min_ack_delay_us for " << in;
+          return false;
+        }
+      } break;
+      // active_connection_id_limit
+      case TransportParameters::kActiveConnectionIdLimit: {
+        if (!in.active_connection_id_limit.Write(&writer)) {
+          QUIC_BUG(Failed to write active_connection_id_limit)
+              << "Failed to write active_connection_id_limit for " << in;
+          return false;
+        }
+      } break;
+      // max_datagram_frame_size
+      case TransportParameters::kMaxDatagramFrameSize: {
+        if (!in.max_datagram_frame_size.Write(&writer)) {
+          QUIC_BUG(Failed to write max_datagram_frame_size)
+              << "Failed to write max_datagram_frame_size for " << in;
+          return false;
+        }
+      } break;
+      // initial_round_trip_time_us
+      case TransportParameters::kInitialRoundTripTime: {
+        if (!in.initial_round_trip_time_us.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_round_trip_time_us)
+              << "Failed to write initial_round_trip_time_us for " << in;
+          return false;
+        }
+      } break;
+      // disable_active_migration
+      case TransportParameters::kDisableActiveMigration: {
+        if (in.disable_active_migration) {
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kDisableActiveMigration) ||
+              !writer.WriteVarInt62(/* transport parameter length */ 0)) {
+            QUIC_BUG(Failed to write disable_active_migration)
+                << "Failed to write disable_active_migration for " << in;
+            return false;
+          }
+        }
+      } break;
+      // preferred_address
+      case TransportParameters::kPreferredAddress: {
+        if (in.preferred_address) {
+          std::string v4_address_bytes =
+              in.preferred_address->ipv4_socket_address.host().ToPackedString();
+          std::string v6_address_bytes =
+              in.preferred_address->ipv6_socket_address.host().ToPackedString();
+          if (v4_address_bytes.length() != 4 ||
+              v6_address_bytes.length() != 16 ||
+              in.preferred_address->stateless_reset_token.size() !=
+                  kStatelessResetTokenLength) {
+            QUIC_BUG(quic_bug_10743_12)
+                << "Bad lengths " << *in.preferred_address;
+            return false;
+          }
+          const uint64_t preferred_address_length =
+              v4_address_bytes.length() + /* IPv4 port */ sizeof(uint16_t) +
+              v6_address_bytes.length() + /* IPv6 port */ sizeof(uint16_t) +
+              /* connection ID length byte */ sizeof(uint8_t) +
+              in.preferred_address->connection_id.length() +
+              in.preferred_address->stateless_reset_token.size();
+          if (!writer.WriteVarInt62(TransportParameters::kPreferredAddress) ||
+              !writer.WriteVarInt62(
+                  /* transport parameter length */ preferred_address_length) ||
+              !writer.WriteStringPiece(v4_address_bytes) ||
+              !writer.WriteUInt16(
+                  in.preferred_address->ipv4_socket_address.port()) ||
+              !writer.WriteStringPiece(v6_address_bytes) ||
+              !writer.WriteUInt16(
+                  in.preferred_address->ipv6_socket_address.port()) ||
+              !writer.WriteUInt8(
+                  in.preferred_address->connection_id.length()) ||
+              !writer.WriteBytes(
+                  in.preferred_address->connection_id.data(),
+                  in.preferred_address->connection_id.length()) ||
+              !writer.WriteBytes(
+                  in.preferred_address->stateless_reset_token.data(),
+                  in.preferred_address->stateless_reset_token.size())) {
+            QUIC_BUG(Failed to write preferred_address)
+                << "Failed to write preferred_address for " << in;
+            return false;
+          }
+        }
+      } break;
+      // initial_source_connection_id
+      case TransportParameters::kInitialSourceConnectionId: {
+        if (in.initial_source_connection_id.has_value()) {
+          QuicConnectionId initial_source_connection_id =
+              in.initial_source_connection_id.value();
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kInitialSourceConnectionId) ||
+              !writer.WriteStringPieceVarInt62(
+                  absl::string_view(initial_source_connection_id.data(),
+                                    initial_source_connection_id.length()))) {
+            QUIC_BUG(Failed to write initial_source_connection_id)
+                << "Failed to write initial_source_connection_id "
+                << initial_source_connection_id << " for " << in;
+            return false;
+          }
+        }
+      } break;
+      // retry_source_connection_id
+      case TransportParameters::kRetrySourceConnectionId: {
+        if (in.retry_source_connection_id.has_value()) {
+          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
+          QuicConnectionId retry_source_connection_id =
+              in.retry_source_connection_id.value();
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kRetrySourceConnectionId) ||
+              !writer.WriteStringPieceVarInt62(
+                  absl::string_view(retry_source_connection_id.data(),
+                                    retry_source_connection_id.length()))) {
+            QUIC_BUG(Failed to write retry_source_connection_id)
+                << "Failed to write retry_source_connection_id "
+                << retry_source_connection_id << " for " << in;
+            return false;
+          }
+        }
+      } break;
+      // Google-specific connection options.
+      case TransportParameters::kGoogleConnectionOptions: {
+        if (in.google_connection_options.has_value()) {
+          static_assert(
+              sizeof(in.google_connection_options.value().front()) == 4,
+              "bad size");
+          uint64_t connection_options_length =
+              in.google_connection_options.value().size() * 4;
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kGoogleConnectionOptions) ||
+              !writer.WriteVarInt62(
+                  /* transport parameter length */ connection_options_length)) {
+            QUIC_BUG(Failed to write google_connection_options)
+                << "Failed to write google_connection_options of length "
+                << connection_options_length << " for " << in;
+            return false;
+          }
+          for (const QuicTag& connection_option :
+               in.google_connection_options.value()) {
+            if (!writer.WriteTag(connection_option)) {
+              QUIC_BUG(Failed to write google_connection_option)
+                  << "Failed to write google_connection_option "
+                  << QuicTagToString(connection_option) << " for " << in;
+              return false;
+            }
+          }
+        }
+      } break;
+      // Google-specific version extension.
+      case TransportParameters::kGoogleQuicVersion: {
+        if (!in.legacy_version_information.has_value()) {
+          break;
+        }
+        static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
+                      "bad length");
+        uint64_t google_version_length =
+            sizeof(in.legacy_version_information.value().version);
+        if (in.perspective == Perspective::IS_SERVER) {
+          google_version_length +=
+              /* versions length */ sizeof(uint8_t) +
+              sizeof(QuicVersionLabel) * in.legacy_version_information.value()
+                                             .supported_versions.size();
+        }
+        if (!writer.WriteVarInt62(TransportParameters::kGoogleQuicVersion) ||
+            !writer.WriteVarInt62(
+                /* transport parameter length */ google_version_length) ||
+            !writer.WriteUInt32(
+                in.legacy_version_information.value().version)) {
+          QUIC_BUG(Failed to write Google version extension)
+              << "Failed to write Google version extension for " << in;
+          return false;
+        }
+        if (in.perspective == Perspective::IS_SERVER) {
+          if (!writer.WriteUInt8(sizeof(QuicVersionLabel) *
+                                 in.legacy_version_information.value()
+                                     .supported_versions.size())) {
+            QUIC_BUG(Failed to write versions length)
+                << "Failed to write versions length for " << in;
+            return false;
+          }
+          for (QuicVersionLabel version_label :
+               in.legacy_version_information.value().supported_versions) {
+            if (!writer.WriteUInt32(version_label)) {
+              QUIC_BUG(Failed to write supported version)
+                  << "Failed to write supported version for " << in;
+              return false;
+            }
+          }
+        }
+      } break;
+      // version_information.
+      case TransportParameters::kVersionInformation: {
+        if (!in.version_information.has_value()) {
+          break;
+        }
+        static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
+                      "bad length");
+        QuicVersionLabelVector other_versions =
+            in.version_information.value().other_versions;
+        // Insert one GREASE version at a random index.
+        const size_t grease_index =
+            random->InsecureRandUint64() % (other_versions.size() + 1);
+        other_versions.insert(
+            other_versions.begin() + grease_index,
+            CreateQuicVersionLabel(QuicVersionReservedForNegotiation()));
+        const uint64_t version_information_length =
+            sizeof(in.version_information.value().chosen_version) +
+            sizeof(QuicVersionLabel) * other_versions.size();
+        if (!writer.WriteVarInt62(TransportParameters::kVersionInformation) ||
+            !writer.WriteVarInt62(
+                /* transport parameter length */ version_information_length) ||
+            !writer.WriteUInt32(
+                in.version_information.value().chosen_version)) {
+          QUIC_BUG(Failed to write chosen version)
+              << "Failed to write chosen version for " << in;
+          return false;
+        }
+        for (QuicVersionLabel version_label : other_versions) {
+          if (!writer.WriteUInt32(version_label)) {
+            QUIC_BUG(Failed to write other version)
+                << "Failed to write other version for " << in;
+            return false;
+          }
+        }
+      } break;
+      // Custom parameters and GREASE.
+      default: {
+        auto it = custom_parameters.find(parameter_id);
+        if (it == custom_parameters.end()) {
+          QUIC_BUG(Unknown parameter) << "Unknown parameter " << parameter_id;
+          return false;
+        }
+        if (!writer.WriteVarInt62(parameter_id) ||
+            !writer.WriteStringPieceVarInt62(it->second)) {
+          QUIC_BUG(Failed to write custom parameter)
+              << "Failed to write custom parameter " << parameter_id;
+          return false;
+        }
+      } break;
+    }
+  }
+
+  out->resize(writer.length());
+
+  QUIC_DLOG(INFO) << "Serialized " << in << " as " << writer.length()
+                  << " bytes";
+
+  return true;
+}
+
+bool ParseTransportParameters(ParsedQuicVersion version,
+                              Perspective perspective,
+                              const uint8_t* in,
+                              size_t in_len,
+                              TransportParameters* out,
+                              std::string* error_details) {
+  out->perspective = perspective;
+  QuicDataReader reader(reinterpret_cast<const char*>(in), in_len);
+
+  while (!reader.IsDoneReading()) {
+    uint64_t param_id64;
+    if (!reader.ReadVarInt62(&param_id64)) {
+      *error_details = "Failed to parse transport parameter ID";
+      return false;
+    }
+    TransportParameters::TransportParameterId param_id =
+        static_cast<TransportParameters::TransportParameterId>(param_id64);
+    absl::string_view value;
+    if (!reader.ReadStringPieceVarInt62(&value)) {
+      *error_details =
+          "Failed to read length and value of transport parameter " +
+          TransportParameterIdToString(param_id);
+      return false;
+    }
+    QuicDataReader value_reader(value);
+    bool parse_success = true;
+    switch (param_id) {
+      case TransportParameters::kOriginalDestinationConnectionId: {
+        if (out->original_destination_connection_id.has_value()) {
+          *error_details =
+              "Received a second original_destination_connection_id";
+          return false;
+        }
+        const size_t connection_id_length = value_reader.BytesRemaining();
+        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
+                connection_id_length, version.transport_version)) {
+          *error_details = absl::StrCat(
+              "Received original_destination_connection_id of invalid length ",
+              connection_id_length);
+          return false;
+        }
+        QuicConnectionId original_destination_connection_id;
+        if (!value_reader.ReadConnectionId(&original_destination_connection_id,
+                                           connection_id_length)) {
+          *error_details = "Failed to read original_destination_connection_id";
+          return false;
+        }
+        out->original_destination_connection_id =
+            original_destination_connection_id;
+      } break;
+      case TransportParameters::kMaxIdleTimeout:
+        parse_success =
+            out->max_idle_timeout_ms.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kStatelessResetToken: {
+        if (!out->stateless_reset_token.empty()) {
+          *error_details = "Received a second stateless_reset_token";
+          return false;
+        }
+        absl::string_view stateless_reset_token =
+            value_reader.ReadRemainingPayload();
+        if (stateless_reset_token.length() != kStatelessResetTokenLength) {
+          *error_details =
+              absl::StrCat("Received stateless_reset_token of invalid length ",
+                           stateless_reset_token.length());
+          return false;
+        }
+        out->stateless_reset_token.assign(
+            stateless_reset_token.data(),
+            stateless_reset_token.data() + stateless_reset_token.length());
+      } break;
+      case TransportParameters::kMaxPacketSize:
+        parse_success =
+            out->max_udp_payload_size.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxData:
+        parse_success =
+            out->initial_max_data.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamDataBidiLocal:
+        parse_success = out->initial_max_stream_data_bidi_local.Read(
+            &value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamDataBidiRemote:
+        parse_success = out->initial_max_stream_data_bidi_remote.Read(
+            &value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamDataUni:
+        parse_success =
+            out->initial_max_stream_data_uni.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamsBidi:
+        parse_success =
+            out->initial_max_streams_bidi.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamsUni:
+        parse_success =
+            out->initial_max_streams_uni.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kAckDelayExponent:
+        parse_success =
+            out->ack_delay_exponent.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kMaxAckDelay:
+        parse_success = out->max_ack_delay.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kDisableActiveMigration:
+        if (out->disable_active_migration) {
+          *error_details = "Received a second disable_active_migration";
+          return false;
+        }
+        out->disable_active_migration = true;
+        break;
+      case TransportParameters::kPreferredAddress: {
+        TransportParameters::PreferredAddress preferred_address;
+        uint16_t ipv4_port, ipv6_port;
+        in_addr ipv4_address;
+        in6_addr ipv6_address;
+        preferred_address.stateless_reset_token.resize(
+            kStatelessResetTokenLength);
+        if (!value_reader.ReadBytes(&ipv4_address, sizeof(ipv4_address)) ||
+            !value_reader.ReadUInt16(&ipv4_port) ||
+            !value_reader.ReadBytes(&ipv6_address, sizeof(ipv6_address)) ||
+            !value_reader.ReadUInt16(&ipv6_port) ||
+            !value_reader.ReadLengthPrefixedConnectionId(
+                &preferred_address.connection_id) ||
+            !value_reader.ReadBytes(&preferred_address.stateless_reset_token[0],
+                                    kStatelessResetTokenLength)) {
+          *error_details = "Failed to read preferred_address";
+          return false;
+        }
+        preferred_address.ipv4_socket_address =
+            QuicSocketAddress(QuicIpAddress(ipv4_address), ipv4_port);
+        preferred_address.ipv6_socket_address =
+            QuicSocketAddress(QuicIpAddress(ipv6_address), ipv6_port);
+        if (!preferred_address.ipv4_socket_address.host().IsIPv4() ||
+            !preferred_address.ipv6_socket_address.host().IsIPv6()) {
+          *error_details = "Received preferred_address of bad families " +
+                           preferred_address.ToString();
+          return false;
+        }
+        if (!QuicUtils::IsConnectionIdValidForVersion(
+                preferred_address.connection_id, version.transport_version)) {
+          *error_details = "Received invalid preferred_address connection ID " +
+                           preferred_address.ToString();
+          return false;
+        }
+        out->preferred_address =
+            std::make_unique<TransportParameters::PreferredAddress>(
+                preferred_address);
+      } break;
+      case TransportParameters::kActiveConnectionIdLimit:
+        parse_success =
+            out->active_connection_id_limit.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialSourceConnectionId: {
+        if (out->initial_source_connection_id.has_value()) {
+          *error_details = "Received a second initial_source_connection_id";
+          return false;
+        }
+        const size_t connection_id_length = value_reader.BytesRemaining();
+        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
+                connection_id_length, version.transport_version)) {
+          *error_details = absl::StrCat(
+              "Received initial_source_connection_id of invalid length ",
+              connection_id_length);
+          return false;
+        }
+        QuicConnectionId initial_source_connection_id;
+        if (!value_reader.ReadConnectionId(&initial_source_connection_id,
+                                           connection_id_length)) {
+          *error_details = "Failed to read initial_source_connection_id";
+          return false;
+        }
+        out->initial_source_connection_id = initial_source_connection_id;
+      } break;
+      case TransportParameters::kRetrySourceConnectionId: {
+        if (out->retry_source_connection_id.has_value()) {
+          *error_details = "Received a second retry_source_connection_id";
+          return false;
+        }
+        const size_t connection_id_length = value_reader.BytesRemaining();
+        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
+                connection_id_length, version.transport_version)) {
+          *error_details = absl::StrCat(
+              "Received retry_source_connection_id of invalid length ",
+              connection_id_length);
+          return false;
+        }
+        QuicConnectionId retry_source_connection_id;
+        if (!value_reader.ReadConnectionId(&retry_source_connection_id,
+                                           connection_id_length)) {
+          *error_details = "Failed to read retry_source_connection_id";
+          return false;
+        }
+        out->retry_source_connection_id = retry_source_connection_id;
+      } break;
+      case TransportParameters::kMaxDatagramFrameSize:
+        parse_success =
+            out->max_datagram_frame_size.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialRoundTripTime:
+        parse_success =
+            out->initial_round_trip_time_us.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kGoogleConnectionOptions: {
+        if (out->google_connection_options.has_value()) {
+          *error_details = "Received a second google_connection_options";
+          return false;
+        }
+        out->google_connection_options = QuicTagVector{};
+        while (!value_reader.IsDoneReading()) {
+          QuicTag connection_option;
+          if (!value_reader.ReadTag(&connection_option)) {
+            *error_details = "Failed to read a google_connection_options";
+            return false;
+          }
+          out->google_connection_options.value().push_back(connection_option);
+        }
+      } break;
+      case TransportParameters::kGoogleQuicVersion: {
+        if (!out->legacy_version_information.has_value()) {
+          out->legacy_version_information =
+              TransportParameters::LegacyVersionInformation();
+        }
+        if (!value_reader.ReadUInt32(
+                &out->legacy_version_information.value().version)) {
+          *error_details = "Failed to read Google version extension version";
+          return false;
+        }
+        if (perspective == Perspective::IS_SERVER) {
+          uint8_t versions_length;
+          if (!value_reader.ReadUInt8(&versions_length)) {
+            *error_details = "Failed to parse Google supported versions length";
+            return false;
+          }
+          const uint8_t num_versions = versions_length / sizeof(uint32_t);
+          for (uint8_t i = 0; i < num_versions; ++i) {
+            QuicVersionLabel version;
+            if (!value_reader.ReadUInt32(&version)) {
+              *error_details = "Failed to parse Google supported version";
+              return false;
+            }
+            out->legacy_version_information.value()
+                .supported_versions.push_back(version);
+          }
+        }
+      } break;
+      case TransportParameters::kVersionInformation: {
+        if (out->version_information.has_value()) {
+          *error_details = "Received a second version_information";
+          return false;
+        }
+        out->version_information = TransportParameters::VersionInformation();
+        if (!value_reader.ReadUInt32(
+                &out->version_information.value().chosen_version)) {
+          *error_details = "Failed to read chosen version";
+          return false;
+        }
+        while (!value_reader.IsDoneReading()) {
+          QuicVersionLabel other_version;
+          if (!value_reader.ReadUInt32(&other_version)) {
+            *error_details = "Failed to parse other version";
+            return false;
+          }
+          out->version_information.value().other_versions.push_back(
+              other_version);
+        }
+      } break;
+      case TransportParameters::kMinAckDelay:
+        parse_success =
+            out->min_ack_delay_us.Read(&value_reader, error_details);
+        break;
+      default:
+        if (out->custom_parameters.find(param_id) !=
+            out->custom_parameters.end()) {
+          *error_details = "Received a second unknown parameter" +
+                           TransportParameterIdToString(param_id);
+          return false;
+        }
+        out->custom_parameters[param_id] =
+            std::string(value_reader.ReadRemainingPayload());
+        break;
+    }
+    if (!parse_success) {
+      QUICHE_DCHECK(!error_details->empty());
+      return false;
+    }
+    if (!value_reader.IsDoneReading()) {
+      *error_details = absl::StrCat(
+          "Received unexpected ", value_reader.BytesRemaining(),
+          " bytes after parsing ", TransportParameterIdToString(param_id));
+      return false;
+    }
+  }
+
+  if (!out->AreValid(error_details)) {
+    QUICHE_DCHECK(!error_details->empty());
+    return false;
+  }
+
+  QUIC_DLOG(INFO) << "Parsed transport parameters " << *out << " from "
+                  << in_len << " bytes";
+
+  return true;
+}
+
+namespace {
+
+bool DigestUpdateIntegerParam(
+    EVP_MD_CTX* hash_ctx,
+    const TransportParameters::IntegerParameter& param) {
+  uint64_t value = param.value();
+  return EVP_DigestUpdate(hash_ctx, &value, sizeof(value));
+}
+
+}  // namespace
+
+bool SerializeTransportParametersForTicket(
+    const TransportParameters& in,
+    const std::vector<uint8_t>& application_data,
+    std::vector<uint8_t>* out) {
+  std::string error_details;
+  if (!in.AreValid(&error_details)) {
+    QUIC_BUG(quic_bug_10743_26)
+        << "Not serializing invalid transport parameters: " << error_details;
+    return false;
+  }
+
+  out->resize(SHA256_DIGEST_LENGTH + 1);
+  const uint8_t serialization_version = 0;
+  (*out)[0] = serialization_version;
+
+  bssl::ScopedEVP_MD_CTX hash_ctx;
+  // Write application data:
+  uint64_t app_data_len = application_data.size();
+  const uint64_t parameter_version = 0;
+  // The format of the input to the hash function is as follows:
+  // - The application data, prefixed with a 64-bit length field.
+  // - Transport parameters:
+  //   - A 64-bit version field indicating which version of encoding is used
+  //     for transport parameters.
+  //   - A list of 64-bit integers representing the relevant parameters.
+  //
+  //   When changing which parameters are included, additional parameters can be
+  //   added to the end of the list without changing the version field. New
+  //   parameters that are variable length must be length prefixed. If
+  //   parameters are removed from the list, the version field must be
+  //   incremented.
+  //
+  // Integers happen to be written in host byte order, not network byte order.
+  if (!EVP_DigestInit(hash_ctx.get(), EVP_sha256()) ||
+      !EVP_DigestUpdate(hash_ctx.get(), &app_data_len, sizeof(app_data_len)) ||
+      !EVP_DigestUpdate(hash_ctx.get(), application_data.data(),
+                        application_data.size()) ||
+      !EVP_DigestUpdate(hash_ctx.get(), &parameter_version,
+                        sizeof(parameter_version))) {
+    QUIC_BUG(quic_bug_10743_27)
+        << "Unexpected failure of EVP_Digest functions when hashing "
+           "Transport Parameters for ticket";
+    return false;
+  }
+
+  // Write transport parameters specified by draft-ietf-quic-transport-28,
+  // section 7.4.1, that are remembered for 0-RTT.
+  if (!DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_data) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(),
+                                in.initial_max_stream_data_bidi_local) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(),
+                                in.initial_max_stream_data_bidi_remote) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(),
+                                in.initial_max_stream_data_uni) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_bidi) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_uni) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(),
+                                in.active_connection_id_limit)) {
+    QUIC_BUG(quic_bug_10743_28)
+        << "Unexpected failure of EVP_Digest functions when hashing "
+           "Transport Parameters for ticket";
+    return false;
+  }
+  uint8_t disable_active_migration = in.disable_active_migration ? 1 : 0;
+  if (!EVP_DigestUpdate(hash_ctx.get(), &disable_active_migration,
+                        sizeof(disable_active_migration)) ||
+      !EVP_DigestFinal(hash_ctx.get(), out->data() + 1, nullptr)) {
+    QUIC_BUG(quic_bug_10743_29)
+        << "Unexpected failure of EVP_Digest functions when hashing "
+           "Transport Parameters for ticket";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/transport_parameters.h b/quiche/quic/core/crypto/transport_parameters.h
new file mode 100644
index 0000000..7ccd557
--- /dev/null
+++ b/quiche/quic/core/crypto/transport_parameters.h
@@ -0,0 +1,314 @@
+// Copyright (c) 2018 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_CRYPTO_TRANSPORT_PARAMETERS_H_
+#define QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// TransportParameters contains parameters for QUIC's transport layer that are
+// exchanged during the TLS handshake. This struct is a mirror of the struct in
+// the "Transport Parameter Encoding" section of draft-ietf-quic-transport.
+// This struct currently uses the values from draft 29.
+struct QUIC_EXPORT_PRIVATE TransportParameters {
+  // The identifier used to differentiate transport parameters.
+  enum TransportParameterId : uint64_t;
+  // A map used to specify custom parameters.
+  using ParameterMap = absl::flat_hash_map<TransportParameterId, std::string>;
+  // Represents an individual QUIC transport parameter that only encodes a
+  // variable length integer. Can only be created inside the constructor for
+  // TransportParameters.
+  class QUIC_EXPORT_PRIVATE IntegerParameter {
+   public:
+    // Forbid constructing and copying apart from TransportParameters.
+    IntegerParameter() = delete;
+    IntegerParameter& operator=(const IntegerParameter&) = delete;
+    // Sets the value of this transport parameter.
+    void set_value(uint64_t value);
+    // Gets the value of this transport parameter.
+    uint64_t value() const;
+    // Validates whether the current value is valid.
+    bool IsValid() const;
+    // Writes to a crypto byte buffer, used during serialization. Does not write
+    // anything if the value is equal to the parameter's default value.
+    // Returns whether the write was successful.
+    bool Write(QuicDataWriter* writer) const;
+    // Reads from a crypto byte string, used during parsing.
+    // Returns whether the read was successful.
+    // On failure, this method will write a human-readable error message to
+    // |error_details|.
+    bool Read(QuicDataReader* reader, std::string* error_details);
+    // operator<< allows easily logging integer transport parameters.
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os,
+        const IntegerParameter& param);
+
+   private:
+    friend struct TransportParameters;
+    // Constructors for initial setup used by TransportParameters only.
+    // This constructor sets |default_value| and |min_value| to 0, and
+    // |max_value| to kVarInt62MaxValue.
+    explicit IntegerParameter(TransportParameterId param_id);
+    IntegerParameter(TransportParameterId param_id,
+                     uint64_t default_value,
+                     uint64_t min_value,
+                     uint64_t max_value);
+    IntegerParameter(const IntegerParameter& other) = default;
+    IntegerParameter(IntegerParameter&& other) = default;
+    // Human-readable string representation.
+    std::string ToString(bool for_use_in_list) const;
+
+    // Number used to indicate this transport parameter.
+    TransportParameterId param_id_;
+    // Current value of the transport parameter.
+    uint64_t value_;
+    // Default value of this transport parameter, as per IETF specification.
+    const uint64_t default_value_;
+    // Minimum value of this transport parameter, as per IETF specification.
+    const uint64_t min_value_;
+    // Maximum value of this transport parameter, as per IETF specification.
+    const uint64_t max_value_;
+    // Ensures this parameter is not parsed twice in the same message.
+    bool has_been_read_;
+  };
+
+  // Represents the preferred_address transport parameter that a server can
+  // send to clients.
+  struct QUIC_EXPORT_PRIVATE PreferredAddress {
+    PreferredAddress();
+    PreferredAddress(const PreferredAddress& other) = default;
+    PreferredAddress(PreferredAddress&& other) = default;
+    ~PreferredAddress();
+    bool operator==(const PreferredAddress& rhs) const;
+    bool operator!=(const PreferredAddress& rhs) const;
+
+    QuicSocketAddress ipv4_socket_address;
+    QuicSocketAddress ipv6_socket_address;
+    QuicConnectionId connection_id;
+    std::vector<uint8_t> stateless_reset_token;
+
+    // Allows easily logging.
+    std::string ToString() const;
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os,
+        const TransportParameters& params);
+  };
+
+  // LegacyVersionInformation represents the Google QUIC downgrade prevention
+  // mechanism ported to QUIC+TLS. It is exchanged using transport parameter ID
+  // 0x4752 and will eventually be deprecated in favor of
+  // draft-ietf-quic-version-negotiation.
+  struct QUIC_EXPORT_PRIVATE LegacyVersionInformation {
+    LegacyVersionInformation();
+    LegacyVersionInformation(const LegacyVersionInformation& other) = default;
+    LegacyVersionInformation& operator=(const LegacyVersionInformation& other) =
+        default;
+    LegacyVersionInformation& operator=(LegacyVersionInformation&& other) =
+        default;
+    LegacyVersionInformation(LegacyVersionInformation&& other) = default;
+    ~LegacyVersionInformation() = default;
+    bool operator==(const LegacyVersionInformation& rhs) const;
+    bool operator!=(const LegacyVersionInformation& rhs) const;
+    // When sent by the client, |version| is the initial version offered by the
+    // client (before any version negotiation packets) for this connection. When
+    // sent by the server, |version| is the version that is in use.
+    QuicVersionLabel version;
+
+    // When sent by the server, |supported_versions| contains a list of all
+    // versions that the server would send in a version negotiation packet. When
+    // sent by the client, this is empty.
+    QuicVersionLabelVector supported_versions;
+
+    // Allows easily logging.
+    std::string ToString() const;
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os,
+        const LegacyVersionInformation& legacy_version_information);
+  };
+
+  // Version information used for version downgrade prevention and compatible
+  // version negotiation. See draft-ietf-quic-version-negotiation-05.
+  struct QUIC_EXPORT_PRIVATE VersionInformation {
+    VersionInformation();
+    VersionInformation(const VersionInformation& other) = default;
+    VersionInformation& operator=(const VersionInformation& other) = default;
+    VersionInformation& operator=(VersionInformation&& other) = default;
+    VersionInformation(VersionInformation&& other) = default;
+    ~VersionInformation() = default;
+    bool operator==(const VersionInformation& rhs) const;
+    bool operator!=(const VersionInformation& rhs) const;
+
+    // Version that the sender has chosen to use on this connection.
+    QuicVersionLabel chosen_version;
+
+    // When sent by the client, |other_versions| contains all the versions that
+    // this first flight is compatible with. When sent by the server,
+    // |other_versions| contains all of the versions supported by the server.
+    QuicVersionLabelVector other_versions;
+
+    // Allows easily logging.
+    std::string ToString() const;
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os, const VersionInformation& version_information);
+  };
+
+  TransportParameters();
+  TransportParameters(const TransportParameters& other);
+  ~TransportParameters();
+  bool operator==(const TransportParameters& rhs) const;
+  bool operator!=(const TransportParameters& rhs) const;
+
+  // Represents the sender of the transport parameters. When |perspective| is
+  // Perspective::IS_CLIENT, this struct is being used in the client_hello
+  // handshake message; when it is Perspective::IS_SERVER, it is being used in
+  // the encrypted_extensions handshake message.
+  Perspective perspective;
+
+  // Google QUIC downgrade prevention mechanism sent over QUIC+TLS.
+  absl::optional<LegacyVersionInformation> legacy_version_information;
+
+  // IETF downgrade prevention and compatible version negotiation, see
+  // draft-ietf-quic-version-negotiation.
+  absl::optional<VersionInformation> version_information;
+
+  // The value of the Destination Connection ID field from the first
+  // Initial packet sent by the client.
+  absl::optional<QuicConnectionId> original_destination_connection_id;
+
+  // Maximum idle timeout expressed in milliseconds.
+  IntegerParameter max_idle_timeout_ms;
+
+  // Stateless reset token used in verifying stateless resets.
+  std::vector<uint8_t> stateless_reset_token;
+
+  // Limits the size of packets that the endpoint is willing to receive.
+  // This indicates that packets larger than this limit will be dropped.
+  IntegerParameter max_udp_payload_size;
+
+  // Contains the initial value for the maximum amount of data that can
+  // be sent on the connection.
+  IntegerParameter initial_max_data;
+
+  // Initial flow control limit for locally-initiated bidirectional streams.
+  IntegerParameter initial_max_stream_data_bidi_local;
+
+  // Initial flow control limit for peer-initiated bidirectional streams.
+  IntegerParameter initial_max_stream_data_bidi_remote;
+
+  // Initial flow control limit for unidirectional streams.
+  IntegerParameter initial_max_stream_data_uni;
+
+  // Initial maximum number of bidirectional streams the peer may initiate.
+  IntegerParameter initial_max_streams_bidi;
+
+  // Initial maximum number of unidirectional streams the peer may initiate.
+  IntegerParameter initial_max_streams_uni;
+
+  // Exponent used to decode the ACK Delay field in ACK frames.
+  IntegerParameter ack_delay_exponent;
+
+  // Maximum amount of time in milliseconds by which the endpoint will
+  // delay sending acknowledgments.
+  IntegerParameter max_ack_delay;
+
+  // Minimum amount of time in microseconds by which the endpoint will
+  // delay sending acknowledgments. Used to enable sender control of ack delay.
+  IntegerParameter min_ack_delay_us;
+
+  // Indicates lack of support for connection migration.
+  bool disable_active_migration;
+
+  // Used to effect a change in server address at the end of the handshake.
+  std::unique_ptr<PreferredAddress> preferred_address;
+
+  // Maximum number of connection IDs from the peer that an endpoint is willing
+  // to store.
+  IntegerParameter active_connection_id_limit;
+
+  // The value that the endpoint included in the Source Connection ID field of
+  // the first Initial packet it sent.
+  absl::optional<QuicConnectionId> initial_source_connection_id;
+
+  // The value that the server included in the Source Connection ID field of a
+  // Retry packet it sent.
+  absl::optional<QuicConnectionId> retry_source_connection_id;
+
+  // Indicates support for the DATAGRAM frame and the maximum frame size that
+  // the sender accepts. See draft-ietf-quic-datagram.
+  IntegerParameter max_datagram_frame_size;
+
+  // Google-specific transport parameter that carries an estimate of the
+  // initial round-trip time in microseconds.
+  IntegerParameter initial_round_trip_time_us;
+
+  // Google-specific connection options.
+  absl::optional<QuicTagVector> google_connection_options;
+
+  // Validates whether transport parameters are valid according to
+  // the specification. If the transport parameters are not valid, this method
+  // will write a human-readable error message to |error_details|.
+  bool AreValid(std::string* error_details) const;
+
+  // Custom parameters that may be specific to application protocol.
+  ParameterMap custom_parameters;
+
+  // Allows easily logging transport parameters.
+  std::string ToString() const;
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const TransportParameters& params);
+};
+
+// Serializes a TransportParameters struct into the format for sending it in a
+// TLS extension. The serialized bytes are written to |*out|. Returns if the
+// parameters are valid and serialization succeeded.
+QUIC_EXPORT_PRIVATE bool SerializeTransportParameters(
+    ParsedQuicVersion version,
+    const TransportParameters& in,
+    std::vector<uint8_t>* out);
+
+// Parses bytes from the quic_transport_parameters TLS extension and writes the
+// parsed parameters into |*out|. Input is read from |in| for |in_len| bytes.
+// |perspective| indicates whether the input came from a client or a server.
+// This method returns true if the input was successfully parsed.
+// On failure, this method will write a human-readable error message to
+// |error_details|.
+QUIC_EXPORT_PRIVATE bool ParseTransportParameters(ParsedQuicVersion version,
+                                                  Perspective perspective,
+                                                  const uint8_t* in,
+                                                  size_t in_len,
+                                                  TransportParameters* out,
+                                                  std::string* error_details);
+
+// Serializes |in| and |application_data| in a deterministic format so that
+// multiple calls to SerializeTransportParametersForTicket with the same inputs
+// will generate the same output, and if the inputs differ, then the output will
+// differ. The output of this function is used by the server in
+// SSL_set_quic_early_data_context to determine whether early data should be
+// accepted: Early data will only be accepted if the inputs to this function
+// match what they were on the connection that issued an early data capable
+// ticket.
+QUIC_EXPORT_PRIVATE bool SerializeTransportParametersForTicket(
+    const TransportParameters& in,
+    const std::vector<uint8_t>& application_data,
+    std::vector<uint8_t>* out);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
diff --git a/quiche/quic/core/crypto/transport_parameters_test.cc b/quiche/quic/core/crypto/transport_parameters_test.cc
new file mode 100644
index 0000000..fea6608
--- /dev/null
+++ b/quiche/quic/core/crypto/transport_parameters_test.cc
@@ -0,0 +1,1131 @@
+// Copyright (c) 2018 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 "quiche/quic/core/crypto/transport_parameters.h"
+
+#include <cstring>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+const QuicVersionLabel kFakeVersionLabel = 0x01234567;
+const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
+const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
+const uint64_t kFakeInitialMaxData = 101;
+const uint64_t kFakeInitialMaxStreamDataBidiLocal = 2001;
+const uint64_t kFakeInitialMaxStreamDataBidiRemote = 2002;
+const uint64_t kFakeInitialMaxStreamDataUni = 3000;
+const uint64_t kFakeInitialMaxStreamsBidi = 21;
+const uint64_t kFakeInitialMaxStreamsUni = 22;
+const bool kFakeDisableMigration = true;
+const uint64_t kFakeInitialRoundTripTime = 53;
+const uint8_t kFakePreferredStatelessResetTokenData[16] = {
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
+
+const auto kCustomParameter1 =
+    static_cast<TransportParameters::TransportParameterId>(0xffcd);
+const char* kCustomParameter1Value = "foo";
+const auto kCustomParameter2 =
+    static_cast<TransportParameters::TransportParameterId>(0xff34);
+const char* kCustomParameter2Value = "bar";
+
+QuicConnectionId CreateFakeOriginalDestinationConnectionId() {
+  return TestConnectionId(0x1337);
+}
+
+QuicConnectionId CreateFakeInitialSourceConnectionId() {
+  return TestConnectionId(0x2345);
+}
+
+QuicConnectionId CreateFakeRetrySourceConnectionId() {
+  return TestConnectionId(0x9876);
+}
+
+QuicConnectionId CreateFakePreferredConnectionId() {
+  return TestConnectionId(0xBEEF);
+}
+
+std::vector<uint8_t> CreateFakePreferredStatelessResetToken() {
+  return std::vector<uint8_t>(
+      kFakePreferredStatelessResetTokenData,
+      kFakePreferredStatelessResetTokenData +
+          sizeof(kFakePreferredStatelessResetTokenData));
+}
+
+QuicSocketAddress CreateFakeV4SocketAddress() {
+  QuicIpAddress ipv4_address;
+  if (!ipv4_address.FromString("65.66.67.68")) {  // 0x41, 0x42, 0x43, 0x44
+    QUIC_LOG(FATAL) << "Failed to create IPv4 address";
+    return QuicSocketAddress();
+  }
+  return QuicSocketAddress(ipv4_address, 0x4884);
+}
+
+QuicSocketAddress CreateFakeV6SocketAddress() {
+  QuicIpAddress ipv6_address;
+  if (!ipv6_address.FromString("6061:6263:6465:6667:6869:6A6B:6C6D:6E6F")) {
+    QUIC_LOG(FATAL) << "Failed to create IPv6 address";
+    return QuicSocketAddress();
+  }
+  return QuicSocketAddress(ipv6_address, 0x6336);
+}
+
+std::unique_ptr<TransportParameters::PreferredAddress>
+CreateFakePreferredAddress() {
+  TransportParameters::PreferredAddress preferred_address;
+  preferred_address.ipv4_socket_address = CreateFakeV4SocketAddress();
+  preferred_address.ipv6_socket_address = CreateFakeV6SocketAddress();
+  preferred_address.connection_id = CreateFakePreferredConnectionId();
+  preferred_address.stateless_reset_token =
+      CreateFakePreferredStatelessResetToken();
+  return std::make_unique<TransportParameters::PreferredAddress>(
+      preferred_address);
+}
+
+TransportParameters::LegacyVersionInformation
+CreateFakeLegacyVersionInformationClient() {
+  TransportParameters::LegacyVersionInformation legacy_version_information;
+  legacy_version_information.version = kFakeVersionLabel;
+  return legacy_version_information;
+}
+
+TransportParameters::LegacyVersionInformation
+CreateFakeLegacyVersionInformationServer() {
+  TransportParameters::LegacyVersionInformation legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
+  return legacy_version_information;
+}
+
+TransportParameters::VersionInformation CreateFakeVersionInformation() {
+  TransportParameters::VersionInformation version_information;
+  version_information.chosen_version = kFakeVersionLabel;
+  version_information.other_versions.push_back(kFakeVersionLabel);
+  version_information.other_versions.push_back(kFakeVersionLabel2);
+  return version_information;
+}
+
+QuicTagVector CreateFakeGoogleConnectionOptions() {
+  return {kALPN, MakeQuicTag('E', 'F', 'G', 0x00),
+          MakeQuicTag('H', 'I', 'J', 0xff)};
+}
+
+void RemoveGreaseParameters(TransportParameters* params) {
+  std::vector<TransportParameters::TransportParameterId> grease_params;
+  for (const auto& kv : params->custom_parameters) {
+    if (kv.first % 31 == 27) {
+      grease_params.push_back(kv.first);
+    }
+  }
+  EXPECT_EQ(grease_params.size(), 1u);
+  for (TransportParameters::TransportParameterId param_id : grease_params) {
+    params->custom_parameters.erase(param_id);
+  }
+  // Remove all GREASE versions from version_information.other_versions.
+  if (params->version_information.has_value()) {
+    QuicVersionLabelVector& other_versions =
+        params->version_information.value().other_versions;
+    for (auto it = other_versions.begin(); it != other_versions.end();) {
+      if ((*it & 0x0f0f0f0f) == 0x0a0a0a0a) {
+        it = other_versions.erase(it);
+      } else {
+        ++it;
+      }
+    }
+  }
+}
+
+}  // namespace
+
+class TransportParametersTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  TransportParametersTest() : version_(GetParam()) {}
+
+  ParsedQuicVersion version_;
+};
+
+INSTANTIATE_TEST_SUITE_P(TransportParametersTests,
+                         TransportParametersTest,
+                         ::testing::ValuesIn(AllSupportedVersionsWithTls()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(TransportParametersTest, Comparator) {
+  TransportParameters orig_params;
+  TransportParameters new_params;
+  // Test comparison on primitive members.
+  orig_params.perspective = Perspective::IS_CLIENT;
+  new_params.perspective = Perspective::IS_SERVER;
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  new_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.version_information = CreateFakeVersionInformation();
+  new_params.version_information = CreateFakeVersionInformation();
+  orig_params.disable_active_migration = true;
+  new_params.disable_active_migration = true;
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on vectors.
+  orig_params.legacy_version_information.value().supported_versions.push_back(
+      kFakeVersionLabel);
+  new_params.legacy_version_information.value().supported_versions.push_back(
+      kFakeVersionLabel2);
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.legacy_version_information.value().supported_versions.pop_back();
+  new_params.legacy_version_information.value().supported_versions.push_back(
+      kFakeVersionLabel);
+  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  new_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on IntegerParameters.
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  new_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest + 1);
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on PreferredAddress
+  orig_params.preferred_address = CreateFakePreferredAddress();
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.preferred_address = CreateFakePreferredAddress();
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on CustomMap
+  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+
+  new_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+  new_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on connection IDs.
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  new_params.initial_source_connection_id = absl::nullopt;
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.initial_source_connection_id = TestConnectionId(0xbadbad);
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+}
+
+TEST_P(TransportParametersTest, CopyConstructor) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.version_information = CreateFakeVersionInformation();
+  orig_params.original_destination_connection_id =
+      CreateFakeOriginalDestinationConnectionId();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
+  orig_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal);
+  orig_params.initial_max_stream_data_bidi_remote.set_value(
+      kFakeInitialMaxStreamDataBidiRemote);
+  orig_params.initial_max_stream_data_uni.set_value(
+      kFakeInitialMaxStreamDataUni);
+  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
+  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
+  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  orig_params.disable_active_migration = kFakeDisableMigration;
+  orig_params.preferred_address = CreateFakePreferredAddress();
+  orig_params.active_connection_id_limit.set_value(
+      kActiveConnectionIdLimitForTest);
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
+  orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
+  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
+  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+
+  TransportParameters new_params(orig_params);
+  EXPECT_EQ(new_params, orig_params);
+}
+
+TEST_P(TransportParametersTest, RoundTripClient) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.version_information = CreateFakeVersionInformation();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
+  orig_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal);
+  orig_params.initial_max_stream_data_bidi_remote.set_value(
+      kFakeInitialMaxStreamDataBidiRemote);
+  orig_params.initial_max_stream_data_uni.set_value(
+      kFakeInitialMaxStreamDataUni);
+  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
+  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
+  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  orig_params.disable_active_migration = kFakeDisableMigration;
+  orig_params.active_connection_id_limit.set_value(
+      kActiveConnectionIdLimitForTest);
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
+  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
+  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                       serialized.data(), serialized.size(),
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  RemoveGreaseParameters(&new_params);
+  EXPECT_EQ(new_params, orig_params);
+}
+
+TEST_P(TransportParametersTest, RoundTripServer) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_SERVER;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationServer();
+  orig_params.version_information = CreateFakeVersionInformation();
+  orig_params.original_destination_connection_id =
+      CreateFakeOriginalDestinationConnectionId();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
+  orig_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal);
+  orig_params.initial_max_stream_data_bidi_remote.set_value(
+      kFakeInitialMaxStreamDataBidiRemote);
+  orig_params.initial_max_stream_data_uni.set_value(
+      kFakeInitialMaxStreamDataUni);
+  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
+  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
+  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  orig_params.disable_active_migration = kFakeDisableMigration;
+  orig_params.preferred_address = CreateFakePreferredAddress();
+  orig_params.active_connection_id_limit.set_value(
+      kActiveConnectionIdLimitForTest);
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
+  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
+                                       serialized.data(), serialized.size(),
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  RemoveGreaseParameters(&new_params);
+  EXPECT_EQ(new_params, orig_params);
+}
+
+TEST_P(TransportParametersTest, AreValid) {
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+  }
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_idle_timeout_ms.set_value(601000);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+  }
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_udp_payload_size.set_value(1200);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_udp_payload_size.set_value(65535);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_udp_payload_size.set_value(9999999);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_udp_payload_size.set_value(0);
+    error_details = "";
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client max_udp_payload_size 0 "
+              "(Invalid)]");
+    params.max_udp_payload_size.set_value(1199);
+    error_details = "";
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client max_udp_payload_size 1199 "
+              "(Invalid)]");
+  }
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.ack_delay_exponent.set_value(0);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.ack_delay_exponent.set_value(20);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.ack_delay_exponent.set_value(21);
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client ack_delay_exponent 21 "
+              "(Invalid)]");
+  }
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.active_connection_id_limit.set_value(2);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.active_connection_id_limit.set_value(999999);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.active_connection_id_limit.set_value(1);
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client active_connection_id_limit"
+              " 1 (Invalid)]");
+    params.active_connection_id_limit.set_value(0);
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client active_connection_id_limit"
+              " 0 (Invalid)]");
+  }
+}
+
+TEST_P(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+
+  std::vector<uint8_t> out;
+  bool ok = true;
+  EXPECT_QUIC_BUG(
+      ok = SerializeTransportParameters(version_, orig_params, &out),
+      "Not serializing invalid transport parameters: Client cannot send "
+      "stateless reset token");
+  EXPECT_FALSE(ok);
+}
+
+TEST_P(TransportParametersTest, ParseClientParams) {
+  // clang-format off
+  const uint8_t kClientParams[] = {
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // initial_max_data
+      0x04,  // parameter id
+      0x02,  // length
+      0x40, 0x65,  // value
+      // initial_max_stream_data_bidi_local
+      0x05,  // parameter id
+      0x02,  // length
+      0x47, 0xD1,  // value
+      // initial_max_stream_data_bidi_remote
+      0x06,  // parameter id
+      0x02,  // length
+      0x47, 0xD2,  // value
+      // initial_max_stream_data_uni
+      0x07,  // parameter id
+      0x02,  // length
+      0x4B, 0xB8,  // value
+      // initial_max_streams_bidi
+      0x08,  // parameter id
+      0x01,  // length
+      0x15,  // value
+      // initial_max_streams_uni
+      0x09,  // parameter id
+      0x01,  // length
+      0x16,  // value
+      // ack_delay_exponent
+      0x0a,  // parameter id
+      0x01,  // length
+      0x0a,  // value
+      // max_ack_delay
+      0x0b,  // parameter id
+      0x01,  // length
+      0x33,  // value
+      // min_ack_delay_us
+      0x80, 0x00, 0xde, 0x1a,  // parameter id
+      0x02,  // length
+      0x43, 0xe8,  // value
+      // disable_active_migration
+      0x0c,  // parameter id
+      0x00,  // length
+      // active_connection_id_limit
+      0x0e,  // parameter id
+      0x01,  // length
+      0x34,  // value
+      // initial_source_connection_id
+      0x0f,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
+      // initial_round_trip_time_us
+      0x71, 0x27,  // parameter id
+      0x01,  // length
+      0x35,  // value
+      // google_connection_options
+      0x71, 0x28,  // parameter id
+      0x0c,  // length
+      'A', 'L', 'P', 'N',  // value
+      'E', 'F', 'G', 0x00,
+      'H', 'I', 'J', 0xff,
+      // Google version extension
+      0x80, 0x00, 0x47, 0x52,  // parameter id
+      0x04,  // length
+      0x01, 0x23, 0x45, 0x67,  // initial version
+      // version_information
+      0x80, 0xFF, 0x73, 0xDB,  // parameter id
+      0x0C,  // length
+      0x01, 0x23, 0x45, 0x67,  // chosen version
+      0x01, 0x23, 0x45, 0x67,  // other version 1
+      0x89, 0xab, 0xcd, 0xef,  // other version 2
+  };
+  // clang-format on
+  const uint8_t* client_params =
+      reinterpret_cast<const uint8_t*>(kClientParams);
+  size_t client_params_length = ABSL_ARRAYSIZE(kClientParams);
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                       client_params, client_params_length,
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  EXPECT_EQ(Perspective::IS_CLIENT, new_params.perspective);
+  ASSERT_TRUE(new_params.legacy_version_information.has_value());
+  EXPECT_EQ(kFakeVersionLabel,
+            new_params.legacy_version_information.value().version);
+  EXPECT_TRUE(
+      new_params.legacy_version_information.value().supported_versions.empty());
+  ASSERT_TRUE(new_params.version_information.has_value());
+  EXPECT_EQ(new_params.version_information.value(),
+            CreateFakeVersionInformation());
+  EXPECT_FALSE(new_params.original_destination_connection_id.has_value());
+  EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
+            new_params.max_idle_timeout_ms.value());
+  EXPECT_TRUE(new_params.stateless_reset_token.empty());
+  EXPECT_EQ(kMaxPacketSizeForTest, new_params.max_udp_payload_size.value());
+  EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
+            new_params.initial_max_stream_data_bidi_local.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
+            new_params.initial_max_stream_data_bidi_remote.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataUni,
+            new_params.initial_max_stream_data_uni.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsBidi,
+            new_params.initial_max_streams_bidi.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsUni,
+            new_params.initial_max_streams_uni.value());
+  EXPECT_EQ(kAckDelayExponentForTest, new_params.ack_delay_exponent.value());
+  EXPECT_EQ(kMaxAckDelayForTest, new_params.max_ack_delay.value());
+  EXPECT_EQ(kMinAckDelayUsForTest, new_params.min_ack_delay_us.value());
+  EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
+  EXPECT_EQ(kActiveConnectionIdLimitForTest,
+            new_params.active_connection_id_limit.value());
+  ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
+  EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
+            new_params.initial_source_connection_id.value());
+  EXPECT_FALSE(new_params.retry_source_connection_id.has_value());
+  EXPECT_EQ(kFakeInitialRoundTripTime,
+            new_params.initial_round_trip_time_us.value());
+  ASSERT_TRUE(new_params.google_connection_options.has_value());
+  EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
+            new_params.google_connection_options.value());
+}
+
+TEST_P(TransportParametersTest,
+       ParseClientParamsFailsWithFullStatelessResetToken) {
+  // clang-format off
+  const uint8_t kClientParamsWithFullToken[] = {
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x10,  // length
+      0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+      0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // initial_max_data
+      0x04,  // parameter id
+      0x02,  // length
+      0x40, 0x65,  // value
+  };
+  // clang-format on
+  const uint8_t* client_params =
+      reinterpret_cast<const uint8_t*>(kClientParamsWithFullToken);
+  size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithFullToken);
+  TransportParameters out_params;
+  std::string error_details;
+  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                        client_params, client_params_length,
+                                        &out_params, &error_details));
+  EXPECT_EQ(error_details, "Client cannot send stateless reset token");
+}
+
+TEST_P(TransportParametersTest,
+       ParseClientParamsFailsWithEmptyStatelessResetToken) {
+  // clang-format off
+  const uint8_t kClientParamsWithEmptyToken[] = {
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x00,  // length
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // initial_max_data
+      0x04,  // parameter id
+      0x02,  // length
+      0x40, 0x65,  // value
+  };
+  // clang-format on
+  const uint8_t* client_params =
+      reinterpret_cast<const uint8_t*>(kClientParamsWithEmptyToken);
+  size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithEmptyToken);
+  TransportParameters out_params;
+  std::string error_details;
+  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                        client_params, client_params_length,
+                                        &out_params, &error_details));
+  EXPECT_EQ(error_details,
+            "Received stateless_reset_token of invalid length 0");
+}
+
+TEST_P(TransportParametersTest, ParseClientParametersRepeated) {
+  // clang-format off
+  const uint8_t kClientParamsRepeated[] = {
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // max_idle_timeout (repeated)
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+  };
+  // clang-format on
+  const uint8_t* client_params =
+      reinterpret_cast<const uint8_t*>(kClientParamsRepeated);
+  size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsRepeated);
+  TransportParameters out_params;
+  std::string error_details;
+  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                        client_params, client_params_length,
+                                        &out_params, &error_details));
+  EXPECT_EQ(error_details, "Received a second max_idle_timeout");
+}
+
+TEST_P(TransportParametersTest, ParseServerParams) {
+  // clang-format off
+  const uint8_t kServerParams[] = {
+      // original_destination_connection_id
+      0x00,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x10,  // length
+      0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+      0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // initial_max_data
+      0x04,  // parameter id
+      0x02,  // length
+      0x40, 0x65,  // value
+      // initial_max_stream_data_bidi_local
+      0x05,  // parameter id
+      0x02,  // length
+      0x47, 0xD1,  // value
+      // initial_max_stream_data_bidi_remote
+      0x06,  // parameter id
+      0x02,  // length
+      0x47, 0xD2,  // value
+      // initial_max_stream_data_uni
+      0x07,  // parameter id
+      0x02,  // length
+      0x4B, 0xB8,  // value
+      // initial_max_streams_bidi
+      0x08,  // parameter id
+      0x01,  // length
+      0x15,  // value
+      // initial_max_streams_uni
+      0x09,  // parameter id
+      0x01,  // length
+      0x16,  // value
+      // ack_delay_exponent
+      0x0a,  // parameter id
+      0x01,  // length
+      0x0a,  // value
+      // max_ack_delay
+      0x0b,  // parameter id
+      0x01,  // length
+      0x33,  // value
+      // min_ack_delay_us
+      0x80, 0x00, 0xde, 0x1a,  // parameter id
+      0x02,  // length
+      0x43, 0xe8,  // value
+      // disable_active_migration
+      0x0c,  // parameter id
+      0x00,  // length
+      // preferred_address
+      0x0d,  // parameter id
+      0x31,  // length
+      0x41, 0x42, 0x43, 0x44,  // IPv4 address
+      0x48, 0x84,  // IPv4 port
+      0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,  // IPv6 address
+      0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+      0x63, 0x36,  // IPv6 port
+      0x08,        // connection ID length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF,  // connection ID
+      0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  // stateless reset token
+      0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+      // active_connection_id_limit
+      0x0e,  // parameter id
+      0x01,  // length
+      0x34,  // value
+      // initial_source_connection_id
+      0x0f,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
+      // retry_source_connection_id
+      0x10,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x76,
+      // google_connection_options
+      0x71, 0x28,  // parameter id
+      0x0c,  // length
+      'A', 'L', 'P', 'N',  // value
+      'E', 'F', 'G', 0x00,
+      'H', 'I', 'J', 0xff,
+      // Google version extension
+      0x80, 0x00, 0x47, 0x52,  // parameter id
+      0x0d,  // length
+      0x01, 0x23, 0x45, 0x67,  // negotiated_version
+      0x08,  // length of supported versions array
+      0x01, 0x23, 0x45, 0x67,
+      0x89, 0xab, 0xcd, 0xef,
+      // version_information
+      0x80, 0xFF, 0x73, 0xDB,  // parameter id
+      0x0C,  // length
+      0x01, 0x23, 0x45, 0x67,  // chosen version
+      0x01, 0x23, 0x45, 0x67,  // other version 1
+      0x89, 0xab, 0xcd, 0xef,  // other version 2
+  };
+  // clang-format on
+  const uint8_t* server_params =
+      reinterpret_cast<const uint8_t*>(kServerParams);
+  size_t server_params_length = ABSL_ARRAYSIZE(kServerParams);
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
+                                       server_params, server_params_length,
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  EXPECT_EQ(Perspective::IS_SERVER, new_params.perspective);
+  ASSERT_TRUE(new_params.legacy_version_information.has_value());
+  EXPECT_EQ(kFakeVersionLabel,
+            new_params.legacy_version_information.value().version);
+  ASSERT_EQ(
+      2u,
+      new_params.legacy_version_information.value().supported_versions.size());
+  EXPECT_EQ(
+      kFakeVersionLabel,
+      new_params.legacy_version_information.value().supported_versions[0]);
+  EXPECT_EQ(
+      kFakeVersionLabel2,
+      new_params.legacy_version_information.value().supported_versions[1]);
+  ASSERT_TRUE(new_params.version_information.has_value());
+  EXPECT_EQ(new_params.version_information.value(),
+            CreateFakeVersionInformation());
+  ASSERT_TRUE(new_params.original_destination_connection_id.has_value());
+  EXPECT_EQ(CreateFakeOriginalDestinationConnectionId(),
+            new_params.original_destination_connection_id.value());
+  EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
+            new_params.max_idle_timeout_ms.value());
+  EXPECT_EQ(CreateStatelessResetTokenForTest(),
+            new_params.stateless_reset_token);
+  EXPECT_EQ(kMaxPacketSizeForTest, new_params.max_udp_payload_size.value());
+  EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
+            new_params.initial_max_stream_data_bidi_local.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
+            new_params.initial_max_stream_data_bidi_remote.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataUni,
+            new_params.initial_max_stream_data_uni.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsBidi,
+            new_params.initial_max_streams_bidi.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsUni,
+            new_params.initial_max_streams_uni.value());
+  EXPECT_EQ(kAckDelayExponentForTest, new_params.ack_delay_exponent.value());
+  EXPECT_EQ(kMaxAckDelayForTest, new_params.max_ack_delay.value());
+  EXPECT_EQ(kMinAckDelayUsForTest, new_params.min_ack_delay_us.value());
+  EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
+  ASSERT_NE(nullptr, new_params.preferred_address.get());
+  EXPECT_EQ(CreateFakeV4SocketAddress(),
+            new_params.preferred_address->ipv4_socket_address);
+  EXPECT_EQ(CreateFakeV6SocketAddress(),
+            new_params.preferred_address->ipv6_socket_address);
+  EXPECT_EQ(CreateFakePreferredConnectionId(),
+            new_params.preferred_address->connection_id);
+  EXPECT_EQ(CreateFakePreferredStatelessResetToken(),
+            new_params.preferred_address->stateless_reset_token);
+  EXPECT_EQ(kActiveConnectionIdLimitForTest,
+            new_params.active_connection_id_limit.value());
+  ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
+  EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
+            new_params.initial_source_connection_id.value());
+  ASSERT_TRUE(new_params.retry_source_connection_id.has_value());
+  EXPECT_EQ(CreateFakeRetrySourceConnectionId(),
+            new_params.retry_source_connection_id.value());
+  ASSERT_TRUE(new_params.google_connection_options.has_value());
+  EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
+            new_params.google_connection_options.value());
+}
+
+TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
+  // clang-format off
+  const uint8_t kServerParamsRepeated[] = {
+      // original_destination_connection_id
+      0x00,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x10,  // length
+      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+      0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+      // max_idle_timeout (repeated)
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+  };
+  // clang-format on
+  const uint8_t* server_params =
+      reinterpret_cast<const uint8_t*>(kServerParamsRepeated);
+  size_t server_params_length = ABSL_ARRAYSIZE(kServerParamsRepeated);
+  TransportParameters out_params;
+  std::string error_details;
+  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_SERVER,
+                                        server_params, server_params_length,
+                                        &out_params, &error_details));
+  EXPECT_EQ(error_details, "Received a second max_idle_timeout");
+}
+
+TEST_P(TransportParametersTest,
+       ParseServerParametersEmptyOriginalConnectionId) {
+  // clang-format off
+  const uint8_t kServerParamsEmptyOriginalConnectionId[] = {
+      // original_destination_connection_id
+      0x00,  // parameter id
+      0x00,  // length
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x10,  // length
+      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+      0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+  };
+  // clang-format on
+  const uint8_t* server_params =
+      reinterpret_cast<const uint8_t*>(kServerParamsEmptyOriginalConnectionId);
+  size_t server_params_length =
+      ABSL_ARRAYSIZE(kServerParamsEmptyOriginalConnectionId);
+  TransportParameters out_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
+                                       server_params, server_params_length,
+                                       &out_params, &error_details))
+      << error_details;
+  ASSERT_TRUE(out_params.original_destination_connection_id.has_value());
+  EXPECT_EQ(out_params.original_destination_connection_id.value(),
+            EmptyQuicConnectionId());
+}
+
+TEST_P(TransportParametersTest, VeryLongCustomParameter) {
+  // Ensure we can handle a 70KB custom parameter on both send and receive.
+  std::string custom_value(70000, '?');
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.custom_parameters[kCustomParameter1] = custom_value;
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                       serialized.data(), serialized.size(),
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  RemoveGreaseParameters(&new_params);
+  EXPECT_EQ(new_params, orig_params);
+}
+
+TEST_P(TransportParametersTest, SerializationOrderIsRandom) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
+  orig_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal);
+  orig_params.initial_max_stream_data_bidi_remote.set_value(
+      kFakeInitialMaxStreamDataBidiRemote);
+  orig_params.initial_max_stream_data_uni.set_value(
+      kFakeInitialMaxStreamDataUni);
+  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
+  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
+  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  orig_params.disable_active_migration = kFakeDisableMigration;
+  orig_params.active_connection_id_limit.set_value(
+      kActiveConnectionIdLimitForTest);
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
+  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
+  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+
+  std::vector<uint8_t> first_serialized;
+  ASSERT_TRUE(
+      SerializeTransportParameters(version_, orig_params, &first_serialized));
+  // Test that a subsequent serialization is different from the first.
+  // Run in a loop to avoid a failure in the unlikely event that randomization
+  // produces the same result multiple times.
+  for (int i = 0; i < 1000; i++) {
+    std::vector<uint8_t> serialized;
+    ASSERT_TRUE(
+        SerializeTransportParameters(version_, orig_params, &serialized));
+    if (serialized != first_serialized) {
+      return;
+    }
+  }
+}
+
+class TransportParametersTicketSerializationTest : public QuicTest {
+ protected:
+  void SetUp() override {
+    original_params_.perspective = Perspective::IS_SERVER;
+    original_params_.legacy_version_information =
+        CreateFakeLegacyVersionInformationServer();
+    original_params_.original_destination_connection_id =
+        CreateFakeOriginalDestinationConnectionId();
+    original_params_.max_idle_timeout_ms.set_value(
+        kFakeIdleTimeoutMilliseconds);
+    original_params_.stateless_reset_token = CreateStatelessResetTokenForTest();
+    original_params_.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+    original_params_.initial_max_data.set_value(kFakeInitialMaxData);
+    original_params_.initial_max_stream_data_bidi_local.set_value(
+        kFakeInitialMaxStreamDataBidiLocal);
+    original_params_.initial_max_stream_data_bidi_remote.set_value(
+        kFakeInitialMaxStreamDataBidiRemote);
+    original_params_.initial_max_stream_data_uni.set_value(
+        kFakeInitialMaxStreamDataUni);
+    original_params_.initial_max_streams_bidi.set_value(
+        kFakeInitialMaxStreamsBidi);
+    original_params_.initial_max_streams_uni.set_value(
+        kFakeInitialMaxStreamsUni);
+    original_params_.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+    original_params_.max_ack_delay.set_value(kMaxAckDelayForTest);
+    original_params_.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+    original_params_.disable_active_migration = kFakeDisableMigration;
+    original_params_.preferred_address = CreateFakePreferredAddress();
+    original_params_.active_connection_id_limit.set_value(
+        kActiveConnectionIdLimitForTest);
+    original_params_.initial_source_connection_id =
+        CreateFakeInitialSourceConnectionId();
+    original_params_.retry_source_connection_id =
+        CreateFakeRetrySourceConnectionId();
+    original_params_.google_connection_options =
+        CreateFakeGoogleConnectionOptions();
+
+    ASSERT_TRUE(SerializeTransportParametersForTicket(
+        original_params_, application_state_, &original_serialized_params_));
+  }
+
+  TransportParameters original_params_;
+  std::vector<uint8_t> application_state_ = {0, 1};
+  std::vector<uint8_t> original_serialized_params_;
+};
+
+TEST_F(TransportParametersTicketSerializationTest,
+       StatelessResetTokenDoesntChangeOutput) {
+  // Test that changing the stateless reset token doesn't change the ticket
+  // serialization.
+  TransportParameters new_params = original_params_;
+  new_params.stateless_reset_token = CreateFakePreferredStatelessResetToken();
+  EXPECT_NE(new_params, original_params_);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParametersForTicket(
+      new_params, application_state_, &serialized));
+  EXPECT_EQ(original_serialized_params_, serialized);
+}
+
+TEST_F(TransportParametersTicketSerializationTest,
+       ConnectionIDDoesntChangeOutput) {
+  // Changing original destination CID doesn't change serialization.
+  TransportParameters new_params = original_params_;
+  new_params.original_destination_connection_id = TestConnectionId(0xCAFE);
+  EXPECT_NE(new_params, original_params_);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParametersForTicket(
+      new_params, application_state_, &serialized));
+  EXPECT_EQ(original_serialized_params_, serialized);
+}
+
+TEST_F(TransportParametersTicketSerializationTest, StreamLimitChangesOutput) {
+  // Changing a stream limit does change the serialization.
+  TransportParameters new_params = original_params_;
+  new_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal + 1);
+  EXPECT_NE(new_params, original_params_);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParametersForTicket(
+      new_params, application_state_, &serialized));
+  EXPECT_NE(original_serialized_params_, serialized);
+}
+
+TEST_F(TransportParametersTicketSerializationTest,
+       ApplicationStateChangesOutput) {
+  // Changing the application state changes the serialization.
+  std::vector<uint8_t> new_application_state = {0};
+  EXPECT_NE(new_application_state, application_state_);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParametersForTicket(
+      original_params_, new_application_state, &serialized));
+  EXPECT_NE(original_serialized_params_, serialized);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc
new file mode 100644
index 0000000..1353137
--- /dev/null
+++ b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc
@@ -0,0 +1,229 @@
+// Copyright 2020 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 "quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
+
+#include <cstdint>
+#include <memory>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_replace.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace {
+
+constexpr size_t kFingerprintLength = SHA256_DIGEST_LENGTH * 3 - 1;
+
+// Assumes that the character is normalized to lowercase beforehand.
+bool IsNormalizedHexDigit(char c) {
+  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
+}
+
+void NormalizeFingerprint(CertificateFingerprint& fingerprint) {
+  fingerprint.fingerprint =
+      quiche::QuicheTextUtils::ToLower(fingerprint.fingerprint);
+}
+
+}  // namespace
+
+constexpr char CertificateFingerprint::kSha256[];
+constexpr char WebTransportHash::kSha256[];
+
+ProofVerifyDetails* WebTransportFingerprintProofVerifier::Details::Clone()
+    const {
+  return new Details(*this);
+}
+
+WebTransportFingerprintProofVerifier::WebTransportFingerprintProofVerifier(
+    const QuicClock* clock, int max_validity_days)
+    : clock_(clock),
+      max_validity_days_(max_validity_days),
+      // Add an extra second to max validity to accomodate various edge cases.
+      max_validity_(
+          QuicTime::Delta::FromSeconds(max_validity_days * 86400 + 1)) {}
+
+bool WebTransportFingerprintProofVerifier::AddFingerprint(
+    CertificateFingerprint fingerprint) {
+  NormalizeFingerprint(fingerprint);
+  if (fingerprint.algorithm != CertificateFingerprint::kSha256) {
+    QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
+    return false;
+  }
+  if (fingerprint.fingerprint.size() != kFingerprintLength) {
+    QUIC_DLOG(WARNING) << "Invalid fingerprint length";
+    return false;
+  }
+  for (size_t i = 0; i < fingerprint.fingerprint.size(); i++) {
+    char current = fingerprint.fingerprint[i];
+    if (i % 3 == 2) {
+      if (current != ':') {
+        QUIC_DLOG(WARNING)
+            << "Missing colon separator between the bytes of the hash";
+        return false;
+      }
+    } else {
+      if (!IsNormalizedHexDigit(current)) {
+        QUIC_DLOG(WARNING) << "Fingerprint must be in hexadecimal";
+        return false;
+      }
+    }
+  }
+
+  std::string normalized =
+      absl::StrReplaceAll(fingerprint.fingerprint, {{":", ""}});
+  hashes_.push_back(WebTransportHash{fingerprint.algorithm,
+                                     absl::HexStringToBytes(normalized)});
+  return true;
+}
+
+bool WebTransportFingerprintProofVerifier::AddFingerprint(
+    WebTransportHash hash) {
+  if (hash.algorithm != CertificateFingerprint::kSha256) {
+    QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
+    return false;
+  }
+  if (hash.value.size() != SHA256_DIGEST_LENGTH) {
+    QUIC_DLOG(WARNING) << "Invalid fingerprint length";
+    return false;
+  }
+  hashes_.push_back(std::move(hash));
+  return true;
+}
+
+QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyProof(
+    const std::string& /*hostname*/, const uint16_t /*port*/,
+    const std::string& /*server_config*/,
+    QuicTransportVersion /*transport_version*/, absl::string_view /*chlo_hash*/,
+    const std::vector<std::string>& /*certs*/, const std::string& /*cert_sct*/,
+    const std::string& /*signature*/, const ProofVerifyContext* /*context*/,
+    std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
+    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
+  *error_details =
+      "QUIC crypto certificate verification is not supported in "
+      "WebTransportFingerprintProofVerifier";
+  QUIC_BUG(quic_bug_10879_1) << *error_details;
+  *details = std::make_unique<Details>(Status::kInternalError);
+  return QUIC_FAILURE;
+}
+
+QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain(
+    const std::string& /*hostname*/, const uint16_t /*port*/,
+    const std::vector<std::string>& certs, const std::string& /*ocsp_response*/,
+    const std::string& /*cert_sct*/, const ProofVerifyContext* /*context*/,
+    std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
+    uint8_t* /*out_alert*/,
+    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
+  if (certs.empty()) {
+    *details = std::make_unique<Details>(Status::kInternalError);
+    *error_details = "No certificates provided";
+    return QUIC_FAILURE;
+  }
+
+  if (!HasKnownFingerprint(certs[0])) {
+    *details = std::make_unique<Details>(Status::kUnknownFingerprint);
+    *error_details = "Certificate does not match any fingerprint";
+    return QUIC_FAILURE;
+  }
+
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(certs[0]);
+  if (view == nullptr) {
+    *details = std::make_unique<Details>(Status::kCertificateParseFailure);
+    *error_details = "Failed to parse the certificate";
+    return QUIC_FAILURE;
+  }
+
+  if (!HasValidExpiry(*view)) {
+    *details = std::make_unique<Details>(Status::kExpiryTooLong);
+    *error_details =
+        absl::StrCat("Certificate expiry exceeds the configured limit of ",
+                     max_validity_days_, " days");
+    return QUIC_FAILURE;
+  }
+
+  if (!IsWithinValidityPeriod(*view)) {
+    *details = std::make_unique<Details>(Status::kExpired);
+    *error_details =
+        "Certificate has expired or has validity listed in the future";
+    return QUIC_FAILURE;
+  }
+
+  if (!IsKeyTypeAllowedByPolicy(*view)) {
+    *details = std::make_unique<Details>(Status::kDisallowedKeyAlgorithm);
+    *error_details =
+        absl::StrCat("Certificate uses a disallowed public key type (",
+                     PublicKeyTypeToString(view->public_key_type()), ")");
+    return QUIC_FAILURE;
+  }
+
+  *details = std::make_unique<Details>(Status::kValidCertificate);
+  return QUIC_SUCCESS;
+}
+
+std::unique_ptr<ProofVerifyContext>
+WebTransportFingerprintProofVerifier::CreateDefaultContext() {
+  return nullptr;
+}
+
+bool WebTransportFingerprintProofVerifier::HasKnownFingerprint(
+    absl::string_view der_certificate) {
+  // https://w3c.github.io/webtransport/#verify-a-certificate-hash
+  const std::string hash = RawSha256(der_certificate);
+  for (const WebTransportHash& reference : hashes_) {
+    if (reference.algorithm != WebTransportHash::kSha256) {
+      QUIC_BUG(quic_bug_10879_2) << "Unexpected non-SHA-256 hash";
+      continue;
+    }
+    if (hash == reference.value) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool WebTransportFingerprintProofVerifier::HasValidExpiry(
+    const CertificateView& certificate) {
+  if (!certificate.validity_start().IsBefore(certificate.validity_end())) {
+    return false;
+  }
+
+  const QuicTime::Delta duration_seconds =
+      certificate.validity_end() - certificate.validity_start();
+  return duration_seconds <= max_validity_;
+}
+
+bool WebTransportFingerprintProofVerifier::IsWithinValidityPeriod(
+    const CertificateView& certificate) {
+  QuicWallTime now = clock_->WallNow();
+  return now.IsAfter(certificate.validity_start()) &&
+         now.IsBefore(certificate.validity_end());
+}
+
+bool WebTransportFingerprintProofVerifier::IsKeyTypeAllowedByPolicy(
+    const CertificateView& certificate) {
+  switch (certificate.public_key_type()) {
+    // https://github.com/w3c/webtransport/pull/375 defines P-256 as an MTI
+    // algorithm, and prohibits RSA.  We also allow P-384 and Ed25519.
+    case PublicKeyType::kP256:
+    case PublicKeyType::kP384:
+    case PublicKeyType::kEd25519:
+      return true;
+    case PublicKeyType::kRsa:
+      // TODO(b/213614428): this should be false by default.
+      return true;
+    default:
+      return false;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h
new file mode 100644
index 0000000..87ecf2a
--- /dev/null
+++ b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h
@@ -0,0 +1,135 @@
+// Copyright 2020 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_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
+#define QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
+
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Represents a fingerprint of an X.509 certificate in a format based on
+// https://w3c.github.io/webrtc-pc/#dom-rtcdtlsfingerprint.
+// TODO(vasilvv): remove this once all consumers of this API use
+// WebTransportHash.
+struct QUIC_EXPORT_PRIVATE CertificateFingerprint {
+  static constexpr char kSha256[] = "sha-256";
+
+  // An algorithm described by one of the names in
+  // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
+  std::string algorithm;
+  // Hex-encoded, colon-separated fingerprint of the certificate.  For example,
+  // "12:3d:5b:71:8c:54:df:85:7e:bd:e3:7c:66:da:f9:db:6a:94:8f:85:cb:6e:44:7f:09:3e:05:f2:dd:d4:f7:86"
+  std::string fingerprint;
+};
+
+// Represents a fingerprint of an X.509 certificate in a format based on
+// https://w3c.github.io/webtransport/#dictdef-webtransporthash.
+struct QUIC_EXPORT_PRIVATE WebTransportHash {
+  static constexpr char kSha256[] = "sha-256";
+
+  // An algorithm described by one of the names in
+  // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
+  std::string algorithm;
+  // Raw bytes of the hash.
+  std::string value;
+};
+
+// WebTransportFingerprintProofVerifier verifies the server leaf certificate
+// against a supplied list of certificate fingerprints following the procedure
+// described in the WebTransport specification.  The certificate is deemed
+// trusted if it matches a fingerprint in the list, has expiry dates that are
+// not too long and has not expired.  Only the leaf is checked, the rest of the
+// chain is ignored. Reference specification:
+// https://wicg.github.io/web-transport/#dom-quictransportconfiguration-server_certificate_fingerprints
+class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier
+    : public ProofVerifier {
+ public:
+  // Note: the entries in this list may be logged into a UMA histogram, and thus
+  // should not be renumbered.
+  enum class Status {
+    kValidCertificate = 0,
+    kUnknownFingerprint = 1,
+    kCertificateParseFailure = 2,
+    kExpiryTooLong = 3,
+    kExpired = 4,
+    kInternalError = 5,
+    kDisallowedKeyAlgorithm = 6,
+
+    kMaxValue = kDisallowedKeyAlgorithm,
+  };
+
+  class QUIC_EXPORT_PRIVATE Details : public ProofVerifyDetails {
+   public:
+    explicit Details(Status status) : status_(status) {}
+    Status status() const { return status_; }
+
+    ProofVerifyDetails* Clone() const override;
+
+   private:
+    const Status status_;
+  };
+
+  // |clock| is used to check if the certificate has expired.  It is not owned
+  // and must outlive the object.  |max_validity_days| is the maximum time for
+  // which the certificate is allowed to be valid.
+  WebTransportFingerprintProofVerifier(const QuicClock* clock,
+                                       int max_validity_days);
+
+  // Adds a certificate fingerprint to be trusted.  The fingerprints are
+  // case-insensitive and are validated internally; the function returns true if
+  // the validation passes.
+  bool AddFingerprint(CertificateFingerprint fingerprint);
+  bool AddFingerprint(WebTransportHash hash);
+
+  // ProofVerifier implementation.
+  QuicAsyncStatus VerifyProof(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::string& server_config,
+      QuicTransportVersion transport_version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& certs,
+      const std::string& cert_sct,
+      const std::string& signature,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      std::unique_ptr<ProofVerifierCallback> callback) override;
+  QuicAsyncStatus VerifyCertChain(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::vector<std::string>& certs,
+      const std::string& ocsp_response,
+      const std::string& cert_sct,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override;
+  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override;
+
+ protected:
+  virtual bool IsKeyTypeAllowedByPolicy(const CertificateView& certificate);
+
+ private:
+  bool HasKnownFingerprint(absl::string_view der_certificate);
+  bool HasValidExpiry(const CertificateView& certificate);
+  bool IsWithinValidityPeriod(const CertificateView& certificate);
+
+  const QuicClock* clock_;  // Unowned.
+  const int max_validity_days_;
+  const QuicTime::Delta max_validity_;
+  std::vector<WebTransportHash> hashes_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
diff --git a/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc
new file mode 100644
index 0000000..11c769d
--- /dev/null
+++ b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc
@@ -0,0 +1,183 @@
+// Copyright 2020 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 "quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
+
+#include <memory>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::HasSubstr;
+
+// 2020-02-01 12:35:56 UTC
+constexpr QuicTime::Delta kValidTime = QuicTime::Delta::FromSeconds(1580560556);
+
+struct VerifyResult {
+  QuicAsyncStatus status;
+  WebTransportFingerprintProofVerifier::Status detailed_status;
+  std::string error;
+};
+
+class WebTransportFingerprintProofVerifierTest : public QuicTest {
+ public:
+  WebTransportFingerprintProofVerifierTest() {
+    clock_.AdvanceTime(kValidTime);
+    verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+        &clock_, /*max_validity_days=*/365);
+    AddTestCertificate();
+  }
+
+ protected:
+  VerifyResult Verify(absl::string_view certificate) {
+    VerifyResult result;
+    std::unique_ptr<ProofVerifyDetails> details;
+    uint8_t tls_alert;
+    result.status = verifier_->VerifyCertChain(
+        /*hostname=*/"", /*port=*/0,
+        std::vector<std::string>{std::string(certificate)},
+        /*ocsp_response=*/"",
+        /*cert_sct=*/"",
+        /*context=*/nullptr, &result.error, &details, &tls_alert,
+        /*callback=*/nullptr);
+    result.detailed_status =
+        static_cast<WebTransportFingerprintProofVerifier::Details*>(
+            details.get())
+            ->status();
+    return result;
+  }
+
+  void AddTestCertificate() {
+    EXPECT_TRUE(verifier_->AddFingerprint(WebTransportHash{
+        WebTransportHash::kSha256, RawSha256(kTestCertificate)}));
+  }
+
+  MockClock clock_;
+  std::unique_ptr<WebTransportFingerprintProofVerifier> verifier_;
+};
+
+TEST_F(WebTransportFingerprintProofVerifierTest, Sha256Fingerprint) {
+  // Computed using `openssl x509 -fingerprint -sha256`.
+  EXPECT_EQ(absl::BytesToHexString(RawSha256(kTestCertificate)),
+            "f2e5465e2bf7ecd6f63066a5a37511734aa0eb7c4701"
+            "0e86d6758ed4f4fa1b0f");
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, SimpleFingerprint) {
+  VerifyResult result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_SUCCESS);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+
+  result = Verify(kWildcardCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kUnknownFingerprint);
+
+  result = Verify("Some random text");
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, Validity) {
+  // Validity periods of kTestCertificate, according to `openssl x509 -text`:
+  //     Not Before: Jan 30 18:13:59 2020 GMT
+  //     Not After : Feb  2 18:13:59 2020 GMT
+
+  // 2020-01-29 19:00:00 UTC
+  constexpr QuicTime::Delta kStartTime =
+      QuicTime::Delta::FromSeconds(1580324400);
+  clock_.Reset();
+  clock_.AdvanceTime(kStartTime);
+
+  VerifyResult result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kExpired);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400));
+  result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_SUCCESS);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(4 * 86400));
+  result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kExpired);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, MaxValidity) {
+  verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+      &clock_, /*max_validity_days=*/2);
+  AddTestCertificate();
+  VerifyResult result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kExpiryTooLong);
+  EXPECT_THAT(result.error, HasSubstr("limit of 2 days"));
+
+  // kTestCertificate is valid for exactly four days.
+  verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+      &clock_, /*max_validity_days=*/4);
+  AddTestCertificate();
+  result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_SUCCESS);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, InvalidCertificate) {
+  constexpr absl::string_view kInvalidCertificate = "Hello, world!";
+  ASSERT_TRUE(verifier_->AddFingerprint(WebTransportHash{
+      WebTransportHash::kSha256, RawSha256(kInvalidCertificate)}));
+
+  VerifyResult result = Verify(kInvalidCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(
+      result.detailed_status,
+      WebTransportFingerprintProofVerifier::Status::kCertificateParseFailure);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, AddCertificate) {
+  // Accept all-uppercase fingerprints.
+  verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+      &clock_, /*max_validity_days=*/365);
+  EXPECT_TRUE(verifier_->AddFingerprint(CertificateFingerprint{
+      CertificateFingerprint::kSha256,
+      "F2:E5:46:5E:2B:F7:EC:D6:F6:30:66:A5:A3:75:11:73:4A:A0:EB:"
+      "7C:47:01:0E:86:D6:75:8E:D4:F4:FA:1B:0F"}));
+  EXPECT_EQ(Verify(kTestCertificate).detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+
+  // Reject unknown hash algorithms.
+  EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
+      "sha-1", "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"}));
+  // Reject invalid length.
+  EXPECT_FALSE(verifier_->AddFingerprint(
+      CertificateFingerprint{CertificateFingerprint::kSha256, "00:00:00:00"}));
+  // Reject missing colons.
+  EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
+      CertificateFingerprint::kSha256,
+      "00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00."
+      "00.00.00.00.00.00.00.00.00.00.00.00.00"}));
+  // Reject non-hex symbols.
+  EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
+      CertificateFingerprint::kSha256,
+      "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:"
+      "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz"}));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_ack_frame.cc b/quiche/quic/core/frames/quic_ack_frame.cc
new file mode 100644
index 0000000..c61594b
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ack_frame.cc
@@ -0,0 +1,190 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_ack_frame.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+namespace {
+
+const QuicPacketCount kMaxPrintRange = 128;
+
+}  // namespace
+
+bool IsAwaitingPacket(const QuicAckFrame& ack_frame,
+                      QuicPacketNumber packet_number,
+                      QuicPacketNumber peer_least_packet_awaiting_ack) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  return (!peer_least_packet_awaiting_ack.IsInitialized() ||
+          packet_number >= peer_least_packet_awaiting_ack) &&
+         !ack_frame.packets.Contains(packet_number);
+}
+
+QuicAckFrame::QuicAckFrame() = default;
+
+QuicAckFrame::QuicAckFrame(const QuicAckFrame& other) = default;
+
+QuicAckFrame::~QuicAckFrame() {}
+
+std::ostream& operator<<(std::ostream& os, const QuicAckFrame& ack_frame) {
+  os << "{ largest_acked: " << LargestAcked(ack_frame)
+     << ", ack_delay_time: " << ack_frame.ack_delay_time.ToMicroseconds()
+     << ", packets: [ " << ack_frame.packets << " ]"
+     << ", received_packets: [ ";
+  for (const std::pair<QuicPacketNumber, QuicTime>& p :
+       ack_frame.received_packet_times) {
+    os << p.first << " at " << p.second.ToDebuggingValue() << " ";
+  }
+  os << " ]";
+  os << ", ecn_counters_populated: " << ack_frame.ecn_counters_populated;
+  if (ack_frame.ecn_counters_populated) {
+    os << ", ect_0_count: " << ack_frame.ect_0_count
+       << ", ect_1_count: " << ack_frame.ect_1_count
+       << ", ecn_ce_count: " << ack_frame.ecn_ce_count;
+  }
+
+  os << " }\n";
+  return os;
+}
+
+void QuicAckFrame::Clear() {
+  largest_acked.Clear();
+  ack_delay_time = QuicTime::Delta::Infinite();
+  received_packet_times.clear();
+  packets.Clear();
+}
+
+PacketNumberQueue::PacketNumberQueue() {}
+PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default;
+PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default;
+PacketNumberQueue::~PacketNumberQueue() {}
+
+PacketNumberQueue& PacketNumberQueue::operator=(
+    const PacketNumberQueue& other) = default;
+PacketNumberQueue& PacketNumberQueue::operator=(PacketNumberQueue&& other) =
+    default;
+
+void PacketNumberQueue::Add(QuicPacketNumber packet_number) {
+  if (!packet_number.IsInitialized()) {
+    return;
+  }
+  packet_number_intervals_.AddOptimizedForAppend(packet_number,
+                                                 packet_number + 1);
+}
+
+void PacketNumberQueue::AddRange(QuicPacketNumber lower,
+                                 QuicPacketNumber higher) {
+  if (!lower.IsInitialized() || !higher.IsInitialized() || lower >= higher) {
+    return;
+  }
+
+  packet_number_intervals_.AddOptimizedForAppend(lower, higher);
+}
+
+bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) {
+  if (!higher.IsInitialized() || Empty()) {
+    return false;
+  }
+  return packet_number_intervals_.TrimLessThan(higher);
+}
+
+void PacketNumberQueue::RemoveSmallestInterval() {
+  // TODO(wub): Move this QUIC_BUG to upper level.
+  QUIC_BUG_IF(quic_bug_12614_1, packet_number_intervals_.Size() < 2)
+      << (Empty() ? "No intervals to remove."
+                  : "Can't remove the last interval.");
+  packet_number_intervals_.PopFront();
+}
+
+void PacketNumberQueue::Clear() {
+  packet_number_intervals_.Clear();
+}
+
+bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const {
+  if (!packet_number.IsInitialized()) {
+    return false;
+  }
+  return packet_number_intervals_.Contains(packet_number);
+}
+
+bool PacketNumberQueue::Empty() const {
+  return packet_number_intervals_.Empty();
+}
+
+QuicPacketNumber PacketNumberQueue::Min() const {
+  QUICHE_DCHECK(!Empty());
+  return packet_number_intervals_.begin()->min();
+}
+
+QuicPacketNumber PacketNumberQueue::Max() const {
+  QUICHE_DCHECK(!Empty());
+  return packet_number_intervals_.rbegin()->max() - 1;
+}
+
+QuicPacketCount PacketNumberQueue::NumPacketsSlow() const {
+  QuicPacketCount n_packets = 0;
+  for (const auto& interval : packet_number_intervals_) {
+    n_packets += interval.Length();
+  }
+  return n_packets;
+}
+
+size_t PacketNumberQueue::NumIntervals() const {
+  return packet_number_intervals_.Size();
+}
+
+PacketNumberQueue::const_iterator PacketNumberQueue::begin() const {
+  return packet_number_intervals_.begin();
+}
+
+PacketNumberQueue::const_iterator PacketNumberQueue::end() const {
+  return packet_number_intervals_.end();
+}
+
+PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rbegin() const {
+  return packet_number_intervals_.rbegin();
+}
+
+PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rend() const {
+  return packet_number_intervals_.rend();
+}
+
+QuicPacketCount PacketNumberQueue::LastIntervalLength() const {
+  QUICHE_DCHECK(!Empty());
+  return packet_number_intervals_.rbegin()->Length();
+}
+
+// Largest min...max range for packet numbers where we print the numbers
+// explicitly. If bigger than this, we print as a range  [a,d] rather
+// than [a b c d]
+
+std::ostream& operator<<(std::ostream& os, const PacketNumberQueue& q) {
+  for (const QuicInterval<QuicPacketNumber>& interval : q) {
+    // Print as a range if there is a pathological condition.
+    if ((interval.min() >= interval.max()) ||
+        (interval.max() - interval.min() > kMaxPrintRange)) {
+      // If min>max, it's really a bug, so QUIC_BUG it to
+      // catch it in development.
+      QUIC_BUG_IF(quic_bug_12614_2, interval.min() >= interval.max())
+          << "Ack Range minimum (" << interval.min() << "Not less than max ("
+          << interval.max() << ")";
+      // print range as min...max rather than full list.
+      // in the event of a bug, the list could be very big.
+      os << interval.min() << "..." << (interval.max() - 1) << " ";
+    } else {
+      for (QuicPacketNumber packet_number = interval.min();
+           packet_number < interval.max(); ++packet_number) {
+        os << packet_number << " ";
+      }
+    }
+  }
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_ack_frame.h b/quiche/quic/core/frames/quic_ack_frame.h
new file mode 100644
index 0000000..9d66375
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ack_frame.h
@@ -0,0 +1,148 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_ACK_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+// A sequence of packet numbers where each number is unique. Intended to be used
+// in a sliding window fashion, where smaller old packet numbers are removed and
+// larger new packet numbers are added, with the occasional random access.
+class QUIC_EXPORT_PRIVATE PacketNumberQueue {
+ public:
+  PacketNumberQueue();
+  PacketNumberQueue(const PacketNumberQueue& other);
+  PacketNumberQueue(PacketNumberQueue&& other);
+  ~PacketNumberQueue();
+
+  PacketNumberQueue& operator=(const PacketNumberQueue& other);
+  PacketNumberQueue& operator=(PacketNumberQueue&& other);
+
+  using const_iterator = QuicIntervalSet<QuicPacketNumber>::const_iterator;
+  using const_reverse_iterator =
+      QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator;
+
+  // Adds |packet_number| to the set of packets in the queue.
+  void Add(QuicPacketNumber packet_number);
+
+  // Adds packets between [lower, higher) to the set of packets in the queue.
+  // No-op if |higher| < |lower|.
+  // NOTE(wub): Only used in tests as of Nov 2019.
+  void AddRange(QuicPacketNumber lower, QuicPacketNumber higher);
+
+  // Removes packets with values less than |higher| from the set of packets in
+  // the queue. Returns true if packets were removed.
+  bool RemoveUpTo(QuicPacketNumber higher);
+
+  // Removes the smallest interval in the queue.
+  void RemoveSmallestInterval();
+
+  // Clear this packet number queue.
+  void Clear();
+
+  // Returns true if the queue contains |packet_number|.
+  bool Contains(QuicPacketNumber packet_number) const;
+
+  // Returns true if the queue is empty.
+  bool Empty() const;
+
+  // Returns the minimum packet number stored in the queue. It is undefined
+  // behavior to call this if the queue is empty.
+  QuicPacketNumber Min() const;
+
+  // Returns the maximum packet number stored in the queue. It is undefined
+  // behavior to call this if the queue is empty.
+  QuicPacketNumber Max() const;
+
+  // Returns the number of unique packets stored in the queue. Inefficient; only
+  // exposed for testing.
+  QuicPacketCount NumPacketsSlow() const;
+
+  // Returns the number of disjoint packet number intervals contained in the
+  // queue.
+  size_t NumIntervals() const;
+
+  // Returns the length of last interval.
+  QuicPacketCount LastIntervalLength() const;
+
+  // Returns iterators over the packet number intervals.
+  const_iterator begin() const;
+  const_iterator end() const;
+  const_reverse_iterator rbegin() const;
+  const_reverse_iterator rend() const;
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const PacketNumberQueue& q);
+
+ private:
+  QuicIntervalSet<QuicPacketNumber> packet_number_intervals_;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicAckFrame {
+  QuicAckFrame();
+  QuicAckFrame(const QuicAckFrame& other);
+  ~QuicAckFrame();
+
+  void Clear();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicAckFrame& ack_frame);
+
+  // The highest packet number we've observed from the peer. When |packets| is
+  // not empty, it should always be equal to packets.Max(). The |LargestAcked|
+  // function ensures this invariant in debug mode.
+  QuicPacketNumber largest_acked;
+
+  // Time elapsed since largest_observed() was received until this Ack frame was
+  // sent.
+  QuicTime::Delta ack_delay_time = QuicTime::Delta::Infinite();
+
+  // Vector of <packet_number, time> for when packets arrived.
+  // For IETF versions, packet numbers and timestamps in this vector are both in
+  // ascending orders. Packets received out of order are not saved here.
+  PacketTimeVector received_packet_times;
+
+  // Set of packets.
+  PacketNumberQueue packets;
+
+  // ECN counters, used only in version 99's ACK frame and valid only when
+  // |ecn_counters_populated| is true.
+  bool ecn_counters_populated = false;
+  QuicPacketCount ect_0_count = 0;
+  QuicPacketCount ect_1_count = 0;
+  QuicPacketCount ecn_ce_count = 0;
+};
+
+// The highest acked packet number we've observed from the peer. If no packets
+// have been observed, return 0.
+inline QUIC_EXPORT_PRIVATE QuicPacketNumber
+LargestAcked(const QuicAckFrame& frame) {
+  QUICHE_DCHECK(frame.packets.Empty() ||
+                frame.packets.Max() == frame.largest_acked);
+  return frame.largest_acked;
+}
+
+// True if the packet number is greater than largest_observed or is listed
+// as missing.
+// Always returns false for packet numbers less than least_unacked.
+QUIC_EXPORT_PRIVATE bool IsAwaitingPacket(
+    const QuicAckFrame& ack_frame,
+    QuicPacketNumber packet_number,
+    QuicPacketNumber peer_least_packet_awaiting_ack);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_ack_frequency_frame.cc b/quiche/quic/core/frames/quic_ack_frequency_frame.cc
new file mode 100644
index 0000000..472b882
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ack_frequency_frame.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2020 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 "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include <cstdint>
+#include <limits>
+
+namespace quic {
+
+QuicAckFrequencyFrame::QuicAckFrequencyFrame(
+    QuicControlFrameId control_frame_id,
+    uint64_t sequence_number,
+    uint64_t packet_tolerance,
+    QuicTime::Delta max_ack_delay)
+    : control_frame_id(control_frame_id),
+      sequence_number(sequence_number),
+      packet_tolerance(packet_tolerance),
+      max_ack_delay(max_ack_delay) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicAckFrequencyFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", sequence_number: " << frame.sequence_number
+     << ", packet_tolerance: " << frame.packet_tolerance
+     << ", max_ack_delay_ms: " << frame.max_ack_delay.ToMilliseconds()
+     << ", ignore_order: " << frame.ignore_order << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_ack_frequency_frame.h b/quiche/quic/core/frames/quic_ack_frequency_frame.h
new file mode 100644
index 0000000..f69351a
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ack_frequency_frame.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2020 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_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
+
+#include <cstdint>
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A frame that allows sender control of acknowledgement delays.
+struct QUIC_EXPORT_PRIVATE QuicAckFrequencyFrame {
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicAckFrequencyFrame& ack_frequency_frame);
+
+  QuicAckFrequencyFrame() = default;
+  QuicAckFrequencyFrame(QuicControlFrameId control_frame_id,
+                        uint64_t sequence_number,
+                        uint64_t packet_tolerance,
+                        QuicTime::Delta max_ack_delay);
+
+  // A unique identifier of this control frame. 0 when this frame is
+  // received, and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // If true, do not ack immediately upon observeation of packet reordering.
+  bool ignore_order = false;
+
+  // Sequence number assigned to the ACK_FREQUENCY frame by the sender to allow
+  // receivers to ignore obsolete frames.
+  uint64_t sequence_number = 0;
+
+  // The maximum number of ack-eliciting packets after which the receiver sends
+  // an acknowledgement. Invald if == 0.
+  uint64_t packet_tolerance = 2;
+
+  // The maximum time that ack packets can be delayed.
+  QuicTime::Delta max_ack_delay =
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_blocked_frame.cc b/quiche/quic/core/frames/quic_blocked_frame.cc
new file mode 100644
index 0000000..a3e8ebe
--- /dev/null
+++ b/quiche/quic/core/frames/quic_blocked_frame.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_blocked_frame.h"
+
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+QuicBlockedFrame::QuicBlockedFrame() : QuicInlinedFrame(BLOCKED_FRAME) {}
+
+QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
+                                   QuicStreamId stream_id)
+    : QuicInlinedFrame(BLOCKED_FRAME),
+      control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      offset(0) {}
+
+QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
+                                   QuicStreamId stream_id,
+                                   QuicStreamOffset offset)
+    : QuicInlinedFrame(BLOCKED_FRAME),
+      control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      offset(offset) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicBlockedFrame& blocked_frame) {
+  os << "{ control_frame_id: " << blocked_frame.control_frame_id
+     << ", stream_id: " << blocked_frame.stream_id << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_blocked_frame.h b/quiche/quic/core/frames/quic_blocked_frame.h
new file mode 100644
index 0000000..32a515e
--- /dev/null
+++ b/quiche/quic/core/frames/quic_blocked_frame.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_BLOCKED_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+// The BLOCKED frame is used to indicate to the remote endpoint that this
+// endpoint believes itself to be flow-control blocked but otherwise ready to
+// send data. The BLOCKED frame is purely advisory and optional.
+// Based on SPDY's BLOCKED frame (undocumented as of 2014-01-28).
+struct QUIC_EXPORT_PRIVATE QuicBlockedFrame
+    : public QuicInlinedFrame<QuicBlockedFrame> {
+  QuicBlockedFrame();
+  QuicBlockedFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id);
+  QuicBlockedFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id,
+                   QuicStreamOffset offset);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicBlockedFrame& b);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // 0 is a special case meaning the connection is blocked, rather than a
+  // stream.  So stream_id 0 corresponds to a BLOCKED frame and non-0
+  // corresponds to a STREAM_BLOCKED.
+  // TODO(fkastenholz): This should be converted to use
+  // QuicUtils::GetInvalidStreamId to get the correct invalid stream id value
+  // and not rely on 0.
+  QuicStreamId stream_id = 0;
+
+  // For Google QUIC, the offset is ignored.
+  QuicStreamOffset offset = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_connection_close_frame.cc b/quiche/quic/core/frames/quic_connection_close_frame.cc
new file mode 100644
index 0000000..44fa18a
--- /dev/null
+++ b/quiche/quic/core/frames/quic_connection_close_frame.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_connection_close_frame.h"
+
+#include <memory>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+QuicConnectionCloseFrame::QuicConnectionCloseFrame(
+    QuicTransportVersion transport_version,
+    QuicErrorCode error_code,
+    QuicIetfTransportErrorCodes ietf_error,
+    std::string error_phrase,
+    uint64_t frame_type)
+    : quic_error_code(error_code), error_details(error_phrase) {
+  if (!VersionHasIetfQuicFrames(transport_version)) {
+    close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
+    wire_error_code = error_code;
+    transport_close_frame_type = 0;
+    return;
+  }
+  QuicErrorCodeToIetfMapping mapping =
+      QuicErrorCodeToTransportErrorCode(error_code);
+  if (ietf_error != NO_IETF_QUIC_ERROR) {
+    wire_error_code = ietf_error;
+  } else {
+    wire_error_code = mapping.error_code;
+  }
+  if (mapping.is_transport_close) {
+    // Maps to a transport close
+    close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
+    transport_close_frame_type = frame_type;
+    return;
+  }
+  // Maps to an application close.
+  close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
+  transport_close_frame_type = 0;
+}
+
+std::ostream& operator<<(
+    std::ostream& os,
+    const QuicConnectionCloseFrame& connection_close_frame) {
+  os << "{ Close type: " << connection_close_frame.close_type;
+  switch (connection_close_frame.close_type) {
+    case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
+      os << ", wire_error_code: "
+         << static_cast<QuicIetfTransportErrorCodes>(
+                connection_close_frame.wire_error_code);
+      break;
+    case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
+      os << ", wire_error_code: " << connection_close_frame.wire_error_code;
+      break;
+    case GOOGLE_QUIC_CONNECTION_CLOSE:
+      // Do not log, value same as |quic_error_code|.
+      break;
+  }
+  os << ", quic_error_code: "
+     << QuicErrorCodeToString(connection_close_frame.quic_error_code)
+     << ", error_details: '" << connection_close_frame.error_details << "'";
+  if (connection_close_frame.close_type ==
+      IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+    os << ", frame_type: "
+       << static_cast<QuicIetfFrameType>(
+              connection_close_frame.transport_close_frame_type);
+  }
+  os << "}\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_connection_close_frame.h b/quiche/quic/core/frames/quic_connection_close_frame.h
new file mode 100644
index 0000000..15e83d3
--- /dev/null
+++ b/quiche/quic/core/frames/quic_connection_close_frame.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
+
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicConnectionCloseFrame {
+  QuicConnectionCloseFrame() = default;
+
+  // Builds a connection close frame based on the transport version
+  // and the mapping of error_code. THIS IS THE PREFERRED C'TOR
+  // TO USE IF YOU NEED TO CREATE A CONNECTION-CLOSE-FRAME AND
+  // HAVE IT BE CORRECT FOR THE VERSION AND CODE MAPPINGS.
+  // |ietf_error| may optionally be be used to directly specify the wire
+  // error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
+  // QuicErrorCodeToTransportErrorCode mapping of |error_code| will be used.
+  QuicConnectionCloseFrame(QuicTransportVersion transport_version,
+                           QuicErrorCode error_code,
+                           QuicIetfTransportErrorCodes ietf_error,
+                           std::string error_phrase,
+                           uint64_t transport_close_frame_type);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicConnectionCloseFrame& c);
+
+  // Indicates whether the the frame is a Google QUIC CONNECTION_CLOSE frame,
+  // an IETF QUIC CONNECTION_CLOSE frame with transport error code,
+  // or an IETF QUIC CONNECTION_CLOSE frame with application error code.
+  QuicConnectionCloseType close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
+
+  // The error code on the wire.  For Google QUIC frames, this has the same
+  // value as |quic_error_code|.
+  uint64_t wire_error_code = QUIC_NO_ERROR;
+
+  // The underlying error.  For Google QUIC frames, this has the same value as
+  // |wire_error_code|.  For sent IETF QUIC frames, this is the error that
+  // triggered the closure of the connection.  For received IETF QUIC frames,
+  // this is parsed from the Reason Phrase field of the CONNECTION_CLOSE frame,
+  // or QUIC_IETF_GQUIC_ERROR_MISSING.
+  QuicErrorCode quic_error_code = QUIC_NO_ERROR;
+
+  // String with additional error details. |quic_error_code| and a colon will be
+  // prepended to the error details when sending IETF QUIC frames, and parsed
+  // into |quic_error_code| upon receipt, when present.
+  std::string error_details;
+
+  // The frame type present in the IETF transport connection close frame.
+  // Not populated for the Google QUIC or application connection close frames.
+  // Contains the type of frame that triggered the connection close. Made a
+  // uint64, as opposed to the QuicIetfFrameType, to support possible
+  // extensions as well as reporting invalid frame types received from the peer.
+  uint64_t transport_close_frame_type = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_crypto_frame.cc b/quiche/quic/core/frames/quic_crypto_frame.cc
new file mode 100644
index 0000000..4f27dab
--- /dev/null
+++ b/quiche/quic/core/frames/quic_crypto_frame.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2018 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 "quiche/quic/core/frames/quic_crypto_frame.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
+                                 QuicStreamOffset offset,
+                                 QuicPacketLength data_length)
+    : QuicCryptoFrame(level, offset, nullptr, data_length) {}
+
+QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
+                                 QuicStreamOffset offset,
+                                 absl::string_view data)
+    : QuicCryptoFrame(level, offset, data.data(), data.length()) {}
+
+QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
+                                 QuicStreamOffset offset,
+                                 const char* data_buffer,
+                                 QuicPacketLength data_length)
+    : level(level),
+      data_length(data_length),
+      data_buffer(data_buffer),
+      offset(offset) {}
+
+QuicCryptoFrame::~QuicCryptoFrame() {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicCryptoFrame& stream_frame) {
+  os << "{ level: " << stream_frame.level << ", offset: " << stream_frame.offset
+     << ", length: " << stream_frame.data_length << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_crypto_frame.h b/quiche/quic/core/frames/quic_crypto_frame.h
new file mode 100644
index 0000000..2d1c776
--- /dev/null
+++ b/quiche/quic/core/frames/quic_crypto_frame.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2018 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_FRAMES_QUIC_CRYPTO_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicCryptoFrame {
+  QuicCryptoFrame() = default;
+  QuicCryptoFrame(EncryptionLevel level,
+                  QuicStreamOffset offset,
+                  QuicPacketLength data_length);
+  QuicCryptoFrame(EncryptionLevel level,
+                  QuicStreamOffset offset,
+                  absl::string_view data);
+  ~QuicCryptoFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const QuicCryptoFrame& s);
+
+  // When writing a crypto frame to a packet, the packet must be encrypted at
+  // |level|. When a crypto frame is read, the encryption level of the packet it
+  // was received in is put in |level|.
+  EncryptionLevel level = ENCRYPTION_INITIAL;
+  QuicPacketLength data_length = 0;
+  // When reading, |data_buffer| points to the data that was received in the
+  // frame. |data_buffer| is not used when writing.
+  const char* data_buffer = nullptr;
+  QuicStreamOffset offset = 0;  // Location of this data in the stream.
+
+  QuicCryptoFrame(EncryptionLevel level,
+                  QuicStreamOffset offset,
+                  const char* data_buffer,
+                  QuicPacketLength data_length);
+};
+static_assert(sizeof(QuicCryptoFrame) <= 64,
+              "Keep the QuicCryptoFrame size to a cacheline.");
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_frame.cc b/quiche/quic/core/frames/quic_frame.cc
new file mode 100644
index 0000000..6200eb2
--- /dev/null
+++ b/quiche/quic/core/frames/quic_frame.cc
@@ -0,0 +1,527 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_frame.h"
+
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quic {
+
+QuicFrame::QuicFrame() {}
+
+QuicFrame::QuicFrame(QuicPaddingFrame padding_frame)
+    : padding_frame(padding_frame) {}
+
+QuicFrame::QuicFrame(QuicStreamFrame stream_frame)
+    : stream_frame(stream_frame) {}
+
+QuicFrame::QuicFrame(QuicHandshakeDoneFrame handshake_done_frame)
+    : handshake_done_frame(handshake_done_frame) {}
+
+QuicFrame::QuicFrame(QuicCryptoFrame* crypto_frame)
+    : type(CRYPTO_FRAME), crypto_frame(crypto_frame) {}
+
+QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame)
+    : mtu_discovery_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicStopWaitingFrame frame) : stop_waiting_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicPingFrame frame) : ping_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicRstStreamFrame* frame)
+    : type(RST_STREAM_FRAME), rst_stream_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame)
+    : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
+    : type(GOAWAY_FRAME), goaway_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicWindowUpdateFrame frame)
+    : window_update_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicBlockedFrame frame) : blocked_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicNewConnectionIdFrame* frame)
+    : type(NEW_CONNECTION_ID_FRAME), new_connection_id_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicRetireConnectionIdFrame* frame)
+    : type(RETIRE_CONNECTION_ID_FRAME), retire_connection_id_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicMaxStreamsFrame frame) : max_streams_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicStreamsBlockedFrame frame)
+    : streams_blocked_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicPathResponseFrame* frame)
+    : type(PATH_RESPONSE_FRAME), path_response_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicPathChallengeFrame* frame)
+    : type(PATH_CHALLENGE_FRAME), path_challenge_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicStopSendingFrame frame) : stop_sending_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicMessageFrame* frame)
+    : type(MESSAGE_FRAME), message_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicNewTokenFrame* frame)
+    : type(NEW_TOKEN_FRAME), new_token_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicAckFrequencyFrame* frame)
+    : type(ACK_FREQUENCY_FRAME), ack_frequency_frame(frame) {}
+
+void DeleteFrames(QuicFrames* frames) {
+  for (QuicFrame& frame : *frames) {
+    DeleteFrame(&frame);
+  }
+  frames->clear();
+}
+
+void DeleteFrame(QuicFrame* frame) {
+#if QUIC_FRAME_DEBUG
+  // If the frame is not inlined, check that it can be safely deleted.
+  if (frame->type != PADDING_FRAME && frame->type != MTU_DISCOVERY_FRAME &&
+      frame->type != PING_FRAME && frame->type != MAX_STREAMS_FRAME &&
+      frame->type != STOP_WAITING_FRAME &&
+      frame->type != STREAMS_BLOCKED_FRAME && frame->type != STREAM_FRAME &&
+      frame->type != HANDSHAKE_DONE_FRAME &&
+      frame->type != WINDOW_UPDATE_FRAME && frame->type != BLOCKED_FRAME &&
+      frame->type != STOP_SENDING_FRAME) {
+    QUICHE_CHECK(!frame->delete_forbidden) << *frame;
+  }
+#endif  // QUIC_FRAME_DEBUG
+  switch (frame->type) {
+    // Frames smaller than a pointer are inlined, so don't need to be deleted.
+    case PADDING_FRAME:
+    case MTU_DISCOVERY_FRAME:
+    case PING_FRAME:
+    case MAX_STREAMS_FRAME:
+    case STOP_WAITING_FRAME:
+    case STREAMS_BLOCKED_FRAME:
+    case STREAM_FRAME:
+    case HANDSHAKE_DONE_FRAME:
+    case WINDOW_UPDATE_FRAME:
+    case BLOCKED_FRAME:
+    case STOP_SENDING_FRAME:
+      break;
+    case ACK_FRAME:
+      delete frame->ack_frame;
+      break;
+    case RST_STREAM_FRAME:
+      delete frame->rst_stream_frame;
+      break;
+    case CONNECTION_CLOSE_FRAME:
+      delete frame->connection_close_frame;
+      break;
+    case GOAWAY_FRAME:
+      delete frame->goaway_frame;
+      break;
+    case PATH_CHALLENGE_FRAME:
+      delete frame->path_challenge_frame;
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      delete frame->new_connection_id_frame;
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      delete frame->retire_connection_id_frame;
+      break;
+    case PATH_RESPONSE_FRAME:
+      delete frame->path_response_frame;
+      break;
+    case MESSAGE_FRAME:
+      delete frame->message_frame;
+      break;
+    case CRYPTO_FRAME:
+      delete frame->crypto_frame;
+      break;
+    case NEW_TOKEN_FRAME:
+      delete frame->new_token_frame;
+      break;
+    case ACK_FREQUENCY_FRAME:
+      delete frame->ack_frequency_frame;
+      break;
+    case NUM_FRAME_TYPES:
+      QUICHE_DCHECK(false) << "Cannot delete type: " << frame->type;
+  }
+}
+
+void RemoveFramesForStream(QuicFrames* frames, QuicStreamId stream_id) {
+  auto it = frames->begin();
+  while (it != frames->end()) {
+    if (it->type != STREAM_FRAME || it->stream_frame.stream_id != stream_id) {
+      ++it;
+      continue;
+    }
+    it = frames->erase(it);
+  }
+}
+
+bool IsControlFrame(QuicFrameType type) {
+  switch (type) {
+    case RST_STREAM_FRAME:
+    case GOAWAY_FRAME:
+    case WINDOW_UPDATE_FRAME:
+    case BLOCKED_FRAME:
+    case STREAMS_BLOCKED_FRAME:
+    case MAX_STREAMS_FRAME:
+    case PING_FRAME:
+    case STOP_SENDING_FRAME:
+    case NEW_CONNECTION_ID_FRAME:
+    case RETIRE_CONNECTION_ID_FRAME:
+    case HANDSHAKE_DONE_FRAME:
+    case ACK_FREQUENCY_FRAME:
+    case NEW_TOKEN_FRAME:
+      return true;
+    default:
+      return false;
+  }
+}
+
+QuicControlFrameId GetControlFrameId(const QuicFrame& frame) {
+  switch (frame.type) {
+    case RST_STREAM_FRAME:
+      return frame.rst_stream_frame->control_frame_id;
+    case GOAWAY_FRAME:
+      return frame.goaway_frame->control_frame_id;
+    case WINDOW_UPDATE_FRAME:
+      return frame.window_update_frame.control_frame_id;
+    case BLOCKED_FRAME:
+      return frame.blocked_frame.control_frame_id;
+    case STREAMS_BLOCKED_FRAME:
+      return frame.streams_blocked_frame.control_frame_id;
+    case MAX_STREAMS_FRAME:
+      return frame.max_streams_frame.control_frame_id;
+    case PING_FRAME:
+      return frame.ping_frame.control_frame_id;
+    case STOP_SENDING_FRAME:
+      return frame.stop_sending_frame.control_frame_id;
+    case NEW_CONNECTION_ID_FRAME:
+      return frame.new_connection_id_frame->control_frame_id;
+    case RETIRE_CONNECTION_ID_FRAME:
+      return frame.retire_connection_id_frame->control_frame_id;
+    case HANDSHAKE_DONE_FRAME:
+      return frame.handshake_done_frame.control_frame_id;
+    case ACK_FREQUENCY_FRAME:
+      return frame.ack_frequency_frame->control_frame_id;
+    case NEW_TOKEN_FRAME:
+      return frame.new_token_frame->control_frame_id;
+    default:
+      return kInvalidControlFrameId;
+  }
+}
+
+void SetControlFrameId(QuicControlFrameId control_frame_id, QuicFrame* frame) {
+  switch (frame->type) {
+    case RST_STREAM_FRAME:
+      frame->rst_stream_frame->control_frame_id = control_frame_id;
+      return;
+    case GOAWAY_FRAME:
+      frame->goaway_frame->control_frame_id = control_frame_id;
+      return;
+    case WINDOW_UPDATE_FRAME:
+      frame->window_update_frame.control_frame_id = control_frame_id;
+      return;
+    case BLOCKED_FRAME:
+      frame->blocked_frame.control_frame_id = control_frame_id;
+      return;
+    case PING_FRAME:
+      frame->ping_frame.control_frame_id = control_frame_id;
+      return;
+    case STREAMS_BLOCKED_FRAME:
+      frame->streams_blocked_frame.control_frame_id = control_frame_id;
+      return;
+    case MAX_STREAMS_FRAME:
+      frame->max_streams_frame.control_frame_id = control_frame_id;
+      return;
+    case STOP_SENDING_FRAME:
+      frame->stop_sending_frame.control_frame_id = control_frame_id;
+      return;
+    case NEW_CONNECTION_ID_FRAME:
+      frame->new_connection_id_frame->control_frame_id = control_frame_id;
+      return;
+    case RETIRE_CONNECTION_ID_FRAME:
+      frame->retire_connection_id_frame->control_frame_id = control_frame_id;
+      return;
+    case HANDSHAKE_DONE_FRAME:
+      frame->handshake_done_frame.control_frame_id = control_frame_id;
+      return;
+    case ACK_FREQUENCY_FRAME:
+      frame->ack_frequency_frame->control_frame_id = control_frame_id;
+      return;
+    case NEW_TOKEN_FRAME:
+      frame->new_token_frame->control_frame_id = control_frame_id;
+      return;
+    default:
+      QUIC_BUG(quic_bug_12594_1)
+          << "Try to set control frame id of a frame without control frame id";
+  }
+}
+
+QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame) {
+  QuicFrame copy;
+  switch (frame.type) {
+    case RST_STREAM_FRAME:
+      copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
+      break;
+    case GOAWAY_FRAME:
+      copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
+      break;
+    case WINDOW_UPDATE_FRAME:
+      copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
+      break;
+    case BLOCKED_FRAME:
+      copy = QuicFrame(QuicBlockedFrame(frame.blocked_frame));
+      break;
+    case PING_FRAME:
+      copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
+      break;
+    case STOP_SENDING_FRAME:
+      copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      copy = QuicFrame(
+          new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      copy = QuicFrame(
+          new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
+      break;
+    case STREAMS_BLOCKED_FRAME:
+      copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
+      break;
+    case MAX_STREAMS_FRAME:
+      copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
+      break;
+    case HANDSHAKE_DONE_FRAME:
+      copy = QuicFrame(
+          QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
+      break;
+    case ACK_FREQUENCY_FRAME:
+      copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
+      break;
+    case NEW_TOKEN_FRAME:
+      copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
+      break;
+    default:
+      QUIC_BUG(quic_bug_10533_1)
+          << "Try to copy a non-retransmittable control frame: " << frame;
+      copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
+      break;
+  }
+  return copy;
+}
+
+QuicFrame CopyQuicFrame(quiche::QuicheBufferAllocator* allocator,
+                        const QuicFrame& frame) {
+  QuicFrame copy;
+  switch (frame.type) {
+    case PADDING_FRAME:
+      copy = QuicFrame(QuicPaddingFrame(frame.padding_frame));
+      break;
+    case RST_STREAM_FRAME:
+      copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
+      break;
+    case CONNECTION_CLOSE_FRAME:
+      copy = QuicFrame(
+          new QuicConnectionCloseFrame(*frame.connection_close_frame));
+      break;
+    case GOAWAY_FRAME:
+      copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
+      break;
+    case WINDOW_UPDATE_FRAME:
+      copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
+      break;
+    case BLOCKED_FRAME:
+      copy = QuicFrame(QuicBlockedFrame(frame.blocked_frame));
+      break;
+    case STOP_WAITING_FRAME:
+      copy = QuicFrame(QuicStopWaitingFrame(frame.stop_waiting_frame));
+      break;
+    case PING_FRAME:
+      copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
+      break;
+    case CRYPTO_FRAME:
+      copy = QuicFrame(new QuicCryptoFrame(*frame.crypto_frame));
+      break;
+    case STREAM_FRAME:
+      copy = QuicFrame(QuicStreamFrame(frame.stream_frame));
+      break;
+    case ACK_FRAME:
+      copy = QuicFrame(new QuicAckFrame(*frame.ack_frame));
+      break;
+    case MTU_DISCOVERY_FRAME:
+      copy = QuicFrame(QuicMtuDiscoveryFrame(frame.mtu_discovery_frame));
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      copy = QuicFrame(
+          new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
+      break;
+    case MAX_STREAMS_FRAME:
+      copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
+      break;
+    case STREAMS_BLOCKED_FRAME:
+      copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
+      break;
+    case PATH_RESPONSE_FRAME:
+      copy = QuicFrame(new QuicPathResponseFrame(*frame.path_response_frame));
+      break;
+    case PATH_CHALLENGE_FRAME:
+      copy = QuicFrame(new QuicPathChallengeFrame(*frame.path_challenge_frame));
+      break;
+    case STOP_SENDING_FRAME:
+      copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
+      break;
+    case MESSAGE_FRAME:
+      copy = QuicFrame(new QuicMessageFrame(frame.message_frame->message_id));
+      copy.message_frame->data = frame.message_frame->data;
+      copy.message_frame->message_length = frame.message_frame->message_length;
+      for (const auto& slice : frame.message_frame->message_data) {
+        quiche::QuicheBuffer buffer =
+            quiche::QuicheBuffer::Copy(allocator, slice.AsStringView());
+        copy.message_frame->message_data.push_back(
+            quiche::QuicheMemSlice(std::move(buffer)));
+      }
+      break;
+    case NEW_TOKEN_FRAME:
+      copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      copy = QuicFrame(
+          new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
+      break;
+    case HANDSHAKE_DONE_FRAME:
+      copy = QuicFrame(
+          QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
+      break;
+    case ACK_FREQUENCY_FRAME:
+      copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
+      break;
+    default:
+      QUIC_BUG(quic_bug_10533_2) << "Cannot copy frame: " << frame;
+      copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
+      break;
+  }
+  return copy;
+}
+
+QuicFrames CopyQuicFrames(quiche::QuicheBufferAllocator* allocator,
+                          const QuicFrames& frames) {
+  QuicFrames copy;
+  for (const auto& frame : frames) {
+    copy.push_back(CopyQuicFrame(allocator, frame));
+  }
+  return copy;
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicFrame& frame) {
+  switch (frame.type) {
+    case PADDING_FRAME: {
+      os << "type { PADDING_FRAME } " << frame.padding_frame;
+      break;
+    }
+    case RST_STREAM_FRAME: {
+      os << "type { RST_STREAM_FRAME } " << *(frame.rst_stream_frame);
+      break;
+    }
+    case CONNECTION_CLOSE_FRAME: {
+      os << "type { CONNECTION_CLOSE_FRAME } "
+         << *(frame.connection_close_frame);
+      break;
+    }
+    case GOAWAY_FRAME: {
+      os << "type { GOAWAY_FRAME } " << *(frame.goaway_frame);
+      break;
+    }
+    case WINDOW_UPDATE_FRAME: {
+      os << "type { WINDOW_UPDATE_FRAME } " << frame.window_update_frame;
+      break;
+    }
+    case BLOCKED_FRAME: {
+      os << "type { BLOCKED_FRAME } " << frame.blocked_frame;
+      break;
+    }
+    case STREAM_FRAME: {
+      os << "type { STREAM_FRAME } " << frame.stream_frame;
+      break;
+    }
+    case ACK_FRAME: {
+      os << "type { ACK_FRAME } " << *(frame.ack_frame);
+      break;
+    }
+    case STOP_WAITING_FRAME: {
+      os << "type { STOP_WAITING_FRAME } " << frame.stop_waiting_frame;
+      break;
+    }
+    case PING_FRAME: {
+      os << "type { PING_FRAME } " << frame.ping_frame;
+      break;
+    }
+    case CRYPTO_FRAME: {
+      os << "type { CRYPTO_FRAME } " << *(frame.crypto_frame);
+      break;
+    }
+    case MTU_DISCOVERY_FRAME: {
+      os << "type { MTU_DISCOVERY_FRAME } ";
+      break;
+    }
+    case NEW_CONNECTION_ID_FRAME:
+      os << "type { NEW_CONNECTION_ID } " << *(frame.new_connection_id_frame);
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      os << "type { RETIRE_CONNECTION_ID } "
+         << *(frame.retire_connection_id_frame);
+      break;
+    case MAX_STREAMS_FRAME:
+      os << "type { MAX_STREAMS } " << frame.max_streams_frame;
+      break;
+    case STREAMS_BLOCKED_FRAME:
+      os << "type { STREAMS_BLOCKED } " << frame.streams_blocked_frame;
+      break;
+    case PATH_RESPONSE_FRAME:
+      os << "type { PATH_RESPONSE } " << *(frame.path_response_frame);
+      break;
+    case PATH_CHALLENGE_FRAME:
+      os << "type { PATH_CHALLENGE } " << *(frame.path_challenge_frame);
+      break;
+    case STOP_SENDING_FRAME:
+      os << "type { STOP_SENDING } " << frame.stop_sending_frame;
+      break;
+    case MESSAGE_FRAME:
+      os << "type { MESSAGE_FRAME }" << *(frame.message_frame);
+      break;
+    case NEW_TOKEN_FRAME:
+      os << "type { NEW_TOKEN_FRAME }" << *(frame.new_token_frame);
+      break;
+    case HANDSHAKE_DONE_FRAME:
+      os << "type { HANDSHAKE_DONE_FRAME } " << frame.handshake_done_frame;
+      break;
+    case ACK_FREQUENCY_FRAME:
+      os << "type { ACK_FREQUENCY_FRAME } " << *(frame.ack_frequency_frame);
+      break;
+    default: {
+      QUIC_LOG(ERROR) << "Unknown frame type: " << frame.type;
+      break;
+    }
+  }
+  return os;
+}
+
+std::string QuicFramesToString(const QuicFrames& frames) {
+  std::ostringstream os;
+  for (const QuicFrame& frame : frames) {
+    os << frame;
+  }
+  return os.str();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_frame.h b/quiche/quic/core/frames/quic_frame.h
new file mode 100644
index 0000000..ce82ea7
--- /dev/null
+++ b/quiche/quic/core/frames/quic_frame.h
@@ -0,0 +1,177 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
+
+#include <ostream>
+#include <type_traits>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "quiche/quic/core/frames/quic_ack_frame.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_blocked_frame.h"
+#include "quiche/quic/core/frames/quic_connection_close_frame.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/frames/quic_goaway_frame.h"
+#include "quiche/quic/core/frames/quic_handshake_done_frame.h"
+#include "quiche/quic/core/frames/quic_max_streams_frame.h"
+#include "quiche/quic/core/frames/quic_message_frame.h"
+#include "quiche/quic/core/frames/quic_mtu_discovery_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_new_token_frame.h"
+#include "quiche/quic/core/frames/quic_padding_frame.h"
+#include "quiche/quic/core/frames/quic_path_challenge_frame.h"
+#include "quiche/quic/core/frames/quic_path_response_frame.h"
+#include "quiche/quic/core/frames/quic_ping_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/frames/quic_stop_sending_frame.h"
+#include "quiche/quic/core/frames/quic_stop_waiting_frame.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/frames/quic_streams_blocked_frame.h"
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+#ifndef QUIC_FRAME_DEBUG
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define QUIC_FRAME_DEBUG 1
+#else  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define QUIC_FRAME_DEBUG 0
+#endif  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#endif  // QUIC_FRAME_DEBUG
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicFrame {
+  QuicFrame();
+  // Please keep the constructors in the same order as the union below.
+  explicit QuicFrame(QuicPaddingFrame padding_frame);
+  explicit QuicFrame(QuicMtuDiscoveryFrame frame);
+  explicit QuicFrame(QuicPingFrame frame);
+  explicit QuicFrame(QuicMaxStreamsFrame frame);
+  explicit QuicFrame(QuicStopWaitingFrame frame);
+  explicit QuicFrame(QuicStreamsBlockedFrame frame);
+  explicit QuicFrame(QuicStreamFrame stream_frame);
+  explicit QuicFrame(QuicHandshakeDoneFrame handshake_done_frame);
+  explicit QuicFrame(QuicWindowUpdateFrame frame);
+  explicit QuicFrame(QuicBlockedFrame frame);
+  explicit QuicFrame(QuicStopSendingFrame frame);
+
+  explicit QuicFrame(QuicAckFrame* frame);
+  explicit QuicFrame(QuicRstStreamFrame* frame);
+  explicit QuicFrame(QuicConnectionCloseFrame* frame);
+  explicit QuicFrame(QuicGoAwayFrame* frame);
+  explicit QuicFrame(QuicNewConnectionIdFrame* frame);
+  explicit QuicFrame(QuicRetireConnectionIdFrame* frame);
+  explicit QuicFrame(QuicNewTokenFrame* frame);
+  explicit QuicFrame(QuicPathResponseFrame* frame);
+  explicit QuicFrame(QuicPathChallengeFrame* frame);
+  explicit QuicFrame(QuicMessageFrame* message_frame);
+  explicit QuicFrame(QuicCryptoFrame* crypto_frame);
+  explicit QuicFrame(QuicAckFrequencyFrame* ack_frequency_frame);
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+                                                      const QuicFrame& frame);
+
+  union {
+    // Inlined frames.
+    // Overlapping inlined frames have a |type| field at the same 0 offset as
+    // QuicFrame does for out of line frames below, allowing use of the
+    // remaining 7 bytes after offset for frame-type specific fields.
+    QuicPaddingFrame padding_frame;
+    QuicMtuDiscoveryFrame mtu_discovery_frame;
+    QuicPingFrame ping_frame;
+    QuicMaxStreamsFrame max_streams_frame;
+    QuicStopWaitingFrame stop_waiting_frame;
+    QuicStreamsBlockedFrame streams_blocked_frame;
+    QuicStreamFrame stream_frame;
+    QuicHandshakeDoneFrame handshake_done_frame;
+    QuicWindowUpdateFrame window_update_frame;
+    QuicBlockedFrame blocked_frame;
+    QuicStopSendingFrame stop_sending_frame;
+
+    // Out of line frames.
+    struct {
+      QuicFrameType type;
+
+#if QUIC_FRAME_DEBUG
+      bool delete_forbidden = false;
+#endif  // QUIC_FRAME_DEBUG
+
+      // TODO(wub): These frames can also be inlined without increasing the size
+      // of QuicFrame:
+      // QuicPathResponseFrame, QuicPathChallengeFrame.
+      union {
+        QuicAckFrame* ack_frame;
+        QuicRstStreamFrame* rst_stream_frame;
+        QuicConnectionCloseFrame* connection_close_frame;
+        QuicGoAwayFrame* goaway_frame;
+        QuicNewConnectionIdFrame* new_connection_id_frame;
+        QuicRetireConnectionIdFrame* retire_connection_id_frame;
+        QuicPathResponseFrame* path_response_frame;
+        QuicPathChallengeFrame* path_challenge_frame;
+        QuicMessageFrame* message_frame;
+        QuicCryptoFrame* crypto_frame;
+        QuicAckFrequencyFrame* ack_frequency_frame;
+        QuicNewTokenFrame* new_token_frame;
+      };
+    };
+  };
+};
+
+static_assert(std::is_standard_layout<QuicFrame>::value,
+              "QuicFrame must have a standard layout");
+static_assert(sizeof(QuicFrame) <= 24,
+              "Frames larger than 24 bytes should be referenced by pointer.");
+static_assert(offsetof(QuicStreamFrame, type) == offsetof(QuicFrame, type),
+              "Offset of |type| must match in QuicFrame and QuicStreamFrame");
+
+// A inline size of 1 is chosen to optimize the typical use case of
+// 1-stream-frame in QuicTransmissionInfo.retransmittable_frames.
+using QuicFrames = absl::InlinedVector<QuicFrame, 1>;
+
+// Deletes all the sub-frames contained in |frames|.
+QUIC_EXPORT_PRIVATE void DeleteFrames(QuicFrames* frames);
+
+// Delete the sub-frame contained in |frame|.
+QUIC_EXPORT_PRIVATE void DeleteFrame(QuicFrame* frame);
+
+// Deletes all the QuicStreamFrames for the specified |stream_id|.
+QUIC_EXPORT_PRIVATE void RemoveFramesForStream(QuicFrames* frames,
+                                               QuicStreamId stream_id);
+
+// Returns true if |type| is a retransmittable control frame.
+QUIC_EXPORT_PRIVATE bool IsControlFrame(QuicFrameType type);
+
+// Returns control_frame_id of |frame|. Returns kInvalidControlFrameId if
+// |frame| does not have a valid control_frame_id.
+QUIC_EXPORT_PRIVATE QuicControlFrameId
+GetControlFrameId(const QuicFrame& frame);
+
+// Sets control_frame_id of |frame| to |control_frame_id|.
+QUIC_EXPORT_PRIVATE void SetControlFrameId(QuicControlFrameId control_frame_id,
+                                           QuicFrame* frame);
+
+// Returns a copy of |frame|.
+QUIC_EXPORT_PRIVATE QuicFrame
+CopyRetransmittableControlFrame(const QuicFrame& frame);
+
+// Returns a copy of |frame|.
+QUIC_EXPORT_PRIVATE QuicFrame
+CopyQuicFrame(quiche::QuicheBufferAllocator* allocator, const QuicFrame& frame);
+
+// Returns a copy of |frames|.
+QUIC_EXPORT_PRIVATE QuicFrames CopyQuicFrames(
+    quiche::QuicheBufferAllocator* allocator, const QuicFrames& frames);
+
+// Human-readable description suitable for logging.
+QUIC_EXPORT_PRIVATE std::string QuicFramesToString(const QuicFrames& frames);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_frames_test.cc b/quiche/quic/core/frames/quic_frames_test.cc
new file mode 100644
index 0000000..19c50f5
--- /dev/null
+++ b/quiche/quic/core/frames/quic_frames_test.cc
@@ -0,0 +1,832 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_ack_frame.h"
+#include "quiche/quic/core/frames/quic_blocked_frame.h"
+#include "quiche/quic/core/frames/quic_connection_close_frame.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/frames/quic_goaway_frame.h"
+#include "quiche/quic/core/frames/quic_mtu_discovery_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_padding_frame.h"
+#include "quiche/quic/core/frames/quic_ping_frame.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/frames/quic_stop_waiting_frame.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicFramesTest : public QuicTest {};
+
+TEST_F(QuicFramesTest, AckFrameToString) {
+  QuicAckFrame frame;
+  frame.largest_acked = QuicPacketNumber(5);
+  frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
+  frame.packets.Add(QuicPacketNumber(4));
+  frame.packets.Add(QuicPacketNumber(5));
+  frame.received_packet_times = {
+      {QuicPacketNumber(6),
+       QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ(
+      "{ largest_acked: 5, ack_delay_time: 3, packets: [ 4 5  ], "
+      "received_packets: [ 6 at 7  ], ecn_counters_populated: 0 }\n",
+      stream.str());
+  QuicFrame quic_frame(&frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, BigAckFrameToString) {
+  QuicAckFrame frame;
+  frame.largest_acked = QuicPacketNumber(500);
+  frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
+  frame.packets.AddRange(QuicPacketNumber(4), QuicPacketNumber(501));
+  frame.received_packet_times = {
+      {QuicPacketNumber(500),
+       QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ(
+      "{ largest_acked: 500, ack_delay_time: 3, packets: [ 4...500  ], "
+      "received_packets: [ 500 at 7  ], ecn_counters_populated: 0 }\n",
+      stream.str());
+  QuicFrame quic_frame(&frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, PaddingFrameToString) {
+  QuicPaddingFrame frame;
+  frame.num_padding_bytes = 1;
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ("{ num_padding_bytes: 1 }\n", stream.str());
+  QuicFrame quic_frame(frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, RstStreamFrameToString) {
+  QuicRstStreamFrame rst_stream;
+  QuicFrame frame(&rst_stream);
+  SetControlFrameId(1, &frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame));
+  rst_stream.stream_id = 1;
+  rst_stream.byte_offset = 3;
+  rst_stream.error_code = QUIC_STREAM_CANCELLED;
+  std::ostringstream stream;
+  stream << rst_stream;
+  EXPECT_EQ(
+      "{ control_frame_id: 1, stream_id: 1, byte_offset: 3, error_code: 6, "
+      "ietf_error_code: 0 }\n",
+      stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, StopSendingFrameToString) {
+  QuicFrame frame((QuicStopSendingFrame()));
+  SetControlFrameId(1, &frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame));
+  frame.stop_sending_frame.stream_id = 321;
+  frame.stop_sending_frame.error_code = QUIC_STREAM_CANCELLED;
+  frame.stop_sending_frame.ietf_error_code =
+      static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+  std::ostringstream stream;
+  stream << frame.stop_sending_frame;
+  EXPECT_EQ(
+      "{ control_frame_id: 1, stream_id: 321, error_code: 6, ietf_error_code: "
+      "268 }\n",
+      stream.str());
+}
+
+TEST_F(QuicFramesTest, NewConnectionIdFrameToString) {
+  QuicNewConnectionIdFrame new_connection_id_frame;
+  QuicFrame frame(&new_connection_id_frame);
+  SetControlFrameId(1, &frame);
+  QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame_copy));
+  new_connection_id_frame.connection_id = TestConnectionId(2);
+  new_connection_id_frame.sequence_number = 2u;
+  new_connection_id_frame.retire_prior_to = 1u;
+  new_connection_id_frame.stateless_reset_token =
+      StatelessResetToken{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+  std::ostringstream stream;
+  stream << new_connection_id_frame;
+  EXPECT_EQ(
+      "{ control_frame_id: 1, connection_id: 0000000000000002, "
+      "sequence_number: 2, retire_prior_to: 1 }\n",
+      stream.str());
+  EXPECT_TRUE(IsControlFrame(frame_copy.type));
+  DeleteFrame(&frame_copy);
+}
+
+TEST_F(QuicFramesTest, RetireConnectionIdFrameToString) {
+  QuicRetireConnectionIdFrame retire_connection_id_frame;
+  QuicFrame frame(&retire_connection_id_frame);
+  SetControlFrameId(1, &frame);
+  QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame_copy));
+  retire_connection_id_frame.sequence_number = 1u;
+  std::ostringstream stream;
+  stream << retire_connection_id_frame;
+  EXPECT_EQ("{ control_frame_id: 1, sequence_number: 1 }\n", stream.str());
+  EXPECT_TRUE(IsControlFrame(frame_copy.type));
+  DeleteFrame(&frame_copy);
+}
+
+TEST_F(QuicFramesTest, StreamsBlockedFrameToString) {
+  QuicStreamsBlockedFrame streams_blocked;
+  QuicFrame frame(streams_blocked);
+  SetControlFrameId(1, &frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame));
+  // QuicStreamsBlocked is copied into a QuicFrame (as opposed to putting a
+  // pointer to it into QuicFrame) so need to work with the copy in |frame| and
+  // not the original one, streams_blocked.
+  frame.streams_blocked_frame.stream_count = 321;
+  frame.streams_blocked_frame.unidirectional = false;
+  std::ostringstream stream;
+  stream << frame.streams_blocked_frame;
+  EXPECT_EQ("{ control_frame_id: 1, stream count: 321, bidirectional }\n",
+            stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, MaxStreamsFrameToString) {
+  QuicMaxStreamsFrame max_streams;
+  QuicFrame frame(max_streams);
+  SetControlFrameId(1, &frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame));
+  // QuicMaxStreams is copied into a QuicFrame (as opposed to putting a
+  // pointer to it into QuicFrame) so need to work with the copy in |frame| and
+  // not the original one, max_streams.
+  frame.max_streams_frame.stream_count = 321;
+  frame.max_streams_frame.unidirectional = true;
+  std::ostringstream stream;
+  stream << frame.max_streams_frame;
+  EXPECT_EQ("{ control_frame_id: 1, stream_count: 321, unidirectional }\n",
+            stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, ConnectionCloseFrameToString) {
+  QuicConnectionCloseFrame frame;
+  frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
+  frame.error_details = "No recent network activity.";
+  std::ostringstream stream;
+  stream << frame;
+  // Note that "extracted_error_code: 122" is QUIC_IETF_GQUIC_ERROR_MISSING,
+  // indicating that, in fact, no extended error code was available from the
+  // underlying frame.
+  EXPECT_EQ(
+      "{ Close type: GOOGLE_QUIC_CONNECTION_CLOSE, "
+      "quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
+      "error_details: 'No recent network activity.'}\n",
+      stream.str());
+  QuicFrame quic_frame(&frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, TransportConnectionCloseFrameToString) {
+  QuicConnectionCloseFrame frame;
+  frame.close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
+  frame.wire_error_code = FINAL_SIZE_ERROR;
+  frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
+  frame.error_details = "No recent network activity.";
+  frame.transport_close_frame_type = IETF_STREAM;
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ(
+      "{ Close type: IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, "
+      "wire_error_code: FINAL_SIZE_ERROR, "
+      "quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
+      "error_details: 'No recent "
+      "network activity.', "
+      "frame_type: IETF_STREAM"
+      "}\n",
+      stream.str());
+  QuicFrame quic_frame(&frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, GoAwayFrameToString) {
+  QuicGoAwayFrame goaway_frame;
+  QuicFrame frame(&goaway_frame);
+  SetControlFrameId(2, &frame);
+  EXPECT_EQ(2u, GetControlFrameId(frame));
+  goaway_frame.error_code = QUIC_NETWORK_IDLE_TIMEOUT;
+  goaway_frame.last_good_stream_id = 2;
+  goaway_frame.reason_phrase = "Reason";
+  std::ostringstream stream;
+  stream << goaway_frame;
+  EXPECT_EQ(
+      "{ control_frame_id: 2, error_code: 25, last_good_stream_id: 2, "
+      "reason_phrase: "
+      "'Reason' }\n",
+      stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, WindowUpdateFrameToString) {
+  QuicFrame frame((QuicWindowUpdateFrame()));
+  SetControlFrameId(3, &frame);
+  EXPECT_EQ(3u, GetControlFrameId(frame));
+  std::ostringstream stream;
+  frame.window_update_frame.stream_id = 1;
+  frame.window_update_frame.max_data = 2;
+  stream << frame.window_update_frame;
+  EXPECT_EQ("{ control_frame_id: 3, stream_id: 1, max_data: 2 }\n",
+            stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, BlockedFrameToString) {
+  QuicFrame frame((QuicBlockedFrame()));
+  SetControlFrameId(4, &frame);
+  EXPECT_EQ(4u, GetControlFrameId(frame));
+  frame.blocked_frame.stream_id = 1;
+  std::ostringstream stream;
+  stream << frame.blocked_frame;
+  EXPECT_EQ("{ control_frame_id: 4, stream_id: 1 }\n", stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, PingFrameToString) {
+  QuicPingFrame ping;
+  QuicFrame frame(ping);
+  SetControlFrameId(5, &frame);
+  EXPECT_EQ(5u, GetControlFrameId(frame));
+  std::ostringstream stream;
+  stream << frame.ping_frame;
+  EXPECT_EQ("{ control_frame_id: 5 }\n", stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, HandshakeDoneFrameToString) {
+  QuicHandshakeDoneFrame handshake_done;
+  QuicFrame frame(handshake_done);
+  SetControlFrameId(6, &frame);
+  EXPECT_EQ(6u, GetControlFrameId(frame));
+  std::ostringstream stream;
+  stream << frame.handshake_done_frame;
+  EXPECT_EQ("{ control_frame_id: 6 }\n", stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, QuicAckFreuqncyFrameToString) {
+  QuicAckFrequencyFrame ack_frequency_frame;
+  ack_frequency_frame.sequence_number = 1;
+  ack_frequency_frame.packet_tolerance = 2;
+  ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(25);
+  ack_frequency_frame.ignore_order = false;
+  QuicFrame frame(&ack_frequency_frame);
+  ASSERT_EQ(ACK_FREQUENCY_FRAME, frame.type);
+  SetControlFrameId(6, &frame);
+  EXPECT_EQ(6u, GetControlFrameId(frame));
+  std::ostringstream stream;
+  stream << *frame.ack_frequency_frame;
+  EXPECT_EQ(
+      "{ control_frame_id: 6, sequence_number: 1, packet_tolerance: 2, "
+      "max_ack_delay_ms: 25, ignore_order: 0 }\n",
+      stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, StreamFrameToString) {
+  QuicStreamFrame frame;
+  frame.stream_id = 1;
+  frame.fin = false;
+  frame.offset = 2;
+  frame.data_length = 3;
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ("{ stream_id: 1, fin: 0, offset: 2, length: 3 }\n", stream.str());
+  EXPECT_FALSE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, StopWaitingFrameToString) {
+  QuicStopWaitingFrame frame;
+  frame.least_unacked = QuicPacketNumber(2);
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ("{ least_unacked: 2 }\n", stream.str());
+  QuicFrame quic_frame(frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, IsAwaitingPacket) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.largest_acked = QuicPacketNumber(10u);
+  ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(11));
+  EXPECT_TRUE(
+      IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
+  EXPECT_FALSE(
+      IsAwaitingPacket(ack_frame1, QuicPacketNumber(1u), QuicPacketNumber()));
+
+  ack_frame1.packets.Add(QuicPacketNumber(12));
+  EXPECT_TRUE(
+      IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
+
+  QuicAckFrame ack_frame2;
+  ack_frame2.largest_acked = QuicPacketNumber(100u);
+  ack_frame2.packets.AddRange(QuicPacketNumber(21), QuicPacketNumber(100));
+  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(11u),
+                                QuicPacketNumber(20u)));
+  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(80u),
+                                QuicPacketNumber(20u)));
+  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
+                               QuicPacketNumber(20u)));
+
+  ack_frame2.packets.AddRange(QuicPacketNumber(102), QuicPacketNumber(200));
+  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
+                               QuicPacketNumber(20u)));
+}
+
+TEST_F(QuicFramesTest, AddPacket) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.packets.Add(QuicPacketNumber(1));
+  ack_frame1.packets.Add(QuicPacketNumber(99));
+
+  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(
+      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(99), QuicPacketNumber(100)));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+
+  ack_frame1.packets.Add(QuicPacketNumber(20));
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2;
+  expected_intervals2.emplace_back(
+      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
+  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(20), QuicPacketNumber(21)));
+  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(99), QuicPacketNumber(100)));
+
+  EXPECT_EQ(3u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(expected_intervals2, actual_intervals2);
+
+  ack_frame1.packets.Add(QuicPacketNumber(19));
+  ack_frame1.packets.Add(QuicPacketNumber(21));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals3(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals3;
+  expected_intervals3.emplace_back(
+      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
+  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(19), QuicPacketNumber(22)));
+  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(99), QuicPacketNumber(100)));
+
+  EXPECT_EQ(expected_intervals3, actual_intervals3);
+
+  ack_frame1.packets.Add(QuicPacketNumber(20));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals4(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals3, actual_intervals4);
+
+  QuicAckFrame ack_frame2;
+  ack_frame2.packets.Add(QuicPacketNumber(20));
+  ack_frame2.packets.Add(QuicPacketNumber(40));
+  ack_frame2.packets.Add(QuicPacketNumber(60));
+  ack_frame2.packets.Add(QuicPacketNumber(10));
+  ack_frame2.packets.Add(QuicPacketNumber(80));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals5(
+      ack_frame2.packets.begin(), ack_frame2.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals5;
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(10), QuicPacketNumber(11)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(20), QuicPacketNumber(21)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(40), QuicPacketNumber(41)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(60), QuicPacketNumber(61)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(80), QuicPacketNumber(81)));
+
+  EXPECT_EQ(expected_intervals5, actual_intervals5);
+}
+
+TEST_F(QuicFramesTest, AddInterval) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
+  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
+
+  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals{
+      {QuicPacketNumber(1), QuicPacketNumber(10)},
+      {QuicPacketNumber(50), QuicPacketNumber(100)},
+  };
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+
+  // Add a range in the middle.
+  ack_frame1.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2{
+      {QuicPacketNumber(1), QuicPacketNumber(10)},
+      {QuicPacketNumber(20), QuicPacketNumber(30)},
+      {QuicPacketNumber(50), QuicPacketNumber(100)},
+  };
+
+  EXPECT_EQ(expected_intervals2.size(), ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(expected_intervals2, actual_intervals2);
+
+  // Add ranges at both ends.
+  QuicAckFrame ack_frame2;
+  ack_frame2.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(25));
+  ack_frame2.packets.AddRange(QuicPacketNumber(40), QuicPacketNumber(45));
+  ack_frame2.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(65));
+  ack_frame2.packets.AddRange(QuicPacketNumber(10), QuicPacketNumber(15));
+  ack_frame2.packets.AddRange(QuicPacketNumber(80), QuicPacketNumber(85));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals8(
+      ack_frame2.packets.begin(), ack_frame2.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals8{
+      {QuicPacketNumber(10), QuicPacketNumber(15)},
+      {QuicPacketNumber(20), QuicPacketNumber(25)},
+      {QuicPacketNumber(40), QuicPacketNumber(45)},
+      {QuicPacketNumber(60), QuicPacketNumber(65)},
+      {QuicPacketNumber(80), QuicPacketNumber(85)},
+  };
+
+  EXPECT_EQ(expected_intervals8, actual_intervals8);
+}
+
+TEST_F(QuicFramesTest, AddAdjacentForward) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.packets.Add(QuicPacketNumber(49));
+  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
+  ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
+  ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(49), QuicPacketNumber(100)));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+}
+
+TEST_F(QuicFramesTest, AddAdjacentReverse) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
+  ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
+  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
+  ack_frame1.packets.Add(QuicPacketNumber(49));
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(49), QuicPacketNumber(100)));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+}
+
+TEST_F(QuicFramesTest, RemoveSmallestInterval) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.largest_acked = QuicPacketNumber(100u);
+  ack_frame1.packets.AddRange(QuicPacketNumber(51), QuicPacketNumber(60));
+  ack_frame1.packets.AddRange(QuicPacketNumber(71), QuicPacketNumber(80));
+  ack_frame1.packets.AddRange(QuicPacketNumber(91), QuicPacketNumber(100));
+  ack_frame1.packets.RemoveSmallestInterval();
+  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(71u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
+
+  ack_frame1.packets.RemoveSmallestInterval();
+  EXPECT_EQ(1u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(91u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
+}
+
+TEST_F(QuicFramesTest, CopyQuicFrames) {
+  QuicFrames frames;
+  QuicMessageFrame* message_frame =
+      new QuicMessageFrame(1, MemSliceFromString("message"));
+  // Construct a frame list.
+  for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
+    switch (i) {
+      case PADDING_FRAME:
+        frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+        break;
+      case RST_STREAM_FRAME:
+        frames.push_back(QuicFrame(new QuicRstStreamFrame()));
+        break;
+      case CONNECTION_CLOSE_FRAME:
+        frames.push_back(QuicFrame(new QuicConnectionCloseFrame()));
+        break;
+      case GOAWAY_FRAME:
+        frames.push_back(QuicFrame(new QuicGoAwayFrame()));
+        break;
+      case WINDOW_UPDATE_FRAME:
+        frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
+        break;
+      case BLOCKED_FRAME:
+        frames.push_back(QuicFrame(QuicBlockedFrame()));
+        break;
+      case STOP_WAITING_FRAME:
+        frames.push_back(QuicFrame(QuicStopWaitingFrame()));
+        break;
+      case PING_FRAME:
+        frames.push_back(QuicFrame(QuicPingFrame()));
+        break;
+      case CRYPTO_FRAME:
+        frames.push_back(QuicFrame(new QuicCryptoFrame()));
+        break;
+      case STREAM_FRAME:
+        frames.push_back(QuicFrame(QuicStreamFrame()));
+        break;
+      case ACK_FRAME:
+        frames.push_back(QuicFrame(new QuicAckFrame()));
+        break;
+      case MTU_DISCOVERY_FRAME:
+        frames.push_back(QuicFrame(QuicMtuDiscoveryFrame()));
+        break;
+      case NEW_CONNECTION_ID_FRAME:
+        frames.push_back(QuicFrame(new QuicNewConnectionIdFrame()));
+        break;
+      case MAX_STREAMS_FRAME:
+        frames.push_back(QuicFrame(QuicMaxStreamsFrame()));
+        break;
+      case STREAMS_BLOCKED_FRAME:
+        frames.push_back(QuicFrame(QuicStreamsBlockedFrame()));
+        break;
+      case PATH_RESPONSE_FRAME:
+        frames.push_back(QuicFrame(new QuicPathResponseFrame()));
+        break;
+      case PATH_CHALLENGE_FRAME:
+        frames.push_back(QuicFrame(new QuicPathChallengeFrame()));
+        break;
+      case STOP_SENDING_FRAME:
+        frames.push_back(QuicFrame(QuicStopSendingFrame()));
+        break;
+      case MESSAGE_FRAME:
+        frames.push_back(QuicFrame(message_frame));
+        break;
+      case NEW_TOKEN_FRAME:
+        frames.push_back(QuicFrame(new QuicNewTokenFrame()));
+        break;
+      case RETIRE_CONNECTION_ID_FRAME:
+        frames.push_back(QuicFrame(new QuicRetireConnectionIdFrame()));
+        break;
+      case HANDSHAKE_DONE_FRAME:
+        frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
+        break;
+      case ACK_FREQUENCY_FRAME:
+        frames.push_back(QuicFrame(new QuicAckFrequencyFrame()));
+        break;
+      default:
+        ASSERT_TRUE(false)
+            << "Please fix CopyQuicFrames if a new frame type is added.";
+        break;
+    }
+  }
+
+  QuicFrames copy =
+      CopyQuicFrames(quiche::SimpleBufferAllocator::Get(), frames);
+  ASSERT_EQ(NUM_FRAME_TYPES, copy.size());
+  for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
+    EXPECT_EQ(i, copy[i].type);
+    if (i != MESSAGE_FRAME) {
+      continue;
+    }
+    // Verify message frame is correctly copied.
+    EXPECT_EQ(1u, copy[i].message_frame->message_id);
+    EXPECT_EQ(nullptr, copy[i].message_frame->data);
+    EXPECT_EQ(7u, copy[i].message_frame->message_length);
+    ASSERT_EQ(1u, copy[i].message_frame->message_data.size());
+    EXPECT_EQ(0, memcmp(copy[i].message_frame->message_data[0].data(),
+                        frames[i].message_frame->message_data[0].data(), 7));
+  }
+  DeleteFrames(&frames);
+  DeleteFrames(&copy);
+}
+
+class PacketNumberQueueTest : public QuicTest {};
+
+// Tests that a queue contains the expected data after calls to Add().
+TEST_F(PacketNumberQueueTest, AddRange) {
+  PacketNumberQueue queue;
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(51));
+  queue.Add(QuicPacketNumber(53));
+
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
+  for (int i = 1; i < 51; ++i) {
+    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
+  }
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(52)));
+  EXPECT_TRUE(queue.Contains(QuicPacketNumber(53)));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(54)));
+  EXPECT_EQ(51u, queue.NumPacketsSlow());
+  EXPECT_EQ(QuicPacketNumber(1u), queue.Min());
+  EXPECT_EQ(QuicPacketNumber(53u), queue.Max());
+
+  queue.Add(QuicPacketNumber(70));
+  EXPECT_EQ(QuicPacketNumber(70u), queue.Max());
+}
+
+// Tests Contains function
+TEST_F(PacketNumberQueueTest, Contains) {
+  PacketNumberQueue queue;
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
+  queue.AddRange(QuicPacketNumber(5), QuicPacketNumber(10));
+  queue.Add(QuicPacketNumber(20));
+
+  for (int i = 1; i < 5; ++i) {
+    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
+  }
+
+  for (int i = 5; i < 10; ++i) {
+    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
+  }
+  for (int i = 10; i < 20; ++i) {
+    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
+  }
+  EXPECT_TRUE(queue.Contains(QuicPacketNumber(20)));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(21)));
+
+  PacketNumberQueue queue2;
+  EXPECT_FALSE(queue2.Contains(QuicPacketNumber(1)));
+  for (int i = 1; i < 51; ++i) {
+    queue2.Add(QuicPacketNumber(2 * i));
+  }
+  EXPECT_FALSE(queue2.Contains(QuicPacketNumber()));
+  for (int i = 1; i < 51; ++i) {
+    if (i % 2 == 0) {
+      EXPECT_TRUE(queue2.Contains(QuicPacketNumber(i)));
+    } else {
+      EXPECT_FALSE(queue2.Contains(QuicPacketNumber(i)));
+    }
+  }
+  EXPECT_FALSE(queue2.Contains(QuicPacketNumber(101)));
+}
+
+// Tests that a queue contains the expected data after calls to RemoveUpTo().
+TEST_F(PacketNumberQueueTest, Removal) {
+  PacketNumberQueue queue;
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
+
+  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(51)));
+  EXPECT_FALSE(queue.RemoveUpTo(QuicPacketNumber(51)));
+
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
+  for (int i = 1; i < 51; ++i) {
+    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
+  }
+  for (int i = 51; i < 100; ++i) {
+    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
+  }
+  EXPECT_EQ(49u, queue.NumPacketsSlow());
+  EXPECT_EQ(QuicPacketNumber(51u), queue.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), queue.Max());
+
+  PacketNumberQueue queue2;
+  queue2.AddRange(QuicPacketNumber(1), QuicPacketNumber(5));
+  EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(3)));
+  EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(50)));
+  EXPECT_TRUE(queue2.Empty());
+}
+
+// Tests that a queue is empty when all of its elements are removed.
+TEST_F(PacketNumberQueueTest, Empty) {
+  PacketNumberQueue queue;
+  EXPECT_TRUE(queue.Empty());
+  EXPECT_EQ(0u, queue.NumPacketsSlow());
+
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
+  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(100)));
+  EXPECT_TRUE(queue.Empty());
+  EXPECT_EQ(0u, queue.NumPacketsSlow());
+}
+
+// Tests that logging the state of a PacketNumberQueue does not crash.
+TEST_F(PacketNumberQueueTest, LogDoesNotCrash) {
+  std::ostringstream oss;
+  PacketNumberQueue queue;
+  oss << queue;
+
+  queue.Add(QuicPacketNumber(1));
+  queue.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
+  oss << queue;
+}
+
+// Tests that the iterators returned from a packet queue iterate over the queue.
+TEST_F(PacketNumberQueueTest, Iterators) {
+  PacketNumberQueue queue;
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      queue.begin(), queue.end());
+
+  PacketNumberQueue queue2;
+  for (int i = 1; i < 100; i++) {
+    queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
+  }
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
+      queue2.begin(), queue2.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(1), QuicPacketNumber(100)));
+  EXPECT_EQ(expected_intervals, actual_intervals);
+  EXPECT_EQ(expected_intervals, actual_intervals2);
+  EXPECT_EQ(actual_intervals, actual_intervals2);
+}
+
+TEST_F(PacketNumberQueueTest, ReversedIterators) {
+  PacketNumberQueue queue;
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
+  PacketNumberQueue queue2;
+  for (int i = 1; i < 100; i++) {
+    queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
+  }
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      queue.rbegin(), queue.rend());
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
+      queue2.rbegin(), queue2.rend());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(1), QuicPacketNumber(100)));
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+  EXPECT_EQ(expected_intervals, actual_intervals2);
+  EXPECT_EQ(actual_intervals, actual_intervals2);
+
+  PacketNumberQueue queue3;
+  for (int i = 1; i < 20; i++) {
+    queue3.Add(QuicPacketNumber(2 * i));
+  }
+
+  auto begin = queue3.begin();
+  auto end = queue3.end();
+  --end;
+  auto rbegin = queue3.rbegin();
+  auto rend = queue3.rend();
+  --rend;
+
+  EXPECT_EQ(*begin, *rend);
+  EXPECT_EQ(*rbegin, *end);
+}
+
+TEST_F(PacketNumberQueueTest, IntervalLengthAndRemoveInterval) {
+  PacketNumberQueue queue;
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
+  queue.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
+  queue.AddRange(QuicPacketNumber(40), QuicPacketNumber(50));
+  EXPECT_EQ(3u, queue.NumIntervals());
+  EXPECT_EQ(10u, queue.LastIntervalLength());
+
+  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(25)));
+  EXPECT_EQ(2u, queue.NumIntervals());
+  EXPECT_EQ(10u, queue.LastIntervalLength());
+  EXPECT_EQ(QuicPacketNumber(25u), queue.Min());
+  EXPECT_EQ(QuicPacketNumber(49u), queue.Max());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_goaway_frame.cc b/quiche/quic/core/frames/quic_goaway_frame.cc
new file mode 100644
index 0000000..277d84d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_goaway_frame.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2016 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 <string>
+
+#include "quiche/quic/core/frames/quic_goaway_frame.h"
+
+namespace quic {
+
+QuicGoAwayFrame::QuicGoAwayFrame(QuicControlFrameId control_frame_id,
+                                 QuicErrorCode error_code,
+                                 QuicStreamId last_good_stream_id,
+                                 const std::string& reason)
+    : control_frame_id(control_frame_id),
+      error_code(error_code),
+      last_good_stream_id(last_good_stream_id),
+      reason_phrase(reason) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicGoAwayFrame& goaway_frame) {
+  os << "{ control_frame_id: " << goaway_frame.control_frame_id
+     << ", error_code: " << goaway_frame.error_code
+     << ", last_good_stream_id: " << goaway_frame.last_good_stream_id
+     << ", reason_phrase: '" << goaway_frame.reason_phrase << "' }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_goaway_frame.h b/quiche/quic/core/frames/quic_goaway_frame.h
new file mode 100644
index 0000000..ac31dbc
--- /dev/null
+++ b/quiche/quic/core/frames/quic_goaway_frame.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_GOAWAY_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
+
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicGoAwayFrame {
+  QuicGoAwayFrame() = default;
+  QuicGoAwayFrame(QuicControlFrameId control_frame_id,
+                  QuicErrorCode error_code,
+                  QuicStreamId last_good_stream_id,
+                  const std::string& reason);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const QuicGoAwayFrame& g);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+  QuicErrorCode error_code = QUIC_NO_ERROR;
+  QuicStreamId last_good_stream_id = 0;
+  std::string reason_phrase;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_handshake_done_frame.cc b/quiche/quic/core/frames/quic_handshake_done_frame.cc
new file mode 100644
index 0000000..e8a7110
--- /dev/null
+++ b/quiche/quic/core/frames/quic_handshake_done_frame.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2020 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 "quiche/quic/core/frames/quic_handshake_done_frame.h"
+
+namespace quic {
+
+QuicHandshakeDoneFrame::QuicHandshakeDoneFrame()
+    : QuicInlinedFrame(HANDSHAKE_DONE_FRAME) {}
+
+QuicHandshakeDoneFrame::QuicHandshakeDoneFrame(
+    QuicControlFrameId control_frame_id)
+    : QuicInlinedFrame(HANDSHAKE_DONE_FRAME),
+      control_frame_id(control_frame_id) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicHandshakeDoneFrame& handshake_done_frame) {
+  os << "{ control_frame_id: " << handshake_done_frame.control_frame_id
+     << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_handshake_done_frame.h b/quiche/quic/core/frames/quic_handshake_done_frame.h
new file mode 100644
index 0000000..7c9639a
--- /dev/null
+++ b/quiche/quic/core/frames/quic_handshake_done_frame.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2020 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_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A HANDSHAKE_DONE frame contains no payload, and it is retransmittable,
+// and ACK'd just like other normal frames.
+struct QUIC_EXPORT_PRIVATE QuicHandshakeDoneFrame
+    : public QuicInlinedFrame<QuicHandshakeDoneFrame> {
+  QuicHandshakeDoneFrame();
+  explicit QuicHandshakeDoneFrame(QuicControlFrameId control_frame_id);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicHandshakeDoneFrame& handshake_done_frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_inlined_frame.h b/quiche/quic/core/frames/quic_inlined_frame.h
new file mode 100644
index 0000000..8cab158
--- /dev/null
+++ b/quiche/quic/core/frames/quic_inlined_frame.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 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_FRAMES_QUIC_INLINED_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
+
+#include <type_traits>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicInlinedFrame is the base class of all frame types that is inlined in the
+// QuicFrame class. It gurantees all inlined frame types contain a 'type' field
+// at offset 0, such that QuicFrame.type can get the correct frame type for both
+// inline and out-of-line frame types.
+template <typename DerivedT>
+struct QUIC_EXPORT_PRIVATE QuicInlinedFrame {
+  QuicInlinedFrame(QuicFrameType type) {
+    static_cast<DerivedT*>(this)->type = type;
+    static_assert(std::is_standard_layout<DerivedT>::value,
+                  "Inlined frame must have a standard layout");
+    static_assert(offsetof(DerivedT, type) == 0,
+                  "type must be the first field.");
+    static_assert(sizeof(DerivedT) <= 24,
+                  "Frames larger than 24 bytes should not be inlined.");
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_max_streams_frame.cc b/quiche/quic/core/frames/quic_max_streams_frame.cc
new file mode 100644
index 0000000..594224b
--- /dev/null
+++ b/quiche/quic/core/frames/quic_max_streams_frame.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2019 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 "quiche/quic/core/frames/quic_max_streams_frame.h"
+
+namespace quic {
+
+QuicMaxStreamsFrame::QuicMaxStreamsFrame()
+    : QuicInlinedFrame(MAX_STREAMS_FRAME) {}
+
+QuicMaxStreamsFrame::QuicMaxStreamsFrame(QuicControlFrameId control_frame_id,
+                                         QuicStreamCount stream_count,
+                                         bool unidirectional)
+    : QuicInlinedFrame(MAX_STREAMS_FRAME),
+      control_frame_id(control_frame_id),
+      stream_count(stream_count),
+      unidirectional(unidirectional) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicMaxStreamsFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", stream_count: " << frame.stream_count
+     << ((frame.unidirectional) ? ", unidirectional }\n"
+                                : ", bidirectional }\n");
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_max_streams_frame.h b/quiche/quic/core/frames/quic_max_streams_frame.h
new file mode 100644
index 0000000..97434c7
--- /dev/null
+++ b/quiche/quic/core/frames/quic_max_streams_frame.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2019 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_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// IETF format MAX_STREAMS frame.
+// This frame is used by the sender to inform the peer of the number of
+// streams that the peer may open and that the sender will accept.
+struct QUIC_EXPORT_PRIVATE QuicMaxStreamsFrame
+    : public QuicInlinedFrame<QuicMaxStreamsFrame> {
+  QuicMaxStreamsFrame();
+  QuicMaxStreamsFrame(QuicControlFrameId control_frame_id,
+                      QuicStreamCount stream_count,
+                      bool unidirectional);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicMaxStreamsFrame& frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // The number of streams that may be opened.
+  QuicStreamCount stream_count = 0;
+  // Whether uni- or bi-directional streams
+  bool unidirectional = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_message_frame.cc b/quiche/quic/core/frames/quic_message_frame.cc
new file mode 100644
index 0000000..935d7ce
--- /dev/null
+++ b/quiche/quic/core/frames/quic_message_frame.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2018 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 "quiche/quic/core/frames/quic_message_frame.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id)
+    : message_id(message_id), data(nullptr), message_length(0) {}
+
+QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id,
+                                   absl::Span<quiche::QuicheMemSlice> span)
+    : message_id(message_id), data(nullptr), message_length(0) {
+  for (quiche::QuicheMemSlice& slice : span) {
+    if (slice.empty()) {
+      continue;
+    }
+    message_length += slice.length();
+    message_data.push_back(std::move(slice));
+  }
+}
+QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id,
+                                   quiche::QuicheMemSlice slice)
+    : QuicMessageFrame(message_id, absl::MakeSpan(&slice, 1)) {}
+
+QuicMessageFrame::QuicMessageFrame(const char* data, QuicPacketLength length)
+    : message_id(0), data(data), message_length(length) {}
+
+QuicMessageFrame::~QuicMessageFrame() {}
+
+std::ostream& operator<<(std::ostream& os, const QuicMessageFrame& s) {
+  os << " message_id: " << s.message_id
+     << ", message_length: " << s.message_length << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_message_frame.h b/quiche/quic/core/frames/quic_message_frame.h
new file mode 100644
index 0000000..30c40a0
--- /dev/null
+++ b/quiche/quic/core/frames/quic_message_frame.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2018 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_FRAMES_QUIC_MESSAGE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
+
+#include "absl/container/inlined_vector.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+using QuicMessageData = absl::InlinedVector<quiche::QuicheMemSlice, 1>;
+
+struct QUIC_EXPORT_PRIVATE QuicMessageFrame {
+  QuicMessageFrame() = default;
+  explicit QuicMessageFrame(QuicMessageId message_id);
+  QuicMessageFrame(QuicMessageId message_id,
+                   absl::Span<quiche::QuicheMemSlice> span);
+  QuicMessageFrame(QuicMessageId message_id, quiche::QuicheMemSlice slice);
+  QuicMessageFrame(const char* data, QuicPacketLength length);
+
+  QuicMessageFrame(const QuicMessageFrame& other) = delete;
+  QuicMessageFrame& operator=(const QuicMessageFrame& other) = delete;
+
+  QuicMessageFrame(QuicMessageFrame&& other) = default;
+  QuicMessageFrame& operator=(QuicMessageFrame&& other) = default;
+
+  ~QuicMessageFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicMessageFrame& s);
+
+  // message_id is only used on the sender side and does not get serialized on
+  // wire.
+  QuicMessageId message_id = 0;
+  // Not owned, only used on read path.
+  const char* data = nullptr;
+  // Total length of message_data, must be fit into one packet.
+  QuicPacketLength message_length = 0;
+
+  // The actual message data which is reference counted, used on write path.
+  QuicMessageData message_data;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_mtu_discovery_frame.h b/quiche/quic/core/frames/quic_mtu_discovery_frame.h
new file mode 100644
index 0000000..7189463
--- /dev/null
+++ b/quiche/quic/core/frames/quic_mtu_discovery_frame.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A path MTU discovery frame contains no payload and is serialized as a ping
+// frame.
+struct QUIC_EXPORT_PRIVATE QuicMtuDiscoveryFrame
+    : public QuicInlinedFrame<QuicMtuDiscoveryFrame> {
+  QuicMtuDiscoveryFrame() : QuicInlinedFrame(MTU_DISCOVERY_FRAME) {}
+
+  QuicFrameType type;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_new_connection_id_frame.cc b/quiche/quic/core/frames/quic_new_connection_id_frame.cc
new file mode 100644
index 0000000..cf5511b
--- /dev/null
+++ b/quiche/quic/core/frames/quic_new_connection_id_frame.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+
+namespace quic {
+
+QuicNewConnectionIdFrame::QuicNewConnectionIdFrame(
+    QuicControlFrameId control_frame_id,
+    QuicConnectionId connection_id,
+    QuicConnectionIdSequenceNumber sequence_number,
+    StatelessResetToken stateless_reset_token,
+    uint64_t retire_prior_to)
+    : control_frame_id(control_frame_id),
+      connection_id(connection_id),
+      sequence_number(sequence_number),
+      stateless_reset_token(stateless_reset_token),
+      retire_prior_to(retire_prior_to) {
+  QUICHE_DCHECK(retire_prior_to <= sequence_number);
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicNewConnectionIdFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", connection_id: " << frame.connection_id
+     << ", sequence_number: " << frame.sequence_number
+     << ", retire_prior_to: " << frame.retire_prior_to << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_new_connection_id_frame.h b/quiche/quic/core/frames/quic_new_connection_id_frame.h
new file mode 100644
index 0000000..6221b03
--- /dev/null
+++ b/quiche/quic/core/frames/quic_new_connection_id_frame.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicNewConnectionIdFrame {
+  QuicNewConnectionIdFrame() = default;
+  QuicNewConnectionIdFrame(QuicControlFrameId control_frame_id,
+                           QuicConnectionId connection_id,
+                           QuicConnectionIdSequenceNumber sequence_number,
+                           StatelessResetToken stateless_reset_token,
+                           uint64_t retire_prior_to);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicNewConnectionIdFrame& frame);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+  QuicConnectionId connection_id = EmptyQuicConnectionId();
+  QuicConnectionIdSequenceNumber sequence_number = 0;
+  StatelessResetToken stateless_reset_token;
+  uint64_t retire_prior_to = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_new_token_frame.cc b/quiche/quic/core/frames/quic_new_token_frame.cc
new file mode 100644
index 0000000..7b5190d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_new_token_frame.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2018 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 "quiche/quic/core/frames/quic_new_token_frame.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicNewTokenFrame::QuicNewTokenFrame(QuicControlFrameId control_frame_id,
+                                     absl::string_view token)
+    : control_frame_id(control_frame_id),
+      token(std::string(token.data(), token.length())) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicNewTokenFrame& s) {
+  os << "{ control_frame_id: " << s.control_frame_id
+     << ", token: " << absl::BytesToHexString(s.token) << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_new_token_frame.h b/quiche/quic/core/frames/quic_new_token_frame.h
new file mode 100644
index 0000000..7900149
--- /dev/null
+++ b/quiche/quic/core/frames/quic_new_token_frame.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2018 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_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicNewTokenFrame {
+  QuicNewTokenFrame() = default;
+  QuicNewTokenFrame(QuicControlFrameId control_frame_id,
+                    absl::string_view token);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicNewTokenFrame& s);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  std::string token;
+};
+static_assert(sizeof(QuicNewTokenFrame) <= 64,
+              "Keep the QuicNewTokenFrame size to a cacheline.");
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_padding_frame.cc b/quiche/quic/core/frames/quic_padding_frame.cc
new file mode 100644
index 0000000..2170835
--- /dev/null
+++ b/quiche/quic/core/frames/quic_padding_frame.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_padding_frame.h"
+
+namespace quic {
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicPaddingFrame& padding_frame) {
+  os << "{ num_padding_bytes: " << padding_frame.num_padding_bytes << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_padding_frame.h b/quiche/quic/core/frames/quic_padding_frame.h
new file mode 100644
index 0000000..25edc3f
--- /dev/null
+++ b/quiche/quic/core/frames/quic_padding_frame.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_PADDING_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
+
+#include <cstdint>
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A padding frame contains no payload.
+struct QUIC_EXPORT_PRIVATE QuicPaddingFrame
+    : public QuicInlinedFrame<QuicPaddingFrame> {
+  QuicPaddingFrame() : QuicInlinedFrame(PADDING_FRAME) {}
+  explicit QuicPaddingFrame(int num_padding_bytes)
+      : QuicInlinedFrame(PADDING_FRAME), num_padding_bytes(num_padding_bytes) {}
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPaddingFrame& padding_frame);
+
+  QuicFrameType type;
+
+  // -1: full padding to the end of a max-sized packet
+  // otherwise: only pad up to num_padding_bytes bytes
+  int num_padding_bytes = -1;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_path_challenge_frame.cc b/quiche/quic/core/frames/quic_path_challenge_frame.cc
new file mode 100644
index 0000000..c4781a0
--- /dev/null
+++ b/quiche/quic/core/frames/quic_path_challenge_frame.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2018 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 "quiche/quic/core/frames/quic_path_challenge_frame.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QuicPathChallengeFrame::QuicPathChallengeFrame(
+    QuicControlFrameId control_frame_id,
+    const QuicPathFrameBuffer& data_buff)
+    : control_frame_id(control_frame_id) {
+  memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
+}
+
+QuicPathChallengeFrame::~QuicPathChallengeFrame() {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicPathChallengeFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
+     << absl::BytesToHexString(absl::string_view(
+            reinterpret_cast<const char*>(frame.data_buffer.data()),
+            frame.data_buffer.size()))
+     << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_path_challenge_frame.h b/quiche/quic/core/frames/quic_path_challenge_frame.h
new file mode 100644
index 0000000..fb0ad24
--- /dev/null
+++ b/quiche/quic/core/frames/quic_path_challenge_frame.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 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_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicPathChallengeFrame {
+  QuicPathChallengeFrame() = default;
+  QuicPathChallengeFrame(QuicControlFrameId control_frame_id,
+                         const QuicPathFrameBuffer& data_buff);
+  ~QuicPathChallengeFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPathChallengeFrame& frame);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  QuicPathFrameBuffer data_buffer{};
+};
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_path_response_frame.cc b/quiche/quic/core/frames/quic_path_response_frame.cc
new file mode 100644
index 0000000..384387d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_path_response_frame.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2018 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 "quiche/quic/core/frames/quic_path_response_frame.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QuicPathResponseFrame::QuicPathResponseFrame(
+    QuicControlFrameId control_frame_id,
+    const QuicPathFrameBuffer& data_buff)
+    : control_frame_id(control_frame_id) {
+  memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
+}
+
+QuicPathResponseFrame::~QuicPathResponseFrame() {}
+
+std::ostream& operator<<(std::ostream& os, const QuicPathResponseFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
+     << absl::BytesToHexString(absl::string_view(
+            reinterpret_cast<const char*>(frame.data_buffer.data()),
+            frame.data_buffer.size()))
+     << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_path_response_frame.h b/quiche/quic/core/frames/quic_path_response_frame.h
new file mode 100644
index 0000000..df2391f
--- /dev/null
+++ b/quiche/quic/core/frames/quic_path_response_frame.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 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_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicPathResponseFrame {
+  QuicPathResponseFrame() = default;
+  QuicPathResponseFrame(QuicControlFrameId control_frame_id,
+                        const QuicPathFrameBuffer& data_buff);
+  ~QuicPathResponseFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPathResponseFrame& frame);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  QuicPathFrameBuffer data_buffer{};
+};
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_ping_frame.cc b/quiche/quic/core/frames/quic_ping_frame.cc
new file mode 100644
index 0000000..c28e671
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ping_frame.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2017 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 "quiche/quic/core/frames/quic_ping_frame.h"
+
+namespace quic {
+
+QuicPingFrame::QuicPingFrame() : QuicInlinedFrame(PING_FRAME) {}
+
+QuicPingFrame::QuicPingFrame(QuicControlFrameId control_frame_id)
+    : QuicInlinedFrame(PING_FRAME), control_frame_id(control_frame_id) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicPingFrame& ping_frame) {
+  os << "{ control_frame_id: " << ping_frame.control_frame_id << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_ping_frame.h b/quiche/quic/core/frames/quic_ping_frame.h
new file mode 100644
index 0000000..d39bf6d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ping_frame.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_PING_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ping frame contains no payload, though it is retransmittable,
+// and ACK'd just like other normal frames.
+struct QUIC_EXPORT_PRIVATE QuicPingFrame
+    : public QuicInlinedFrame<QuicPingFrame> {
+  QuicPingFrame();
+  explicit QuicPingFrame(QuicControlFrameId control_frame_id);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPingFrame& ping_frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_retire_connection_id_frame.cc b/quiche/quic/core/frames/quic_retire_connection_id_frame.cc
new file mode 100644
index 0000000..93e7e49
--- /dev/null
+++ b/quiche/quic/core/frames/quic_retire_connection_id_frame.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2019 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 "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+
+namespace quic {
+
+QuicRetireConnectionIdFrame::QuicRetireConnectionIdFrame(
+    QuicControlFrameId control_frame_id,
+    QuicConnectionIdSequenceNumber sequence_number)
+    : control_frame_id(control_frame_id), sequence_number(sequence_number) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicRetireConnectionIdFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", sequence_number: " << frame.sequence_number << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_retire_connection_id_frame.h b/quiche/quic/core/frames/quic_retire_connection_id_frame.h
new file mode 100644
index 0000000..41ce972
--- /dev/null
+++ b/quiche/quic/core/frames/quic_retire_connection_id_frame.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2019 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_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicRetireConnectionIdFrame {
+  QuicRetireConnectionIdFrame() = default;
+  QuicRetireConnectionIdFrame(QuicControlFrameId control_frame_id,
+                              QuicConnectionIdSequenceNumber sequence_number);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicRetireConnectionIdFrame& frame);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+  QuicConnectionIdSequenceNumber sequence_number = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_rst_stream_frame.cc b/quiche/quic/core/frames/quic_rst_stream_frame.cc
new file mode 100644
index 0000000..a6d3052
--- /dev/null
+++ b/quiche/quic/core/frames/quic_rst_stream_frame.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_rst_stream_frame.h"
+
+#include "quiche/quic/core/quic_error_codes.h"
+
+namespace quic {
+
+QuicRstStreamFrame::QuicRstStreamFrame(QuicControlFrameId control_frame_id,
+                                       QuicStreamId stream_id,
+                                       QuicRstStreamErrorCode error_code,
+                                       QuicStreamOffset bytes_written)
+    : control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      error_code(error_code),
+      ietf_error_code(RstStreamErrorCodeToIetfResetStreamErrorCode(error_code)),
+      byte_offset(bytes_written) {}
+
+QuicRstStreamFrame::QuicRstStreamFrame(QuicControlFrameId control_frame_id,
+                                       QuicStreamId stream_id,
+                                       QuicResetStreamError error,
+                                       QuicStreamOffset bytes_written)
+    : control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      error_code(error.internal_code()),
+      ietf_error_code(error.ietf_application_code()),
+      byte_offset(bytes_written) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicRstStreamFrame& rst_frame) {
+  os << "{ control_frame_id: " << rst_frame.control_frame_id
+     << ", stream_id: " << rst_frame.stream_id
+     << ", byte_offset: " << rst_frame.byte_offset
+     << ", error_code: " << rst_frame.error_code
+     << ", ietf_error_code: " << rst_frame.ietf_error_code << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_rst_stream_frame.h b/quiche/quic/core/frames/quic_rst_stream_frame.h
new file mode 100644
index 0000000..c346aff
--- /dev/null
+++ b/quiche/quic/core/frames/quic_rst_stream_frame.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_RST_STREAM_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicRstStreamFrame {
+  QuicRstStreamFrame() = default;
+  QuicRstStreamFrame(QuicControlFrameId control_frame_id,
+                     QuicStreamId stream_id, QuicRstStreamErrorCode error_code,
+                     QuicStreamOffset bytes_written);
+  QuicRstStreamFrame(QuicControlFrameId control_frame_id,
+                     QuicStreamId stream_id, QuicResetStreamError error,
+                     QuicStreamOffset bytes_written);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const QuicRstStreamFrame& r);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  QuicStreamId stream_id = 0;
+
+  // When using Google QUIC: the RST_STREAM error code on the wire.
+  // When using IETF QUIC: for an outgoing RESET_STREAM frame, the error code
+  // generated by the application that determines |ietf_error_code| to be sent
+  // on the wire; for an incoming RESET_STREAM frame, the error code inferred
+  // from the |ietf_error_code| received on the wire.
+  QuicRstStreamErrorCode error_code = QUIC_STREAM_NO_ERROR;
+
+  // Application error code of RESET_STREAM frame.  Used for IETF QUIC only.
+  uint64_t ietf_error_code = 0;
+
+  // Used to update flow control windows. On termination of a stream, both
+  // endpoints must inform the peer of the number of bytes they have sent on
+  // that stream. This can be done through normal termination (data packet with
+  // FIN) or through a RST.
+  QuicStreamOffset byte_offset = 0;
+
+  // Returns a tuple of both |error_code| and |ietf_error_code|.
+  QuicResetStreamError error() const {
+    return QuicResetStreamError(error_code, ietf_error_code);
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_stop_sending_frame.cc b/quiche/quic/core/frames/quic_stop_sending_frame.cc
new file mode 100644
index 0000000..f70b785
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stop_sending_frame.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2018 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 "quiche/quic/core/frames/quic_stop_sending_frame.h"
+
+#include "quiche/quic/core/quic_error_codes.h"
+
+namespace quic {
+
+QuicStopSendingFrame::QuicStopSendingFrame()
+    : QuicInlinedFrame(STOP_SENDING_FRAME) {}
+
+QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
+                                           QuicStreamId stream_id,
+                                           QuicRstStreamErrorCode error_code)
+    : QuicStopSendingFrame(control_frame_id, stream_id,
+                           QuicResetStreamError::FromInternal(error_code)) {}
+
+QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
+                                           QuicStreamId stream_id,
+                                           QuicResetStreamError error)
+    : QuicInlinedFrame(STOP_SENDING_FRAME),
+      control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      error_code(error.internal_code()),
+      ietf_error_code(error.ietf_application_code()) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicStopSendingFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", stream_id: " << frame.stream_id
+     << ", error_code: " << frame.error_code
+     << ", ietf_error_code: " << frame.ietf_error_code << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_stop_sending_frame.h b/quiche/quic/core/frames/quic_stop_sending_frame.h
new file mode 100644
index 0000000..e21937d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stop_sending_frame.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2018 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_FRAMES_QUIC_STOP_SENDING_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicStopSendingFrame
+    : public QuicInlinedFrame<QuicStopSendingFrame> {
+  QuicStopSendingFrame();
+  QuicStopSendingFrame(QuicControlFrameId control_frame_id,
+                       QuicStreamId stream_id,
+                       QuicRstStreamErrorCode error_code);
+  QuicStopSendingFrame(QuicControlFrameId control_frame_id,
+                       QuicStreamId stream_id, QuicResetStreamError error);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicStopSendingFrame& frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+  QuicStreamId stream_id = 0;
+
+  // For an outgoing frame, the error code generated by the application that
+  // determines |ietf_error_code| to be sent on the wire; for an incoming frame,
+  // the error code inferred from |ietf_error_code| received on the wire.
+  QuicRstStreamErrorCode error_code = QUIC_STREAM_NO_ERROR;
+
+  // On-the-wire application error code of the frame.
+  uint64_t ietf_error_code = 0;
+
+  // Returns a tuple of both |error_code| and |ietf_error_code|.
+  QuicResetStreamError error() const {
+    return QuicResetStreamError(error_code, ietf_error_code);
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_stop_waiting_frame.cc b/quiche/quic/core/frames/quic_stop_waiting_frame.cc
new file mode 100644
index 0000000..32941aa
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stop_waiting_frame.cc
@@ -0,0 +1,20 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_stop_waiting_frame.h"
+
+#include "quiche/quic/core/quic_constants.h"
+
+namespace quic {
+
+QuicStopWaitingFrame::QuicStopWaitingFrame()
+    : QuicInlinedFrame(STOP_WAITING_FRAME) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicStopWaitingFrame& sent_info) {
+  os << "{ least_unacked: " << sent_info.least_unacked << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_stop_waiting_frame.h b/quiche/quic/core/frames/quic_stop_waiting_frame.h
new file mode 100644
index 0000000..d04f57a
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stop_waiting_frame.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_STOP_WAITING_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicStopWaitingFrame
+    : public QuicInlinedFrame<QuicStopWaitingFrame> {
+  QuicStopWaitingFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicStopWaitingFrame& s);
+
+  QuicFrameType type;
+
+  // The lowest packet we've sent which is unacked, and we expect an ack for.
+  QuicPacketNumber least_unacked;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_stream_frame.cc b/quiche/quic/core/frames/quic_stream_frame.cc
new file mode 100644
index 0000000..81fbe04
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stream_frame.cc
@@ -0,0 +1,56 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_stream_frame.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicStreamFrame::QuicStreamFrame() : QuicInlinedFrame(STREAM_FRAME) {}
+
+QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
+                                 bool fin,
+                                 QuicStreamOffset offset,
+                                 absl::string_view data)
+    : QuicStreamFrame(stream_id, fin, offset, data.data(), data.length()) {}
+
+QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
+                                 bool fin,
+                                 QuicStreamOffset offset,
+                                 QuicPacketLength data_length)
+    : QuicStreamFrame(stream_id, fin, offset, nullptr, data_length) {}
+
+QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
+                                 bool fin,
+                                 QuicStreamOffset offset,
+                                 const char* data_buffer,
+                                 QuicPacketLength data_length)
+    : QuicInlinedFrame(STREAM_FRAME),
+      fin(fin),
+      data_length(data_length),
+      stream_id(stream_id),
+      data_buffer(data_buffer),
+      offset(offset) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicStreamFrame& stream_frame) {
+  os << "{ stream_id: " << stream_frame.stream_id
+     << ", fin: " << stream_frame.fin << ", offset: " << stream_frame.offset
+     << ", length: " << stream_frame.data_length << " }\n";
+  return os;
+}
+
+bool QuicStreamFrame::operator==(const QuicStreamFrame& rhs) const {
+  return fin == rhs.fin && data_length == rhs.data_length &&
+         stream_id == rhs.stream_id && data_buffer == rhs.data_buffer &&
+         offset == rhs.offset;
+}
+
+bool QuicStreamFrame::operator!=(const QuicStreamFrame& rhs) const {
+  return !(*this == rhs);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_stream_frame.h b/quiche/quic/core/frames/quic_stream_frame.h
new file mode 100644
index 0000000..6bcd41e
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stream_frame.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_STREAM_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicStreamFrame
+    : public QuicInlinedFrame<QuicStreamFrame> {
+  QuicStreamFrame();
+  QuicStreamFrame(QuicStreamId stream_id,
+                  bool fin,
+                  QuicStreamOffset offset,
+                  absl::string_view data);
+  QuicStreamFrame(QuicStreamId stream_id,
+                  bool fin,
+                  QuicStreamOffset offset,
+                  QuicPacketLength data_length);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const QuicStreamFrame& s);
+
+  bool operator==(const QuicStreamFrame& rhs) const;
+
+  bool operator!=(const QuicStreamFrame& rhs) const;
+
+  QuicFrameType type;
+  bool fin = false;
+  QuicPacketLength data_length = 0;
+  // TODO(wub): Change to a QuicUtils::GetInvalidStreamId when it is not version
+  // dependent.
+  QuicStreamId stream_id = -1;
+  const char* data_buffer = nullptr;  // Not owned.
+  QuicStreamOffset offset = 0;        // Location of this data in the stream.
+
+  QuicStreamFrame(QuicStreamId stream_id,
+                  bool fin,
+                  QuicStreamOffset offset,
+                  const char* data_buffer,
+                  QuicPacketLength data_length);
+};
+static_assert(sizeof(QuicStreamFrame) <= 64,
+              "Keep the QuicStreamFrame size to a cacheline.");
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_streams_blocked_frame.cc b/quiche/quic/core/frames/quic_streams_blocked_frame.cc
new file mode 100644
index 0000000..2ca554e
--- /dev/null
+++ b/quiche/quic/core/frames/quic_streams_blocked_frame.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2019 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 "quiche/quic/core/frames/quic_streams_blocked_frame.h"
+
+namespace quic {
+
+QuicStreamsBlockedFrame::QuicStreamsBlockedFrame()
+    : QuicInlinedFrame(STREAMS_BLOCKED_FRAME) {}
+
+QuicStreamsBlockedFrame::QuicStreamsBlockedFrame(
+    QuicControlFrameId control_frame_id,
+    QuicStreamCount stream_count,
+    bool unidirectional)
+    : QuicInlinedFrame(STREAMS_BLOCKED_FRAME),
+      control_frame_id(control_frame_id),
+      stream_count(stream_count),
+      unidirectional(unidirectional) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicStreamsBlockedFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", stream count: " << frame.stream_count
+     << ((frame.unidirectional) ? ", unidirectional }\n"
+                                : ", bidirectional }\n");
+
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_streams_blocked_frame.h b/quiche/quic/core/frames/quic_streams_blocked_frame.h
new file mode 100644
index 0000000..05eb1cc
--- /dev/null
+++ b/quiche/quic/core/frames/quic_streams_blocked_frame.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2019 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_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// IETF format STREAMS_BLOCKED frame.
+// The sender uses this to inform the peer that the sender wished to
+// open a new stream, exceeding the limit on the number of streams.
+struct QUIC_EXPORT_PRIVATE QuicStreamsBlockedFrame
+    : public QuicInlinedFrame<QuicStreamsBlockedFrame> {
+  QuicStreamsBlockedFrame();
+  QuicStreamsBlockedFrame(QuicControlFrameId control_frame_id,
+                          QuicStreamCount stream_count,
+                          bool unidirectional);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicStreamsBlockedFrame& frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // The number of streams that the sender wishes to exceed
+  QuicStreamCount stream_count = 0;
+
+  // Whether uni- or bi-directional streams
+  bool unidirectional = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_window_update_frame.cc b/quiche/quic/core/frames/quic_window_update_frame.cc
new file mode 100644
index 0000000..3c13454
--- /dev/null
+++ b/quiche/quic/core/frames/quic_window_update_frame.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_window_update_frame.h"
+
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+QuicWindowUpdateFrame::QuicWindowUpdateFrame()
+    : QuicInlinedFrame(WINDOW_UPDATE_FRAME) {}
+
+QuicWindowUpdateFrame::QuicWindowUpdateFrame(
+    QuicControlFrameId control_frame_id, QuicStreamId stream_id,
+    QuicByteCount max_data)
+    : QuicInlinedFrame(WINDOW_UPDATE_FRAME),
+      control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      max_data(max_data) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicWindowUpdateFrame& window_update_frame) {
+  os << "{ control_frame_id: " << window_update_frame.control_frame_id
+     << ", stream_id: " << window_update_frame.stream_id
+     << ", max_data: " << window_update_frame.max_data << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_window_update_frame.h b/quiche/quic/core/frames/quic_window_update_frame.h
new file mode 100644
index 0000000..1cbd7ff
--- /dev/null
+++ b/quiche/quic/core/frames/quic_window_update_frame.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2016 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_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+// Flow control updates per-stream and at the connection level.
+// Based on SPDY's WINDOW_UPDATE frame, but uses an absolute max data bytes
+// rather than a window delta.
+struct QUIC_EXPORT_PRIVATE QuicWindowUpdateFrame
+    : public QuicInlinedFrame<QuicWindowUpdateFrame> {
+  QuicWindowUpdateFrame();
+  QuicWindowUpdateFrame(QuicControlFrameId control_frame_id,
+                        QuicStreamId stream_id, QuicByteCount max_data);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const QuicWindowUpdateFrame& w);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // The stream this frame applies to.  0 is a special case meaning the overall
+  // connection rather than a specific stream.
+  QuicStreamId stream_id = 0;
+
+  // Maximum data allowed in the stream or connection. The receiver of this
+  // frame must not send data which would exceedes this restriction.
+  QuicByteCount max_data = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
diff --git a/quiche/quic/core/handshaker_delegate_interface.h b/quiche/quic/core/handshaker_delegate_interface.h
new file mode 100644
index 0000000..d6e2501
--- /dev/null
+++ b/quiche/quic/core/handshaker_delegate_interface.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2019 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_HANDSHAKER_DELEGATE_INTERFACE_H_
+#define QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
+
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+
+namespace quic {
+
+class QuicDecrypter;
+class QuicEncrypter;
+
+// Pure virtual class to get notified when particular handshake events occurred.
+class QUIC_EXPORT_PRIVATE HandshakerDelegateInterface {
+ public:
+  virtual ~HandshakerDelegateInterface() {}
+
+  // Called when new decryption key of |level| is available. Returns true if
+  // decrypter is set successfully, otherwise, returns false.
+  virtual bool OnNewDecryptionKeyAvailable(
+      EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
+      bool set_alternative_decrypter, bool latch_once_used) = 0;
+
+  // Called when new encryption key of |level| is available.
+  virtual void OnNewEncryptionKeyAvailable(
+      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) = 0;
+
+  // Called to set default encryption level to |level|. Only used in QUIC
+  // crypto.
+  virtual void SetDefaultEncryptionLevel(EncryptionLevel level) = 0;
+
+  // Called when both 1-RTT read and write keys are available. Only used in TLS
+  // handshake.
+  virtual void OnTlsHandshakeComplete() = 0;
+
+  // Called to discard old decryption keys to stop processing packets of
+  // encryption |level|.
+  virtual void DiscardOldDecryptionKey(EncryptionLevel level) = 0;
+
+  // Called to discard old encryption keys (and neuter obsolete data).
+  // TODO(fayang): consider to combine this with DiscardOldDecryptionKey.
+  virtual void DiscardOldEncryptionKey(EncryptionLevel level) = 0;
+
+  // Called to neuter ENCRYPTION_INITIAL data (without discarding initial keys).
+  virtual void NeuterUnencryptedData() = 0;
+
+  // Called to neuter data of HANDSHAKE_DATA packet number space. Only used in
+  // QUIC crypto. This is called 1) when a client switches to forward secure
+  // encryption level and 2) a server successfully processes a forward secure
+  // packet.
+  virtual void NeuterHandshakeData() = 0;
+
+  // Called when 0-RTT data is rejected by the server. This is only called in
+  // TLS handshakes and only called on clients.
+  virtual void OnZeroRttRejected(int reason) = 0;
+
+  // Fills in |params| with values from the delegate's QuicConfig.
+  // Returns whether the operation succeeded.
+  virtual bool FillTransportParameters(TransportParameters* params) = 0;
+
+  // Read |params| and apply the values to the delegate's QuicConfig.
+  // On failure, returns a QuicErrorCode and saves a detailed error in
+  // |error_details|.
+  virtual QuicErrorCode ProcessTransportParameters(
+      const TransportParameters& params, bool is_resumption,
+      std::string* error_details) = 0;
+
+  // Called at the end of an handshake operation callback.
+  virtual void OnHandshakeCallbackDone() = 0;
+
+  // Whether a packet flusher is currently attached.
+  virtual bool PacketFlusherAttached() const = 0;
+
+  // Get the QUIC version currently in use. tls_handshaker needs this to pass
+  // to crypto_utils to apply version-dependent HKDF labels.
+  virtual ParsedQuicVersion parsed_version() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
diff --git a/quiche/quic/core/http/capsule.cc b/quiche/quic/core/http/capsule.cc
new file mode 100644
index 0000000..f17c769
--- /dev/null
+++ b/quiche/quic/core/http/capsule.cc
@@ -0,0 +1,749 @@
+// Copyright (c) 2021 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 "quiche/quic/core/http/capsule.h"
+
+#include <type_traits>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+std::string CapsuleTypeToString(CapsuleType capsule_type) {
+  switch (capsule_type) {
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      return "REGISTER_DATAGRAM_CONTEXT";
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      return "CLOSE_DATAGRAM_CONTEXT";
+    case CapsuleType::LEGACY_DATAGRAM:
+      return "LEGACY_DATAGRAM";
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      return "DATAGRAM_WITH_CONTEXT";
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      return "DATAGRAM_WITHOUT_CONTEXT";
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      return "REGISTER_DATAGRAM_NO_CONTEXT";
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      return "CLOSE_WEBTRANSPORT_SESSION";
+  }
+  return absl::StrCat("Unknown(", static_cast<uint64_t>(capsule_type), ")");
+}
+
+std::ostream& operator<<(std::ostream& os, const CapsuleType& capsule_type) {
+  os << CapsuleTypeToString(capsule_type);
+  return os;
+}
+
+std::string DatagramFormatTypeToString(
+    DatagramFormatType datagram_format_type) {
+  switch (datagram_format_type) {
+    case DatagramFormatType::UDP_PAYLOAD:
+      return "UDP_PAYLOAD";
+    case DatagramFormatType::WEBTRANSPORT:
+      return "WEBTRANSPORT";
+  }
+  return absl::StrCat("Unknown(", static_cast<uint64_t>(datagram_format_type),
+                      ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const DatagramFormatType& datagram_format_type) {
+  os << DatagramFormatTypeToString(datagram_format_type);
+  return os;
+}
+
+std::string ContextCloseCodeToString(ContextCloseCode context_close_code) {
+  switch (context_close_code) {
+    case ContextCloseCode::CLOSE_NO_ERROR:
+      return "NO_ERROR";
+    case ContextCloseCode::UNKNOWN_FORMAT:
+      return "UNKNOWN_FORMAT";
+    case ContextCloseCode::DENIED:
+      return "DENIED";
+    case ContextCloseCode::RESOURCE_LIMIT:
+      return "RESOURCE_LIMIT";
+  }
+  return absl::StrCat("Unknown(", static_cast<uint64_t>(context_close_code),
+                      ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ContextCloseCode& context_close_code) {
+  os << ContextCloseCodeToString(context_close_code);
+  return os;
+}
+
+Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
+  switch (capsule_type) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      static_assert(
+          std::is_standard_layout<LegacyDatagramCapsule>::value &&
+              std::is_trivially_destructible<LegacyDatagramCapsule>::value,
+          "All capsule structs must have these properties");
+      legacy_datagram_capsule_ = LegacyDatagramCapsule();
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      static_assert(
+          std::is_standard_layout<DatagramWithContextCapsule>::value &&
+              std::is_trivially_destructible<DatagramWithContextCapsule>::value,
+          "All capsule structs must have these properties");
+      datagram_with_context_capsule_ = DatagramWithContextCapsule();
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      static_assert(
+          std::is_standard_layout<DatagramWithoutContextCapsule>::value &&
+              std::is_trivially_destructible<
+                  DatagramWithoutContextCapsule>::value,
+          "All capsule structs must have these properties");
+      datagram_without_context_capsule_ = DatagramWithoutContextCapsule();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      static_assert(
+          std::is_standard_layout<RegisterDatagramContextCapsule>::value &&
+              std::is_trivially_destructible<
+                  RegisterDatagramContextCapsule>::value,
+          "All capsule structs must have these properties");
+      register_datagram_context_capsule_ = RegisterDatagramContextCapsule();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      static_assert(
+          std::is_standard_layout<RegisterDatagramNoContextCapsule>::value &&
+              std::is_trivially_destructible<
+                  RegisterDatagramNoContextCapsule>::value,
+          "All capsule structs must have these properties");
+      register_datagram_no_context_capsule_ =
+          RegisterDatagramNoContextCapsule();
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      static_assert(
+          std::is_standard_layout<CloseDatagramContextCapsule>::value &&
+              std::is_trivially_destructible<
+                  CloseDatagramContextCapsule>::value,
+          "All capsule structs must have these properties");
+      close_datagram_context_capsule_ = CloseDatagramContextCapsule();
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      static_assert(
+          std::is_standard_layout<CloseWebTransportSessionCapsule>::value &&
+              std::is_trivially_destructible<
+                  CloseWebTransportSessionCapsule>::value,
+          "All capsule structs must have these properties");
+      close_web_transport_session_capsule_ = CloseWebTransportSessionCapsule();
+      break;
+    default:
+      unknown_capsule_data_ = absl::string_view();
+      break;
+  }
+}
+
+// static
+Capsule Capsule::LegacyDatagram(
+    absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view http_datagram_payload) {
+  Capsule capsule(CapsuleType::LEGACY_DATAGRAM);
+  capsule.legacy_datagram_capsule().context_id = context_id;
+  capsule.legacy_datagram_capsule().http_datagram_payload =
+      http_datagram_payload;
+  return capsule;
+}
+
+// static
+Capsule Capsule::DatagramWithContext(QuicDatagramContextId context_id,
+                                     absl::string_view http_datagram_payload) {
+  Capsule capsule(CapsuleType::DATAGRAM_WITH_CONTEXT);
+  capsule.datagram_with_context_capsule().context_id = context_id;
+  capsule.datagram_with_context_capsule().http_datagram_payload =
+      http_datagram_payload;
+  return capsule;
+}
+
+// static
+Capsule Capsule::DatagramWithoutContext(
+    absl::string_view http_datagram_payload) {
+  Capsule capsule(CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
+  capsule.datagram_without_context_capsule().http_datagram_payload =
+      http_datagram_payload;
+  return capsule;
+}
+
+// static
+Capsule Capsule::RegisterDatagramContext(
+    QuicDatagramContextId context_id, DatagramFormatType format_type,
+    absl::string_view format_additional_data) {
+  Capsule capsule(CapsuleType::REGISTER_DATAGRAM_CONTEXT);
+  capsule.register_datagram_context_capsule().context_id = context_id;
+  capsule.register_datagram_context_capsule().format_type = format_type;
+  capsule.register_datagram_context_capsule().format_additional_data =
+      format_additional_data;
+  return capsule;
+}
+
+// static
+Capsule Capsule::RegisterDatagramNoContext(
+    DatagramFormatType format_type, absl::string_view format_additional_data) {
+  Capsule capsule(CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
+  capsule.register_datagram_no_context_capsule().format_type = format_type;
+  capsule.register_datagram_no_context_capsule().format_additional_data =
+      format_additional_data;
+  return capsule;
+}
+
+// static
+Capsule Capsule::CloseDatagramContext(QuicDatagramContextId context_id,
+                                      ContextCloseCode close_code,
+                                      absl::string_view close_details) {
+  Capsule capsule(CapsuleType::CLOSE_DATAGRAM_CONTEXT);
+  capsule.close_datagram_context_capsule().context_id = context_id;
+  capsule.close_datagram_context_capsule().close_code = close_code;
+  capsule.close_datagram_context_capsule().close_details = close_details;
+  return capsule;
+}
+
+// static
+Capsule Capsule::CloseWebTransportSession(WebTransportSessionError error_code,
+                                          absl::string_view error_message) {
+  Capsule capsule(CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
+  capsule.close_web_transport_session_capsule().error_code = error_code;
+  capsule.close_web_transport_session_capsule().error_message = error_message;
+  return capsule;
+}
+
+// static
+Capsule Capsule::Unknown(uint64_t capsule_type,
+                         absl::string_view unknown_capsule_data) {
+  Capsule capsule(static_cast<CapsuleType>(capsule_type));
+  capsule.unknown_capsule_data() = unknown_capsule_data;
+  return capsule;
+}
+
+Capsule& Capsule::operator=(const Capsule& other) {
+  capsule_type_ = other.capsule_type_;
+  switch (capsule_type_) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      legacy_datagram_capsule_ = other.legacy_datagram_capsule_;
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      datagram_with_context_capsule_ = other.datagram_with_context_capsule_;
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      datagram_without_context_capsule_ =
+          other.datagram_without_context_capsule_;
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      register_datagram_context_capsule_ =
+          other.register_datagram_context_capsule_;
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      register_datagram_no_context_capsule_ =
+          other.register_datagram_no_context_capsule_;
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      close_datagram_context_capsule_ = other.close_datagram_context_capsule_;
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      close_web_transport_session_capsule_ =
+          other.close_web_transport_session_capsule_;
+      break;
+    default:
+      unknown_capsule_data_ = other.unknown_capsule_data_;
+      break;
+  }
+  return *this;
+}
+
+Capsule::Capsule(const Capsule& other) : Capsule(other.capsule_type_) {
+  *this = other;
+}
+
+bool Capsule::operator==(const Capsule& other) const {
+  if (capsule_type_ != other.capsule_type_) {
+    return false;
+  }
+  switch (capsule_type_) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      return legacy_datagram_capsule_.context_id ==
+                 other.legacy_datagram_capsule_.context_id &&
+             legacy_datagram_capsule_.http_datagram_payload ==
+                 other.legacy_datagram_capsule_.http_datagram_payload;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      return datagram_with_context_capsule_.context_id ==
+                 other.datagram_with_context_capsule_.context_id &&
+             datagram_with_context_capsule_.http_datagram_payload ==
+                 other.datagram_with_context_capsule_.http_datagram_payload;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      return datagram_without_context_capsule_.http_datagram_payload ==
+             other.datagram_without_context_capsule_.http_datagram_payload;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      return register_datagram_context_capsule_.context_id ==
+                 other.register_datagram_context_capsule_.context_id &&
+             register_datagram_context_capsule_.format_type ==
+                 other.register_datagram_context_capsule_.format_type &&
+             register_datagram_context_capsule_.format_additional_data ==
+                 other.register_datagram_context_capsule_
+                     .format_additional_data;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      return register_datagram_no_context_capsule_.format_type ==
+                 other.register_datagram_no_context_capsule_.format_type &&
+             register_datagram_no_context_capsule_.format_additional_data ==
+                 other.register_datagram_no_context_capsule_
+                     .format_additional_data;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      return close_datagram_context_capsule_.context_id ==
+                 other.close_datagram_context_capsule_.context_id &&
+             close_datagram_context_capsule_.close_code ==
+                 other.close_datagram_context_capsule_.close_code &&
+             close_datagram_context_capsule_.close_details ==
+                 other.close_datagram_context_capsule_.close_details;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      return close_web_transport_session_capsule_.error_code ==
+                 other.close_web_transport_session_capsule_.error_code &&
+             close_web_transport_session_capsule_.error_message ==
+                 other.close_web_transport_session_capsule_.error_message;
+    default:
+      return unknown_capsule_data_ == other.unknown_capsule_data_;
+  }
+}
+
+std::string Capsule::ToString() const {
+  std::string rv = CapsuleTypeToString(capsule_type_);
+  switch (capsule_type_) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      if (legacy_datagram_capsule_.context_id.has_value()) {
+        absl::StrAppend(&rv, "(", legacy_datagram_capsule_.context_id.value(),
+                        ")");
+      }
+      absl::StrAppend(&rv, "[",
+                      absl::BytesToHexString(
+                          legacy_datagram_capsule_.http_datagram_payload),
+                      "]");
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      absl::StrAppend(&rv, "(", datagram_with_context_capsule_.context_id, ")[",
+                      absl::BytesToHexString(
+                          datagram_with_context_capsule_.http_datagram_payload),
+                      "]");
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      absl::StrAppend(
+          &rv, "[",
+          absl::BytesToHexString(
+              datagram_without_context_capsule_.http_datagram_payload),
+          "]");
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      absl::StrAppend(
+          &rv, "(context_id=", register_datagram_context_capsule_.context_id,
+          ",format_type=",
+          DatagramFormatTypeToString(
+              register_datagram_context_capsule_.format_type),
+          "){",
+          absl::BytesToHexString(
+              register_datagram_context_capsule_.format_additional_data),
+          "}");
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      absl::StrAppend(
+          &rv, "(format_type=",
+          DatagramFormatTypeToString(
+              register_datagram_no_context_capsule_.format_type),
+          "){",
+          absl::BytesToHexString(
+              register_datagram_no_context_capsule_.format_additional_data),
+          "}");
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      absl::StrAppend(
+          &rv, "(context_id=", close_datagram_context_capsule_.context_id,
+          ",close_code=",
+          ContextCloseCodeToString(close_datagram_context_capsule_.close_code),
+          ",close_details=\"",
+          absl::BytesToHexString(close_datagram_context_capsule_.close_details),
+          "\")");
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      absl::StrAppend(
+          &rv, "(error_code=", close_web_transport_session_capsule_.error_code,
+          ",error_message=\"",
+          close_web_transport_session_capsule_.error_message, "\")");
+      break;
+    default:
+      absl::StrAppend(&rv, "[", absl::BytesToHexString(unknown_capsule_data_),
+                      "]");
+      break;
+  }
+  return rv;
+}
+
+std::ostream& operator<<(std::ostream& os, const Capsule& capsule) {
+  os << capsule.ToString();
+  return os;
+}
+
+CapsuleParser::CapsuleParser(Visitor* visitor) : visitor_(visitor) {
+  QUICHE_DCHECK_NE(visitor_, nullptr);
+}
+
+quiche::QuicheBuffer SerializeCapsule(
+    const Capsule& capsule, quiche::QuicheBufferAllocator* allocator) {
+  QuicByteCount capsule_type_length = QuicDataWriter::GetVarInt62Len(
+      static_cast<uint64_t>(capsule.capsule_type()));
+  QuicByteCount capsule_data_length;
+  switch (capsule.capsule_type()) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      capsule_data_length =
+          capsule.legacy_datagram_capsule().http_datagram_payload.length();
+      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
+        capsule_data_length += QuicDataWriter::GetVarInt62Len(
+            capsule.legacy_datagram_capsule().context_id.value());
+      }
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      capsule_data_length =
+          QuicDataWriter::GetVarInt62Len(
+              capsule.datagram_with_context_capsule().context_id) +
+          capsule.datagram_with_context_capsule()
+              .http_datagram_payload.length();
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      capsule_data_length = capsule.datagram_without_context_capsule()
+                                .http_datagram_payload.length();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      capsule_data_length =
+          QuicDataWriter::GetVarInt62Len(
+              capsule.register_datagram_context_capsule().context_id) +
+          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
+              capsule.register_datagram_context_capsule().format_type)) +
+          capsule.register_datagram_context_capsule()
+              .format_additional_data.length();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      capsule_data_length =
+          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
+              capsule.register_datagram_no_context_capsule().format_type)) +
+          capsule.register_datagram_no_context_capsule()
+              .format_additional_data.length();
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      capsule_data_length =
+          QuicDataWriter::GetVarInt62Len(
+              capsule.close_datagram_context_capsule().context_id) +
+          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
+              capsule.close_datagram_context_capsule().close_code)) +
+          capsule.close_datagram_context_capsule().close_details.length();
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      capsule_data_length =
+          sizeof(WebTransportSessionError) +
+          capsule.close_web_transport_session_capsule().error_message.size();
+      break;
+    default:
+      capsule_data_length = capsule.unknown_capsule_data().length();
+      break;
+  }
+  QuicByteCount capsule_length_length =
+      QuicDataWriter::GetVarInt62Len(capsule_data_length);
+  QuicByteCount total_capsule_length =
+      capsule_type_length + capsule_length_length + capsule_data_length;
+  quiche::QuicheBuffer buffer(allocator, total_capsule_length);
+  QuicDataWriter writer(buffer.size(), buffer.data());
+  if (!writer.WriteVarInt62(static_cast<uint64_t>(capsule.capsule_type()))) {
+    QUIC_BUG(capsule type write fail) << "Failed to write CAPSULE type";
+    return {};
+  }
+  if (!writer.WriteVarInt62(capsule_data_length)) {
+    QUIC_BUG(capsule length write fail) << "Failed to write CAPSULE length";
+    return {};
+  }
+  switch (capsule.capsule_type()) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
+        if (!writer.WriteVarInt62(
+                capsule.legacy_datagram_capsule().context_id.value())) {
+          QUIC_BUG(datagram capsule context ID write fail)
+              << "Failed to write LEGACY_DATAGRAM CAPSULE context ID";
+          return {};
+        }
+      }
+      if (!writer.WriteStringPiece(
+              capsule.legacy_datagram_capsule().http_datagram_payload)) {
+        QUIC_BUG(datagram capsule payload write fail)
+            << "Failed to write LEGACY_DATAGRAM CAPSULE payload";
+        return {};
+      }
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      if (!writer.WriteVarInt62(
+              capsule.datagram_with_context_capsule().context_id)) {
+        QUIC_BUG(datagram capsule context ID write fail)
+            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE context ID";
+        return {};
+      }
+      if (!writer.WriteStringPiece(
+              capsule.datagram_with_context_capsule().http_datagram_payload)) {
+        QUIC_BUG(datagram capsule payload write fail)
+            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE payload";
+        return {};
+      }
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      if (!writer.WriteStringPiece(capsule.datagram_without_context_capsule()
+                                       .http_datagram_payload)) {
+        QUIC_BUG(datagram capsule payload write fail)
+            << "Failed to write DATAGRAM_WITHOUT_CONTEXT CAPSULE payload";
+        return {};
+      }
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      if (!writer.WriteVarInt62(
+              capsule.register_datagram_context_capsule().context_id)) {
+        QUIC_BUG(register context capsule context ID write fail)
+            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE context ID";
+        return {};
+      }
+      if (!writer.WriteVarInt62(static_cast<uint64_t>(
+              capsule.register_datagram_context_capsule().format_type))) {
+        QUIC_BUG(register context capsule format type write fail)
+            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE format type";
+        return {};
+      }
+      if (!writer.WriteStringPiece(capsule.register_datagram_context_capsule()
+                                       .format_additional_data)) {
+        QUIC_BUG(register context capsule additional data write fail)
+            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE additional "
+               "data";
+        return {};
+      }
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      if (!writer.WriteVarInt62(static_cast<uint64_t>(
+              capsule.register_datagram_no_context_capsule().format_type))) {
+        QUIC_BUG(register no context capsule format type write fail)
+            << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE format "
+               "type";
+        return {};
+      }
+      if (!writer.WriteStringPiece(
+              capsule.register_datagram_no_context_capsule()
+                  .format_additional_data)) {
+        QUIC_BUG(register no context capsule additional data write fail)
+            << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE "
+               "additional data";
+        return {};
+      }
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      if (!writer.WriteVarInt62(
+              capsule.close_datagram_context_capsule().context_id)) {
+        QUIC_BUG(close context capsule context ID write fail)
+            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE context ID";
+        return {};
+      }
+      if (!writer.WriteVarInt62(static_cast<uint64_t>(
+              capsule.close_datagram_context_capsule().close_code))) {
+        QUIC_BUG(close context capsule close code write fail)
+            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close code";
+        return {};
+      }
+      if (!writer.WriteStringPiece(
+              capsule.close_datagram_context_capsule().close_details)) {
+        QUIC_BUG(close context capsule close details write fail)
+            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close details";
+        return {};
+      }
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      if (!writer.WriteUInt32(
+              capsule.close_web_transport_session_capsule().error_code)) {
+        QUIC_BUG(close webtransport session capsule error code write fail)
+            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error code";
+        return {};
+      }
+      if (!writer.WriteStringPiece(
+              capsule.close_web_transport_session_capsule().error_message)) {
+        QUIC_BUG(close webtransport session capsule error message write fail)
+            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error message";
+        return {};
+      }
+      break;
+    default:
+      if (!writer.WriteStringPiece(capsule.unknown_capsule_data())) {
+        QUIC_BUG(capsule data write fail) << "Failed to write CAPSULE data";
+        return {};
+      }
+      break;
+  }
+  if (writer.remaining() != 0) {
+    QUIC_BUG(capsule write length mismatch)
+        << "CAPSULE serialization wrote " << writer.length() << " instead of "
+        << writer.capacity();
+    return {};
+  }
+  return buffer;
+}
+
+bool CapsuleParser::IngestCapsuleFragment(absl::string_view capsule_fragment) {
+  if (parsing_error_occurred_) {
+    return false;
+  }
+  absl::StrAppend(&buffered_data_, capsule_fragment);
+  while (true) {
+    const size_t buffered_data_read = AttemptParseCapsule();
+    if (parsing_error_occurred_) {
+      QUICHE_DCHECK_EQ(buffered_data_read, 0u);
+      buffered_data_.clear();
+      return false;
+    }
+    if (buffered_data_read == 0) {
+      break;
+    }
+    buffered_data_.erase(0, buffered_data_read);
+  }
+  static constexpr size_t kMaxCapsuleBufferSize = 1024 * 1024;
+  if (buffered_data_.size() > kMaxCapsuleBufferSize) {
+    buffered_data_.clear();
+    ReportParseFailure("Refusing to buffer too much capsule data");
+    return false;
+  }
+  return true;
+}
+
+size_t CapsuleParser::AttemptParseCapsule() {
+  QUICHE_DCHECK(!parsing_error_occurred_);
+  if (buffered_data_.empty()) {
+    return 0;
+  }
+  QuicDataReader capsule_fragment_reader(buffered_data_);
+  uint64_t capsule_type64;
+  if (!capsule_fragment_reader.ReadVarInt62(&capsule_type64)) {
+    QUIC_DVLOG(2) << "Partial read: not enough data to read capsule type";
+    return 0;
+  }
+  absl::string_view capsule_data;
+  if (!capsule_fragment_reader.ReadStringPieceVarInt62(&capsule_data)) {
+    QUIC_DVLOG(2) << "Partial read: not enough data to read capsule length or "
+                     "full capsule data";
+    return 0;
+  }
+  QuicDataReader capsule_data_reader(capsule_data);
+  Capsule capsule(static_cast<CapsuleType>(capsule_type64));
+  switch (capsule.capsule_type()) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      if (datagram_context_id_present_) {
+        uint64_t context_id;
+        if (!capsule_data_reader.ReadVarInt62(&context_id)) {
+          ReportParseFailure(
+              "Unable to parse capsule LEGACY_DATAGRAM context ID");
+          return 0;
+        }
+        capsule.legacy_datagram_capsule().context_id = context_id;
+      }
+      capsule.legacy_datagram_capsule().http_datagram_payload =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      uint64_t context_id;
+      if (!capsule_data_reader.ReadVarInt62(&context_id)) {
+        ReportParseFailure(
+            "Unable to parse capsule DATAGRAM_WITH_CONTEXT context ID");
+        return 0;
+      }
+      capsule.datagram_with_context_capsule().context_id = context_id;
+      capsule.datagram_with_context_capsule().http_datagram_payload =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      capsule.datagram_without_context_capsule().http_datagram_payload =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      if (!capsule_data_reader.ReadVarInt62(
+              &capsule.register_datagram_context_capsule().context_id)) {
+        ReportParseFailure(
+            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT context ID");
+        return 0;
+      }
+      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
+              &capsule.register_datagram_context_capsule().format_type))) {
+        ReportParseFailure(
+            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT format type");
+        return 0;
+      }
+      capsule.register_datagram_context_capsule().format_additional_data =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
+              &capsule.register_datagram_no_context_capsule().format_type))) {
+        ReportParseFailure(
+            "Unable to parse capsule REGISTER_DATAGRAM_NO_CONTEXT format type");
+        return 0;
+      }
+      capsule.register_datagram_no_context_capsule().format_additional_data =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      if (!capsule_data_reader.ReadVarInt62(
+              &capsule.close_datagram_context_capsule().context_id)) {
+        ReportParseFailure(
+            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT context ID");
+        return 0;
+      }
+      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
+              &capsule.close_datagram_context_capsule().close_code))) {
+        ReportParseFailure(
+            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT close code");
+        return 0;
+      }
+      capsule.close_datagram_context_capsule().close_details =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      if (!capsule_data_reader.ReadUInt32(
+              &capsule.close_web_transport_session_capsule().error_code)) {
+        ReportParseFailure(
+            "Unable to parse capsule CLOSE_WEBTRANSPORT_SESSION error code");
+        return 0;
+      }
+      capsule.close_web_transport_session_capsule().error_message =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    default:
+      capsule.unknown_capsule_data() =
+          capsule_data_reader.ReadRemainingPayload();
+  }
+  if (!visitor_->OnCapsule(capsule)) {
+    ReportParseFailure("Visitor failed to process capsule");
+    return 0;
+  }
+  return capsule_fragment_reader.PreviouslyReadPayload().length();
+}
+
+void CapsuleParser::ReportParseFailure(const std::string& error_message) {
+  if (parsing_error_occurred_) {
+    QUIC_BUG(multiple parse errors) << "Experienced multiple parse failures";
+    return;
+  }
+  parsing_error_occurred_ = true;
+  visitor_->OnCapsuleParseFailure(error_message);
+}
+
+void CapsuleParser::ErrorIfThereIsRemainingBufferedData() {
+  if (parsing_error_occurred_) {
+    return;
+  }
+  if (!buffered_data_.empty()) {
+    ReportParseFailure("Incomplete capsule left at the end of the stream");
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/capsule.h b/quiche/quic/core/http/capsule.h
new file mode 100644
index 0000000..5a93bd3
--- /dev/null
+++ b/quiche/quic/core/http/capsule.h
@@ -0,0 +1,291 @@
+// Copyright (c) 2021 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_HTTP_CAPSULE_H_
+#define QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quic {
+
+enum class CapsuleType : uint64_t {
+  // Casing in this enum matches the IETF specification.
+  LEGACY_DATAGRAM = 0xff37a0,  // draft-ietf-masque-h3-datagram-04
+  REGISTER_DATAGRAM_CONTEXT = 0xff37a1,
+  REGISTER_DATAGRAM_NO_CONTEXT = 0xff37a2,
+  CLOSE_DATAGRAM_CONTEXT = 0xff37a3,
+  DATAGRAM_WITH_CONTEXT = 0xff37a4,
+  DATAGRAM_WITHOUT_CONTEXT = 0xff37a5,
+  CLOSE_WEBTRANSPORT_SESSION = 0x2843,
+};
+
+QUIC_EXPORT_PRIVATE std::string CapsuleTypeToString(CapsuleType capsule_type);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const CapsuleType& capsule_type);
+
+enum class DatagramFormatType : uint64_t {
+  // Casing in this enum matches the IETF specification.
+  UDP_PAYLOAD = 0xff6f00,
+  WEBTRANSPORT = 0xff7c00,
+};
+
+QUIC_EXPORT_PRIVATE std::string DatagramFormatTypeToString(
+    DatagramFormatType datagram_format_type);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const DatagramFormatType& datagram_format_type);
+
+enum class ContextCloseCode : uint64_t {
+  // Casing in this enum matches the IETF specification.
+  CLOSE_NO_ERROR = 0xff78a0,  // NO_ERROR already exists in winerror.h.
+  UNKNOWN_FORMAT = 0xff78a1,
+  DENIED = 0xff78a2,
+  RESOURCE_LIMIT = 0xff78a3,
+};
+
+QUIC_EXPORT_PRIVATE std::string ContextCloseCodeToString(
+    ContextCloseCode context_close_code);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ContextCloseCode& context_close_code);
+
+struct QUIC_EXPORT_PRIVATE LegacyDatagramCapsule {
+  absl::optional<QuicDatagramContextId> context_id;
+  absl::string_view http_datagram_payload;
+};
+struct QUIC_EXPORT_PRIVATE DatagramWithContextCapsule {
+  QuicDatagramContextId context_id;
+  absl::string_view http_datagram_payload;
+};
+struct QUIC_EXPORT_PRIVATE DatagramWithoutContextCapsule {
+  absl::string_view http_datagram_payload;
+};
+struct QUIC_EXPORT_PRIVATE RegisterDatagramContextCapsule {
+  QuicDatagramContextId context_id;
+  DatagramFormatType format_type;
+  absl::string_view format_additional_data;
+};
+struct QUIC_EXPORT_PRIVATE RegisterDatagramNoContextCapsule {
+  DatagramFormatType format_type;
+  absl::string_view format_additional_data;
+};
+struct QUIC_EXPORT_PRIVATE CloseDatagramContextCapsule {
+  QuicDatagramContextId context_id;
+  ContextCloseCode close_code;
+  absl::string_view close_details;
+};
+struct QUIC_EXPORT_PRIVATE CloseWebTransportSessionCapsule {
+  WebTransportSessionError error_code;
+  absl::string_view error_message;
+};
+
+// Capsule from draft-ietf-masque-h3-datagram.
+// IMPORTANT NOTE: Capsule does not own any of the absl::string_view memory it
+// points to. Strings saved into a capsule must outlive the capsule object. Any
+// code that sees a capsule in a callback needs to either process it immediately
+// or perform its own deep copy.
+class QUIC_EXPORT_PRIVATE Capsule {
+ public:
+  static Capsule LegacyDatagram(
+      absl::optional<QuicDatagramContextId> context_id = absl::nullopt,
+      absl::string_view http_datagram_payload = absl::string_view());
+  static Capsule DatagramWithContext(
+      QuicDatagramContextId context_id,
+      absl::string_view http_datagram_payload = absl::string_view());
+  static Capsule DatagramWithoutContext(
+      absl::string_view http_datagram_payload = absl::string_view());
+  static Capsule RegisterDatagramContext(
+      QuicDatagramContextId context_id, DatagramFormatType format_type,
+      absl::string_view format_additional_data = absl::string_view());
+  static Capsule RegisterDatagramNoContext(
+      DatagramFormatType format_type,
+      absl::string_view format_additional_data = absl::string_view());
+  static Capsule CloseDatagramContext(
+      QuicDatagramContextId context_id,
+      ContextCloseCode close_code = ContextCloseCode::CLOSE_NO_ERROR,
+      absl::string_view close_details = absl::string_view());
+  static Capsule CloseWebTransportSession(
+      WebTransportSessionError error_code = 0,
+      absl::string_view error_message = "");
+  static Capsule Unknown(
+      uint64_t capsule_type,
+      absl::string_view unknown_capsule_data = absl::string_view());
+
+  explicit Capsule(CapsuleType capsule_type);
+  Capsule(const Capsule& other);
+  Capsule& operator=(const Capsule& other);
+  bool operator==(const Capsule& other) const;
+
+  // Human-readable information string for debugging purposes.
+  std::string ToString() const;
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const Capsule& capsule);
+
+  CapsuleType capsule_type() const { return capsule_type_; }
+  LegacyDatagramCapsule& legacy_datagram_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::LEGACY_DATAGRAM);
+    return legacy_datagram_capsule_;
+  }
+  const LegacyDatagramCapsule& legacy_datagram_capsule() const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::LEGACY_DATAGRAM);
+    return legacy_datagram_capsule_;
+  }
+  DatagramWithContextCapsule& datagram_with_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
+    return datagram_with_context_capsule_;
+  }
+  const DatagramWithContextCapsule& datagram_with_context_capsule() const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
+    return datagram_with_context_capsule_;
+  }
+  DatagramWithoutContextCapsule& datagram_without_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
+    return datagram_without_context_capsule_;
+  }
+  const DatagramWithoutContextCapsule& datagram_without_context_capsule()
+      const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
+    return datagram_without_context_capsule_;
+  }
+  RegisterDatagramContextCapsule& register_datagram_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
+    return register_datagram_context_capsule_;
+  }
+  const RegisterDatagramContextCapsule& register_datagram_context_capsule()
+      const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
+    return register_datagram_context_capsule_;
+  }
+  RegisterDatagramNoContextCapsule& register_datagram_no_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
+    return register_datagram_no_context_capsule_;
+  }
+  const RegisterDatagramNoContextCapsule& register_datagram_no_context_capsule()
+      const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
+    return register_datagram_no_context_capsule_;
+  }
+  CloseDatagramContextCapsule& close_datagram_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
+    return close_datagram_context_capsule_;
+  }
+  const CloseDatagramContextCapsule& close_datagram_context_capsule() const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
+    return close_datagram_context_capsule_;
+  }
+  CloseWebTransportSessionCapsule& close_web_transport_session_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
+    return close_web_transport_session_capsule_;
+  }
+  const CloseWebTransportSessionCapsule& close_web_transport_session_capsule()
+      const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
+    return close_web_transport_session_capsule_;
+  }
+  absl::string_view& unknown_capsule_data() {
+    QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
+                  capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
+                  capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
+                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
+                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
+                  capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
+                  capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
+        << capsule_type_;
+    return unknown_capsule_data_;
+  }
+  const absl::string_view& unknown_capsule_data() const {
+    QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
+                  capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
+                  capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
+                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
+                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
+                  capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
+                  capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
+        << capsule_type_;
+    return unknown_capsule_data_;
+  }
+
+ private:
+  CapsuleType capsule_type_;
+  union {
+    LegacyDatagramCapsule legacy_datagram_capsule_;
+    DatagramWithContextCapsule datagram_with_context_capsule_;
+    DatagramWithoutContextCapsule datagram_without_context_capsule_;
+    RegisterDatagramContextCapsule register_datagram_context_capsule_;
+    RegisterDatagramNoContextCapsule register_datagram_no_context_capsule_;
+    CloseDatagramContextCapsule close_datagram_context_capsule_;
+    CloseWebTransportSessionCapsule close_web_transport_session_capsule_;
+    absl::string_view unknown_capsule_data_;
+  };
+};
+
+namespace test {
+class CapsuleParserPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE CapsuleParser {
+ public:
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() {}
+
+    // Called when a capsule has been successfully parsed. The return value
+    // indicates whether the contents of the capsule are valid: if false is
+    // returned, the parse operation will be considered failed and
+    // OnCapsuleParseFailure will be called. Note that since Capsule does not
+    // own the memory backing its string_views, that memory is only valid until
+    // this callback returns. Visitors that wish to access the capsule later
+    // MUST make a deep copy before this returns.
+    virtual bool OnCapsule(const Capsule& capsule) = 0;
+
+    virtual void OnCapsuleParseFailure(const std::string& error_message) = 0;
+  };
+
+  // |visitor| must be non-null, and must outlive CapsuleParser.
+  explicit CapsuleParser(Visitor* visitor);
+
+  void set_datagram_context_id_present(bool datagram_context_id_present) {
+    datagram_context_id_present_ = datagram_context_id_present;
+  }
+
+  // Ingests a capsule fragment (any fragment of bytes from the capsule data
+  // stream) and parses and complete capsules it encounters. Returns false if a
+  // parsing error occurred.
+  bool IngestCapsuleFragment(absl::string_view capsule_fragment);
+
+  void ErrorIfThereIsRemainingBufferedData();
+
+  friend class test::CapsuleParserPeer;
+
+ private:
+  // Attempts to parse a single capsule from |buffered_data_|. If a full capsule
+  // is not available, returns 0. If a parsing error occurs, returns 0.
+  // Otherwise, returns the number of bytes in the parsed capsule.
+  size_t AttemptParseCapsule();
+  void ReportParseFailure(const std::string& error_message);
+
+  // Whether HTTP Datagram Context IDs are present.
+  bool datagram_context_id_present_ = false;
+  // Whether a parsing error has occurred.
+  bool parsing_error_occurred_ = false;
+  // Visitor which will receive callbacks, unowned.
+  Visitor* visitor_;
+
+  std::string buffered_data_;
+};
+
+// Serializes |capsule| into a newly allocated buffer.
+QUIC_EXPORT_PRIVATE quiche::QuicheBuffer SerializeCapsule(
+    const Capsule& capsule, quiche::QuicheBufferAllocator* allocator);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
diff --git a/quiche/quic/core/http/capsule_test.cc b/quiche/quic/core/http/capsule_test.cc
new file mode 100644
index 0000000..895f275
--- /dev/null
+++ b/quiche/quic/core/http/capsule_test.cc
@@ -0,0 +1,364 @@
+// Copyright (c) 2021 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 "quiche/quic/core/http/capsule.h"
+
+#include <cstddef>
+#include <deque>
+#include <string>
+#include <vector>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::Return;
+
+namespace quic {
+namespace test {
+
+class CapsuleParserPeer {
+ public:
+  static std::string* buffered_data(CapsuleParser* capsule_parser) {
+    return &capsule_parser->buffered_data_;
+  }
+};
+
+namespace {
+
+constexpr DatagramFormatType kFakeFormatType =
+    static_cast<DatagramFormatType>(0x123456);
+constexpr ContextCloseCode kFakeCloseCode =
+    static_cast<ContextCloseCode>(0x654321);
+
+class MockCapsuleParserVisitor : public CapsuleParser::Visitor {
+ public:
+  MockCapsuleParserVisitor() {
+    ON_CALL(*this, OnCapsule(_)).WillByDefault(Return(true));
+  }
+  ~MockCapsuleParserVisitor() override = default;
+  MOCK_METHOD(bool, OnCapsule, (const Capsule& capsule), (override));
+  MOCK_METHOD(void, OnCapsuleParseFailure, (const std::string& error_message),
+              (override));
+};
+
+class CapsuleTest : public QuicTest {
+ public:
+  CapsuleTest() : capsule_parser_(&visitor_) {}
+
+  void ValidateParserIsEmpty() {
+    EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
+    EXPECT_CALL(visitor_, OnCapsuleParseFailure(_)).Times(0);
+    capsule_parser_.ErrorIfThereIsRemainingBufferedData();
+    EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
+  }
+
+  void TestSerialization(const Capsule& capsule,
+                         const std::string& expected_bytes) {
+    quiche::QuicheBuffer serialized_capsule =
+        SerializeCapsule(capsule, quiche::SimpleBufferAllocator::Get());
+    quiche::test::CompareCharArraysWithHexError(
+        "Serialized capsule", serialized_capsule.data(),
+        serialized_capsule.size(), expected_bytes.data(),
+        expected_bytes.size());
+  }
+
+  ::testing::StrictMock<MockCapsuleParserVisitor> visitor_;
+  CapsuleParser capsule_parser_;
+};
+
+TEST_F(CapsuleTest, LegacyDatagramCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a0"          // LEGACY_DATAGRAM capsule type
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule =
+      Capsule::LegacyDatagram(/*context_id=*/absl::nullopt, datagram_payload);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, LegacyDatagramCapsuleWithContext) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a0"          // LEGACY_DATAGRAM capsule type
+      "09"                // capsule length
+      "04"                // context ID
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+  );
+  capsule_parser_.set_datagram_context_id_present(true);
+  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule =
+      Capsule::LegacyDatagram(/*context_id=*/4, datagram_payload);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, DatagramWithoutContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule = Capsule::DatagramWithoutContext(datagram_payload);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, DatagramWithContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a4"          // DATAGRAM_WITH_CONTEXT capsule type
+      "09"                // capsule length
+      "04"                // context ID
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule =
+      Capsule::DatagramWithContext(/*context_id=*/4, datagram_payload);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, RegisterContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a1"          // REGISTER_DATAGRAM_CONTEXT capsule type
+      "0d"                // capsule length
+      "04"                // context ID
+      "80123456"          // 0x123456 datagram format type
+      "f1f2f3f4f5f6f7f8"  // format additional data
+  );
+  std::string format_additional_data =
+      absl::HexStringToBytes("f1f2f3f4f5f6f7f8");
+  Capsule expected_capsule = Capsule::RegisterDatagramContext(
+      /*context_id=*/4, kFakeFormatType, format_additional_data);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, RegisterNoContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a2"          // REGISTER_DATAGRAM_NO_CONTEXT capsule type
+      "0c"                // capsule length
+      "80123456"          // 0x123456 datagram format type
+      "f1f2f3f4f5f6f7f8"  // format additional data
+  );
+  std::string format_additional_data =
+      absl::HexStringToBytes("f1f2f3f4f5f6f7f8");
+  Capsule expected_capsule = Capsule::RegisterDatagramNoContext(
+      kFakeFormatType, format_additional_data);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, CloseContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a3"  // CLOSE_DATAGRAM_CONTEXT capsule type
+      "27"        // capsule length
+      "04"        // context ID
+      "80654321"  // 0x654321 close code
+  );
+  std::string close_details = "All your contexts are belong to us";
+  capsule_fragment += close_details;
+  Capsule expected_capsule = Capsule::CloseDatagramContext(
+      /*context_id=*/4, kFakeCloseCode, close_details);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, CloseWebTransportStreamCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "6843"        // CLOSE_WEBTRANSPORT_STREAM capsule type
+      "09"          // capsule length
+      "00001234"    // 0x1234 error code
+      "68656c6c6f"  // "hello" error message
+  );
+  Capsule expected_capsule = Capsule::CloseWebTransportSession(
+      /*error_code=*/0x1234, /*error_message=*/"hello");
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, UnknownCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "33"                // unknown capsule type of 0x33
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // unknown capsule data
+  );
+  std::string unknown_capsule_data = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule = Capsule::Unknown(0x33, unknown_capsule_data);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, TwoCapsules) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "b1b2b3b4b5b6b7b8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
+  Capsule expected_capsule1 =
+      Capsule::DatagramWithoutContext(datagram_payload1);
+  Capsule expected_capsule2 =
+      Capsule::DatagramWithoutContext(datagram_payload2);
+  {
+    InSequence s;
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+}
+
+TEST_F(CapsuleTest, TwoCapsulesPartialReads) {
+  std::string capsule_fragment1 = absl::HexStringToBytes(
+      "80ff37a5"  // first capsule DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"        // frist capsule length
+      "a1a2a3a4"  // first half of HTTP Datagram payload of first capsule
+  );
+  std::string capsule_fragment2 = absl::HexStringToBytes(
+      "a5a6a7a8"  // second half of HTTP Datagram payload 1
+      "80ff37a5"  // second capsule DATAGRAM_WITHOUT_CONTEXT capsule type
+  );
+  std::string capsule_fragment3 = absl::HexStringToBytes(
+      "08"                // second capsule length
+      "b1b2b3b4b5b6b7b8"  // HTTP Datagram payload of second capsule
+  );
+  capsule_parser_.ErrorIfThereIsRemainingBufferedData();
+  std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
+  Capsule expected_capsule1 =
+      Capsule::DatagramWithoutContext(datagram_payload1);
+  Capsule expected_capsule2 =
+      Capsule::DatagramWithoutContext(datagram_payload2);
+  {
+    InSequence s;
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment1));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment2));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment3));
+  }
+  ValidateParserIsEmpty();
+}
+
+TEST_F(CapsuleTest, TwoCapsulesOneByteAtATime) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "b1b2b3b4b5b6b7b8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
+  Capsule expected_capsule1 =
+      Capsule::DatagramWithoutContext(datagram_payload1);
+  Capsule expected_capsule2 =
+      Capsule::DatagramWithoutContext(datagram_payload2);
+  for (size_t i = 0; i < capsule_fragment.size(); i++) {
+    if (i < capsule_fragment.size() / 2 - 1) {
+      EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
+      ASSERT_TRUE(
+          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
+    } else if (i == capsule_fragment.size() / 2 - 1) {
+      EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
+      ASSERT_TRUE(
+          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
+      EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
+    } else if (i < capsule_fragment.size() - 1) {
+      EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
+      ASSERT_TRUE(
+          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
+    } else {
+      EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
+      ASSERT_TRUE(
+          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
+      EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
+    }
+  }
+  capsule_parser_.ErrorIfThereIsRemainingBufferedData();
+  EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
+}
+
+TEST_F(CapsuleTest, PartialCapsuleThenError) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a5"  // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"        // capsule length
+      "a1a2a3a4"  // first half of HTTP Datagram payload
+  );
+  EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
+  {
+    EXPECT_CALL(visitor_, OnCapsuleParseFailure(_)).Times(0);
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  {
+    EXPECT_CALL(visitor_,
+                OnCapsuleParseFailure(
+                    "Incomplete capsule left at the end of the stream"));
+    capsule_parser_.ErrorIfThereIsRemainingBufferedData();
+  }
+}
+
+TEST_F(CapsuleTest, RejectOverlyLongCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+                                     "33"        // unknown capsule type of 0x33
+                                     "80123456"  // capsule length
+                                     ) +
+                                 std::string(1111111, '?');
+  EXPECT_CALL(visitor_, OnCapsuleParseFailure(
+                            "Refusing to buffer too much capsule data"));
+  EXPECT_FALSE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
new file mode 100644
index 0000000..9338295
--- /dev/null
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -0,0 +1,6908 @@
+// 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 <cstddef>
+#include <cstdint>
+#include <list>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/time/clock.h"
+#include "absl/time/time.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_client_session_cache.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_loopback.h"
+#include "quiche/quic/test_tools/bad_packet_writer.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/packet_dropping_test_writer.h"
+#include "quiche/quic/test_tools/packet_reordering_writer.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/quic/test_tools/quic_client_peer.h"
+#include "quiche/quic/test_tools/quic_client_session_cache_peer.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_server_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_peer.h"
+#include "quiche/quic/test_tools/quic_test_backend.h"
+#include "quiche/quic/test_tools/quic_test_client.h"
+#include "quiche/quic/test_tools/quic_test_server.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_transport_test_tools.h"
+#include "quiche/quic/test_tools/server_thread.h"
+#include "quiche/quic/tools/quic_backend_response.h"
+#include "quiche/quic/tools/quic_client.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/quic/tools/quic_server.h"
+#include "quiche/quic/tools/quic_simple_client_stream.h"
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+using spdy::kV3LowestPriority;
+using spdy::SpdyFramer;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdySerializedFrame;
+using spdy::SpdySettingsIR;
+using ::testing::_;
+using ::testing::Assign;
+using ::testing::Invoke;
+using ::testing::NiceMock;
+using ::testing::UnorderedElementsAreArray;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kFooResponseBody[] = "Artichoke hearts make me happy.";
+const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
+const char kTestUserAgentId[] = "quic/core/http/end_to_end_test.cc";
+const float kSessionToStreamRatio = 1.5;
+
+// Run all tests with the cross products of all versions.
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, QuicTag congestion_control_tag)
+      : version(version), congestion_control_tag(congestion_control_tag) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
+    os << "{ version: " << ParsedQuicVersionToString(p.version);
+    os << " congestion_control_tag: "
+       << QuicTagToString(p.congestion_control_tag) << " }";
+    return os;
+  }
+
+  ParsedQuicVersion version;
+  QuicTag congestion_control_tag;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  std::string rv = absl::StrCat(ParsedQuicVersionToString(p.version), "_",
+                                QuicTagToString(p.congestion_control_tag));
+  std::replace(rv.begin(), rv.end(), ',', '_');
+  std::replace(rv.begin(), rv.end(), ' ', '_');
+  return rv;
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC, kB2ON}) {
+    if (!GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
+        congestion_control_tag == kB2ON) {
+      continue;
+    }
+    for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
+      params.push_back(TestParams(version, congestion_control_tag));
+    }  // End of outer version loop.
+  }    // End of congestion_control_tag loop.
+
+  return params;
+}
+
+void WriteHeadersOnStream(QuicSpdyStream* stream) {
+  // Since QuicSpdyStream uses QuicHeaderList::empty() to detect too large
+  // headers, it also fails when receiving empty headers.
+  SpdyHeaderBlock headers;
+  headers[":authority"] = "test.example.com:443";
+  headers[":path"] = "/path";
+  headers[":method"] = "GET";
+  headers[":scheme"] = "https";
+  stream->WriteHeaders(std::move(headers), /* fin = */ false, nullptr);
+}
+
+class ServerDelegate : public PacketDroppingTestWriter::Delegate {
+ public:
+  explicit ServerDelegate(QuicDispatcher* dispatcher)
+      : dispatcher_(dispatcher) {}
+  ~ServerDelegate() override = default;
+  void OnCanWrite() override { dispatcher_->OnCanWrite(); }
+
+ private:
+  QuicDispatcher* dispatcher_;
+};
+
+class ClientDelegate : public PacketDroppingTestWriter::Delegate {
+ public:
+  explicit ClientDelegate(QuicClient* client) : client_(client) {}
+  ~ClientDelegate() override = default;
+  void OnCanWrite() override {
+    QuicEpollEvent event(EPOLLOUT);
+    client_->epoll_network_helper()->OnEvent(client_->GetLatestFD(), &event);
+  }
+
+ private:
+  QuicClient* client_;
+};
+
+class EndToEndTest : public QuicTestWithParam<TestParams> {
+ protected:
+  EndToEndTest()
+      : initialized_(false),
+        connect_to_server_on_initialize_(true),
+        server_address_(QuicSocketAddress(TestLoopback(), 0)),
+        server_hostname_("test.example.com"),
+        client_writer_(nullptr),
+        server_writer_(nullptr),
+        version_(GetParam().version),
+        client_supported_versions_({version_}),
+        server_supported_versions_(CurrentSupportedVersions()),
+        chlo_multiplier_(0),
+        stream_factory_(nullptr),
+        expected_server_connection_id_length_(kQuicDefaultConnectionIdLength) {
+    QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
+
+    // Use different flow control windows for client/server.
+    client_config_.SetInitialStreamFlowControlWindowToSend(
+        2 * kInitialStreamFlowControlWindowForTest);
+    client_config_.SetInitialSessionFlowControlWindowToSend(
+        2 * kInitialSessionFlowControlWindowForTest);
+    server_config_.SetInitialStreamFlowControlWindowToSend(
+        3 * kInitialStreamFlowControlWindowForTest);
+    server_config_.SetInitialSessionFlowControlWindowToSend(
+        3 * kInitialSessionFlowControlWindowForTest);
+
+    // The default idle timeouts can be too strict when running on a busy
+    // machine.
+    const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(30);
+    client_config_.set_max_time_before_crypto_handshake(timeout);
+    client_config_.set_max_idle_time_before_crypto_handshake(timeout);
+    server_config_.set_max_time_before_crypto_handshake(timeout);
+    server_config_.set_max_idle_time_before_crypto_handshake(timeout);
+
+    AddToCache("/foo", 200, kFooResponseBody);
+    AddToCache("/bar", 200, kBarResponseBody);
+    // Enable fixes for bugs found in tests and prod.
+  }
+
+  virtual void CreateClientWithWriter() {
+    client_.reset(CreateQuicClient(client_writer_));
+  }
+
+  QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
+    QuicTestClient* client =
+        new QuicTestClient(server_address_, server_hostname_, client_config_,
+                           client_supported_versions_,
+                           crypto_test_utils::ProofVerifierForTesting(),
+                           std::make_unique<QuicClientSessionCache>());
+    client->SetUserAgentID(kTestUserAgentId);
+    client->UseWriter(writer);
+    if (!pre_shared_key_client_.empty()) {
+      client->client()->SetPreSharedKey(pre_shared_key_client_);
+    }
+    client->UseConnectionIdLength(override_server_connection_id_length_);
+    client->UseClientConnectionIdLength(override_client_connection_id_length_);
+    client->client()->set_connection_debug_visitor(connection_debug_visitor_);
+    client->client()->set_enable_web_transport(enable_web_transport_);
+    client->client()->set_use_datagram_contexts(use_datagram_contexts_);
+    client->Connect();
+    return client;
+  }
+
+  void set_smaller_flow_control_receive_window() {
+    const uint32_t kClientIFCW = 64 * 1024;
+    const uint32_t kServerIFCW = 1024 * 1024;
+    set_client_initial_stream_flow_control_receive_window(kClientIFCW);
+    set_client_initial_session_flow_control_receive_window(
+        kSessionToStreamRatio * kClientIFCW);
+    set_server_initial_stream_flow_control_receive_window(kServerIFCW);
+    set_server_initial_session_flow_control_receive_window(
+        kSessionToStreamRatio * kServerIFCW);
+  }
+
+  void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
+    ASSERT_TRUE(client_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting client initial stream flow control window: "
+                    << window;
+    client_config_.SetInitialStreamFlowControlWindowToSend(window);
+  }
+
+  void set_client_initial_session_flow_control_receive_window(uint32_t window) {
+    ASSERT_TRUE(client_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting client initial session flow control window: "
+                    << window;
+    client_config_.SetInitialSessionFlowControlWindowToSend(window);
+  }
+
+  void set_client_initial_max_stream_data_incoming_bidirectional(
+      uint32_t window) {
+    ASSERT_TRUE(client_ == nullptr);
+    QUIC_DLOG(INFO)
+        << "Setting client initial max stream data incoming bidirectional: "
+        << window;
+    client_config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+        window);
+  }
+
+  void set_server_initial_max_stream_data_outgoing_bidirectional(
+      uint32_t window) {
+    ASSERT_TRUE(client_ == nullptr);
+    QUIC_DLOG(INFO)
+        << "Setting server initial max stream data outgoing bidirectional: "
+        << window;
+    server_config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+        window);
+  }
+
+  void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
+    ASSERT_TRUE(server_thread_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting server initial stream flow control window: "
+                    << window;
+    server_config_.SetInitialStreamFlowControlWindowToSend(window);
+  }
+
+  void set_server_initial_session_flow_control_receive_window(uint32_t window) {
+    ASSERT_TRUE(server_thread_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting server initial session flow control window: "
+                    << window;
+    server_config_.SetInitialSessionFlowControlWindowToSend(window);
+  }
+
+  const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession() {
+    QuicConnection* server_connection = GetServerConnection();
+    if (server_connection == nullptr) {
+      ADD_FAILURE() << "Missing server connection";
+      return nullptr;
+    }
+    return &server_connection->sent_packet_manager();
+  }
+
+  const QuicSentPacketManager* GetSentPacketManagerFromClientSession() {
+    QuicConnection* client_connection = GetClientConnection();
+    if (client_connection == nullptr) {
+      ADD_FAILURE() << "Missing client connection";
+      return nullptr;
+    }
+    return &client_connection->sent_packet_manager();
+  }
+
+  QuicSpdyClientSession* GetClientSession() {
+    if (!client_) {
+      ADD_FAILURE() << "Missing QuicTestClient";
+      return nullptr;
+    }
+    if (client_->client() == nullptr) {
+      ADD_FAILURE() << "Missing MockableQuicClient";
+      return nullptr;
+    }
+    return client_->client()->client_session();
+  }
+
+  QuicConnection* GetClientConnection() {
+    QuicSpdyClientSession* client_session = GetClientSession();
+    if (client_session == nullptr) {
+      ADD_FAILURE() << "Missing client session";
+      return nullptr;
+    }
+    return client_session->connection();
+  }
+
+  QuicConnection* GetServerConnection() {
+    QuicSpdySession* server_session = GetServerSession();
+    if (server_session == nullptr) {
+      ADD_FAILURE() << "Missing server session";
+      return nullptr;
+    }
+    return server_session->connection();
+  }
+
+  QuicSpdySession* GetServerSession() {
+    if (!server_thread_) {
+      ADD_FAILURE() << "Missing server thread";
+      return nullptr;
+    }
+    QuicServer* quic_server = server_thread_->server();
+    if (quic_server == nullptr) {
+      ADD_FAILURE() << "Missing server";
+      return nullptr;
+    }
+    QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(quic_server);
+    if (dispatcher == nullptr) {
+      ADD_FAILURE() << "Missing dispatcher";
+      return nullptr;
+    }
+    if (dispatcher->NumSessions() == 0) {
+      ADD_FAILURE() << "Empty dispatcher session map";
+      return nullptr;
+    }
+    EXPECT_EQ(1u, dispatcher->NumSessions());
+    return static_cast<QuicSpdySession*>(
+        QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher));
+  }
+
+  bool Initialize() {
+    if (enable_web_transport_) {
+      memory_cache_backend_.set_enable_webtransport(true);
+    }
+    if (use_datagram_contexts_) {
+      memory_cache_backend_.set_use_datagram_contexts(true);
+    }
+
+    QuicTagVector copt;
+    server_config_.SetConnectionOptionsToSend(copt);
+    copt = client_extra_copts_;
+
+    // TODO(nimia): Consider setting the congestion control algorithm for the
+    // client as well according to the test parameter.
+    copt.push_back(GetParam().congestion_control_tag);
+    copt.push_back(k2PTO);
+    if (version_.HasIetfQuicFrames()) {
+      copt.push_back(kILD0);
+    }
+    copt.push_back(kPLE1);
+    if (!GetQuicReloadableFlag(
+            quic_remove_connection_migration_connection_option)) {
+      copt.push_back(kRVCM);
+    }
+    client_config_.SetConnectionOptionsToSend(copt);
+
+    // Start the server first, because CreateQuicClient() attempts
+    // to connect to the server.
+    StartServer();
+
+    if (!connect_to_server_on_initialize_) {
+      initialized_ = true;
+      return true;
+    }
+
+    CreateClientWithWriter();
+    if (!client_) {
+      ADD_FAILURE() << "Missing QuicTestClient";
+      return false;
+    }
+    MockableQuicClient* client = client_->client();
+    if (client == nullptr) {
+      ADD_FAILURE() << "Missing MockableQuicClient";
+      return false;
+    }
+    static QuicEpollEvent event(EPOLLOUT);
+    if (client_writer_ != nullptr) {
+      QuicConnection* client_connection = GetClientConnection();
+      if (client_connection == nullptr) {
+        ADD_FAILURE() << "Missing client connection";
+        return false;
+      }
+      client_writer_->Initialize(
+          QuicConnectionPeer::GetHelper(client_connection),
+          QuicConnectionPeer::GetAlarmFactory(client_connection),
+          std::make_unique<ClientDelegate>(client));
+    }
+    initialized_ = true;
+    return client->connected();
+  }
+
+  void SetUp() override {
+    // The ownership of these gets transferred to the QuicPacketWriterWrapper
+    // when Initialize() is executed.
+    client_writer_ = new PacketDroppingTestWriter();
+    server_writer_ = new PacketDroppingTestWriter();
+  }
+
+  void TearDown() override {
+    EXPECT_TRUE(initialized_) << "You must call Initialize() in every test "
+                              << "case. Otherwise, your test will leak memory.";
+    QuicConnection* client_connection = GetClientConnection();
+    if (client_connection != nullptr) {
+      client_connection->set_debug_visitor(nullptr);
+    } else {
+      ADD_FAILURE() << "Missing client connection";
+    }
+    StopServer();
+  }
+
+  void StartServer() {
+    auto* test_server = new QuicTestServer(
+        crypto_test_utils::ProofSourceForTesting(), server_config_,
+        server_supported_versions_, &memory_cache_backend_,
+        expected_server_connection_id_length_);
+    server_thread_ =
+        std::make_unique<ServerThread>(test_server, server_address_);
+    if (chlo_multiplier_ != 0) {
+      server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
+    }
+    if (!pre_shared_key_server_.empty()) {
+      server_thread_->server()->SetPreSharedKey(pre_shared_key_server_);
+    }
+    server_thread_->Initialize();
+    server_address_ =
+        QuicSocketAddress(server_address_.host(), server_thread_->GetPort());
+    QuicDispatcher* dispatcher =
+        QuicServerPeer::GetDispatcher(server_thread_->server());
+    QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
+
+    server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
+                               QuicDispatcherPeer::GetAlarmFactory(dispatcher),
+                               std::make_unique<ServerDelegate>(dispatcher));
+    if (stream_factory_ != nullptr) {
+      static_cast<QuicTestServer*>(server_thread_->server())
+          ->SetSpdyStreamFactory(stream_factory_);
+    }
+
+    server_thread_->Start();
+  }
+
+  void StopServer() {
+    if (server_thread_) {
+      server_thread_->Quit();
+      server_thread_->Join();
+    }
+  }
+
+  void AddToCache(absl::string_view path, int response_code,
+                  absl::string_view body) {
+    memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
+                                            response_code, body);
+  }
+
+  void SetPacketLossPercentage(int32_t loss) {
+    client_writer_->set_fake_packet_loss_percentage(loss);
+    server_writer_->set_fake_packet_loss_percentage(loss);
+  }
+
+  void SetPacketSendDelay(QuicTime::Delta delay) {
+    client_writer_->set_fake_packet_delay(delay);
+    server_writer_->set_fake_packet_delay(delay);
+  }
+
+  void SetReorderPercentage(int32_t reorder) {
+    client_writer_->set_fake_reorder_percentage(reorder);
+    server_writer_->set_fake_reorder_percentage(reorder);
+  }
+
+  // Verifies that the client and server connections were both free of packets
+  // being discarded, based on connection stats.
+  // Calls server_thread_ Pause() and Resume(), which may only be called once
+  // per test.
+  void VerifyCleanConnection(bool had_packet_loss) {
+    QuicConnection* client_connection = GetClientConnection();
+    if (client_connection == nullptr) {
+      ADD_FAILURE() << "Missing client connection";
+      return;
+    }
+    QuicConnectionStats client_stats = client_connection->GetStats();
+    // TODO(ianswett): Determine why this becomes even more flaky with BBR
+    // enabled.  b/62141144
+    if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
+      EXPECT_EQ(0u, client_stats.packets_lost);
+    }
+    EXPECT_EQ(0u, client_stats.packets_discarded);
+    // When client starts with an unsupported version, the version negotiation
+    // packet sent by server for the old connection (respond for the connection
+    // close packet) will be dropped by the client.
+    if (!ServerSendsVersionNegotiation()) {
+      EXPECT_EQ(0u, client_stats.packets_dropped);
+    }
+    if (!version_.UsesTls()) {
+      // Only enforce this for QUIC crypto because accounting of number of
+      // packets received, processed gets complicated with packets coalescing
+      // and key dropping. For example, a received undecryptable coalesced
+      // packet can be processed later and each sub-packet increases
+      // packets_processed.
+      EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
+    }
+
+    if (!server_thread_) {
+      ADD_FAILURE() << "Missing server thread";
+      return;
+    }
+    server_thread_->Pause();
+    QuicSpdySession* server_session = GetServerSession();
+    if (server_session != nullptr) {
+      QuicConnection* server_connection = server_session->connection();
+      if (server_connection != nullptr) {
+        QuicConnectionStats server_stats = server_connection->GetStats();
+        if (!had_packet_loss) {
+          EXPECT_EQ(0u, server_stats.packets_lost);
+        }
+        EXPECT_EQ(0u, server_stats.packets_discarded);
+      } else {
+        ADD_FAILURE() << "Missing server connection";
+      }
+    } else {
+      ADD_FAILURE() << "Missing server session";
+    }
+    // TODO(ianswett): Restore the check for packets_dropped equals 0.
+    // The expect for packets received is equal to packets processed fails
+    // due to version negotiation packets.
+    server_thread_->Resume();
+  }
+
+  // Returns true when client starts with an unsupported version, and client
+  // closes connection when version negotiation is received.
+  bool ServerSendsVersionNegotiation() {
+    return client_supported_versions_[0] != version_;
+  }
+
+  bool SupportsIetfQuicWithTls(ParsedQuicVersion version) {
+    return version.HasIetfInvariantHeader() &&
+           version.handshake_protocol == PROTOCOL_TLS1_3;
+  }
+
+  static void ExpectFlowControlsSynced(QuicSession* client,
+                                       QuicSession* server) {
+    EXPECT_EQ(
+        QuicFlowControllerPeer::SendWindowSize(client->flow_controller()),
+        QuicFlowControllerPeer::ReceiveWindowSize(server->flow_controller()));
+    EXPECT_EQ(
+        QuicFlowControllerPeer::ReceiveWindowSize(client->flow_controller()),
+        QuicFlowControllerPeer::SendWindowSize(server->flow_controller()));
+  }
+
+  static void ExpectFlowControlsSynced(QuicStream* client, QuicStream* server) {
+    EXPECT_EQ(QuicStreamPeer::SendWindowSize(client),
+              QuicStreamPeer::ReceiveWindowSize(server));
+    EXPECT_EQ(QuicStreamPeer::ReceiveWindowSize(client),
+              QuicStreamPeer::SendWindowSize(server));
+  }
+
+  // Must be called before Initialize to have effect.
+  void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
+    stream_factory_ = factory;
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        version_.transport_version, n);
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return GetNthServerInitiatedBidirectionalStreamId(
+        version_.transport_version, n);
+  }
+
+  bool CheckResponseHeaders(QuicTestClient* client,
+                            const std::string& expected_status) {
+    const spdy::SpdyHeaderBlock* response_headers = client->response_headers();
+    auto it = response_headers->find(":status");
+    if (it == response_headers->end()) {
+      ADD_FAILURE() << "Did not find :status header in response";
+      return false;
+    }
+    if (it->second != expected_status) {
+      ADD_FAILURE() << "Got bad :status response: \"" << it->second << "\"";
+      return false;
+    }
+    return true;
+  }
+
+  bool CheckResponseHeaders(QuicTestClient* client) {
+    return CheckResponseHeaders(client, "200");
+  }
+
+  bool CheckResponseHeaders(const std::string& expected_status) {
+    return CheckResponseHeaders(client_.get(), expected_status);
+  }
+
+  bool CheckResponseHeaders() { return CheckResponseHeaders(client_.get()); }
+
+  bool CheckResponse(QuicTestClient* client,
+                     const std::string& received_response,
+                     const std::string& expected_response) {
+    EXPECT_THAT(client_->stream_error(), IsQuicStreamNoError());
+    EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+
+    if (received_response.empty() && !expected_response.empty()) {
+      ADD_FAILURE() << "Failed to get any response for request";
+      return false;
+    }
+    if (received_response != expected_response) {
+      ADD_FAILURE() << "Got wrong response: \"" << received_response << "\"";
+      return false;
+    }
+    return CheckResponseHeaders(client);
+  }
+
+  bool SendSynchronousRequestAndCheckResponse(
+      QuicTestClient* client, const std::string& request,
+      const std::string& expected_response) {
+    std::string received_response = client->SendSynchronousRequest(request);
+    return CheckResponse(client, received_response, expected_response);
+  }
+
+  bool SendSynchronousRequestAndCheckResponse(
+      const std::string& request, const std::string& expected_response) {
+    return SendSynchronousRequestAndCheckResponse(client_.get(), request,
+                                                  expected_response);
+  }
+
+  bool SendSynchronousFooRequestAndCheckResponse(QuicTestClient* client) {
+    return SendSynchronousRequestAndCheckResponse(client, "/foo",
+                                                  kFooResponseBody);
+  }
+
+  bool SendSynchronousFooRequestAndCheckResponse() {
+    return SendSynchronousFooRequestAndCheckResponse(client_.get());
+  }
+
+  bool SendSynchronousBarRequestAndCheckResponse() {
+    std::string received_response = client_->SendSynchronousRequest("/bar");
+    return CheckResponse(client_.get(), received_response, kBarResponseBody);
+  }
+
+  bool WaitForFooResponseAndCheckIt(QuicTestClient* client) {
+    client->WaitForResponse();
+    std::string received_response = client->response_body();
+    return CheckResponse(client_.get(), received_response, kFooResponseBody);
+  }
+
+  bool WaitForFooResponseAndCheckIt() {
+    return WaitForFooResponseAndCheckIt(client_.get());
+  }
+
+  WebTransportHttp3* CreateWebTransportSession(
+      const std::string& path, bool wait_for_server_response,
+      QuicSpdyStream** connect_stream_out = nullptr) {
+    // Wait until we receive the settings from the server indicating
+    // WebTransport support.
+    client_->WaitUntil(
+        2000, [this]() { return GetClientSession()->SupportsWebTransport(); });
+    if (!GetClientSession()->SupportsWebTransport()) {
+      return nullptr;
+    }
+
+    spdy::SpdyHeaderBlock headers;
+    headers[":scheme"] = "https";
+    headers[":authority"] = "localhost";
+    headers[":path"] = path;
+    headers[":method"] = "CONNECT";
+    headers[":protocol"] = "webtransport";
+
+    client_->SendMessage(headers, "", /*fin=*/false);
+    QuicSpdyStream* stream = client_->latest_created_stream();
+    if (stream->web_transport() == nullptr) {
+      return nullptr;
+    }
+    WebTransportSessionId id = client_->latest_created_stream()->id();
+    QuicSpdySession* client_session = GetClientSession();
+    if (client_session->GetWebTransportSession(id) == nullptr) {
+      return nullptr;
+    }
+    WebTransportHttp3* session = client_session->GetWebTransportSession(id);
+    if (wait_for_server_response) {
+      client_->WaitUntil(-1,
+                         [stream]() { return stream->headers_decompressed(); });
+      EXPECT_TRUE(session->ready());
+    }
+    if (connect_stream_out != nullptr) {
+      *connect_stream_out = stream;
+    }
+    return session;
+  }
+
+  NiceMock<MockClientVisitor>& SetupWebTransportVisitor(
+      WebTransportHttp3* session) {
+    auto visitor_owned = std::make_unique<NiceMock<MockClientVisitor>>();
+    NiceMock<MockClientVisitor>& visitor = *visitor_owned;
+    session->SetVisitor(std::move(visitor_owned));
+    return visitor;
+  }
+
+  std::string ReadDataFromWebTransportStreamUntilFin(
+      WebTransportStream* stream, MockStreamVisitor* visitor = nullptr) {
+    QuicStreamId id = stream->GetStreamId();
+    std::string buffer;
+
+    // Try reading data if immediately available.
+    WebTransportStream::ReadResult result = stream->Read(&buffer);
+    if (result.fin) {
+      return buffer;
+    }
+
+    while (true) {
+      bool can_read = false;
+      if (visitor == nullptr) {
+        auto visitor_owned = std::make_unique<MockStreamVisitor>();
+        visitor = visitor_owned.get();
+        stream->SetVisitor(std::move(visitor_owned));
+      }
+      EXPECT_CALL(*visitor, OnCanRead()).WillOnce(Assign(&can_read, true));
+      client_->WaitUntil(5000 /*ms*/, [&can_read]() { return can_read; });
+      if (!can_read) {
+        ADD_FAILURE() << "Waiting for readable data on stream " << id
+                      << " timed out";
+        return buffer;
+      }
+      if (GetClientSession()->GetOrCreateSpdyDataStream(id) == nullptr) {
+        ADD_FAILURE() << "Stream " << id
+                      << " was deleted while waiting for incoming data";
+        return buffer;
+      }
+
+      result = stream->Read(&buffer);
+      if (result.fin) {
+        return buffer;
+      }
+      if (result.bytes_read == 0) {
+        ADD_FAILURE() << "No progress made while reading from stream "
+                      << stream->GetStreamId();
+        return buffer;
+      }
+    }
+  }
+
+  void ReadAllIncomingWebTransportUnidirectionalStreams(
+      WebTransportSession* session) {
+    while (true) {
+      WebTransportStream* received_stream =
+          session->AcceptIncomingUnidirectionalStream();
+      if (received_stream == nullptr) {
+        break;
+      }
+      received_webtransport_unidirectional_streams_.push_back(
+          ReadDataFromWebTransportStreamUntilFin(received_stream));
+    }
+  }
+
+  void WaitForNewConnectionIds() {
+    // Wait until a new server CID is available for another migration.
+    const auto* client_connection = GetClientConnection();
+    while (!QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
+               client_connection) ||
+           (!client_connection->client_connection_id().IsEmpty() &&
+            !QuicConnectionPeer::HasSelfIssuedConnectionIdToConsume(
+                client_connection))) {
+      client_->client()->WaitForEvents();
+    }
+  }
+
+  ScopedEnvironmentForThreads environment_;
+  bool initialized_;
+  // If true, the Initialize() function will create |client_| and starts to
+  // connect to the server.
+  // Default is true.
+  bool connect_to_server_on_initialize_;
+  QuicSocketAddress server_address_;
+  std::string server_hostname_;
+  QuicTestBackend memory_cache_backend_;
+  std::unique_ptr<ServerThread> server_thread_;
+  std::unique_ptr<QuicTestClient> client_;
+  QuicConnectionDebugVisitor* connection_debug_visitor_ = nullptr;
+  PacketDroppingTestWriter* client_writer_;
+  PacketDroppingTestWriter* server_writer_;
+  QuicConfig client_config_;
+  QuicConfig server_config_;
+  ParsedQuicVersion version_;
+  ParsedQuicVersionVector client_supported_versions_;
+  ParsedQuicVersionVector server_supported_versions_;
+  QuicTagVector client_extra_copts_;
+  size_t chlo_multiplier_;
+  QuicTestServer::StreamFactory* stream_factory_;
+  std::string pre_shared_key_client_;
+  std::string pre_shared_key_server_;
+  int override_server_connection_id_length_ = -1;
+  int override_client_connection_id_length_ = -1;
+  uint8_t expected_server_connection_id_length_;
+  bool enable_web_transport_ = false;
+  bool use_datagram_contexts_ = false;
+  std::vector<std::string> received_webtransport_unidirectional_streams_;
+};
+
+// Run all end to end tests with all supported versions.
+INSTANTIATE_TEST_SUITE_P(EndToEndTests, EndToEndTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(EndToEndTest, HandshakeSuccessful) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicCryptoStream* client_crypto_stream =
+      QuicSessionPeer::GetMutableCryptoStream(client_session);
+  ASSERT_TRUE(client_crypto_stream);
+  QuicStreamSequencer* client_sequencer =
+      QuicStreamPeer::sequencer(client_crypto_stream);
+  ASSERT_TRUE(client_sequencer);
+  EXPECT_FALSE(
+      QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(client_sequencer));
+
+  // We've had bugs in the past where the connections could end up on the wrong
+  // version. This was never diagnosed but could have been due to in-connection
+  // version negotiation back when that existed. At this point in time, our test
+  // setup ensures that connections here always use |version_|, but we add this
+  // sanity check out of paranoia to catch a regression of this type.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(client_connection->version(), version_);
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  QuicConnection* server_connection = nullptr;
+  QuicCryptoStream* server_crypto_stream = nullptr;
+  QuicStreamSequencer* server_sequencer = nullptr;
+  if (server_session != nullptr) {
+    server_connection = server_session->connection();
+    server_crypto_stream =
+        QuicSessionPeer::GetMutableCryptoStream(server_session);
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  if (server_crypto_stream != nullptr) {
+    server_sequencer = QuicStreamPeer::sequencer(server_crypto_stream);
+  } else {
+    ADD_FAILURE() << "Missing server crypto stream";
+  }
+  if (server_sequencer != nullptr) {
+    EXPECT_FALSE(
+        QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(server_sequencer));
+  } else {
+    ADD_FAILURE() << "Missing server sequencer";
+  }
+  if (server_connection != nullptr) {
+    EXPECT_EQ(server_connection->version(), version_);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ExportKeyingMaterial) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.UsesTls()) {
+    return;
+  }
+  const char* kExportLabel = "label";
+  const int kExportLen = 30;
+  std::string client_keying_material_export, server_keying_material_export;
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  QuicCryptoStream* server_crypto_stream = nullptr;
+  if (server_session != nullptr) {
+    server_crypto_stream =
+        QuicSessionPeer::GetMutableCryptoStream(server_session);
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  if (server_crypto_stream != nullptr) {
+    ASSERT_TRUE(server_crypto_stream->ExportKeyingMaterial(
+        kExportLabel, /*context=*/"", kExportLen,
+        &server_keying_material_export));
+
+  } else {
+    ADD_FAILURE() << "Missing server crypto stream";
+  }
+  server_thread_->Resume();
+
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicCryptoStream* client_crypto_stream =
+      QuicSessionPeer::GetMutableCryptoStream(client_session);
+  ASSERT_TRUE(client_crypto_stream);
+  ASSERT_TRUE(client_crypto_stream->ExportKeyingMaterial(
+      kExportLabel, /*context=*/"", kExportLen,
+      &client_keying_material_export));
+  ASSERT_EQ(client_keying_material_export.size(),
+            static_cast<size_t>(kExportLen));
+  EXPECT_EQ(client_keying_material_export, server_keying_material_export);
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponse) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  if (version_.UsesHttp3()) {
+    QuicSpdyClientSession* client_session = GetClientSession();
+    ASSERT_TRUE(client_session);
+    EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(client_session));
+    EXPECT_TRUE(QuicSpdySessionPeer::GetReceiveControlStream(client_session));
+    server_thread_->Pause();
+    QuicSpdySession* server_session = GetServerSession();
+    if (server_session != nullptr) {
+      EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(server_session));
+      EXPECT_TRUE(QuicSpdySessionPeer::GetReceiveControlStream(server_session));
+    } else {
+      ADD_FAILURE() << "Missing server session";
+    }
+    server_thread_->Resume();
+  }
+  QuicConnectionStats client_stats = GetClientConnection()->GetStats();
+  EXPECT_TRUE(client_stats.handshake_completion_time.IsInitialized());
+}
+
+TEST_P(EndToEndTest, HandshakeConfirmed) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.UsesTls()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+  // Verify handshake state.
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_EQ(HANDSHAKE_CONFIRMED, client_session->GetHandshakeState());
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  if (server_session != nullptr) {
+    EXPECT_EQ(HANDSHAKE_CONFIRMED, server_session->GetHandshakeState());
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  server_thread_->Resume();
+  client_->Disconnect();
+}
+
+TEST_P(EndToEndTest, SendAndReceiveCoalescedPackets) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.CanSendCoalescedPackets()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+  // Verify client successfully processes coalesced packets.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionStats client_stats = client_connection->GetStats();
+  EXPECT_LT(0u, client_stats.num_coalesced_packets_received);
+  EXPECT_EQ(client_stats.num_coalesced_packets_processed,
+            client_stats.num_coalesced_packets_received);
+  // TODO(fayang): verify server successfully processes coalesced packets.
+}
+
+// Simple transaction, but set a non-default ack delay at the client
+// and ensure it gets to the server.
+TEST_P(EndToEndTest, SimpleRequestResponseWithAckDelayChange) {
+  // Force the ACK delay to be something other than the default.
+  constexpr uint32_t kClientMaxAckDelay = kDefaultDelayedAckTimeMs + 100u;
+  client_config_.SetMaxAckDelayToSendMs(kClientMaxAckDelay);
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  server_thread_->Pause();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (server_sent_packet_manager != nullptr) {
+    EXPECT_EQ(
+        kClientMaxAckDelay,
+        server_sent_packet_manager->peer_max_ack_delay().ToMilliseconds());
+  } else {
+    ADD_FAILURE() << "Missing server sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+// Simple transaction, but set a non-default ack exponent at the client
+// and ensure it gets to the server.
+TEST_P(EndToEndTest, SimpleRequestResponseWithAckExponentChange) {
+  const uint32_t kClientAckDelayExponent = 19;
+  EXPECT_NE(kClientAckDelayExponent, kDefaultAckDelayExponent);
+  // Force the ACK exponent to be something other than the default.
+  // Note that it is sent only with QUIC+TLS.
+  client_config_.SetAckDelayExponentToSend(kClientAckDelayExponent);
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    if (version_.UsesTls()) {
+      // Should be only sent with QUIC+TLS.
+      EXPECT_EQ(kClientAckDelayExponent,
+                server_connection->framer().peer_ack_delay_exponent());
+    } else {
+      // No change for QUIC_CRYPTO.
+      EXPECT_EQ(kDefaultAckDelayExponent,
+                server_connection->framer().peer_ack_delay_exponent());
+    }
+    // No change, regardless of version.
+    EXPECT_EQ(kDefaultAckDelayExponent,
+              server_connection->framer().local_ack_delay_exponent());
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseForcedVersionNegotiation) {
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  connection_debug_visitor_ = &visitor;
+  EXPECT_CALL(visitor, OnVersionNegotiationPacket(_)).Times(1);
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+}
+
+TEST_P(EndToEndTest, ForcedVersionNegotiation) {
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 0;
+  expected_server_connection_id_length_ = 0;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(client_connection->connection_id(),
+            QuicUtils::CreateZeroConnectionId(version_.transport_version));
+}
+
+TEST_P(EndToEndTest, ZeroConnectionID) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 0;
+  expected_server_connection_id_length_ = 0;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(client_connection->connection_id(),
+            QuicUtils::CreateZeroConnectionId(version_.transport_version));
+}
+
+TEST_P(EndToEndTest, BadConnectionIdLength) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 9;
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+}
+
+// Tests a very long (16-byte) initial destination connection ID to make
+// sure the dispatcher properly replaces it with an 8-byte one.
+TEST_P(EndToEndTest, LongBadConnectionIdLength) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 16;
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+}
+
+TEST_P(EndToEndTest, ClientConnectionId) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(override_client_connection_id_length_, client_->client()
+                                                       ->client_session()
+                                                       ->connection()
+                                                       ->client_connection_id()
+                                                       .length());
+}
+
+TEST_P(EndToEndTest, ForcedVersionNegotiationAndClientConnectionId) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(override_client_connection_id_length_, client_->client()
+                                                       ->client_session()
+                                                       ->connection()
+                                                       ->client_connection_id()
+                                                       .length());
+}
+
+TEST_P(EndToEndTest, ForcedVersionNegotiationAndBadConnectionIdLength) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  override_server_connection_id_length_ = 9;
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+}
+
+// Forced Version Negotiation with a client connection ID and a long
+// connection ID.
+TEST_P(EndToEndTest, ForcedVersNegoAndClientCIDAndLongCID) {
+  if (!version_.SupportsClientConnectionIds() ||
+      !version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  override_server_connection_id_length_ = 16;
+  override_client_connection_id_length_ = 18;
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+  EXPECT_EQ(override_client_connection_id_length_, client_->client()
+                                                       ->client_session()
+                                                       ->connection()
+                                                       ->client_connection_id()
+                                                       .length());
+}
+
+TEST_P(EndToEndTest, MixGoodAndBadConnectionIdLengths) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  // Start client_ which will use a bad connection ID length.
+  override_server_connection_id_length_ = 9;
+  ASSERT_TRUE(Initialize());
+  override_server_connection_id_length_ = -1;
+
+  // Start client2 which will use a good connection ID length.
+  std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+  client2->SendMessage(headers, "", /*fin=*/false);
+  client2->SendData("eep", true);
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+
+  WaitForFooResponseAndCheckIt(client2.get());
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client2->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseWithIetfDraftSupport) {
+  if (!version_.HasIetfQuicFrames()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  QuicVersionInitializeSupportForIetfDraft();
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) {
+  chlo_multiplier_ = 1;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  if (version_.UsesTls()) {
+    // REJ messages are a QUIC crypto feature, so TLS always returns false.
+    EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  } else {
+    EXPECT_TRUE(client_->client()->ReceivedInchoateReject());
+  }
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponsev6) {
+  server_address_ =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), server_address_.port());
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest,
+       ClientDoesNotAllowServerDataOnServerInitiatedBidirectionalStreams) {
+  set_client_initial_max_stream_data_incoming_bidirectional(0);
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest,
+       ServerDoesNotAllowClientDataOnServerInitiatedBidirectionalStreams) {
+  set_server_initial_max_stream_data_outgoing_bidirectional(0);
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest,
+       BothEndpointsDisallowDataOnServerInitiatedBidirectionalStreams) {
+  set_client_initial_max_stream_data_incoming_bidirectional(0);
+  set_server_initial_max_stream_data_outgoing_bidirectional(0);
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// Regression test for a bug where we would always fail to decrypt the first
+// initial packet. Undecryptable packets can be seen after the handshake
+// is complete due to dropping the initial keys at that point, so we only test
+// for undecryptable packets before then.
+TEST_P(EndToEndTest, NoUndecryptablePacketsBeforeHandshakeComplete) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionStats client_stats = client_connection->GetStats();
+  EXPECT_EQ(
+      0u,
+      client_stats.undecryptable_packets_received_before_handshake_complete);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_EQ(
+        0u,
+        server_stats.undecryptable_packets_received_before_handshake_complete);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, SeparateFinPacket) {
+  ASSERT_TRUE(Initialize());
+
+  // Send a request in two parts: the request and then an empty packet with FIN.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->SendData("", true);
+  WaitForFooResponseAndCheckIt();
+
+  // Now do the same thing but with a content length.
+  headers["content-length"] = "3";
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->SendData("foo", true);
+  WaitForFooResponseAndCheckIt();
+}
+
+TEST_P(EndToEndTest, MultipleRequestResponse) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  SendSynchronousBarRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, MultipleRequestResponseZeroConnectionID) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 0;
+  expected_server_connection_id_length_ = 0;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  SendSynchronousBarRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, MultipleStreams) {
+  // Verifies quic_test_client can track responses of all active streams.
+  ASSERT_TRUE(Initialize());
+
+  const int kNumRequests = 10;
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  for (int i = 0; i < kNumRequests; ++i) {
+    client_->SendMessage(headers, "bar", /*fin=*/true);
+  }
+
+  while (kNumRequests > client_->num_responses()) {
+    client_->ClearPerRequestState();
+    ASSERT_TRUE(WaitForFooResponseAndCheckIt());
+  }
+}
+
+TEST_P(EndToEndTest, MultipleClients) {
+  ASSERT_TRUE(Initialize());
+  std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client2->SendMessage(headers, "", /*fin=*/false);
+
+  client_->SendData("bar", true);
+  WaitForFooResponseAndCheckIt();
+
+  client2->SendData("eep", true);
+  WaitForFooResponseAndCheckIt(client2.get());
+}
+
+TEST_P(EndToEndTest, RequestOverMultiplePackets) {
+  // Send a large enough request to guarantee fragmentation.
+  std::string huge_request =
+      "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
+  AddToCache(huge_request, 200, kBarResponseBody);
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousRequestAndCheckResponse(huge_request, kBarResponseBody);
+}
+
+TEST_P(EndToEndTest, MultiplePacketsRandomOrder) {
+  // Send a large enough request to guarantee fragmentation.
+  std::string huge_request =
+      "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
+  AddToCache(huge_request, 200, kBarResponseBody);
+
+  ASSERT_TRUE(Initialize());
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(50);
+
+  SendSynchronousRequestAndCheckResponse(huge_request, kBarResponseBody);
+}
+
+TEST_P(EndToEndTest, PostMissingBytes) {
+  ASSERT_TRUE(Initialize());
+
+  // Add a content length header with no body.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  // This should be detected as stream fin without complete request,
+  // triggering an error response.
+  client_->SendCustomSynchronousRequest(headers, "");
+  EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
+            client_->response_body());
+  CheckResponseHeaders("500");
+}
+
+TEST_P(EndToEndTest, LargePostNoPacketLoss) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // TODO(ianswett): There should not be packet loss in this test, but on some
+  // platforms the receive buffer overflows.
+  VerifyCleanConnection(true);
+}
+
+TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
+  ASSERT_TRUE(Initialize());
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // 100 KB body.
+  std::string body(100 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  VerifyCleanConnection(false);
+}
+
+TEST_P(EndToEndTest, LargePostWithPacketLoss) {
+  // Connect with lower fake packet loss than we'd like to test.
+  // Until b/10126687 is fixed, losing handshake packets is pretty
+  // brutal.
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  SetPacketLossPercentage(5);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  SetPacketLossPercentage(30);
+
+  // 10 KB body.
+  std::string body(1024 * 10, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  VerifyCleanConnection(true);
+}
+
+// Regression test for b/80090281.
+TEST_P(EndToEndTest, LargePostWithPacketLossAndAlwaysBundleWindowUpdates) {
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Normally server only bundles a retransmittable frame once every other
+  // kMaxConsecutiveNonRetransmittablePackets ack-only packets. Setting the max
+  // to 0 to reliably reproduce b/80090281.
+  server_thread_->Schedule([this]() {
+    QuicConnection* server_connection = GetServerConnection();
+    if (server_connection != nullptr) {
+      QuicConnectionPeer::
+          SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
+              server_connection, 0);
+    } else {
+      ADD_FAILURE() << "Missing server connection";
+    }
+  });
+
+  SetPacketLossPercentage(30);
+
+  // 10 KB body.
+  std::string body(1024 * 10, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  VerifyCleanConnection(true);
+}
+
+TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
+  // Connect with lower fake packet loss than we'd like to test.  Until
+  // b/10126687 is fixed, losing handshake packets is pretty brutal.
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  SetPacketLossPercentage(5);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  SetPacketLossPercentage(10);
+  client_writer_->set_fake_blocked_socket_percentage(10);
+
+  // 10 KB body.
+  std::string body(1024 * 10, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+}
+
+TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  // Both of these must be called when the writer is not actively used.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+}
+
+TEST_P(EndToEndTest, AddressToken) {
+  client_extra_copts_.push_back(kTRTT);
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames()) {
+    return;
+  }
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  ASSERT_TRUE(client_->client()->connected());
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_session != nullptr && server_connection != nullptr) {
+    // Verify address is validated via validating token received in INITIAL
+    // packet.
+    EXPECT_FALSE(
+        server_connection->GetStats().address_validated_via_decrypting_packet);
+    EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
+
+    // Verify the server received a cached min_rtt from the token and used it as
+    // the initial rtt.
+    const CachedNetworkParameters* server_received_network_params =
+        static_cast<const QuicCryptoServerStreamBase*>(
+            server_session->GetCryptoStream())
+            ->PreviousCachedNetworkParams();
+
+    ASSERT_NE(server_received_network_params, nullptr);
+    // QuicSentPacketManager::SetInitialRtt clamps the initial_rtt to between
+    // [min_initial_rtt, max_initial_rtt].
+    const QuicTime::Delta min_initial_rtt =
+        server_connection->sent_packet_manager().use_lower_min_irtt()
+            ? QuicTime::Delta::FromMicroseconds(
+                  kMinTrustedInitialRoundTripTimeUs)
+            : QuicTime::Delta::FromMicroseconds(
+                  kMinUntrustedInitialRoundTripTimeUs);
+    const QuicTime::Delta max_initial_rtt =
+        QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
+    const QuicTime::Delta expected_initial_rtt =
+        std::max(min_initial_rtt,
+                 std::min(max_initial_rtt,
+                          QuicTime::Delta::FromMilliseconds(
+                              server_received_network_params->min_rtt_ms())));
+    EXPECT_EQ(
+        server_connection->sent_packet_manager().GetRttStats()->initial_rtt(),
+        expected_initial_rtt);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+
+  server_thread_->Resume();
+
+  client_->Disconnect();
+
+  // Regression test for b/206087883.
+  // Mock server crash.
+  StopServer();
+
+  // The handshake fails due to idle timeout.
+  client_->Connect();
+  ASSERT_FALSE(client_->client()->WaitForOneRttKeysAvailable());
+  client_->WaitForWriteToFlush();
+  client_->WaitForResponse();
+  ASSERT_FALSE(client_->client()->connected());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_NETWORK_IDLE_TIMEOUT));
+
+  // Server restarts.
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  // Client re-connect.
+  client_->Connect();
+  ASSERT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  client_->WaitForWriteToFlush();
+  client_->WaitForResponse();
+  ASSERT_TRUE(client_->client()->connected());
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  server_thread_->Pause();
+  server_session = GetServerSession();
+  server_connection = GetServerConnection();
+  // Verify address token is only used once.
+  if (server_session != nullptr && server_connection != nullptr) {
+    // Verify address is validated via decrypting packet.
+    EXPECT_TRUE(
+        server_connection->GetStats().address_validated_via_decrypting_packet);
+    EXPECT_FALSE(server_connection->GetStats().address_validated_via_token);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+
+  client_->Disconnect();
+}
+
+// Verify that client does not reuse a source address token.
+TEST_P(EndToEndTest, AddressTokenNotReusedByClient) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames()) {
+    return;
+  }
+
+  QuicCryptoClientConfig* client_crypto_config =
+      client_->client()->crypto_config();
+  QuicServerId server_id = client_->client()->server_id();
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  QuicClientSessionCache* session_cache = static_cast<QuicClientSessionCache*>(
+      client_crypto_config->mutable_session_cache());
+  ASSERT_TRUE(
+      !QuicClientSessionCachePeer::GetToken(session_cache, server_id).empty());
+
+  // Pause the server thread again to blackhole packets from client.
+  server_thread_->Pause();
+  client_->Connect();
+  EXPECT_FALSE(client_->client()->WaitForOneRttKeysAvailable());
+  EXPECT_FALSE(client_->client()->connected());
+
+  // Verify address token gets cleared.
+  ASSERT_TRUE(
+      QuicClientSessionCachePeer::GetToken(session_cache, server_id).empty());
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  ASSERT_TRUE(Initialize());
+
+  std::string body(20480, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  VerifyCleanConnection(false);
+}
+
+// Regression test for b/168020146.
+TEST_P(EndToEndTest, MultipleZeroRtt) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+}
+
+TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  VerifyCleanConnection(false);
+}
+
+TEST_P(EndToEndTest, LargePostSynchronousRequest) {
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  ASSERT_TRUE(Initialize());
+
+  std::string body(20480, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  VerifyCleanConnection(false);
+}
+
+// This is a regression test for b/162595387
+TEST_P(EndToEndTest, PostZeroRTTRequestDuringHandshake) {
+  if (!version_.UsesTls()) {
+    // This test is TLS specific.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  connection_debug_visitor_ = &visitor;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  ON_CALL(visitor, OnCryptoFrame(_))
+      .WillByDefault(Invoke([this](const QuicCryptoFrame& frame) {
+        if (frame.level != ENCRYPTION_HANDSHAKE) {
+          return;
+        }
+        // At this point in the handshake, the client should have derived
+        // ENCRYPTION_ZERO_RTT keys (thus set encryption_established). It
+        // should also have set ENCRYPTION_HANDSHAKE keys after receiving
+        // the server's ENCRYPTION_INITIAL flight.
+        EXPECT_TRUE(
+            GetClientSession()->GetCryptoStream()->encryption_established());
+        EXPECT_TRUE(
+            GetClientConnection()->framer().HasEncrypterOfEncryptionLevel(
+                ENCRYPTION_HANDSHAKE));
+        SpdyHeaderBlock headers;
+        headers[":method"] = "POST";
+        headers[":path"] = "/foo";
+        headers[":scheme"] = "https";
+        headers[":authority"] = server_hostname_;
+        EXPECT_GT(
+            client_->SendMessage(headers, "", /*fin*/ true, /*flush*/ false),
+            0);
+      }));
+  client_->Connect();
+  ASSERT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  client_->WaitForWriteToFlush();
+  client_->WaitForResponse();
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->response_body());
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+}
+
+// Regression test for b/166836136.
+TEST_P(EndToEndTest, RetransmissionAfterZeroRTTRejectBeforeOneRtt) {
+  if (!version_.UsesTls()) {
+    // This test is TLS specific.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  connection_debug_visitor_ = &visitor;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  ON_CALL(visitor, OnZeroRttRejected(_)).WillByDefault(Invoke([this]() {
+    EXPECT_FALSE(GetClientSession()->IsEncryptionEstablished());
+  }));
+
+  // The 0-RTT handshake should fail.
+  client_->Connect();
+  ASSERT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  client_->WaitForWriteToFlush();
+  client_->WaitForResponse();
+  ASSERT_TRUE(client_->client()->connected());
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+}
+
+TEST_P(EndToEndTest, RejectWithPacketLoss) {
+  // In this test, we intentionally drop the first packet from the
+  // server, which corresponds with the initial REJ response from
+  // the server.
+  server_writer_->set_fake_drop_first_n_packets(1);
+  ASSERT_TRUE(Initialize());
+}
+
+TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
+  QuicTagVector initial_received_options;
+  initial_received_options.push_back(kTBBR);
+  initial_received_options.push_back(kIW10);
+  initial_received_options.push_back(kPRST);
+  EXPECT_TRUE(server_config_.SetInitialReceivedConnectionOptions(
+      initial_received_options));
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
+      initial_received_options));
+
+  // Verify that server's configuration is correct.
+  server_thread_->Pause();
+  EXPECT_TRUE(server_config_.HasReceivedConnectionOptions());
+  EXPECT_TRUE(
+      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kTBBR));
+  EXPECT_TRUE(
+      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kIW10));
+  EXPECT_TRUE(
+      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
+}
+
+TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
+  ASSERT_TRUE(Initialize());
+  SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
+  // 256KB per second with a 256KB buffer from server to client.  Wireless
+  // clients commonly have larger buffers, but our max CWND is 200.
+  server_writer_->set_max_bandwidth_and_buffer_size(
+      QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // This connection may drop packets, because the buffer is smaller than the
+  // max CWND.
+  VerifyCleanConnection(true);
+}
+
+TEST_P(EndToEndTest, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
+  // Regression test for b/14677858.
+  // Test that the resume write alarm is not set in QuicConnection::OnCanWrite
+  // if currently connection level flow control blocked. If set, this results in
+  // an infinite loop in the EpollServer, as the alarm fires and is immediately
+  // rescheduled.
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // Ensure both stream and connection level are flow control blocked by setting
+  // the send window offset to 0.
+  const uint64_t flow_control_window =
+      server_config_.GetInitialStreamFlowControlWindowToSend();
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  QuicSession* session = GetClientSession();
+  ASSERT_TRUE(session);
+  QuicStreamPeer::SetSendWindowOffset(stream, 0);
+  QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0);
+  EXPECT_TRUE(stream->IsFlowControlBlocked());
+  EXPECT_TRUE(session->flow_controller()->IsBlocked());
+
+  // Make sure that the stream has data pending so that it will be marked as
+  // write blocked when it receives a stream level WINDOW_UPDATE.
+  stream->WriteOrBufferBody("hello", false);
+
+  // The stream now attempts to write, fails because it is still connection
+  // level flow control blocked, and is added to the write blocked list.
+  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream->id(),
+                                      2 * flow_control_window);
+  stream->OnWindowUpdateFrame(window_update);
+
+  // Prior to fixing b/14677858 this call would result in an infinite loop in
+  // Chromium. As a proxy for detecting this, we now check whether the
+  // send alarm is set after OnCanWrite. It should not be, as the
+  // connection is still flow control blocked.
+  session->connection()->OnCanWrite();
+
+  QuicAlarm* send_alarm =
+      QuicConnectionPeer::GetSendAlarm(session->connection());
+  EXPECT_FALSE(send_alarm->IsSet());
+}
+
+TEST_P(EndToEndTest, InvalidStream) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  std::string body(kMaxOutgoingPacketSize, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  // Force the client to write with a stream ID belonging to a nonexistent
+  // server-side stream.
+  QuicSpdySession* session = GetClientSession();
+  ASSERT_TRUE(session);
+  QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
+      session, GetNthServerInitiatedBidirectionalId(0));
+
+  client_->SendCustomSynchronousRequest(headers, body);
+  EXPECT_THAT(client_->stream_error(),
+              IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_INVALID_STREAM_ID));
+}
+
+// Test that the server resets the stream if the client sends a request
+// with overly large headers.
+TEST_P(EndToEndTest, LargeHeaders) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  std::string body(kMaxOutgoingPacketSize, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["key1"] = std::string(15 * 1024, 'a');
+  headers["key2"] = std::string(15 * 1024, 'a');
+  headers["key3"] = std::string(15 * 1024, 'a');
+
+  client_->SendCustomSynchronousRequest(headers, body);
+
+  if (version_.UsesHttp3()) {
+    // QuicSpdyStream::OnHeadersTooLarge() resets the stream with
+    // QUIC_HEADERS_TOO_LARGE.  This is sent as H3_EXCESSIVE_LOAD, the closest
+    // HTTP/3 error code, and translated back to QUIC_STREAM_EXCESSIVE_LOAD on
+    // the receiving side.
+    EXPECT_THAT(client_->stream_error(),
+                IsStreamError(QUIC_STREAM_EXCESSIVE_LOAD));
+  } else {
+    EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
+  }
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  std::string large_body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  // Insert an invalid content_length field in request to trigger an early
+  // response from server.
+  headers["content-length"] = "-3";
+
+  client_->SendCustomSynchronousRequest(headers, large_body);
+  EXPECT_EQ("bad", client_->response_body());
+  CheckResponseHeaders("500");
+  EXPECT_THAT(client_->stream_error(), IsQuicStreamNoError());
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+// TODO(rch): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(MultipleTermination)) {
+  ASSERT_TRUE(Initialize());
+
+  // Set the offset so we won't frame.  Otherwise when we pick up termination
+  // before HTTP framing is complete, we send an error and close the stream,
+  // and the second write is picked up as writing on a closed stream.
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamPeer::SetStreamBytesWritten(3, stream);
+
+  client_->SendData("bar", true);
+  client_->WaitForWriteToFlush();
+
+  // By default the stream protects itself from writes after terminte is set.
+  // Override this to test the server handling buggy clients.
+  QuicStreamPeer::SetWriteSideClosed(false, client_->GetOrCreateStream());
+
+  EXPECT_QUIC_BUG(client_->SendData("eep", true), "Fin already buffered");
+}
+
+TEST_P(EndToEndTest, Timeout) {
+  client_config_.SetIdleNetworkTimeout(QuicTime::Delta::FromMicroseconds(500));
+  // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
+  // that's enough to validate timeout in this case.
+  Initialize();
+  while (client_->client()->connected()) {
+    client_->client()->WaitForEvents();
+  }
+}
+
+TEST_P(EndToEndTest, MaxDynamicStreamsLimitRespected) {
+  // Set a limit on maximum number of incoming dynamic streams.
+  // Make sure the limit is respected by the peer.
+  const uint32_t kServerMaxDynamicStreams = 1;
+  server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
+  ASSERT_TRUE(Initialize());
+  if (version_.HasIetfQuicFrames()) {
+    // Do not run this test for /IETF QUIC. This test relies on the fact that
+    // Google QUIC allows a small number of additional streams beyond the
+    // negotiated limit, which is not supported in IETF QUIC. Note that the test
+    // needs to be here, after calling Initialize(), because all tests end up
+    // calling EndToEndTest::TearDown(), which asserts that Initialize has been
+    // called and then proceeds to tear things down -- which fails if they are
+    // not properly set up.
+    return;
+  }
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // Make the client misbehave after negotiation.
+  const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicSessionPeer::SetMaxOpenOutgoingStreams(client_session,
+                                             kServerMaxStreams + 1);
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  // The server supports a small number of additional streams beyond the
+  // negotiated limit. Open enough streams to go beyond that limit.
+  for (int i = 0; i < kServerMaxStreams + 1; ++i) {
+    client_->SendMessage(headers, "", /*fin=*/false);
+  }
+  client_->WaitForResponse();
+
+  EXPECT_TRUE(client_->connected());
+  EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_REFUSED_STREAM));
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(EndToEndTest, SetIndependentMaxDynamicStreamsLimits) {
+  // Each endpoint can set max dynamic streams independently.
+  const uint32_t kClientMaxDynamicStreams = 4;
+  const uint32_t kServerMaxDynamicStreams = 3;
+  client_config_.SetMaxBidirectionalStreamsToSend(kClientMaxDynamicStreams);
+  server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
+  client_config_.SetMaxUnidirectionalStreamsToSend(kClientMaxDynamicStreams);
+  server_config_.SetMaxUnidirectionalStreamsToSend(kServerMaxDynamicStreams);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // The client has received the server's limit and vice versa.
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  // The value returned by max_allowed... includes the Crypto and Header
+  // stream (created as a part of initialization). The config. values,
+  // above, are treated as "number of requests/responses" - that is, they do
+  // not include the static Crypto and Header streams. Reduce the value
+  // returned by max_allowed... by 2 to remove the static streams from the
+  // count.
+  size_t client_max_open_outgoing_bidirectional_streams =
+      version_.HasIetfQuicFrames()
+          ? QuicSessionPeer::ietf_streamid_manager(client_session)
+                ->max_outgoing_bidirectional_streams()
+          : QuicSessionPeer::GetStreamIdManager(client_session)
+                ->max_open_outgoing_streams();
+  size_t client_max_open_outgoing_unidirectional_streams =
+      version_.HasIetfQuicFrames()
+          ? QuicSessionPeer::ietf_streamid_manager(client_session)
+                    ->max_outgoing_unidirectional_streams() -
+                kHttp3StaticUnidirectionalStreamCount
+          : QuicSessionPeer::GetStreamIdManager(client_session)
+                ->max_open_outgoing_streams();
+  EXPECT_EQ(kServerMaxDynamicStreams,
+            client_max_open_outgoing_bidirectional_streams);
+  EXPECT_EQ(kServerMaxDynamicStreams,
+            client_max_open_outgoing_unidirectional_streams);
+  server_thread_->Pause();
+  QuicSession* server_session = GetServerSession();
+  if (server_session != nullptr) {
+    size_t server_max_open_outgoing_bidirectional_streams =
+        version_.HasIetfQuicFrames()
+            ? QuicSessionPeer::ietf_streamid_manager(server_session)
+                  ->max_outgoing_bidirectional_streams()
+            : QuicSessionPeer::GetStreamIdManager(server_session)
+                  ->max_open_outgoing_streams();
+    size_t server_max_open_outgoing_unidirectional_streams =
+        version_.HasIetfQuicFrames()
+            ? QuicSessionPeer::ietf_streamid_manager(server_session)
+                      ->max_outgoing_unidirectional_streams() -
+                  kHttp3StaticUnidirectionalStreamCount
+            : QuicSessionPeer::GetStreamIdManager(server_session)
+                  ->max_open_outgoing_streams();
+    EXPECT_EQ(kClientMaxDynamicStreams,
+              server_max_open_outgoing_bidirectional_streams);
+    EXPECT_EQ(kClientMaxDynamicStreams,
+              server_max_open_outgoing_unidirectional_streams);
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, NegotiateCongestionControl) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  CongestionControlType expected_congestion_control_type = kRenoBytes;
+  switch (GetParam().congestion_control_tag) {
+    case kRENO:
+      expected_congestion_control_type = kRenoBytes;
+      break;
+    case kTBBR:
+      expected_congestion_control_type = kBBR;
+      break;
+    case kQBIC:
+      expected_congestion_control_type = kCubicBytes;
+      break;
+    case kB2ON:
+      expected_congestion_control_type = kBBRv2;
+      break;
+    default:
+      QUIC_DLOG(FATAL) << "Unexpected congestion control tag";
+  }
+
+  server_thread_->Pause();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (server_sent_packet_manager != nullptr) {
+    EXPECT_EQ(
+        expected_congestion_control_type,
+        QuicSentPacketManagerPeer::GetSendAlgorithm(*server_sent_packet_manager)
+            ->GetCongestionControlType());
+  } else {
+    ADD_FAILURE() << "Missing server sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ClientSuggestsRTT) {
+  // Client suggests initial RTT, verify it is used.
+  const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
+  client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager* client_sent_packet_manager =
+      GetSentPacketManagerFromClientSession();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (client_sent_packet_manager != nullptr &&
+      server_sent_packet_manager != nullptr) {
+    EXPECT_EQ(kInitialRTT,
+              client_sent_packet_manager->GetRttStats()->initial_rtt());
+    EXPECT_EQ(kInitialRTT,
+              server_sent_packet_manager->GetRttStats()->initial_rtt());
+  } else {
+    ADD_FAILURE() << "Missing sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ClientSuggestsIgnoredRTT) {
+  // Client suggests initial RTT, but also specifies NRTT, so it's not used.
+  const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
+  client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
+  QuicTagVector options;
+  options.push_back(kNRTT);
+  client_config_.SetConnectionOptionsToSend(options);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager* client_sent_packet_manager =
+      GetSentPacketManagerFromClientSession();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (client_sent_packet_manager != nullptr &&
+      server_sent_packet_manager != nullptr) {
+    EXPECT_EQ(kInitialRTT,
+              client_sent_packet_manager->GetRttStats()->initial_rtt());
+    EXPECT_EQ(kInitialRTT,
+              server_sent_packet_manager->GetRttStats()->initial_rtt());
+  } else {
+    ADD_FAILURE() << "Missing sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+// Regression test for b/171378845
+TEST_P(EndToEndTest, ClientDisablesGQuicZeroRtt) {
+  if (version_.UsesTls()) {
+    // This feature is gQUIC only.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  QuicTagVector options;
+  options.push_back(kQNZ2);
+  client_config_.SetClientConnectionOptions(options);
+
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // Make sure that the request succeeds but 0-RTT was not used.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+}
+
+TEST_P(EndToEndTest, MaxInitialRTT) {
+  // Client tries to suggest twice the server's max initial rtt and the server
+  // uses the max.
+  client_config_.SetInitialRoundTripTimeUsToSend(2 *
+                                                 kMaxInitialRoundTripTimeUs);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager* client_sent_packet_manager =
+      GetSentPacketManagerFromClientSession();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (client_sent_packet_manager != nullptr &&
+      server_sent_packet_manager != nullptr) {
+    // Now that acks have been exchanged, the RTT estimate has decreased on the
+    // server and is not infinite on the client.
+    EXPECT_FALSE(
+        client_sent_packet_manager->GetRttStats()->smoothed_rtt().IsInfinite());
+    const RttStats* server_rtt_stats =
+        server_sent_packet_manager->GetRttStats();
+    EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
+              server_rtt_stats->initial_rtt().ToMicroseconds());
+    EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
+              server_rtt_stats->smoothed_rtt().ToMicroseconds());
+  } else {
+    ADD_FAILURE() << "Missing sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, MinInitialRTT) {
+  // Client tries to suggest 0 and the server uses the default.
+  client_config_.SetInitialRoundTripTimeUsToSend(0);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager* client_sent_packet_manager =
+      GetSentPacketManagerFromClientSession();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (client_sent_packet_manager != nullptr &&
+      server_sent_packet_manager != nullptr) {
+    // Now that acks have been exchanged, the RTT estimate has decreased on the
+    // server and is not infinite on the client.
+    EXPECT_FALSE(
+        client_sent_packet_manager->GetRttStats()->smoothed_rtt().IsInfinite());
+    // Expect the default rtt of 100ms.
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
+              server_sent_packet_manager->GetRttStats()->initial_rtt());
+    // Ensure the bandwidth is valid.
+    client_sent_packet_manager->BandwidthEstimate();
+    server_sent_packet_manager->BandwidthEstimate();
+  } else {
+    ADD_FAILURE() << "Missing sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, 0ByteConnectionId) {
+  if (version_.HasIetfInvariantHeader()) {
+    // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetBytesForConnectionIdToSend(0);
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicPacketHeader* header =
+      QuicConnectionPeer::GetLastHeader(client_connection);
+  EXPECT_EQ(CONNECTION_ID_ABSENT, header->source_connection_id_included);
+}
+
+TEST_P(EndToEndTest, 8ByteConnectionId) {
+  if (version_.HasIetfInvariantHeader()) {
+    // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetBytesForConnectionIdToSend(8);
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicPacketHeader* header =
+      QuicConnectionPeer::GetLastHeader(client_connection);
+  EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
+}
+
+TEST_P(EndToEndTest, 15ByteConnectionId) {
+  if (version_.HasIetfInvariantHeader()) {
+    // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetBytesForConnectionIdToSend(15);
+  ASSERT_TRUE(Initialize());
+
+  // Our server is permissive and allows for out of bounds values.
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicPacketHeader* header =
+      QuicConnectionPeer::GetLastHeader(client_connection);
+  EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
+}
+
+TEST_P(EndToEndTest, ResetConnection) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  client_->ResetConnection();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  SendSynchronousBarRequestAndCheckResponse();
+}
+
+// Regression test for b/180737158.
+TEST_P(
+    EndToEndTest,
+    HalfRttResponseBlocksShloRetransmissionWithoutTokenBasedAddressValidation) {
+  // Turn off token based address validation to make the server get constrained
+  // by amplification factor during handshake.
+  SetQuicFlag(FLAGS_quic_reject_retry_token_in_initial_packet, true);
+  ASSERT_TRUE(Initialize());
+  if (!version_.SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  // Perform a full 1-RTT handshake to get the new session ticket such that the
+  // next connection will perform a 0-RTT handshake.
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  client_->Disconnect();
+
+  server_thread_->Pause();
+  // Drop the 1st server packet which is the coalesced INITIAL + HANDSHAKE +
+  // 1RTT.
+  PacketDroppingTestWriter* writer = new PacketDroppingTestWriter();
+  writer->set_fake_drop_first_n_packets(1);
+  QuicDispatcherPeer::UseWriter(
+      QuicServerPeer::GetDispatcher(server_thread_->server()), writer);
+  server_thread_->Resume();
+
+  // Large response (100KB) for 0-RTT request.
+  std::string large_body(102400, 'a');
+  AddToCache("/large_response", 200, large_body);
+  SendSynchronousRequestAndCheckResponse(client_.get(), "/large_response",
+                                         large_body);
+}
+
+TEST_P(EndToEndTest, MaxStreamsUberTest) {
+  // Connect with lower fake packet loss than we'd like to test.  Until
+  // b/10126687 is fixed, losing handshake packets is pretty brutal.
+  SetPacketLossPercentage(1);
+  ASSERT_TRUE(Initialize());
+  std::string large_body(10240, 'a');
+  int max_streams = 100;
+
+  AddToCache("/large_response", 200, large_body);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  SetPacketLossPercentage(10);
+
+  for (int i = 0; i < max_streams; ++i) {
+    EXPECT_LT(0, client_->SendRequest("/large_response"));
+  }
+
+  // WaitForEvents waits 50ms and returns true if there are outstanding
+  // requests.
+  while (client_->client()->WaitForEvents()) {
+    ASSERT_TRUE(client_->connected());
+  }
+}
+
+TEST_P(EndToEndTest, StreamCancelErrorTest) {
+  ASSERT_TRUE(Initialize());
+  std::string small_body(256, 'a');
+
+  AddToCache("/small_response", 200, small_body);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  QuicSession* session = GetClientSession();
+  ASSERT_TRUE(session);
+  // Lose the request.
+  SetPacketLossPercentage(100);
+  EXPECT_LT(0, client_->SendRequest("/small_response"));
+  client_->client()->WaitForEvents();
+  // Transmit the cancel, and ensure the connection is torn down properly.
+  SetPacketLossPercentage(0);
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  const QuicPacketCount packets_sent_before =
+      client_connection->GetStats().packets_sent;
+  session->ResetStream(stream_id, QUIC_STREAM_CANCELLED);
+  const QuicPacketCount packets_sent_now =
+      client_connection->GetStats().packets_sent;
+
+  if (version_.UsesHttp3()) {
+    // Make sure 2 packets were sent, one for QPACK instructions, another for
+    // RESET_STREAM and STOP_SENDING.
+    EXPECT_EQ(packets_sent_before + 2, packets_sent_now);
+  }
+
+  // WaitForEvents waits 50ms and returns true if there are outstanding
+  // requests.
+  while (client_->client()->WaitForEvents()) {
+    ASSERT_TRUE(client_->connected());
+  }
+  // It should be completely fine to RST a stream before any data has been
+  // received for that stream.
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) {
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress old_host =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_host, new_host);
+  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  if (!version_.HasIetfQuicFrames() ||
+      !client_->client()->session()->connection()->validate_client_address()) {
+    return;
+  }
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Send another request.
+  SendSynchronousBarRequestAndCheckResponse();
+  // By the time the 2nd request is completed, the PATH_RESPONSE must have been
+  // received by the server.
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_FALSE(server_connection->HasPendingPathValidation());
+    EXPECT_EQ(1u, server_connection->GetStats().num_validated_peer_migration);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, IetfConnectionMigrationClientIPChangedMultipleTimes) {
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress host0 =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection != nullptr);
+
+  // Migrate socket to a new IP address.
+  QuicIpAddress host1 = TestLoopback(2);
+  EXPECT_NE(host0, host1);
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+  QuicConnectionId server_cid0 = client_connection->connection_id();
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  EXPECT_FALSE(server_cid1.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid1);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Send another request and wait for response making sure path response is
+  // received at server.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Migrate socket to a new IP address.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  QuicIpAddress host2 = TestLoopback(3);
+  EXPECT_NE(host0, host2);
+  EXPECT_NE(host1, host2);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(client_->client()->MigrateSocket(host2));
+  QuicConnectionId server_cid2 = client_connection->connection_id();
+  EXPECT_FALSE(server_cid2.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid2);
+  EXPECT_NE(server_cid1, server_cid2);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send another request using the new socket and wait for response making sure
+  // path response is received at server.
+  SendSynchronousBarRequestAndCheckResponse();
+  EXPECT_EQ(2u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Migrate socket back to an old IP address.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
+  QuicConnectionId server_cid3 = client_connection->connection_id();
+  EXPECT_FALSE(server_cid3.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid3);
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  const auto* client_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(client_connection);
+  EXPECT_TRUE(client_packet_creator->GetClientConnectionId().IsEmpty());
+  EXPECT_EQ(server_cid3, client_packet_creator->GetServerConnectionId());
+
+  // Send another request using the new socket and wait for response making sure
+  // path response is received at server.
+  SendSynchronousBarRequestAndCheckResponse();
+  // Even this is an old path, server has forgotten about it and thus needs to
+  // validate the path again.
+  EXPECT_EQ(3u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  WaitForNewConnectionIds();
+  EXPECT_EQ(3u, client_connection->GetStats().num_retire_connection_id_sent);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  // By the time the 2nd request is completed, the PATH_RESPONSE must have been
+  // received by the server.
+  EXPECT_FALSE(server_connection->HasPendingPathValidation());
+  EXPECT_EQ(3u, server_connection->GetStats().num_validated_peer_migration);
+  EXPECT_EQ(server_cid3, server_connection->connection_id());
+  const auto* server_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(server_connection);
+  EXPECT_EQ(server_cid3, server_packet_creator->GetServerConnectionId());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  server_connection)
+                  .IsEmpty());
+  EXPECT_EQ(4u, server_connection->GetStats().num_new_connection_id_sent);
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest,
+       ConnectionMigrationWithNonZeroConnectionIDClientIPChangedMultipleTimes) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress host0 =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection != nullptr);
+
+  // Migrate socket to a new IP address.
+  QuicIpAddress host1 = TestLoopback(2);
+  EXPECT_NE(host0, host1);
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+  QuicConnectionId server_cid0 = client_connection->connection_id();
+  QuicConnectionId client_cid0 = client_connection->client_connection_id();
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  QuicConnectionId client_cid1 = client_connection->client_connection_id();
+  EXPECT_FALSE(server_cid1.IsEmpty());
+  EXPECT_FALSE(client_cid1.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid1);
+  EXPECT_NE(client_cid0, client_cid1);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send another request to ensure that the server will have time to finish the
+  // reverse path validation and send address token.
+  SendSynchronousBarRequestAndCheckResponse();
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Migrate socket to a new IP address.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(2u, client_connection->GetStats().num_new_connection_id_sent);
+  QuicIpAddress host2 = TestLoopback(3);
+  EXPECT_NE(host0, host2);
+  EXPECT_NE(host1, host2);
+  EXPECT_TRUE(client_->client()->MigrateSocket(host2));
+  QuicConnectionId server_cid2 = client_connection->connection_id();
+  QuicConnectionId client_cid2 = client_connection->client_connection_id();
+  EXPECT_FALSE(server_cid2.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid2);
+  EXPECT_NE(server_cid1, server_cid2);
+  EXPECT_FALSE(client_cid2.IsEmpty());
+  EXPECT_NE(client_cid0, client_cid2);
+  EXPECT_NE(client_cid1, client_cid2);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send another request to ensure that the server will have time to finish the
+  // reverse path validation and send address token.
+  SendSynchronousBarRequestAndCheckResponse();
+  EXPECT_EQ(2u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Migrate socket back to an old IP address.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(3u, client_connection->GetStats().num_new_connection_id_sent);
+  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
+  QuicConnectionId server_cid3 = client_connection->connection_id();
+  QuicConnectionId client_cid3 = client_connection->client_connection_id();
+  EXPECT_FALSE(server_cid3.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid3);
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  EXPECT_FALSE(client_cid3.IsEmpty());
+  EXPECT_NE(client_cid0, client_cid3);
+  EXPECT_NE(client_cid1, client_cid3);
+  EXPECT_NE(client_cid2, client_cid3);
+  const auto* client_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(client_connection);
+  EXPECT_EQ(client_cid3, client_packet_creator->GetClientConnectionId());
+  EXPECT_EQ(server_cid3, client_packet_creator->GetServerConnectionId());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send another request to ensure that the server will have time to finish the
+  // reverse path validation and send address token.
+  SendSynchronousBarRequestAndCheckResponse();
+  // Even this is an old path, server has forgotten about it and thus needs to
+  // validate the path again.
+  EXPECT_EQ(3u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  WaitForNewConnectionIds();
+  EXPECT_EQ(3u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(4u, client_connection->GetStats().num_new_connection_id_sent);
+
+  server_thread_->Pause();
+  // By the time the 2nd request is completed, the PATH_RESPONSE must have been
+  // received by the server.
+  QuicConnection* server_connection = GetServerConnection();
+  EXPECT_FALSE(server_connection->HasPendingPathValidation());
+  EXPECT_EQ(3u, server_connection->GetStats().num_validated_peer_migration);
+  EXPECT_EQ(server_cid3, server_connection->connection_id());
+  EXPECT_EQ(client_cid3, server_connection->client_connection_id());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  server_connection)
+                  .IsEmpty());
+  const auto* server_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(server_connection);
+  EXPECT_EQ(client_cid3, server_packet_creator->GetClientConnectionId());
+  EXPECT_EQ(server_cid3, server_packet_creator->GetServerConnectionId());
+  EXPECT_EQ(3u, server_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(4u, server_connection->GetStats().num_new_connection_id_sent);
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ConnectionMigrationNewTokenForNewIp) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames() ||
+      !client_->client()->session()->connection()->validate_client_address()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress old_host =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_host, new_host);
+  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Send another request to ensure that the server will have time to finish the
+  // reverse path validation and send address token.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  client_->Disconnect();
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  SendSynchronousFooRequestAndCheckResponse();
+
+  EXPECT_TRUE(GetClientSession()->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    // Verify address is validated via validating token received in INITIAL
+    // packet.
+    EXPECT_FALSE(
+        server_connection->GetStats().address_validated_via_decrypting_packet);
+    EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+  client_->Disconnect();
+}
+
+// A writer which copies the packet and send the copy with a specified self
+// address and then send the same packet with the original self address.
+class DuplicatePacketWithSpoofedSelfAddressWriter
+    : public QuicPacketWriterWrapper {
+ public:
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override {
+    if (self_address_to_overwrite_.IsInitialized()) {
+      // Send the same packet on the overwriting address before sending on the
+      // actual self address.
+      QuicPacketWriterWrapper::WritePacket(
+          buffer, buf_len, self_address_to_overwrite_, peer_address, options);
+    }
+    return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                                peer_address, options);
+  }
+
+  void set_self_address_to_overwrite(const QuicIpAddress& self_address) {
+    self_address_to_overwrite_ = self_address;
+  }
+
+ private:
+  QuicIpAddress self_address_to_overwrite_;
+};
+
+TEST_P(EndToEndTest, ClientAddressSpoofedForSomePeriod) {
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  auto writer = new DuplicatePacketWithSpoofedSelfAddressWriter();
+  client_.reset(CreateQuicClient(writer));
+
+  // Make sure client has unused peer connection ID before migration.
+  SendSynchronousFooRequestAndCheckResponse();
+  ASSERT_TRUE(QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
+      GetClientConnection()));
+
+  QuicIpAddress real_host =
+      client_->client()->session()->connection()->self_address().host();
+  ASSERT_TRUE(client_->MigrateSocket(real_host));
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(
+      0u, GetClientConnection()->GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(
+      real_host,
+      client_->client()->network_helper()->GetLatestClientAddress().host());
+  client_->WaitForDelayedAcks();
+
+  std::string large_body(10240, 'a');
+  AddToCache("/large_response", 200, large_body);
+
+  QuicIpAddress spoofed_host = TestLoopback(2);
+  writer->set_self_address_to_overwrite(spoofed_host);
+
+  client_->SendRequest("/large_response");
+  QuicConnection* client_connection = GetClientConnection();
+  QuicPacketCount num_packets_received =
+      client_connection->GetStats().packets_received;
+
+  while (client_->client()->WaitForEvents() && client_->connected()) {
+    if (client_connection->GetStats().packets_received > num_packets_received) {
+      // Ideally the client won't receive any packets till the server finds out
+      // the new client address is not working. But there are 2 corner cases:
+      // 1) Before the server received the packet from spoofed address, it might
+      // send packets to the real client address. So the client will immediately
+      // switch back to use the original address;
+      // 2) Between the server fails reverse path validation and the client
+      // receives packets again, the client might sent some packets with the
+      // spoofed address and triggers another migration.
+      // In both corner cases, the attempted migration should fail and fall back
+      // to the working path.
+      writer->set_self_address_to_overwrite(QuicIpAddress());
+    }
+  }
+  client_->WaitForResponse();
+  EXPECT_EQ(large_body, client_->response_body());
+}
+
+TEST_P(EndToEndTest,
+       AsynchronousConnectionMigrationClientIPChangedMultipleTimes) {
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  client_.reset(CreateQuicClient(nullptr));
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress host0 =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+  QuicConnection* client_connection = GetClientConnection();
+  QuicConnectionId server_cid0 = client_connection->connection_id();
+  // Server should have one new connection ID upon handshake completion.
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+
+  // Migrate socket to new IP address #1.
+  QuicIpAddress host1 = TestLoopback(2);
+  EXPECT_NE(host0, host1);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host1));
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host1, client_->client()->session()->self_address().host());
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  EXPECT_NE(server_cid0, server_cid1);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Migrate socket to new IP address #2.
+  WaitForNewConnectionIds();
+  QuicIpAddress host2 = TestLoopback(3);
+  EXPECT_NE(host0, host1);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
+
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host2, client_->client()->session()->self_address().host());
+  EXPECT_EQ(2u,
+            client_connection->GetStats().num_connectivity_probing_received);
+  QuicConnectionId server_cid2 = client_connection->connection_id();
+  EXPECT_NE(server_cid0, server_cid2);
+  EXPECT_NE(server_cid1, server_cid2);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Migrate socket back to IP address #1.
+  WaitForNewConnectionIds();
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host1));
+
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host1, client_->client()->session()->self_address().host());
+  EXPECT_EQ(3u,
+            client_connection->GetStats().num_connectivity_probing_received);
+  QuicConnectionId server_cid3 = client_connection->connection_id();
+  EXPECT_NE(server_cid0, server_cid3);
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+  server_thread_->Pause();
+  const QuicConnection* server_connection = GetServerConnection();
+  EXPECT_EQ(server_connection->connection_id(), server_cid3);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  server_connection)
+                  .IsEmpty());
+  server_thread_->Resume();
+
+  // There should be 1 new connection ID issued by the server.
+  WaitForNewConnectionIds();
+}
+
+TEST_P(EndToEndTest,
+       AsynchronousConnectionMigrationClientIPChangedWithNonEmptyClientCID) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  client_.reset(CreateQuicClient(nullptr));
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress old_host =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+  auto* client_connection = GetClientConnection();
+  QuicConnectionId client_cid0 = client_connection->client_connection_id();
+  QuicConnectionId server_cid0 = client_connection->connection_id();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_host, new_host);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(new_host));
+
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(new_host, client_->client()->session()->self_address().host());
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+  QuicConnectionId client_cid1 = client_connection->client_connection_id();
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  const auto* client_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(client_connection);
+  EXPECT_EQ(client_cid1, client_packet_creator->GetClientConnectionId());
+  EXPECT_EQ(server_cid1, client_packet_creator->GetServerConnectionId());
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  EXPECT_EQ(client_cid1, server_connection->client_connection_id());
+  EXPECT_EQ(server_cid1, server_connection->connection_id());
+  const auto* server_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(server_connection);
+  EXPECT_EQ(client_cid1, server_packet_creator->GetClientConnectionId());
+  EXPECT_EQ(server_cid1, server_packet_creator->GetServerConnectionId());
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
+  // Tests that the client's port can change during an established QUIC
+  // connection, and that doing so does not result in the connection being
+  // closed by the server.
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client address which was used to send the first request.
+  QuicSocketAddress old_address =
+      client_->client()->network_helper()->GetLatestClientAddress();
+  int old_fd = client_->client()->GetLatestFD();
+
+  // Create a new socket before closing the old one, which will result in a new
+  // ephemeral port.
+  QuicClientPeer::CreateUDPSocketAndBind(client_->client());
+
+  // Stop listening and close the old FD.
+  QuicClientPeer::CleanUpUDPSocket(client_->client(), old_fd);
+
+  // The packet writer needs to be updated to use the new FD.
+  client_->client()->network_helper()->CreateQuicPacketWriter();
+
+  // Change the internal state of the client and connection to use the new port,
+  // this is done because in a real NAT rebinding the client wouldn't see any
+  // port change, and so expects no change to incoming port.
+  // This is kind of ugly, but needed as we are simply swapping out the client
+  // FD rather than any more complex NAT rebinding simulation.
+  int new_port =
+      client_->client()->network_helper()->GetLatestClientAddress().port();
+  QuicClientPeer::SetClientPort(client_->client(), new_port);
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionPeer::SetSelfAddress(
+      client_connection,
+      QuicSocketAddress(client_connection->self_address().host(), new_port));
+
+  // Register the new FD for epoll events.
+  int new_fd = client_->client()->GetLatestFD();
+  QuicEpollServer* eps = client_->epoll_server();
+  eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(),
+                  EPOLLIN | EPOLLOUT | EPOLLET);
+
+  // Send a second request, using the new FD.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Verify that the client's ephemeral port is different.
+  QuicSocketAddress new_address =
+      client_->client()->network_helper()->GetLatestClientAddress();
+  EXPECT_EQ(old_address.host(), new_address.host());
+  EXPECT_NE(old_address.port(), new_address.port());
+
+  if (!version_.HasIetfQuicFrames() ||
+      !GetClientConnection()->validate_client_address()) {
+    return;
+  }
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_FALSE(server_connection->HasPendingPathValidation());
+    EXPECT_EQ(1u, server_connection->GetStats().num_validated_peer_migration);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
+  SetQuicReloadableFlag(quic_unified_iw_options, true);
+  client_extra_copts_.push_back(kIW03);
+
+  ASSERT_TRUE(Initialize());
+
+  // Values are exchanged during crypto handshake, so wait for that to finish.
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    QuicPacketCount cwnd =
+        server_connection->sent_packet_manager().initial_congestion_window();
+    EXPECT_EQ(3u, cwnd);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, DifferentFlowControlWindows) {
+  // Client and server can set different initial flow control receive windows.
+  // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
+  // in the crypto handshake.
+  const uint32_t kClientStreamIFCW = 123456;
+  const uint32_t kClientSessionIFCW = 234567;
+  set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
+  set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
+
+  uint32_t kServerStreamIFCW = 32 * 1024;
+  uint32_t kServerSessionIFCW = 48 * 1024;
+  set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
+  set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
+
+  ASSERT_TRUE(Initialize());
+
+  // Values are exchanged during crypto handshake, so wait for that to finish.
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Open a data stream to make sure the stream level flow control is updated.
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  WriteHeadersOnStream(stream);
+  stream->WriteOrBufferBody("hello", false);
+
+  if (!version_.UsesTls()) {
+    // IFWA only exists with QUIC_CRYPTO.
+    // Client should have the right values for server's receive window.
+    ASSERT_TRUE(client_->client()
+                    ->client_session()
+                    ->config()
+                    ->HasReceivedInitialStreamFlowControlWindowBytes());
+    EXPECT_EQ(kServerStreamIFCW,
+              client_->client()
+                  ->client_session()
+                  ->config()
+                  ->ReceivedInitialStreamFlowControlWindowBytes());
+    ASSERT_TRUE(client_->client()
+                    ->client_session()
+                    ->config()
+                    ->HasReceivedInitialSessionFlowControlWindowBytes());
+    EXPECT_EQ(kServerSessionIFCW,
+              client_->client()
+                  ->client_session()
+                  ->config()
+                  ->ReceivedInitialSessionFlowControlWindowBytes());
+  }
+  EXPECT_EQ(kServerStreamIFCW, QuicStreamPeer::SendWindowOffset(stream));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_EQ(kServerSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
+                                    client_session->flow_controller()));
+
+  // Server should have the right values for client's receive window.
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  if (server_session == nullptr) {
+    ADD_FAILURE() << "Missing server session";
+    server_thread_->Resume();
+    return;
+  }
+  QuicConfig server_config = *server_session->config();
+  EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
+                                    server_session->flow_controller()));
+  server_thread_->Resume();
+  if (version_.UsesTls()) {
+    // IFWA only exists with QUIC_CRYPTO.
+    return;
+  }
+  ASSERT_TRUE(server_config.HasReceivedInitialStreamFlowControlWindowBytes());
+  EXPECT_EQ(kClientStreamIFCW,
+            server_config.ReceivedInitialStreamFlowControlWindowBytes());
+  ASSERT_TRUE(server_config.HasReceivedInitialSessionFlowControlWindowBytes());
+  EXPECT_EQ(kClientSessionIFCW,
+            server_config.ReceivedInitialSessionFlowControlWindowBytes());
+}
+
+// Test negotiation of IFWA connection option.
+TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
+  const uint32_t kClientStreamIFCW = 123456;
+  const uint32_t kClientSessionIFCW = 234567;
+  set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
+  set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
+
+  uint32_t kServerStreamIFCW = 32 * 1024;
+  uint32_t kServerSessionIFCW = 48 * 1024;
+  set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
+  set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
+
+  // Bump the window.
+  const uint32_t kExpectedStreamIFCW = 1024 * 1024;
+  const uint32_t kExpectedSessionIFCW = 1.5 * 1024 * 1024;
+  client_extra_copts_.push_back(kIFWA);
+
+  ASSERT_TRUE(Initialize());
+
+  // Values are exchanged during crypto handshake, so wait for that to finish.
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Open a data stream to make sure the stream level flow control is updated.
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  WriteHeadersOnStream(stream);
+  stream->WriteOrBufferBody("hello", false);
+
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+
+  if (!version_.UsesTls()) {
+    // IFWA only exists with QUIC_CRYPTO.
+    // Client should have the right values for server's receive window.
+    ASSERT_TRUE(client_session->config()
+                    ->HasReceivedInitialStreamFlowControlWindowBytes());
+    EXPECT_EQ(kExpectedStreamIFCW,
+              client_session->config()
+                  ->ReceivedInitialStreamFlowControlWindowBytes());
+    ASSERT_TRUE(client_session->config()
+                    ->HasReceivedInitialSessionFlowControlWindowBytes());
+    EXPECT_EQ(kExpectedSessionIFCW,
+              client_session->config()
+                  ->ReceivedInitialSessionFlowControlWindowBytes());
+  }
+  EXPECT_EQ(kExpectedStreamIFCW, QuicStreamPeer::SendWindowOffset(stream));
+  EXPECT_EQ(kExpectedSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
+                                      client_session->flow_controller()));
+}
+
+TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
+  // The special headers and crypto streams should be subject to per-stream flow
+  // control limits, but should not be subject to connection level flow control
+  const uint32_t kStreamIFCW = 32 * 1024;
+  const uint32_t kSessionIFCW = 48 * 1024;
+  set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
+  set_client_initial_session_flow_control_receive_window(kSessionIFCW);
+  set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
+  set_server_initial_session_flow_control_receive_window(kSessionIFCW);
+
+  ASSERT_TRUE(Initialize());
+
+  // Wait for crypto handshake to finish. This should have contributed to the
+  // crypto stream flow control window, but not affected the session flow
+  // control window.
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicCryptoStream* crypto_stream =
+      QuicSessionPeer::GetMutableCryptoStream(client_session);
+  ASSERT_TRUE(crypto_stream);
+  // In v47 and later, the crypto handshake (sent in CRYPTO frames) is not
+  // subject to flow control.
+  if (!version_.UsesCryptoFrames()) {
+    EXPECT_LT(QuicStreamPeer::SendWindowSize(crypto_stream), kStreamIFCW);
+  }
+  // When stream type is enabled, control streams will send settings and
+  // contribute to flow control windows, so this expectation is no longer valid.
+  if (!version_.UsesHttp3()) {
+    EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
+                                client_session->flow_controller()));
+  }
+
+  // Send a request with no body, and verify that the connection level window
+  // has not been affected.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // No headers stream in IETF QUIC.
+  if (version_.UsesHttp3()) {
+    return;
+  }
+
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(client_session);
+  ASSERT_TRUE(headers_stream);
+  EXPECT_LT(QuicStreamPeer::SendWindowSize(headers_stream), kStreamIFCW);
+  EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
+                              client_session->flow_controller()));
+
+  // Server should be in a similar state: connection flow control window should
+  // not have any bytes marked as received.
+  server_thread_->Pause();
+  QuicSession* server_session = GetServerSession();
+  if (server_session != nullptr) {
+    QuicFlowController* server_connection_flow_controller =
+        server_session->flow_controller();
+    EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
+                                server_connection_flow_controller));
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, FlowControlsSynced) {
+  set_smaller_flow_control_receive_window();
+
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  QuicSpdySession* const client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+
+  if (version_.UsesHttp3()) {
+    // Make sure that the client has received the initial SETTINGS frame, which
+    // is sent in the first packet on the control stream.
+    while (!QuicSpdySessionPeer::GetReceiveControlStream(client_session)) {
+      client_->client()->WaitForEvents();
+      ASSERT_TRUE(client_->connected());
+    }
+  }
+
+  // Make sure that all data sent by the client has been received by the server
+  // (and the ack received by the client).
+  while (client_session->HasUnackedStreamData()) {
+    client_->client()->WaitForEvents();
+    ASSERT_TRUE(client_->connected());
+  }
+
+  server_thread_->Pause();
+
+  QuicSpdySession* const server_session = GetServerSession();
+  if (server_session == nullptr) {
+    ADD_FAILURE() << "Missing server session";
+    server_thread_->Resume();
+    return;
+  }
+  ExpectFlowControlsSynced(client_session, server_session);
+
+  // Check control streams.
+  if (version_.UsesHttp3()) {
+    ExpectFlowControlsSynced(
+        QuicSpdySessionPeer::GetReceiveControlStream(client_session),
+        QuicSpdySessionPeer::GetSendControlStream(server_session));
+    ExpectFlowControlsSynced(
+        QuicSpdySessionPeer::GetSendControlStream(client_session),
+        QuicSpdySessionPeer::GetReceiveControlStream(server_session));
+  }
+
+  // Check crypto stream.
+  if (!version_.UsesCryptoFrames()) {
+    ExpectFlowControlsSynced(
+        QuicSessionPeer::GetMutableCryptoStream(client_session),
+        QuicSessionPeer::GetMutableCryptoStream(server_session));
+  }
+
+  // Check headers stream.
+  if (!version_.UsesHttp3()) {
+    SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
+    SpdySettingsIR settings_frame;
+    settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
+                              kDefaultMaxUncompressedHeaderSize);
+    SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame));
+
+    QuicHeadersStream* client_header_stream =
+        QuicSpdySessionPeer::GetHeadersStream(client_session);
+    QuicHeadersStream* server_header_stream =
+        QuicSpdySessionPeer::GetHeadersStream(server_session);
+    // Both client and server are sending this SETTINGS frame, and the send
+    // window is consumed. But because of timing issue, the server may send or
+    // not send the frame, and the client may send/ not send / receive / not
+    // receive the frame.
+    // TODO(fayang): Rewrite this part because it is hacky.
+    QuicByteCount win_difference1 =
+        QuicStreamPeer::ReceiveWindowSize(server_header_stream) -
+        QuicStreamPeer::SendWindowSize(client_header_stream);
+    if (win_difference1 != 0) {
+      EXPECT_EQ(frame.size(), win_difference1);
+    }
+
+    QuicByteCount win_difference2 =
+        QuicStreamPeer::ReceiveWindowSize(client_header_stream) -
+        QuicStreamPeer::SendWindowSize(server_header_stream);
+    if (win_difference2 != 0) {
+      EXPECT_EQ(frame.size(), win_difference2);
+    }
+
+    // Client *may* have received the SETTINGs frame.
+    // TODO(fayang): Rewrite this part because it is hacky.
+    float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
+                       client_session->flow_controller())) /
+                   QuicStreamPeer::ReceiveWindowSize(
+                       QuicSpdySessionPeer::GetHeadersStream(client_session));
+    float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
+                       client_session->flow_controller())) /
+                   (QuicStreamPeer::ReceiveWindowSize(
+                        QuicSpdySessionPeer::GetHeadersStream(client_session)) +
+                    frame.size());
+    EXPECT_TRUE(ratio1 == kSessionToStreamRatio ||
+                ratio2 == kSessionToStreamRatio);
+  }
+
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
+  // A stream created on receipt of a simple request with no body will never get
+  // a stream frame with a FIN. Verify that we don't keep track of the stream in
+  // the locally closed streams map: it will never be removed if so.
+  ASSERT_TRUE(Initialize());
+
+  // Send a simple headers only request, and receive response.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Now verify that the server is not waiting for a final FIN or RST.
+  server_thread_->Pause();
+  QuicSession* server_session = GetServerSession();
+  if (server_session != nullptr) {
+    EXPECT_EQ(0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(
+                      server_session)
+                      .size());
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  server_thread_->Resume();
+}
+
+// TestAckListener counts how many bytes are acked during its lifetime.
+class TestAckListener : public QuicAckListenerInterface {
+ public:
+  TestAckListener() {}
+
+  void OnPacketAcked(int acked_bytes,
+                     QuicTime::Delta /*delta_largest_observed*/) override {
+    total_bytes_acked_ += acked_bytes;
+  }
+
+  void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
+
+  int total_bytes_acked() const { return total_bytes_acked_; }
+
+ protected:
+  // Object is ref counted.
+  ~TestAckListener() override {}
+
+ private:
+  int total_bytes_acked_ = 0;
+};
+
+class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
+ public:
+  void OnCompleteResponse(QuicStreamId id,
+                          const SpdyHeaderBlock& response_headers,
+                          const std::string& response_body) override {
+    QUIC_DVLOG(1) << "response for stream " << id << " "
+                  << response_headers.DebugString() << "\n"
+                  << response_body;
+  }
+};
+
+TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
+  // Verify that even in the presence of packet loss and occasionally blocked
+  // socket, an AckNotifierDelegate will get informed that the data it is
+  // interested in has been ACKed. This tests end-to-end ACK notification, and
+  // demonstrates that retransmissions do not break this functionality.
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  SetPacketLossPercentage(5);
+  ASSERT_TRUE(Initialize());
+  // Wait for the server SHLO before upping the packet loss.
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  SetPacketLossPercentage(30);
+  client_writer_->set_fake_blocked_socket_percentage(10);
+
+  // Wait for SETTINGS frame from server that sets QPACK dynamic table capacity
+  // to make sure request headers will be compressed using the dynamic table.
+  if (version_.UsesHttp3()) {
+    while (true) {
+      // Waits for up to 50 ms.
+      client_->client()->WaitForEvents();
+      ASSERT_TRUE(client_->connected());
+      QuicSpdyClientSession* client_session = GetClientSession();
+      if (client_session == nullptr) {
+        ADD_FAILURE() << "Missing client session";
+        return;
+      }
+      QpackEncoder* qpack_encoder = client_session->qpack_encoder();
+      if (qpack_encoder == nullptr) {
+        ADD_FAILURE() << "Missing QPACK encoder";
+        return;
+      }
+      QpackEncoderHeaderTable* header_table =
+          QpackEncoderPeer::header_table(qpack_encoder);
+      if (header_table == nullptr) {
+        ADD_FAILURE() << "Missing header table";
+        return;
+      }
+      if (header_table->dynamic_table_capacity() > 0) {
+        break;
+      }
+    }
+  }
+
+  // Create a POST request and send the headers only.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+
+  // Size of headers on the request stream. This is zero if headers are sent on
+  // the header stream.
+  size_t header_size = 0;
+  if (version_.UsesHttp3()) {
+    // Determine size of headers after QPACK compression.
+    NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
+    NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
+    QpackEncoder qpack_encoder(&decoder_stream_error_delegate);
+    qpack_encoder.set_qpack_stream_sender_delegate(
+        &encoder_stream_sender_delegate);
+
+    qpack_encoder.SetMaximumDynamicTableCapacity(
+        kDefaultQpackMaxDynamicTableCapacity);
+    qpack_encoder.SetDynamicTableCapacity(kDefaultQpackMaxDynamicTableCapacity);
+    qpack_encoder.SetMaximumBlockedStreams(kDefaultMaximumBlockedStreams);
+
+    std::string encoded_headers = qpack_encoder.EncodeHeaderList(
+        /* stream_id = */ 0, headers, nullptr);
+    header_size = encoded_headers.size();
+  }
+
+  // Test the AckNotifier's ability to track multiple packets by making the
+  // request body exceed the size of a single packet.
+  std::string request_string = "a request body bigger than one packet" +
+                               std::string(kMaxOutgoingPacketSize, '.');
+
+  const int expected_bytes_acked = header_size + request_string.length();
+
+  // The TestAckListener will cause a failure if not notified.
+  quiche::QuicheReferenceCountedPointer<TestAckListener> ack_listener(
+      new TestAckListener());
+
+  // Send the request, and register the delegate for ACKs.
+  client_->SendData(request_string, true, ack_listener);
+  WaitForFooResponseAndCheckIt();
+
+  // Send another request to flush out any pending ACKs on the server.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Make sure the delegate does get the notification it expects.
+  while (ack_listener->total_bytes_acked() < expected_bytes_acked) {
+    // Waits for up to 50 ms.
+    client_->client()->WaitForEvents();
+    ASSERT_TRUE(client_->connected());
+  }
+  EXPECT_EQ(ack_listener->total_bytes_acked(), expected_bytes_acked)
+      << " header_size " << header_size << " request length "
+      << request_string.length();
+}
+
+// Send a public reset from the server.
+TEST_P(EndToEndTest, ServerSendPublicReset) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  QuicSpdySession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicConfig* config = client_session->config();
+  ASSERT_TRUE(config);
+  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+  StatelessResetToken stateless_reset_token =
+      config->ReceivedStatelessResetToken();
+
+  // Send the public reset.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionId connection_id = client_connection->connection_id();
+  QuicPublicResetPacket header;
+  header.connection_id = connection_id;
+  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
+                    Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
+  std::unique_ptr<QuicEncryptedPacket> packet;
+  if (version_.HasIetfInvariantHeader()) {
+    packet = framer.BuildIetfStatelessResetPacket(
+        connection_id, /*received_packet_length=*/100, stateless_reset_token);
+  } else {
+    packet = framer.BuildPublicResetPacket(header);
+  }
+  // We must pause the server's thread in order to call WritePacket without
+  // race conditions.
+  server_thread_->Pause();
+  auto client_address = client_connection->self_address();
+  server_writer_->WritePacket(packet->data(), packet->length(),
+                              server_address_.host(), client_address, nullptr);
+  server_thread_->Resume();
+
+  // The request should fail.
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  EXPECT_TRUE(client_->response_headers()->empty());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
+}
+
+// Send a public reset from the server for a different connection ID.
+// It should be ignored.
+TEST_P(EndToEndTest, ServerSendPublicResetWithDifferentConnectionId) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  QuicSpdySession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicConfig* config = client_session->config();
+  ASSERT_TRUE(config);
+  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+  StatelessResetToken stateless_reset_token =
+      config->ReceivedStatelessResetToken();
+  // Send the public reset.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionId incorrect_connection_id = TestConnectionId(
+      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
+  QuicPublicResetPacket header;
+  header.connection_id = incorrect_connection_id;
+  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
+                    Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
+  std::unique_ptr<QuicEncryptedPacket> packet;
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  client_connection->set_debug_visitor(&visitor);
+  if (version_.HasIetfInvariantHeader()) {
+    packet = framer.BuildIetfStatelessResetPacket(
+        incorrect_connection_id, /*received_packet_length=*/100,
+        stateless_reset_token);
+    EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
+        .Times(0);
+  } else {
+    packet = framer.BuildPublicResetPacket(header);
+    EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
+        .Times(1);
+  }
+  // We must pause the server's thread in order to call WritePacket without
+  // race conditions.
+  server_thread_->Pause();
+  auto client_address = client_connection->self_address();
+  server_writer_->WritePacket(packet->data(), packet->length(),
+                              server_address_.host(), client_address, nullptr);
+  server_thread_->Resume();
+
+  if (version_.HasIetfInvariantHeader()) {
+    // The request should fail. IETF stateless reset does not include connection
+    // ID.
+    EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+    EXPECT_TRUE(client_->response_headers()->empty());
+    EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
+  } else {
+    // The connection should be unaffected.
+    SendSynchronousFooRequestAndCheckResponse();
+  }
+
+  client_connection->set_debug_visitor(nullptr);
+}
+
+// Send a public reset from the client for a different connection ID.
+// It should be ignored.
+TEST_P(EndToEndTest, ClientSendPublicResetWithDifferentConnectionId) {
+  ASSERT_TRUE(Initialize());
+
+  // Send the public reset.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionId incorrect_connection_id = TestConnectionId(
+      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
+  QuicPublicResetPacket header;
+  header.connection_id = incorrect_connection_id;
+  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
+                    Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      framer.BuildPublicResetPacket(header));
+  client_writer_->WritePacket(
+      packet->data(), packet->length(),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+
+  // The connection should be unaffected.
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// Send a version negotiation packet from the server for a different
+// connection ID.  It should be ignored.
+TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // Send the version negotiation packet.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionId incorrect_connection_id = TestConnectionId(
+      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          incorrect_connection_id, EmptyQuicConnectionId(),
+          version_.HasIetfInvariantHeader(),
+          version_.HasLengthPrefixedConnectionIds(),
+          server_supported_versions_));
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  client_connection->set_debug_visitor(&visitor);
+  EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
+      .Times(1);
+  // We must pause the server's thread in order to call WritePacket without
+  // race conditions.
+  server_thread_->Pause();
+  server_writer_->WritePacket(
+      packet->data(), packet->length(), server_address_.host(),
+      client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
+  server_thread_->Resume();
+
+  // The connection should be unaffected.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_connection->set_debug_visitor(nullptr);
+}
+
+// DowngradePacketWriter is a client writer which will intercept all the client
+// writes for |target_version| and reply to them with version negotiation
+// packets to attempt a version downgrade attack. Once the client has downgraded
+// to a different version, the writer stops intercepting. |server_thread| must
+// start off paused, and will be resumed once interception is done.
+class DowngradePacketWriter : public PacketDroppingTestWriter {
+ public:
+  explicit DowngradePacketWriter(
+      const ParsedQuicVersion& target_version,
+      const ParsedQuicVersionVector& supported_versions, QuicTestClient* client,
+      QuicPacketWriter* server_writer, ServerThread* server_thread)
+      : target_version_(target_version),
+        supported_versions_(supported_versions),
+        client_(client),
+        server_writer_(server_writer),
+        server_thread_(server_thread) {}
+  ~DowngradePacketWriter() override {}
+
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          quic::PerPacketOptions* options) override {
+    if (!intercept_enabled_) {
+      return PacketDroppingTestWriter::WritePacket(
+          buffer, buf_len, self_address, peer_address, options);
+    }
+    PacketHeaderFormat format;
+    QuicLongHeaderType long_packet_type;
+    bool version_present, has_length_prefix;
+    QuicVersionLabel version_label;
+    ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+    QuicConnectionId destination_connection_id, source_connection_id;
+    absl::optional<absl::string_view> retry_token;
+    std::string detailed_error;
+    if (QuicFramer::ParsePublicHeaderDispatcher(
+            QuicEncryptedPacket(buffer, buf_len),
+            kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+            &version_present, &has_length_prefix, &version_label,
+            &parsed_version, &destination_connection_id, &source_connection_id,
+            &retry_token, &detailed_error) != QUIC_NO_ERROR) {
+      ADD_FAILURE() << "Failed to parse our own packet: " << detailed_error;
+      return WriteResult(WRITE_STATUS_ERROR, 0);
+    }
+    if (!version_present || parsed_version != target_version_) {
+      // Client is sending with another version, the attack has succeeded so we
+      // can stop intercepting.
+      intercept_enabled_ = false;
+      server_thread_->Resume();
+      // Pass the client-sent packet through.
+      return WritePacket(buffer, buf_len, self_address, peer_address, options);
+    }
+    // Send a version negotiation packet.
+    std::unique_ptr<QuicEncryptedPacket> packet(
+        QuicFramer::BuildVersionNegotiationPacket(
+            destination_connection_id, source_connection_id,
+            parsed_version.HasIetfInvariantHeader(), has_length_prefix,
+            supported_versions_));
+    server_writer_->WritePacket(
+        packet->data(), packet->length(), peer_address.host(),
+        client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
+    // Drop the client-sent packet but pretend it was sent.
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+ private:
+  bool intercept_enabled_ = true;
+  ParsedQuicVersion target_version_;
+  ParsedQuicVersionVector supported_versions_;
+  QuicTestClient* client_;           // Unowned.
+  QuicPacketWriter* server_writer_;  // Unowned.
+  ServerThread* server_thread_;      // Unowned.
+};
+
+TEST_P(EndToEndTest, VersionNegotiationDowngradeAttackIsDetected) {
+  ParsedQuicVersion target_version = server_supported_versions_.back();
+  if (!version_.UsesTls() || target_version == version_) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  connect_to_server_on_initialize_ = false;
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    target_version);
+  ParsedQuicVersionVector downgrade_versions{version_};
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(server_thread_);
+  // Pause the server thread to allow our DowngradePacketWriter to write version
+  // negotiation packets in a thread-safe manner. It will be resumed by the
+  // DowngradePacketWriter.
+  server_thread_->Pause();
+  client_.reset(new QuicTestClient(server_address_, server_hostname_,
+                                   client_config_, client_supported_versions_,
+                                   crypto_test_utils::ProofVerifierForTesting(),
+                                   std::make_unique<QuicClientSessionCache>()));
+  delete client_writer_;
+  client_writer_ = new DowngradePacketWriter(target_version, downgrade_versions,
+                                             client_.get(), server_writer_,
+                                             server_thread_.get());
+  client_->UseWriter(client_writer_);
+  // Have the client attempt to send a request.
+  client_->Connect();
+  EXPECT_TRUE(client_->SendSynchronousRequest("/foo").empty());
+  // Make sure the downgrade is detected and the handshake fails.
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_FAILED));
+}
+
+// A bad header shouldn't tear down the connection, because the receiver can't
+// tell the connection ID.
+TEST_P(EndToEndTest, BadPacketHeaderTruncated) {
+  ASSERT_TRUE(Initialize());
+
+  // Start the connection.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Packet with invalid public flags.
+  char packet[] = {// public flags (8 byte connection_id)
+                   0x3C,
+                   // truncated connection ID
+                   0x11};
+  client_writer_->WritePacket(
+      &packet[0], sizeof(packet),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+  EXPECT_TRUE(server_thread_->WaitUntil(
+      [&] {
+        return QuicDispatcherPeer::GetAndClearLastError(
+                   QuicServerPeer::GetDispatcher(server_thread_->server())) ==
+               QUIC_INVALID_PACKET_HEADER;
+      },
+      QuicTime::Delta::FromSeconds(5)));
+
+  // The connection should not be terminated.
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// A bad header shouldn't tear down the connection, because the receiver can't
+// tell the connection ID.
+TEST_P(EndToEndTest, BadPacketHeaderFlags) {
+  ASSERT_TRUE(Initialize());
+
+  // Start the connection.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Packet with invalid public flags.
+  uint8_t packet[] = {
+      // invalid public flags
+      0xFF,
+      // connection_id
+      0x10,
+      0x32,
+      0x54,
+      0x76,
+      0x98,
+      0xBA,
+      0xDC,
+      0xFE,
+      // packet sequence number
+      0xBC,
+      0x9A,
+      0x78,
+      0x56,
+      0x34,
+      0x12,
+      // private flags
+      0x00,
+  };
+  client_writer_->WritePacket(
+      reinterpret_cast<const char*>(packet), sizeof(packet),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+
+  EXPECT_TRUE(server_thread_->WaitUntil(
+      [&] {
+        return QuicDispatcherPeer::GetAndClearLastError(
+                   QuicServerPeer::GetDispatcher(server_thread_->server())) ==
+               QUIC_INVALID_PACKET_HEADER;
+      },
+      QuicTime::Delta::FromSeconds(5)));
+
+  // The connection should not be terminated.
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// Send a packet from the client with bad encrypted data.  The server should not
+// tear down the connection.
+TEST_P(EndToEndTest, BadEncryptedData) {
+  ASSERT_TRUE(Initialize());
+
+  // Start the connection.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      client_connection->connection_id(), EmptyQuicConnectionId(), false, false,
+      1, "At least 20 characters.", CONNECTION_ID_PRESENT, CONNECTION_ID_ABSENT,
+      PACKET_4BYTE_PACKET_NUMBER));
+  // Damage the encrypted data.
+  std::string damaged_packet(packet->data(), packet->length());
+  damaged_packet[30] ^= 0x01;
+  QUIC_DLOG(INFO) << "Sending bad packet.";
+  client_writer_->WritePacket(
+      damaged_packet.data(), damaged_packet.length(),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+  // Give the server time to process the packet.
+  absl::SleepFor(absl::Seconds(1));
+  // This error is sent to the connection's OnError (which ignores it), so the
+  // dispatcher doesn't see it.
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher != nullptr) {
+    EXPECT_THAT(QuicDispatcherPeer::GetAndClearLastError(dispatcher),
+                IsQuicNoError());
+  } else {
+    ADD_FAILURE() << "Missing dispatcher";
+  }
+  server_thread_->Resume();
+
+  // The connection should not be terminated.
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, CanceledStreamDoesNotBecomeZombie) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  // Lose the request.
+  SetPacketLossPercentage(100);
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  client_->SendMessage(headers, "test_body", /*fin=*/false);
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+
+  // Cancel the stream.
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  QuicSession* session = GetClientSession();
+  ASSERT_TRUE(session);
+  // Verify canceled stream does not become zombie.
+  EXPECT_EQ(1u, QuicSessionPeer::closed_streams(session).size());
+}
+
+// A test stream that gives |response_body_| as an error response body.
+class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
+ public:
+  ServerStreamWithErrorResponseBody(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend,
+      std::string response_body)
+      : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
+                               quic_simple_server_backend),
+        response_body_(std::move(response_body)) {}
+
+  ~ServerStreamWithErrorResponseBody() override = default;
+
+ protected:
+  void SendErrorResponse() override {
+    QUIC_DLOG(INFO) << "Sending error response for stream " << id();
+    SpdyHeaderBlock headers;
+    headers[":status"] = "500";
+    headers["content-length"] = absl::StrCat(response_body_.size());
+    // This method must call CloseReadSide to cause the test case, StopReading
+    // is not sufficient.
+    QuicStreamPeer::CloseReadSide(this);
+    SendHeadersAndBody(std::move(headers), response_body_);
+  }
+
+  std::string response_body_;
+};
+
+class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
+ public:
+  explicit StreamWithErrorFactory(std::string response_body)
+      : response_body_(std::move(response_body)) {}
+
+  ~StreamWithErrorFactory() override = default;
+
+  QuicSimpleServerStream* CreateStream(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend) override {
+    return new ServerStreamWithErrorResponseBody(
+        id, session, quic_simple_server_backend, response_body_);
+  }
+
+  QuicSimpleServerStream* CreateStream(
+      PendingStream* /*pending*/, QuicSpdySession* /*session*/,
+      QuicSimpleServerBackend* /*response_cache*/) override {
+    return nullptr;
+  }
+
+ private:
+  std::string response_body_;
+};
+
+// A test server stream that drops all received body.
+class ServerStreamThatDropsBody : public QuicSimpleServerStream {
+ public:
+  ServerStreamThatDropsBody(QuicStreamId id, QuicSpdySession* session,
+                            QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
+                               quic_simple_server_backend) {}
+
+  ~ServerStreamThatDropsBody() override = default;
+
+ protected:
+  void OnBodyAvailable() override {
+    while (HasBytesToRead()) {
+      struct iovec iov;
+      if (GetReadableRegions(&iov, 1) == 0) {
+        // No more data to read.
+        break;
+      }
+      QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
+                    << id();
+      MarkConsumed(iov.iov_len);
+    }
+
+    if (!sequencer()->IsClosed()) {
+      sequencer()->SetUnblocked();
+      return;
+    }
+
+    // If the sequencer is closed, then all the body, including the fin, has
+    // been consumed.
+    OnFinRead();
+
+    if (write_side_closed() || fin_buffered()) {
+      return;
+    }
+
+    SendResponse();
+  }
+};
+
+class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
+ public:
+  ServerStreamThatDropsBodyFactory() = default;
+
+  ~ServerStreamThatDropsBodyFactory() override = default;
+
+  QuicSimpleServerStream* CreateStream(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend) override {
+    return new ServerStreamThatDropsBody(id, session,
+                                         quic_simple_server_backend);
+  }
+
+  QuicSimpleServerStream* CreateStream(
+      PendingStream* /*pending*/, QuicSpdySession* /*session*/,
+      QuicSimpleServerBackend* /*response_cache*/) override {
+    return nullptr;
+  }
+};
+
+// A test server stream that sends response with body size greater than 4GB.
+class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
+ public:
+  ServerStreamThatSendsHugeResponse(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend, int64_t body_bytes)
+      : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
+                               quic_simple_server_backend),
+        body_bytes_(body_bytes) {}
+
+  ~ServerStreamThatSendsHugeResponse() override = default;
+
+ protected:
+  void SendResponse() override {
+    QuicBackendResponse response;
+    std::string body(body_bytes_, 'a');
+    response.set_body(body);
+    SendHeadersAndBodyAndTrailers(response.headers().Clone(), response.body(),
+                                  response.trailers().Clone());
+  }
+
+ private:
+  // Use a explicit int64_t rather than size_t to simulate a 64-bit server
+  // talking to a 32-bit client.
+  int64_t body_bytes_;
+};
+
+class ServerStreamThatSendsHugeResponseFactory
+    : public QuicTestServer::StreamFactory {
+ public:
+  explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
+      : body_bytes_(body_bytes) {}
+
+  ~ServerStreamThatSendsHugeResponseFactory() override = default;
+
+  QuicSimpleServerStream* CreateStream(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend) override {
+    return new ServerStreamThatSendsHugeResponse(
+        id, session, quic_simple_server_backend, body_bytes_);
+  }
+
+  QuicSimpleServerStream* CreateStream(
+      PendingStream* /*pending*/, QuicSpdySession* /*session*/,
+      QuicSimpleServerBackend* /*response_cache*/) override {
+    return nullptr;
+  }
+
+  int64_t body_bytes_;
+};
+
+TEST_P(EndToEndTest, EarlyResponseFinRecording) {
+  set_smaller_flow_control_receive_window();
+
+  // Verify that an incoming FIN is recorded in a stream object even if the read
+  // side has been closed.  This prevents an entry from being made in
+  // locally_close_streams_highest_offset_ (which will never be deleted).
+  // To set up the test condition, the server must do the following in order:
+  // start sending the response and call CloseReadSide
+  // receive the FIN of the request
+  // send the FIN of the response
+
+  // The response body must be larger than the flow control window so the server
+  // must receive a window update from the client before it can finish sending
+  // it.
+  uint32_t response_body_size =
+      2 * client_config_.GetInitialStreamFlowControlWindowToSend();
+  std::string response_body(response_body_size, 'a');
+
+  StreamWithErrorFactory stream_factory(response_body);
+  SetSpdyStreamFactory(&stream_factory);
+
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // A POST that gets an early error response, after the headers are received
+  // and before the body is received, due to invalid content-length.
+  // Set an invalid content-length, so the request will receive an early 500
+  // response.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/garbage";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "-1";
+
+  // The body must be large enough that the FIN will be in a different packet
+  // than the end of the headers, but short enough to not require a flow control
+  // update.  This allows headers processing to trigger the error response
+  // before the request FIN is processed but receive the request FIN before the
+  // response is sent completely.
+  const uint32_t kRequestBodySize = kMaxOutgoingPacketSize + 10;
+  std::string request_body(kRequestBodySize, 'a');
+
+  // Send the request.
+  client_->SendMessage(headers, request_body);
+  client_->WaitForResponse();
+  CheckResponseHeaders("500");
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  QuicSession* server_session =
+      QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher);
+  EXPECT_TRUE(server_session != nullptr);
+
+  // The stream is not waiting for the arrival of the peer's final offset.
+  EXPECT_EQ(
+      0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
+              .size());
+
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, Trailers) {
+  // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // Set reordering to ensure that Trailers arriving before body is ok.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // Add a response with headers, body, and trailers.
+  const std::string kBody = "body content";
+
+  SpdyHeaderBlock headers;
+  headers[":status"] = "200";
+  headers["content-length"] = absl::StrCat(kBody.size());
+
+  SpdyHeaderBlock trailers;
+  trailers["some-trailing-header"] = "trailing-header-value";
+
+  memory_cache_backend_.AddResponse(server_hostname_, "/trailer_url",
+                                    std::move(headers), kBody,
+                                    trailers.Clone());
+
+  SendSynchronousRequestAndCheckResponse("/trailer_url", kBody);
+  EXPECT_EQ(trailers, client_->response_trailers());
+}
+
+// TODO(fayang): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
+  // This test tests a huge post with introduced packet loss from client to
+  // server and body size greater than 4GB, making sure QUIC code does not break
+  // for 32-bit builds.
+  ServerStreamThatDropsBodyFactory stream_factory;
+  SetSpdyStreamFactory(&stream_factory);
+  ASSERT_TRUE(Initialize());
+  // Set client's epoll server's time out to 0 to make this test be finished
+  // within a short time.
+  client_->epoll_server()->set_timeout_in_us(0);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  SetPacketLossPercentage(1);
+  // To avoid storing the whole request body in memory, use a loop to repeatedly
+  // send body size of kSizeBytes until the whole request body size is reached.
+  const int kSizeBytes = 128 * 1024;
+  // Request body size is 4G plus one more kSizeBytes.
+  int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
+  ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
+  std::string body(kSizeBytes, 'a');
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = absl::StrCat(request_body_size_bytes);
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+
+  for (int i = 0; i < request_body_size_bytes / kSizeBytes; ++i) {
+    bool fin = (i == request_body_size_bytes - 1);
+    client_->SendData(std::string(body.data(), kSizeBytes), fin);
+    client_->client()->WaitForEvents();
+  }
+  VerifyCleanConnection(true);
+}
+
+// TODO(fayang): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
+  // This test tests a huge response with introduced loss from server to client
+  // and body size greater than 4GB, making sure QUIC code does not break for
+  // 32-bit builds.
+  const int kSizeBytes = 128 * 1024;
+  int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
+  ASSERT_LT(4294967296, response_body_size_bytes);
+  ServerStreamThatSendsHugeResponseFactory stream_factory(
+      response_body_size_bytes);
+  SetSpdyStreamFactory(&stream_factory);
+
+  StartServer();
+
+  // Use a quic client that drops received body.
+  QuicTestClient* client =
+      new QuicTestClient(server_address_, server_hostname_, client_config_,
+                         client_supported_versions_);
+  client->client()->set_drop_response_body(true);
+  client->UseWriter(client_writer_);
+  client->Connect();
+  client_.reset(client);
+  static QuicEpollEvent event(EPOLLOUT);
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  client_writer_->Initialize(
+      QuicConnectionPeer::GetHelper(client_connection),
+      QuicConnectionPeer::GetAlarmFactory(client_connection),
+      std::make_unique<ClientDelegate>(client_->client()));
+  initialized_ = true;
+  ASSERT_TRUE(client_->client()->connected());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  SetPacketLossPercentage(1);
+  client_->SendRequest("/huge_response");
+  client_->WaitForResponse();
+  VerifyCleanConnection(true);
+}
+
+// Regression test for b/111515567
+TEST_P(EndToEndTest, AgreeOnStopWaiting) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    // Verify client and server connections agree on the value of
+    // no_stop_waiting_frames.
+    EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
+              QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+// Regression test for b/111515567
+TEST_P(EndToEndTest, AgreeOnStopWaitingWithNoStopWaitingOption) {
+  QuicTagVector options;
+  options.push_back(kNSTP);
+  client_config_.SetConnectionOptionsToSend(options);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    // Verify client and server connections agree on the value of
+    // no_stop_waiting_frames.
+    EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
+              QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) {
+  // Tests that when client side has no active request and no waiting
+  // PUSH_PROMISE, its headers stream's sequencer buffer should be released.
+  ASSERT_TRUE(Initialize());
+  client_->SendSynchronousRequest("/foo");
+  if (version_.UsesHttp3()) {
+    return;
+  }
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(client_session);
+  ASSERT_TRUE(headers_stream);
+  QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
+  ASSERT_TRUE(sequencer);
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+}
+
+// A single large header value causes a different error than the total size of
+// headers exceeding a smaller limit, tested at EndToEndTest.LargeHeaders.
+TEST_P(EndToEndTest, WayTooLongRequestHeaders) {
+  ASSERT_TRUE(Initialize());
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["key"] = std::string(2 * 1024 * 1024, 'a');
+
+  client_->SendMessage(headers, "");
+  client_->WaitForResponse();
+  if (version_.UsesHttp3()) {
+    EXPECT_THAT(client_->connection_error(),
+                IsError(QUIC_QPACK_DECOMPRESSION_FAILED));
+  } else {
+    EXPECT_THAT(client_->connection_error(),
+                IsError(QUIC_HPACK_VALUE_TOO_LONG));
+  }
+}
+
+class WindowUpdateObserver : public QuicConnectionDebugVisitor {
+ public:
+  WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
+
+  size_t num_window_update_frames() const { return num_window_update_frames_; }
+
+  size_t num_ping_frames() const { return num_ping_frames_; }
+
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
+                           const QuicTime& /*receive_time*/) override {
+    ++num_window_update_frames_;
+  }
+
+  void OnPingFrame(const QuicPingFrame& /*frame*/,
+                   const QuicTime::Delta /*ping_received_delay*/) override {
+    ++num_ping_frames_;
+  }
+
+ private:
+  size_t num_window_update_frames_;
+  size_t num_ping_frames_;
+};
+
+TEST_P(EndToEndTest, WindowUpdateInAck) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  WindowUpdateObserver observer;
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  client_connection->set_debug_visitor(&observer);
+  // 100KB body.
+  std::string body(100 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  client_->Disconnect();
+  EXPECT_LT(0u, observer.num_window_update_frames());
+  EXPECT_EQ(0u, observer.num_ping_frames());
+  client_connection->set_debug_visitor(nullptr);
+}
+
+TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicConfig* config = client_session->config();
+  ASSERT_TRUE(config);
+  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+  QuicConnection* client_connection = client_session->connection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(QuicUtils::GenerateStatelessResetToken(
+                client_connection->connection_id()),
+            config->ReceivedStatelessResetToken());
+  client_->Disconnect();
+}
+
+// Regression test for b/116200989.
+TEST_P(EndToEndTest,
+       SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
+  connect_to_server_on_initialize_ = false;
+  ASSERT_TRUE(Initialize());
+
+  ASSERT_TRUE(server_thread_);
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher == nullptr) {
+    ADD_FAILURE() << "Missing dispatcher";
+    server_thread_->Resume();
+    return;
+  }
+  if (dispatcher->NumSessions() > 0) {
+    ADD_FAILURE() << "Dispatcher session map not empty";
+    server_thread_->Resume();
+    return;
+  }
+  // Note: this writer will only used by the server connection, not the time
+  // wait list.
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This cause the first server-sent packet, a.k.a REJ, to fail.
+      new BadPacketWriter(/*packet_causing_write_error=*/0, EPERM));
+  server_thread_->Resume();
+
+  client_.reset(CreateQuicClient(client_writer_));
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_FAILED));
+}
+
+// Regression test for b/116200989.
+TEST_P(EndToEndTest,
+       SendStatelessResetIfServerConnectionClosedLocallyAfterHandshake) {
+  // Prevent the connection from expiring in the time wait list.
+  SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000);
+  connect_to_server_on_initialize_ = false;
+  ASSERT_TRUE(Initialize());
+
+  // big_response_body is 64K, which is about 48 full-sized packets.
+  const size_t kBigResponseBodySize = 65536;
+  QuicData big_response_body(new char[kBigResponseBodySize](),
+                             kBigResponseBodySize, /*owns_buffer=*/true);
+  AddToCache("/big_response", 200, big_response_body.AsStringPiece());
+
+  ASSERT_TRUE(server_thread_);
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher == nullptr) {
+    ADD_FAILURE() << "Missing dispatcher";
+    server_thread_->Resume();
+    return;
+  }
+  if (dispatcher->NumSessions() > 0) {
+    ADD_FAILURE() << "Dispatcher session map not empty";
+    server_thread_->Resume();
+    return;
+  }
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This will cause an server write error with EPERM, while sending the
+      // response for /big_response.
+      new BadPacketWriter(/*packet_causing_write_error=*/20, EPERM));
+  server_thread_->Resume();
+
+  client_.reset(CreateQuicClient(client_writer_));
+
+  // First, a /foo request with small response should succeed.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Second, a /big_response request with big response should fail.
+  EXPECT_LT(client_->SendSynchronousRequest("/big_response").length(),
+            kBigResponseBodySize);
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
+}
+
+// Regression test of b/70782529.
+TEST_P(EndToEndTest, DoNotCrashOnPacketWriteError) {
+  ASSERT_TRUE(Initialize());
+  BadPacketWriter* bad_writer =
+      new BadPacketWriter(/*packet_causing_write_error=*/5,
+                          /*error_code=*/90);
+  std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
+
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  client->SendCustomSynchronousRequest(headers, body);
+}
+
+// Regression test for b/71711996. This test sends a connectivity probing packet
+// as its last sent packet, and makes sure the server's ACK of that packet does
+// not cause the client to fail.
+TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Wait for the client's ACK (of the response) to be received by the server.
+  client_->WaitForDelayedAcks();
+
+  // We are sending a connectivity probing packet from an unchanged client
+  // address, so the server will not respond to us with a connectivity probing
+  // packet, however the server should send an ack-only packet to us.
+  client_->SendConnectivityProbing();
+
+  // Wait for the server's last ACK to be received by the client.
+  client_->WaitForDelayedAcks();
+}
+
+TEST_P(EndToEndTest, PreSharedKey) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(5));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(5));
+  pre_shared_key_client_ = "foobar";
+  pre_shared_key_server_ = "foobar";
+
+  if (version_.UsesTls()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    bool ok = true;
+    EXPECT_QUIC_BUG(ok = Initialize(),
+                    "QUIC client pre-shared keys not yet supported with TLS");
+    EXPECT_FALSE(ok);
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// TODO: reenable once we have a way to make this run faster.
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_client_ = "foo";
+  pre_shared_key_server_ = "bar";
+
+  if (version_.UsesTls()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    bool ok = true;
+    EXPECT_QUIC_BUG(ok = Initialize(),
+                    "QUIC client pre-shared keys not yet supported with TLS");
+    EXPECT_FALSE(ok);
+    return;
+  }
+
+  // One of two things happens when Initialize() returns:
+  // 1. Crypto handshake has completed, and it is unsuccessful. Initialize()
+  //    returns false.
+  // 2. Crypto handshake has not completed, Initialize() returns true. The call
+  //    to WaitForCryptoHandshakeConfirmed() will wait for the handshake and
+  //    return whether it is successful.
+  ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
+}
+
+// TODO: reenable once we have a way to make this run faster.
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_server_ = "foobar";
+
+  if (version_.UsesTls()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    bool ok = true;
+    EXPECT_QUIC_BUG(ok = Initialize(),
+                    "QUIC server pre-shared keys not yet supported with TLS");
+    EXPECT_FALSE(ok);
+    return;
+  }
+
+  ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
+}
+
+// TODO: reenable once we have a way to make this run faster.
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_client_ = "foobar";
+
+  if (version_.UsesTls()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    bool ok = true;
+    EXPECT_QUIC_BUG(ok = Initialize(),
+                    "QUIC client pre-shared keys not yet supported with TLS");
+    EXPECT_FALSE(ok);
+    return;
+  }
+
+  ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
+}
+
+TEST_P(EndToEndTest, RequestAndStreamRstInOnePacket) {
+  // Regression test for b/80234898.
+  ASSERT_TRUE(Initialize());
+
+  // INCOMPLETE_RESPONSE will cause the server to not to send the trailer
+  // (and the FIN) after the response body.
+  std::string response_body(1305, 'a');
+  SpdyHeaderBlock response_headers;
+  response_headers[":status"] = absl::StrCat(200);
+  response_headers["content-length"] = absl::StrCat(response_body.length());
+  memory_cache_backend_.AddSpecialResponse(
+      server_hostname_, "/test_url", std::move(response_headers), response_body,
+      QuicBackendResponse::INCOMPLETE_RESPONSE);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  client_->WaitForDelayedAcks();
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  const QuicPacketCount packets_sent_before =
+      client_connection->GetStats().packets_sent;
+
+  client_->SendRequestAndRstTogether("/test_url");
+
+  // Expect exactly one packet is sent from the block above.
+  ASSERT_EQ(packets_sent_before + 1,
+            client_connection->GetStats().packets_sent);
+
+  // Wait for the connection to become idle.
+  client_->WaitForDelayedAcks();
+
+  // The real expectation is the test does not crash or timeout.
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(EndToEndTest, ResetStreamOnTtlExpires) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  SetPacketLossPercentage(30);
+
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  // Set a TTL which expires immediately.
+  stream->MaybeSetTtl(QuicTime::Delta::FromMicroseconds(1));
+
+  WriteHeadersOnStream(stream);
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  stream->WriteOrBufferBody(body, true);
+  client_->WaitForResponse();
+  EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_STREAM_TTL_EXPIRED));
+}
+
+TEST_P(EndToEndTest, SendMessages) {
+  if (!version_.SupportsMessageFrames()) {
+    Initialize();
+    return;
+  }
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  QuicSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicConnection* client_connection = client_session->connection();
+  ASSERT_TRUE(client_connection);
+
+  SetPacketLossPercentage(30);
+  ASSERT_GT(kMaxOutgoingPacketSize,
+            client_session->GetCurrentLargestMessagePayload());
+  ASSERT_LT(0, client_session->GetCurrentLargestMessagePayload());
+
+  std::string message_string(kMaxOutgoingPacketSize, 'a');
+  QuicRandom* random =
+      QuicConnectionPeer::GetHelper(client_connection)->GetRandomGenerator();
+  {
+    QuicConnection::ScopedPacketFlusher flusher(client_session->connection());
+    // Verify the largest message gets successfully sent.
+    EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
+              client_session->SendMessage(MemSliceFromString(absl::string_view(
+                  message_string.data(),
+                  client_session->GetCurrentLargestMessagePayload()))));
+    // Send more messages with size (0, largest_payload] until connection is
+    // write blocked.
+    const int kTestMaxNumberOfMessages = 100;
+    for (size_t i = 2; i <= kTestMaxNumberOfMessages; ++i) {
+      size_t message_length =
+          random->RandUint64() %
+              client_session->GetGuaranteedLargestMessagePayload() +
+          1;
+      MessageResult result = client_session->SendMessage(MemSliceFromString(
+          absl::string_view(message_string.data(), message_length)));
+      if (result.status == MESSAGE_STATUS_BLOCKED) {
+        // Connection is write blocked.
+        break;
+      }
+      EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, i), result);
+    }
+  }
+
+  client_->WaitForDelayedAcks();
+  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
+            client_session
+                ->SendMessage(MemSliceFromString(absl::string_view(
+                    message_string.data(),
+                    client_session->GetCurrentLargestMessagePayload() + 1)))
+                .status);
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+class EndToEndPacketReorderingTest : public EndToEndTest {
+ public:
+  void CreateClientWithWriter() override {
+    QUIC_LOG(ERROR) << "create client with reorder_writer_";
+    reorder_writer_ = new PacketReorderingWriter();
+    client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_));
+  }
+
+  void SetUp() override {
+    // Don't initialize client writer in base class.
+    server_writer_ = new PacketDroppingTestWriter();
+  }
+
+ protected:
+  PacketReorderingWriter* reorder_writer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(EndToEndPacketReorderingTests,
+                         EndToEndPacketReorderingTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
+  ASSERT_TRUE(Initialize());
+  if (version_.HasIetfQuicFrames()) {
+    return;
+  }
+
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress old_addr =
+      client_->client()->network_helper()->GetLatestClientAddress();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_addr.host(), new_host);
+  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
+
+  // Write a connectivity probing after the next /foo request.
+  reorder_writer_->SetDelay(1);
+  client_->SendConnectivityProbing();
+
+  ASSERT_TRUE(client_->MigrateSocketWithSpecifiedPort(old_addr.host(),
+                                                      old_addr.port()));
+
+  // The (delayed) connectivity probing will be sent after this request.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Send yet another request after the connectivity probing, when this request
+  // returns, the probing is guaranteed to have been received by the server, and
+  // the server's response to probing is guaranteed to have been received by the
+  // client.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(1u,
+              server_connection->GetStats().num_connectivity_probing_received);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+
+  // Server definitely responded to the connectivity probing. Sometime it also
+  // sends a padded ping that is not a connectivity probing, which is recognized
+  // as connectivity probing because client's self address is ANY.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_LE(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+}
+
+// A writer which holds the next packet to be sent till ReleasePacket() is
+// called.
+class PacketHoldingWriter : public QuicPacketWriterWrapper {
+ public:
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override {
+    if (!hold_next_packet_) {
+      return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                                  peer_address, options);
+    }
+    QUIC_DLOG(INFO) << "Packet is held by the writer";
+    packet_content_ = std::string(buffer, buf_len);
+    self_address_ = self_address;
+    peer_address_ = peer_address;
+    options_ = (options == nullptr ? nullptr : options->Clone());
+    hold_next_packet_ = false;
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+  void HoldNextPacket() {
+    QUICHE_DCHECK(packet_content_.empty())
+        << "There is already one packet on hold.";
+    hold_next_packet_ = true;
+  }
+
+  void ReleasePacket() {
+    QUIC_DLOG(INFO) << "Release packet";
+    ASSERT_EQ(WRITE_STATUS_OK,
+              QuicPacketWriterWrapper::WritePacket(
+                  packet_content_.data(), packet_content_.length(),
+                  self_address_, peer_address_, options_.release())
+                  .status);
+    packet_content_.clear();
+  }
+
+ private:
+  bool hold_next_packet_{false};
+  std::string packet_content_;
+  QuicIpAddress self_address_;
+  QuicSocketAddress peer_address_;
+  std::unique_ptr<PerPacketOptions> options_;
+};
+
+TEST_P(EndToEndTest, ClientValidateNewNetwork) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames() ||
+      !GetClientConnection()->validate_client_address()) {
+    return;
+  }
+  client_.reset(EndToEndTest::CreateQuicClient(nullptr));
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress old_host =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_host, new_host);
+
+  client_->client()->ValidateNewNetwork(new_host);
+  // Send a request using the old socket.
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+  // Client should have received a PATH_CHALLENGE.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Send another request to make sure THE server will receive PATH_RESPONSE.
+  client_->SendSynchronousRequest("/eep");
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(1u,
+              server_connection->GetStats().num_connectivity_probing_received);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndPacketReorderingTest, ReorderedPathChallenge) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames() ||
+      !client_->client()->session()->connection()->use_path_validator()) {
+    return;
+  }
+  client_.reset(EndToEndTest::CreateQuicClient(nullptr));
+
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress old_addr =
+      client_->client()->network_helper()->GetLatestClientAddress();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_addr.host(), new_host);
+
+  // Setup writer wrapper to hold the probing packet.
+  auto holding_writer = new PacketHoldingWriter();
+  client_->UseWriter(holding_writer);
+  // Write a connectivity probing after the next /foo request.
+  holding_writer->HoldNextPacket();
+
+  // A packet with PATH_CHALLENGE will be held in the writer.
+  client_->client()->ValidateNewNetwork(new_host);
+
+  // Send (on-hold) PATH_CHALLENGE after this request.
+  client_->SendRequest("/foo");
+  holding_writer->ReleasePacket();
+
+  client_->WaitForResponse();
+
+  EXPECT_EQ(kFooResponseBody, client_->response_body());
+  // Send yet another request after the PATH_CHALLENGE, when this request
+  // returns, the probing is guaranteed to have been received by the server, and
+  // the server's response to probing is guaranteed to have been received by the
+  // client.
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  // Client should have received a PATH_CHALLENGE.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(client_connection->validate_client_address() ? 1u : 0,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(1u,
+              server_connection->GetStats().num_connectivity_probing_received);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndPacketReorderingTest, PathValidationFailure) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames() ||
+      !client_->client()->session()->connection()->use_path_validator()) {
+    return;
+  }
+
+  client_.reset(CreateQuicClient(nullptr));
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress old_addr = client_->client()->session()->self_address();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_addr.host(), new_host);
+
+  // Drop PATH_RESPONSE packets to timeout the path validation.
+  server_writer_->set_fake_packet_loss_percentage(100);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(new_host));
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(old_addr, client_->client()->session()->self_address());
+  server_writer_->set_fake_packet_loss_percentage(0);
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(3u,
+              server_connection->GetStats().num_connectivity_probing_received);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndPacketReorderingTest, MigrateAgainAfterPathValidationFailure) {
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+
+  client_.reset(CreateQuicClient(nullptr));
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress addr1 = client_->client()->session()->self_address();
+  QuicConnection* client_connection = GetClientConnection();
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress host2 = TestLoopback(2);
+  EXPECT_NE(addr1.host(), host2);
+
+  // Drop PATH_RESPONSE packets to timeout the path validation.
+  server_writer_->set_fake_packet_loss_percentage(100);
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
+
+  QuicConnectionId server_cid2 =
+      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(server_cid2.IsEmpty());
+  EXPECT_NE(server_cid2, server_cid1);
+  // Wait until path validation fails at the client.
+  while (client_->client()->HasPendingPathValidation()) {
+    EXPECT_EQ(server_cid2,
+              QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection));
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(addr1, client_->client()->session()->self_address());
+  EXPECT_EQ(server_cid1, GetClientConnection()->connection_id());
+
+  server_writer_->set_fake_packet_loss_percentage(0);
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  // Server has received 3 path challenges.
+  EXPECT_EQ(3u,
+            server_connection->GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(server_cid1, server_connection->connection_id());
+  EXPECT_EQ(0u, server_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(2u, server_connection->GetStats().num_new_connection_id_sent);
+  server_thread_->Resume();
+
+  // Migrate socket to a new IP address again.
+  QuicIpAddress host3 = TestLoopback(3);
+  EXPECT_NE(addr1.host(), host3);
+  EXPECT_NE(host2, host3);
+
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
+
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host3));
+  QuicConnectionId server_cid3 =
+      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(server_cid3.IsEmpty());
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host3, client_->client()->session()->self_address().host());
+  EXPECT_EQ(server_cid3, GetClientConnection()->connection_id());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  // Server should send a new connection ID to client.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
+}
+
+TEST_P(EndToEndPacketReorderingTest,
+       MigrateAgainAfterPathValidationFailureWithNonZeroClientCid) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  SetQuicReloadableFlag(quic_retire_cid_on_reverse_path_validation_failure,
+                        true);
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+
+  client_.reset(CreateQuicClient(nullptr));
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress addr1 = client_->client()->session()->self_address();
+  QuicConnection* client_connection = GetClientConnection();
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  QuicConnectionId client_cid1 = client_connection->client_connection_id();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress host2 = TestLoopback(2);
+  EXPECT_NE(addr1.host(), host2);
+
+  // Drop PATH_RESPONSE packets to timeout the path validation.
+  server_writer_->set_fake_packet_loss_percentage(100);
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
+  QuicConnectionId server_cid2 =
+      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(server_cid2.IsEmpty());
+  EXPECT_NE(server_cid2, server_cid1);
+  QuicConnectionId client_cid2 =
+      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(client_cid2.IsEmpty());
+  EXPECT_NE(client_cid2, client_cid1);
+  while (client_->client()->HasPendingPathValidation()) {
+    EXPECT_EQ(server_cid2,
+              QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection));
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(addr1, client_->client()->session()->self_address());
+  EXPECT_EQ(server_cid1, GetClientConnection()->connection_id());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  server_writer_->set_fake_packet_loss_percentage(0);
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(2u, client_connection->GetStats().num_new_connection_id_sent);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(3u,
+              server_connection->GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(server_cid1, server_connection->connection_id());
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  EXPECT_EQ(1u, server_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(2u, server_connection->GetStats().num_new_connection_id_sent);
+  server_thread_->Resume();
+
+  // Migrate socket to a new IP address again.
+  QuicIpAddress host3 = TestLoopback(3);
+  EXPECT_NE(addr1.host(), host3);
+  EXPECT_NE(host2, host3);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host3));
+
+  QuicConnectionId server_cid3 =
+      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(server_cid3.IsEmpty());
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  QuicConnectionId client_cid3 =
+      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_NE(client_cid1, client_cid3);
+  EXPECT_NE(client_cid2, client_cid3);
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host3, client_->client()->session()->self_address().host());
+  EXPECT_EQ(server_cid3, GetClientConnection()->connection_id());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  // Server should send new server connection ID to client and retires old
+  // client connection ID.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(3u, client_connection->GetStats().num_new_connection_id_sent);
+}
+
+TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
+  ASSERT_TRUE(Initialize());
+  // Finish one request to make sure handshake established.
+  client_->SendSynchronousRequest("/foo");
+  // Disconnect for next 0-rtt request.
+  client_->Disconnect();
+
+  // Client get valid STK now. Do a 0-rtt request.
+  // Buffer a CHLO till another packets sent out.
+  reorder_writer_->SetDelay(1);
+  // Only send out a CHLO.
+  client_->client()->Initialize();
+  client_->client()->StartConnect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+
+  // Send a request before handshake finishes.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/bar";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  client_->SendMessage(headers, "");
+  client_->WaitForResponse();
+  EXPECT_EQ(kBarResponseBody, client_->response_body());
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionStats client_stats = client_connection->GetStats();
+  // Client sends CHLO in packet 1 and retransmitted in packet 2. Because of
+  // the delay, server processes packet 2 and later drops packet 1. ACK is
+  // bundled with SHLO, such that 1 can be detected loss by time threshold.
+  EXPECT_LE(0u, client_stats.packets_lost);
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+}
+
+TEST_P(EndToEndTest, SimpleStopSendingRstStreamTest) {
+  ASSERT_TRUE(Initialize());
+
+  // Send a request without a fin, to keep the stream open
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  client_->SendMessage(headers, "", /*fin=*/false);
+  // Stream should be open
+  ASSERT_NE(nullptr, client_->latest_created_stream());
+  EXPECT_FALSE(client_->latest_created_stream()->write_side_closed());
+  EXPECT_FALSE(
+      QuicStreamPeer::read_side_closed(client_->latest_created_stream()));
+
+  // Send a RST_STREAM+STOP_SENDING on the stream
+  // Code is not important.
+  client_->latest_created_stream()->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+  client_->WaitForResponse();
+
+  // Stream should be gone.
+  ASSERT_EQ(nullptr, client_->latest_created_stream());
+}
+
+class BadShloPacketWriter : public QuicPacketWriterWrapper {
+ public:
+  BadShloPacketWriter(ParsedQuicVersion version)
+      : error_returned_(false), version_(version) {}
+  ~BadShloPacketWriter() override {}
+
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          quic::PerPacketOptions* options) override {
+    const WriteResult result = QuicPacketWriterWrapper::WritePacket(
+        buffer, buf_len, self_address, peer_address, options);
+    const uint8_t type_byte = buffer[0];
+    if (!error_returned_ && (type_byte & FLAGS_LONG_HEADER) &&
+        TypeByteIsServerHello(type_byte)) {
+      QUIC_DVLOG(1) << "Return write error for packet containing ServerHello";
+      error_returned_ = true;
+      return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
+    }
+    return result;
+  }
+
+  bool TypeByteIsServerHello(uint8_t type_byte) {
+    if (version_.UsesV2PacketTypes()) {
+      return ((type_byte & 0x30) >> 4) == 3;
+    }
+    if (version_.UsesQuicCrypto()) {
+      // ENCRYPTION_ZERO_RTT packet.
+      return ((type_byte & 0x30) >> 4) == 1;
+    }
+    // ENCRYPTION_HANDSHAKE packet.
+    return ((type_byte & 0x30) >> 4) == 2;
+  }
+
+ private:
+  bool error_returned_;
+  ParsedQuicVersion version_;
+};
+
+TEST_P(EndToEndTest, ConnectionCloseBeforeHandshakeComplete) {
+  if (!version_.HasIetfInvariantHeader()) {
+    // Only runs for IETF QUIC header.
+    Initialize();
+    return;
+  }
+  // This test ensures ZERO_RTT_PROTECTED connection close could close a client
+  // which has switched to forward secure.
+  connect_to_server_on_initialize_ = false;
+  ASSERT_TRUE(Initialize());
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher == nullptr) {
+    ADD_FAILURE() << "Missing dispatcher";
+    server_thread_->Resume();
+    return;
+  }
+  if (dispatcher->NumSessions() > 0) {
+    ADD_FAILURE() << "Dispatcher session map not empty";
+    server_thread_->Resume();
+    return;
+  }
+  // Note: this writer will only used by the server connection, not the time
+  // wait list.
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This causes the first server sent ZERO_RTT_PROTECTED packet (i.e.,
+      // SHLO) to be sent, but WRITE_ERROR is returned. Such that a
+      // ZERO_RTT_PROTECTED connection close would be sent to a client with
+      // encryption level FORWARD_SECURE.
+      new BadShloPacketWriter(version_));
+  server_thread_->Resume();
+
+  client_.reset(CreateQuicClient(client_writer_));
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
+  // client which switches to FORWARD_SECURE.
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
+}
+
+class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
+ public:
+  BadShloPacketWriter2(ParsedQuicVersion version)
+      : error_returned_(false), version_(version) {}
+  ~BadShloPacketWriter2() override {}
+
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          quic::PerPacketOptions* options) override {
+    const uint8_t type_byte = buffer[0];
+
+    if (type_byte & FLAGS_LONG_HEADER) {
+      if (((type_byte & 0x30 >> 4) == (version_.UsesV2PacketTypes() ? 2 : 1)) ||
+          ((type_byte & 0x7F) == 0x7C)) {
+        QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
+        return WriteResult(WRITE_STATUS_OK, buf_len);
+      }
+    } else if (!error_returned_) {
+      QUIC_DVLOG(1) << "Return write error for short header packet";
+      error_returned_ = true;
+      return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
+    }
+    return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                                peer_address, options);
+  }
+
+ private:
+  bool error_returned_;
+  ParsedQuicVersion version_;
+};
+
+TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
+  // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
+  // which has ZERO_RTT_PROTECTED encryption level.
+  connect_to_server_on_initialize_ = !version_.HasIetfInvariantHeader();
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfInvariantHeader()) {
+    // Only runs for IETF QUIC header.
+    return;
+  }
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher == nullptr) {
+    ADD_FAILURE() << "Missing dispatcher";
+    server_thread_->Resume();
+    return;
+  }
+  if (dispatcher->NumSessions() > 0) {
+    ADD_FAILURE() << "Dispatcher session map not empty";
+    server_thread_->Resume();
+    return;
+  }
+  // Note: this writer will only used by the server connection, not the time
+  // wait list.
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This causes the all server sent ZERO_RTT_PROTECTED packets to be
+      // dropped, and first short header packet causes write error.
+      new BadShloPacketWriter2(version_));
+  server_thread_->Resume();
+  client_.reset(CreateQuicClient(client_writer_));
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
+  // client.
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
+}
+
+// Test that the stream id manager closes the connection if a stream
+// in excess of the allowed maximum.
+TEST_P(EndToEndTest, TooBigStreamIdClosesConnection) {
+  // Has to be before version test, see EndToEndTest::TearDown()
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames()) {
+    // Only runs for IETF QUIC.
+    return;
+  }
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  std::string body(kMaxOutgoingPacketSize, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  // Force the client to write with a stream ID that exceeds the limit.
+  QuicSpdySession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicStreamIdManager* stream_id_manager =
+      QuicSessionPeer::ietf_bidirectional_stream_id_manager(client_session);
+  ASSERT_TRUE(stream_id_manager);
+  QuicStreamCount max_number_of_streams =
+      stream_id_manager->outgoing_max_streams();
+  QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
+      client_session,
+      GetNthClientInitiatedBidirectionalId(max_number_of_streams + 1));
+  client_->SendCustomSynchronousRequest(headers, body);
+  EXPECT_THAT(client_->stream_error(),
+              IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
+  EXPECT_THAT(client_session->error(), IsError(QUIC_INVALID_STREAM_ID));
+  EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, client_session->close_type());
+  EXPECT_TRUE(
+      IS_IETF_STREAM_FRAME(client_session->transport_close_frame_type()));
+}
+
+TEST_P(EndToEndTest, CustomTransportParameters) {
+  if (!version_.UsesTls()) {
+    // Custom transport parameters are only supported with TLS.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  constexpr auto kCustomParameter =
+      static_cast<TransportParameters::TransportParameterId>(0xff34);
+  client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
+      "test";
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  connection_debug_visitor_ = &visitor;
+  EXPECT_CALL(visitor, OnTransportParametersSent(_))
+      .WillOnce(Invoke([kCustomParameter](
+                           const TransportParameters& transport_parameters) {
+        ASSERT_NE(transport_parameters.custom_parameters.find(kCustomParameter),
+                  transport_parameters.custom_parameters.end());
+        EXPECT_EQ(transport_parameters.custom_parameters.at(kCustomParameter),
+                  "test");
+      }));
+  EXPECT_CALL(visitor, OnTransportParametersReceived(_)).Times(1);
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  QuicConfig* server_config = nullptr;
+  if (server_session != nullptr) {
+    server_config = server_session->config();
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  if (server_config != nullptr) {
+    if (server_config->received_custom_transport_parameters().find(
+            kCustomParameter) !=
+        server_config->received_custom_transport_parameters().end()) {
+      EXPECT_EQ(server_config->received_custom_transport_parameters().at(
+                    kCustomParameter),
+                "test");
+    } else {
+      ADD_FAILURE() << "Did not find custom parameter";
+    }
+  } else {
+    ADD_FAILURE() << "Missing server config";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulation) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_GT(
+      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
+      0u);
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulationWithMultiPacketChlo) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  if (!version_.UsesTls()) {
+    // This test uses custom transport parameters to increase the size of the
+    // CHLO, and those are only supported with TLS.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  constexpr auto kCustomParameter =
+      static_cast<TransportParameters::TransportParameterId>(0xff34);
+  client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
+      std::string(2000, '?');
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_GT(
+      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
+      0u);
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulationWithVersionNegotiation) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_GT(
+      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
+      0u);
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulationWithLoss) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  SetPacketLossPercentage(30);
+  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_GT(
+      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
+      0u);
+}
+
+// Testing packet writer that makes a copy of the first sent packets before
+// sending them. Useful for tests that need access to sent packets.
+class CopyingPacketWriter : public PacketDroppingTestWriter {
+ public:
+  explicit CopyingPacketWriter(int num_packets_to_copy)
+      : num_packets_to_copy_(num_packets_to_copy) {}
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override {
+    if (num_packets_to_copy_ > 0) {
+      num_packets_to_copy_--;
+      packets_.push_back(
+          QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
+    }
+    return PacketDroppingTestWriter::WritePacket(buffer, buf_len, self_address,
+                                                 peer_address, options);
+  }
+
+  std::vector<std::unique_ptr<QuicEncryptedPacket>>& packets() {
+    return packets_;
+  }
+
+ private:
+  int num_packets_to_copy_;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
+};
+
+TEST_P(EndToEndTest, ChaosProtectionDisabled) {
+  if (!version_.UsesCryptoFrames()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  // Replace the client's writer with one that'll save the first packet.
+  auto copying_writer = new CopyingPacketWriter(1);
+  delete client_writer_;
+  client_writer_ = copying_writer;
+  // Disable chaos protection and perform an HTTP request.
+  client_config_.SetClientConnectionOptions(QuicTagVector{kNCHP});
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  // Parse the saved packet to make sure it's valid.
+  SimpleQuicFramer validation_framer({version_});
+  validation_framer.framer()->SetInitialObfuscators(
+      GetClientConnection()->connection_id());
+  ASSERT_GT(copying_writer->packets().size(), 0u);
+  EXPECT_TRUE(validation_framer.ProcessPacket(*copying_writer->packets()[0]));
+  // TODO(dschinazi) figure out a way to use a MockRandom in this test so we
+  // can inspect the contents of this packet.
+}
+
+TEST_P(EndToEndTest, DisablePermuteTlsExtensions) {
+  if (!version_.UsesTls()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  // Disable TLS extension permutation and perform an HTTP request.
+  client_config_.SetClientConnectionOptions(QuicTagVector{kNBPE});
+  ASSERT_TRUE(Initialize());
+  EXPECT_FALSE(GetClientSession()->permutes_tls_extensions());
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, KeyUpdateInitiatedByClient) {
+  if (!version_.UsesTls()) {
+    // Key Update is only supported in TLS handshake.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
+
+  EXPECT_TRUE(
+      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  EXPECT_TRUE(
+      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_EQ(2u, server_stats.key_update_count);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, KeyUpdateInitiatedByServer) {
+  if (!version_.UsesTls()) {
+    // Key Update is only supported in TLS handshake.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
+
+  // Use WaitUntil to ensure the server had executed the key update predicate
+  // before sending the Foo request, otherwise the test can be flaky if it
+  // receives the Foo request before executing the key update.
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          if (!server_connection->IsKeyUpdateAllowed()) {
+            // Server may not have received ack from client yet for the current
+            // key phase, wait a bit and try again.
+            return false;
+          }
+          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
+              KeyUpdateReason::kLocalForTests));
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          if (!server_connection->IsKeyUpdateAllowed()) {
+            return false;
+          }
+          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
+              KeyUpdateReason::kLocalForTests));
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_EQ(2u, server_stats.key_update_count);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, KeyUpdateInitiatedByBoth) {
+  if (!version_.UsesTls()) {
+    // Key Update is only supported in TLS handshake.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Use WaitUntil to ensure the server had executed the key update predicate
+  // before the client sends the Foo request, otherwise the Foo request from
+  // the client could trigger the server key update before the server can
+  // initiate the key update locally. That would mean the test is no longer
+  // hitting the intended test state of both sides locally initiating a key
+  // update before receiving a packet in the new key phase from the other side.
+  // Additionally the test would fail since InitiateKeyUpdate() would not allow
+  // to do another key update yet and return false.
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          if (!server_connection->IsKeyUpdateAllowed()) {
+            // Server may not have received ack from client yet for the current
+            // key phase, wait a bit and try again.
+            return false;
+          }
+          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
+              KeyUpdateReason::kLocalForTests));
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_TRUE(
+      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          if (!server_connection->IsKeyUpdateAllowed()) {
+            return false;
+          }
+          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
+              KeyUpdateReason::kLocalForTests));
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  EXPECT_TRUE(
+      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_EQ(2u, server_stats.key_update_count);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, KeyUpdateInitiatedByConfidentialityLimit) {
+  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 16U);
+
+  if (!version_.UsesTls()) {
+    // Key Update is only supported in TLS handshake.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
+
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          EXPECT_EQ(0u, server_connection->GetStats().key_update_count);
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+
+  for (uint64_t i = 0;
+       i < GetQuicFlag(FLAGS_quic_key_update_confidentiality_limit); ++i) {
+    SendSynchronousFooRequestAndCheckResponse();
+  }
+
+  // Don't know exactly how many packets will be sent in each request/response,
+  // so just test that at least one key update occurred.
+  EXPECT_LE(1u, client_connection->GetStats().key_update_count);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_LE(1u, server_stats.key_update_count);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, TlsResumptionEnabledOnTheFly) {
+  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesTls()) {
+    // This test is TLS specific.
+    return;
+  }
+
+  // Send the first request. Client should not have a resumption ticket.
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
+            ssl_early_data_no_session_offered);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+
+  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false);
+
+  // Send the second request. Client should still have no resumption ticket, but
+  // it will receive one which can be used by the next request.
+  client_->Connect();
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
+            ssl_early_data_no_session_offered);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+
+  // Send the third request in 0RTT.
+  client_->Connect();
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+}
+
+TEST_P(EndToEndTest, TlsResumptionDisabledOnTheFly) {
+  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesTls()) {
+    // This test is TLS specific.
+    return;
+  }
+
+  // Send the first request and then disconnect.
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+
+  // Send the second request in 0RTT.
+  client_->Connect();
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+
+  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true);
+
+  // Send the third request. The client should try resumption but server should
+  // decline it.
+  client_->Connect();
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
+            ssl_early_data_session_not_resumed);
+  client_->Disconnect();
+
+  // Keep sending until the client runs out of resumption tickets.
+  for (int i = 0; i < 10; ++i) {
+    client_->Connect();
+    SendSynchronousFooRequestAndCheckResponse();
+
+    client_session = GetClientSession();
+    ASSERT_TRUE(client_session);
+    EXPECT_FALSE(client_session->EarlyDataAccepted());
+    const auto early_data_reason =
+        client_session->GetCryptoStream()->EarlyDataReason();
+    client_->Disconnect();
+
+    if (early_data_reason != ssl_early_data_session_not_resumed) {
+      EXPECT_EQ(early_data_reason, ssl_early_data_unsupported_for_session);
+      return;
+    }
+  }
+
+  ADD_FAILURE() << "Client should not have 10 resumption tickets.";
+}
+
+TEST_P(EndToEndTest, WebTransportSessionSetup) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* web_transport =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_NE(web_transport, nullptr);
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
+              nullptr);
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, WebTransportSessionSetupWithEchoWithSuffix) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  // "/echoFoo" should be accepted as "echo" with "set-header" query.
+  WebTransportHttp3* web_transport = CreateWebTransportSession(
+      "/echoFoo?set-header=bar:baz", /*wait_for_server_response=*/true);
+  ASSERT_NE(web_transport, nullptr);
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
+              nullptr);
+  server_thread_->Resume();
+  const spdy::SpdyHeaderBlock* response_headers = client_->response_headers();
+  auto it = response_headers->find("bar");
+  EXPECT_NE(it, response_headers->end());
+  EXPECT_EQ(it->second, "baz");
+}
+
+TEST_P(EndToEndTest, WebTransportSessionWithLoss) {
+  enable_web_transport_ = true;
+  // Enable loss to verify all permutations of receiving SETTINGS and
+  // request/response data.
+  SetPacketLossPercentage(30);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* web_transport =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_NE(web_transport, nullptr);
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
+              nullptr);
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, WebTransportSessionUnidirectionalStream) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* outgoing_stream =
+      session->OpenOutgoingUnidirectionalStream();
+  ASSERT_TRUE(outgoing_stream != nullptr);
+
+  auto stream_visitor = std::make_unique<NiceMock<MockStreamVisitor>>();
+  bool data_acknowledged = false;
+  EXPECT_CALL(*stream_visitor, OnWriteSideInDataRecvdState())
+      .WillOnce(Assign(&data_acknowledged, true));
+  outgoing_stream->SetVisitor(std::move(stream_visitor));
+
+  EXPECT_TRUE(outgoing_stream->Write("test"));
+  EXPECT_TRUE(outgoing_stream->SendFin());
+
+  bool stream_received = false;
+  EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
+      .WillOnce(Assign(&stream_received, true));
+  client_->WaitUntil(2000, [&stream_received]() { return stream_received; });
+  EXPECT_TRUE(stream_received);
+  WebTransportStream* received_stream =
+      session->AcceptIncomingUnidirectionalStream();
+  ASSERT_TRUE(received_stream != nullptr);
+  std::string received_data;
+  WebTransportStream::ReadResult result = received_stream->Read(&received_data);
+  EXPECT_EQ(received_data, "test");
+  EXPECT_TRUE(result.fin);
+
+  client_->WaitUntil(2000,
+                     [&data_acknowledged]() { return data_acknowledged; });
+  EXPECT_TRUE(data_acknowledged);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionUnidirectionalStreamSentEarly) {
+  enable_web_transport_ = true;
+  SetPacketLossPercentage(30);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* outgoing_stream =
+      session->OpenOutgoingUnidirectionalStream();
+  ASSERT_TRUE(outgoing_stream != nullptr);
+  EXPECT_TRUE(outgoing_stream->Write("test"));
+  EXPECT_TRUE(outgoing_stream->SendFin());
+
+  bool stream_received = false;
+  EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
+      .WillOnce(Assign(&stream_received, true));
+  client_->WaitUntil(5000, [&stream_received]() { return stream_received; });
+  EXPECT_TRUE(stream_received);
+  WebTransportStream* received_stream =
+      session->AcceptIncomingUnidirectionalStream();
+  ASSERT_TRUE(received_stream != nullptr);
+  std::string received_data;
+  WebTransportStream::ReadResult result = received_stream->Read(&received_data);
+  EXPECT_EQ(received_data, "test");
+  EXPECT_TRUE(result.fin);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionBidirectionalStream) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+
+  auto stream_visitor_owned = std::make_unique<NiceMock<MockStreamVisitor>>();
+  MockStreamVisitor* stream_visitor = stream_visitor_owned.get();
+  bool data_acknowledged = false;
+  EXPECT_CALL(*stream_visitor, OnWriteSideInDataRecvdState())
+      .WillOnce(Assign(&data_acknowledged, true));
+  stream->SetVisitor(std::move(stream_visitor_owned));
+
+  EXPECT_TRUE(stream->Write("test"));
+  EXPECT_TRUE(stream->SendFin());
+
+  std::string received_data =
+      ReadDataFromWebTransportStreamUntilFin(stream, stream_visitor);
+  EXPECT_EQ(received_data, "test");
+
+  client_->WaitUntil(2000,
+                     [&data_acknowledged]() { return data_acknowledged; });
+  EXPECT_TRUE(data_acknowledged);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionBidirectionalStreamWithBuffering) {
+  enable_web_transport_ = true;
+  SetPacketLossPercentage(30);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
+  ASSERT_TRUE(session != nullptr);
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  EXPECT_TRUE(stream->SendFin());
+
+  std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
+  EXPECT_EQ(received_data, "test");
+}
+
+TEST_P(EndToEndTest, WebTransportSessionServerBidirectionalStream) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  bool stream_received = false;
+  EXPECT_CALL(visitor, OnIncomingBidirectionalStreamAvailable())
+      .WillOnce(Assign(&stream_received, true));
+  client_->WaitUntil(5000, [&stream_received]() { return stream_received; });
+  EXPECT_TRUE(stream_received);
+
+  WebTransportStream* stream = session->AcceptIncomingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  EXPECT_TRUE(stream->SendFin());
+
+  std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
+  EXPECT_EQ(received_data, "test");
+}
+
+TEST_P(EndToEndTest, WebTransportDatagrams) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  quiche::SimpleBufferAllocator allocator;
+  for (int i = 0; i < 10; i++) {
+    session->SendOrQueueDatagram(MemSliceFromString("test"));
+  }
+
+  int received = 0;
+  EXPECT_CALL(visitor, OnDatagramReceived(_)).WillRepeatedly([&received]() {
+    received++;
+  });
+  client_->WaitUntil(5000, [&received]() { return received > 0; });
+  EXPECT_GT(received, 0);
+}
+
+TEST_P(EndToEndTest, WebTransportDatagramsWithContexts) {
+  enable_web_transport_ = true;
+  use_datagram_contexts_ = true;
+  SetPacketLossPercentage(30);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  QuicSpdyStream* connect_stream = nullptr;
+  WebTransportHttp3* session = CreateWebTransportSession(
+      "/echo", /*wait_for_server_response=*/true, &connect_stream);
+  ASSERT_TRUE(session != nullptr);
+  ASSERT_TRUE(connect_stream != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  quiche::SimpleBufferAllocator allocator;
+  for (int i = 0; i < 10; i++) {
+    session->SendOrQueueDatagram(MemSliceFromString("test"));
+  }
+
+  int received = 0;
+  EXPECT_CALL(visitor, OnDatagramReceived(_)).WillRepeatedly([&received]() {
+    received++;
+  });
+  client_->WaitUntil(5000, [&received]() { return received > 0; });
+  EXPECT_GT(received, 0);
+  EXPECT_TRUE(QuicSpdyStreamPeer::use_datagram_contexts(connect_stream));
+}
+
+TEST_P(EndToEndTest, WebTransportSessionClose) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamId stream_id = stream->GetStreamId();
+  EXPECT_TRUE(stream->Write("test"));
+  // Keep stream open.
+
+  bool close_received = false;
+  EXPECT_CALL(visitor, OnSessionClosed(42, "test error"))
+      .WillOnce(Assign(&close_received, true));
+  session->CloseSession(42, "test error");
+  client_->WaitUntil(2000, [&]() { return close_received; });
+  EXPECT_TRUE(close_received);
+
+  QuicSpdyStream* spdy_stream =
+      GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
+  EXPECT_TRUE(spdy_stream == nullptr);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionCloseWithoutCapsule) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamId stream_id = stream->GetStreamId();
+  EXPECT_TRUE(stream->Write("test"));
+  // Keep stream open.
+
+  bool close_received = false;
+  EXPECT_CALL(visitor, OnSessionClosed(0, ""))
+      .WillOnce(Assign(&close_received, true));
+  session->CloseSessionWithFinOnlyForTests();
+  client_->WaitUntil(2000, [&]() { return close_received; });
+  EXPECT_TRUE(close_received);
+
+  QuicSpdyStream* spdy_stream =
+      GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
+  EXPECT_TRUE(spdy_stream == nullptr);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionReceiveClose) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session = CreateWebTransportSession(
+      "/session-close", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* stream = session->OpenOutgoingUnidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamId stream_id = stream->GetStreamId();
+  EXPECT_TRUE(stream->Write("42 test error"));
+  EXPECT_TRUE(stream->SendFin());
+
+  // Have some other streams open pending, to ensure they are closed properly.
+  stream = session->OpenOutgoingUnidirectionalStream();
+  stream = session->OpenOutgoingBidirectionalStream();
+
+  bool close_received = false;
+  EXPECT_CALL(visitor, OnSessionClosed(42, "test error"))
+      .WillOnce(Assign(&close_received, true));
+  client_->WaitUntil(2000, [&]() { return close_received; });
+  EXPECT_TRUE(close_received);
+
+  QuicSpdyStream* spdy_stream =
+      GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
+  EXPECT_TRUE(spdy_stream == nullptr);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionStreamTermination) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/resets", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+  EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
+      .WillRepeatedly([this, session]() {
+        ReadAllIncomingWebTransportUnidirectionalStreams(session);
+      });
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  QuicStreamId id1 = stream->GetStreamId();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  stream->ResetWithUserCode(42);
+
+  // This read fails if the stream is closed in both directions, since that
+  // results in stream object being deleted.
+  std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
+  EXPECT_LE(received_data.size(), 4u);
+
+  stream = session->OpenOutgoingBidirectionalStream();
+  QuicStreamId id2 = stream->GetStreamId();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  stream->SendStopSending(24);
+
+  std::array<std::string, 2> expected_log = {
+      absl::StrCat("Received reset for stream ", id1, " with error code 42"),
+      absl::StrCat("Received stop sending for stream ", id2,
+                   " with error code 24"),
+  };
+  client_->WaitUntil(2000, [this, &expected_log]() {
+    return received_webtransport_unidirectional_streams_.size() >=
+           expected_log.size();
+  });
+  EXPECT_THAT(received_webtransport_unidirectional_streams_,
+              UnorderedElementsAreArray(expected_log));
+
+  // Since we closed the read side, cleanly closing the write side should result
+  // in the stream getting deleted.
+  ASSERT_TRUE(GetClientSession()->GetOrCreateSpdyDataStream(id2) != nullptr);
+  EXPECT_TRUE(stream->SendFin());
+  EXPECT_TRUE(client_->WaitUntil(2000, [this, id2]() {
+    return GetClientSession()->GetOrCreateSpdyDataStream(id2) == nullptr;
+  }));
+}
+
+TEST_P(EndToEndTest, WebTransportSession404) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session = CreateWebTransportSession(
+      "/does-not-exist", /*wait_for_server_response=*/false);
+  ASSERT_TRUE(session != nullptr);
+  QuicSpdyStream* connect_stream = client_->latest_created_stream();
+  QuicStreamId connect_stream_id = connect_stream->id();
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  EXPECT_TRUE(stream->SendFin());
+
+  EXPECT_TRUE(client_->WaitUntil(-1, [this, connect_stream_id]() {
+    return GetClientSession()->GetOrCreateSpdyDataStream(connect_stream_id) ==
+           nullptr;
+  }));
+}
+
+TEST_P(EndToEndTest, InvalidExtendedConnect) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+  // Missing :path header.
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "CONNECT";
+  headers[":protocol"] = "webtransport";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  // An early response should be received.
+  CheckResponseHeaders("400");
+}
+
+TEST_P(EndToEndTest, RejectExtendedConnect) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // Disable extended CONNECT.
+  memory_cache_backend_.set_enable_extended_connect(false);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+  // This extended CONNECT should be rejected.
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "CONNECT";
+  headers[":path"] = "/echo";
+  headers[":protocol"] = "webtransport";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  CheckResponseHeaders("400");
+
+  // Vanilla CONNECT should be accepted.
+  spdy::SpdyHeaderBlock headers2;
+  headers2[":authority"] = "localhost";
+  headers2[":method"] = "CONNECT";
+
+  client_->SendMessage(headers2, "body", /*fin=*/true);
+  client_->WaitForResponse();
+  // No :path header, so 404.
+  CheckResponseHeaders("404");
+}
+
+TEST_P(EndToEndTest, RejectInvalidRequestHeader) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "GET";
+  headers[":path"] = "/echo";
+  // transfer-encoding header is not allowed.
+  headers["transfer-encoding"] = "chunk";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  CheckResponseHeaders("400");
+}
+
+TEST_P(EndToEndTest, RejectTransferEncodingResponse) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  // Add a response with transfer-encoding headers.
+  SpdyHeaderBlock headers;
+  headers[":status"] = "200";
+  headers["transfer-encoding"] = "gzip";
+
+  SpdyHeaderBlock trailers;
+  trailers["some-trailing-header"] = "trailing-header-value";
+
+  memory_cache_backend_.AddResponse(server_hostname_, "/eep",
+                                    std::move(headers), "", trailers.Clone());
+
+  std::string received_response = client_->SendSynchronousRequest("/eep");
+  EXPECT_THAT(client_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(EndToEndTest, RejectUpperCaseRequest) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "GET";
+  headers[":path"] = "/echo";
+  headers["UpperCaseHeader"] = "foo";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  CheckResponseHeaders("400");
+}
+
+TEST_P(EndToEndTest, RejectRequestWithInvalidToken) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "GET";
+  headers[":path"] = "/echo";
+  headers["invalid,header"] = "foo";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  CheckResponseHeaders("400");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_constants.cc b/quiche/quic/core/http/http_constants.cc
new file mode 100644
index 0000000..ea372cd
--- /dev/null
+++ b/quiche/quic/core/http/http_constants.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2021 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 "quiche/quic/core/http/http_constants.h"
+
+#include "absl/strings/str_cat.h"
+
+namespace quic {
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x;
+
+std::string H3SettingsToString(Http3AndQpackSettingsIdentifiers identifier) {
+  switch (identifier) {
+    RETURN_STRING_LITERAL(SETTINGS_QPACK_MAX_TABLE_CAPACITY);
+    RETURN_STRING_LITERAL(SETTINGS_MAX_FIELD_SECTION_SIZE);
+    RETURN_STRING_LITERAL(SETTINGS_QPACK_BLOCKED_STREAMS);
+    RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT00);
+    RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT04);
+    RETURN_STRING_LITERAL(SETTINGS_WEBTRANS_DRAFT00);
+    RETURN_STRING_LITERAL(SETTINGS_ENABLE_CONNECT_PROTOCOL);
+  }
+  return absl::StrCat("UNSUPPORTED_SETTINGS_TYPE(", identifier, ")");
+}
+
+const absl::string_view kUserAgentHeaderName = "user-agent";
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_constants.h b/quiche/quic/core/http/http_constants.h
new file mode 100644
index 0000000..097b2a3
--- /dev/null
+++ b/quiche/quic/core/http/http_constants.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2019 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_HTTP_HTTP_CONSTANTS_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Unidirectional stream types.
+enum : uint64_t {
+  // https://quicwg.org/base-drafts/draft-ietf-quic-http.html#unidirectional-streams
+  kControlStream = 0x00,
+  kServerPushStream = 0x01,
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#enc-dec-stream-def
+  kQpackEncoderStream = 0x02,
+  kQpackDecoderStream = 0x03,
+  // https://ietf-wg-webtrans.github.io/draft-ietf-webtrans-http3/draft-ietf-webtrans-http3.html#name-unidirectional-streams
+  kWebTransportUnidirectionalStream = 0x54,
+};
+
+// This includes control stream, QPACK encoder stream, and QPACK decoder stream.
+enum : QuicStreamCount { kHttp3StaticUnidirectionalStreamCount = 3 };
+
+// HTTP/3 and QPACK settings identifiers.
+// https://quicwg.org/base-drafts/draft-ietf-quic-http.html#settings-parameters
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#configuration
+enum Http3AndQpackSettingsIdentifiers : uint64_t {
+  // Same value as spdy::SETTINGS_HEADER_TABLE_SIZE.
+  SETTINGS_QPACK_MAX_TABLE_CAPACITY = 0x01,
+  // Same value as spdy::SETTINGS_MAX_HEADER_LIST_SIZE.
+  SETTINGS_MAX_FIELD_SECTION_SIZE = 0x06,
+  SETTINGS_QPACK_BLOCKED_STREAMS = 0x07,
+  // draft-ietf-masque-h3-datagram-00.
+  SETTINGS_H3_DATAGRAM_DRAFT00 = 0x276,
+  // draft-ietf-masque-h3-datagram-04.
+  SETTINGS_H3_DATAGRAM_DRAFT04 = 0xffd277,
+  // draft-ietf-webtrans-http3-00
+  SETTINGS_WEBTRANS_DRAFT00 = 0x2b603742,
+  // draft-ietf-httpbis-h3-websockets
+  SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08,
+};
+
+// Returns HTTP/3 SETTINGS identifier as a string.
+QUIC_EXPORT std::string H3SettingsToString(
+    Http3AndQpackSettingsIdentifiers identifier);
+
+// Default maximum dynamic table capacity, communicated via
+// SETTINGS_QPACK_MAX_TABLE_CAPACITY.
+enum : QuicByteCount {
+  kDefaultQpackMaxDynamicTableCapacity = 64 * 1024  // 64 KB
+};
+
+// Default limit on the size of uncompressed headers,
+// communicated via SETTINGS_MAX_HEADER_LIST_SIZE.
+enum : QuicByteCount {
+  kDefaultMaxUncompressedHeaderSize = 16 * 1024  // 16 KB
+};
+
+// Default limit on number of blocked streams, communicated via
+// SETTINGS_QPACK_BLOCKED_STREAMS.
+enum : uint64_t { kDefaultMaximumBlockedStreams = 100 };
+
+ABSL_CONST_INIT QUIC_EXPORT_PRIVATE extern const absl::string_view
+    kUserAgentHeaderName;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
diff --git a/quiche/quic/core/http/http_decoder.cc b/quiche/quic/core/http/http_decoder.cc
new file mode 100644
index 0000000..23bc5df
--- /dev/null
+++ b/quiche/quic/core/http/http_decoder.cc
@@ -0,0 +1,674 @@
+// Copyright (c) 2018 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 "quiche/quic/core/http/http_decoder.h"
+
+#include <cstdint>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Limit on the payload length for frames that are buffered by HttpDecoder.
+// If a frame header indicating a payload length exceeding this limit is
+// received, HttpDecoder closes the connection.  Does not apply to frames that
+// are not buffered here but each payload fragment is immediately passed to
+// Visitor, like HEADERS, DATA, and unknown frames.
+constexpr QuicByteCount kPayloadLengthLimit = 1024 * 1024;
+
+}  // anonymous namespace
+
+HttpDecoder::HttpDecoder(Visitor* visitor) : HttpDecoder(visitor, Options()) {}
+HttpDecoder::HttpDecoder(Visitor* visitor, Options options)
+    : visitor_(visitor),
+      allow_web_transport_stream_(options.allow_web_transport_stream),
+      state_(STATE_READING_FRAME_TYPE),
+      current_frame_type_(0),
+      current_length_field_length_(0),
+      remaining_length_field_length_(0),
+      current_frame_length_(0),
+      remaining_frame_length_(0),
+      current_type_field_length_(0),
+      remaining_type_field_length_(0),
+      error_(QUIC_NO_ERROR),
+      error_detail_("") {
+  QUICHE_DCHECK(visitor_);
+}
+
+HttpDecoder::~HttpDecoder() {}
+
+// static
+bool HttpDecoder::DecodeSettings(const char* data,
+                                 QuicByteCount len,
+                                 SettingsFrame* frame) {
+  QuicDataReader reader(data, len);
+  uint64_t frame_type;
+  if (!reader.ReadVarInt62(&frame_type)) {
+    QUIC_DLOG(ERROR) << "Unable to read frame type.";
+    return false;
+  }
+
+  if (frame_type != static_cast<uint64_t>(HttpFrameType::SETTINGS)) {
+    QUIC_DLOG(ERROR) << "Invalid frame type " << frame_type;
+    return false;
+  }
+
+  absl::string_view frame_contents;
+  if (!reader.ReadStringPieceVarInt62(&frame_contents)) {
+    QUIC_DLOG(ERROR) << "Failed to read SETTINGS frame contents";
+    return false;
+  }
+
+  QuicDataReader frame_reader(frame_contents);
+
+  while (!frame_reader.IsDoneReading()) {
+    uint64_t id;
+    if (!frame_reader.ReadVarInt62(&id)) {
+      QUIC_DLOG(ERROR) << "Unable to read setting identifier.";
+      return false;
+    }
+    uint64_t content;
+    if (!frame_reader.ReadVarInt62(&content)) {
+      QUIC_DLOG(ERROR) << "Unable to read setting value.";
+      return false;
+    }
+    auto result = frame->values.insert({id, content});
+    if (!result.second) {
+      QUIC_DLOG(ERROR) << "Duplicate setting identifier.";
+      return false;
+    }
+  }
+  return true;
+}
+
+QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
+  QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
+  QUICHE_DCHECK_NE(STATE_ERROR, state_);
+
+  QuicDataReader reader(data, len);
+  bool continue_processing = true;
+  // BufferOrParsePayload() and FinishParsing() may need to be called even if
+  // there is no more data so that they can finish processing the current frame.
+  while (continue_processing && (reader.BytesRemaining() != 0 ||
+                                 state_ == STATE_BUFFER_OR_PARSE_PAYLOAD ||
+                                 state_ == STATE_FINISH_PARSING)) {
+    // |continue_processing| must have been set to false upon error.
+    QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
+    QUICHE_DCHECK_NE(STATE_ERROR, state_);
+
+    switch (state_) {
+      case STATE_READING_FRAME_TYPE:
+        continue_processing = ReadFrameType(&reader);
+        break;
+      case STATE_READING_FRAME_LENGTH:
+        continue_processing = ReadFrameLength(&reader);
+        break;
+      case STATE_BUFFER_OR_PARSE_PAYLOAD:
+        continue_processing = BufferOrParsePayload(&reader);
+        break;
+      case STATE_READING_FRAME_PAYLOAD:
+        continue_processing = ReadFramePayload(&reader);
+        break;
+      case STATE_FINISH_PARSING:
+        continue_processing = FinishParsing();
+        break;
+      case STATE_PARSING_NO_LONGER_POSSIBLE:
+        continue_processing = false;
+        QUIC_BUG(HttpDecoder PARSING_NO_LONGER_POSSIBLE)
+            << "HttpDecoder called after an indefinite-length frame has been "
+               "received";
+        RaiseError(QUIC_INTERNAL_ERROR,
+                   "HttpDecoder called after an indefinite-length frame has "
+                   "been received");
+        break;
+      case STATE_ERROR:
+        break;
+      default:
+        QUIC_BUG(quic_bug_10411_1) << "Invalid state: " << state_;
+    }
+  }
+
+  return len - reader.BytesRemaining();
+}
+
+bool HttpDecoder::ReadFrameType(QuicDataReader* reader) {
+  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
+  if (current_type_field_length_ == 0) {
+    // A new frame is coming.
+    current_type_field_length_ = reader->PeekVarInt62Length();
+    QUICHE_DCHECK_NE(0u, current_type_field_length_);
+    if (current_type_field_length_ > reader->BytesRemaining()) {
+      // Buffer a new type field.
+      remaining_type_field_length_ = current_type_field_length_;
+      BufferFrameType(reader);
+      return true;
+    }
+    // The reader has all type data needed, so no need to buffer.
+    bool success = reader->ReadVarInt62(&current_frame_type_);
+    QUICHE_DCHECK(success);
+  } else {
+    // Buffer the existing type field.
+    BufferFrameType(reader);
+    // The frame is still not buffered completely.
+    if (remaining_type_field_length_ != 0) {
+      return true;
+    }
+    QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_);
+    bool success = type_reader.ReadVarInt62(&current_frame_type_);
+    QUICHE_DCHECK(success);
+  }
+
+  // https://tools.ietf.org/html/draft-ietf-quic-http-31#section-7.2.8
+  // specifies that the following frames are treated as errors.
+  if (current_frame_type_ ==
+          static_cast<uint64_t>(http2::Http2FrameType::PRIORITY) ||
+      current_frame_type_ ==
+          static_cast<uint64_t>(http2::Http2FrameType::PING) ||
+      current_frame_type_ ==
+          static_cast<uint64_t>(http2::Http2FrameType::WINDOW_UPDATE) ||
+      current_frame_type_ ==
+          static_cast<uint64_t>(http2::Http2FrameType::CONTINUATION)) {
+    RaiseError(QUIC_HTTP_RECEIVE_SPDY_FRAME,
+               absl::StrCat("HTTP/2 frame received in a HTTP/3 connection: ",
+                            current_frame_type_));
+    return false;
+  }
+
+  if (current_frame_type_ ==
+      static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH)) {
+    RaiseError(QUIC_HTTP_FRAME_ERROR, "CANCEL_PUSH frame received.");
+    return false;
+  }
+  if (current_frame_type_ ==
+      static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE)) {
+    RaiseError(QUIC_HTTP_FRAME_ERROR, "PUSH_PROMISE frame received.");
+    return false;
+  }
+
+  state_ = STATE_READING_FRAME_LENGTH;
+  return true;
+}
+
+bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
+  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
+  if (current_length_field_length_ == 0) {
+    // A new frame is coming.
+    current_length_field_length_ = reader->PeekVarInt62Length();
+    QUICHE_DCHECK_NE(0u, current_length_field_length_);
+    if (current_length_field_length_ > reader->BytesRemaining()) {
+      // Buffer a new length field.
+      remaining_length_field_length_ = current_length_field_length_;
+      BufferFrameLength(reader);
+      return true;
+    }
+    // The reader has all length data needed, so no need to buffer.
+    bool success = reader->ReadVarInt62(&current_frame_length_);
+    QUICHE_DCHECK(success);
+  } else {
+    // Buffer the existing length field.
+    BufferFrameLength(reader);
+    // The frame is still not buffered completely.
+    if (remaining_length_field_length_ != 0) {
+      return true;
+    }
+    QuicDataReader length_reader(length_buffer_.data(),
+                                 current_length_field_length_);
+    bool success = length_reader.ReadVarInt62(&current_frame_length_);
+    QUICHE_DCHECK(success);
+  }
+
+  // WEBTRANSPORT_STREAM frames are indefinitely long, and thus require
+  // special handling; the number after the frame type is actually the
+  // WebTransport session ID, and not the length.
+  if (allow_web_transport_stream_ &&
+      current_frame_type_ ==
+          static_cast<uint64_t>(HttpFrameType::WEBTRANSPORT_STREAM)) {
+    visitor_->OnWebTransportStreamFrameType(
+        current_length_field_length_ + current_type_field_length_,
+        current_frame_length_);
+    state_ = STATE_PARSING_NO_LONGER_POSSIBLE;
+    return false;
+  }
+
+  if (IsFrameBuffered() &&
+      current_frame_length_ > MaxFrameLength(current_frame_type_)) {
+    RaiseError(QUIC_HTTP_FRAME_TOO_LARGE, "Frame is too large.");
+    return false;
+  }
+
+  // Calling the following visitor methods does not require parsing of any
+  // frame payload.
+  bool continue_processing = true;
+  const QuicByteCount header_length =
+      current_length_field_length_ + current_type_field_length_;
+
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::DATA):
+      continue_processing =
+          visitor_->OnDataFrameStart(header_length, current_frame_length_);
+      break;
+    case static_cast<uint64_t>(HttpFrameType::HEADERS):
+      continue_processing =
+          visitor_->OnHeadersFrameStart(header_length, current_frame_length_);
+      break;
+    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
+      QUICHE_NOTREACHED();
+      break;
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
+      continue_processing = visitor_->OnSettingsFrameStart(header_length);
+      break;
+    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
+      QUICHE_NOTREACHED();
+      break;
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
+      break;
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
+      break;
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
+      continue_processing = visitor_->OnPriorityUpdateFrameStart(header_length);
+      break;
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
+      continue_processing = visitor_->OnAcceptChFrameStart(header_length);
+      break;
+    default:
+      continue_processing = visitor_->OnUnknownFrameStart(
+          current_frame_type_, header_length, current_frame_length_);
+      break;
+  }
+
+  remaining_frame_length_ = current_frame_length_;
+
+  if (IsFrameBuffered()) {
+    state_ = STATE_BUFFER_OR_PARSE_PAYLOAD;
+    return continue_processing;
+  }
+
+  state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
+                                          : STATE_READING_FRAME_PAYLOAD;
+  return continue_processing;
+}
+
+bool HttpDecoder::IsFrameBuffered() {
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
+      return true;
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
+      return true;
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
+      return true;
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
+      return true;
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
+      return true;
+  }
+
+  // Other defined frame types as well as unknown frames are not buffered.
+  return false;
+}
+
+bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
+  QUICHE_DCHECK(!IsFrameBuffered());
+  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
+  QUICHE_DCHECK_NE(0u, remaining_frame_length_);
+
+  bool continue_processing = true;
+
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::DATA): {
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      absl::string_view payload;
+      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
+      QUICHE_DCHECK(success);
+      QUICHE_DCHECK(!payload.empty());
+      continue_processing = visitor_->OnDataFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::HEADERS): {
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      absl::string_view payload;
+      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
+      QUICHE_DCHECK(success);
+      QUICHE_DCHECK(!payload.empty());
+      continue_processing = visitor_->OnHeadersFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    default: {
+      continue_processing = HandleUnknownFramePayload(reader);
+      break;
+    }
+  }
+
+  if (remaining_frame_length_ == 0) {
+    state_ = STATE_FINISH_PARSING;
+  }
+
+  return continue_processing;
+}
+
+bool HttpDecoder::FinishParsing() {
+  QUICHE_DCHECK(!IsFrameBuffered());
+  QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
+
+  bool continue_processing = true;
+
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::DATA): {
+      continue_processing = visitor_->OnDataFrameEnd();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::HEADERS): {
+      continue_processing = visitor_->OnHeadersFrameEnd();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    default:
+      continue_processing = visitor_->OnUnknownFrameEnd();
+  }
+
+  ResetForNextFrame();
+  return continue_processing;
+}
+
+void HttpDecoder::ResetForNextFrame() {
+  current_length_field_length_ = 0;
+  current_type_field_length_ = 0;
+  state_ = STATE_READING_FRAME_TYPE;
+}
+
+bool HttpDecoder::HandleUnknownFramePayload(QuicDataReader* reader) {
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_frame_length_, reader->BytesRemaining());
+  absl::string_view payload;
+  bool success = reader->ReadStringPiece(&payload, bytes_to_read);
+  QUICHE_DCHECK(success);
+  QUICHE_DCHECK(!payload.empty());
+  remaining_frame_length_ -= payload.length();
+  return visitor_->OnUnknownFramePayload(payload);
+}
+
+bool HttpDecoder::BufferOrParsePayload(QuicDataReader* reader) {
+  QUICHE_DCHECK(IsFrameBuffered());
+  QUICHE_DCHECK_EQ(current_frame_length_,
+                   buffer_.size() + remaining_frame_length_);
+
+  if (buffer_.empty() && reader->BytesRemaining() >= current_frame_length_) {
+    // |*reader| contains entire payload, which might be empty.
+    remaining_frame_length_ = 0;
+    QuicDataReader current_payload_reader(reader->PeekRemainingPayload().data(),
+                                          current_frame_length_);
+    bool continue_processing = ParseEntirePayload(&current_payload_reader);
+
+    reader->Seek(current_frame_length_);
+    ResetForNextFrame();
+    return continue_processing;
+  }
+
+  // Buffer as much of the payload as |*reader| contains.
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_frame_length_, reader->BytesRemaining());
+  absl::StrAppend(&buffer_, reader->PeekRemainingPayload().substr(
+                                /* pos = */ 0, bytes_to_read));
+  reader->Seek(bytes_to_read);
+  remaining_frame_length_ -= bytes_to_read;
+
+  QUICHE_DCHECK_EQ(current_frame_length_,
+                   buffer_.size() + remaining_frame_length_);
+
+  if (remaining_frame_length_ > 0) {
+    QUICHE_DCHECK(reader->IsDoneReading());
+    return false;
+  }
+
+  QuicDataReader buffer_reader(buffer_);
+  bool continue_processing = ParseEntirePayload(&buffer_reader);
+  buffer_.clear();
+
+  ResetForNextFrame();
+  return continue_processing;
+}
+
+bool HttpDecoder::ParseEntirePayload(QuicDataReader* reader) {
+  QUICHE_DCHECK(IsFrameBuffered());
+  QUICHE_DCHECK_EQ(current_frame_length_, reader->BytesRemaining());
+  QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
+
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
+      QUICHE_NOTREACHED();
+      return false;
+    }
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
+      SettingsFrame frame;
+      if (!ParseSettingsFrame(reader, &frame)) {
+        return false;
+      }
+      return visitor_->OnSettingsFrame(frame);
+    }
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
+      GoAwayFrame frame;
+      if (!reader->ReadVarInt62(&frame.id)) {
+        RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read GOAWAY ID.");
+        return false;
+      }
+      if (!reader->IsDoneReading()) {
+        RaiseError(QUIC_HTTP_FRAME_ERROR, "Superfluous data in GOAWAY frame.");
+        return false;
+      }
+      return visitor_->OnGoAwayFrame(frame);
+    }
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
+      MaxPushIdFrame frame;
+      if (!reader->ReadVarInt62(&frame.push_id)) {
+        RaiseError(QUIC_HTTP_FRAME_ERROR,
+                   "Unable to read MAX_PUSH_ID push_id.");
+        return false;
+      }
+      if (!reader->IsDoneReading()) {
+        RaiseError(QUIC_HTTP_FRAME_ERROR,
+                   "Superfluous data in MAX_PUSH_ID frame.");
+        return false;
+      }
+      return visitor_->OnMaxPushIdFrame(frame);
+    }
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
+      PriorityUpdateFrame frame;
+      if (!ParsePriorityUpdateFrame(reader, &frame)) {
+        return false;
+      }
+      return visitor_->OnPriorityUpdateFrame(frame);
+    }
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
+      AcceptChFrame frame;
+      if (!ParseAcceptChFrame(reader, &frame)) {
+        return false;
+      }
+      return visitor_->OnAcceptChFrame(frame);
+    }
+    default:
+      // Only above frame types are parsed by ParseEntirePayload().
+      QUICHE_NOTREACHED();
+      return false;
+  }
+}
+
+void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_length_field_length_, reader->BytesRemaining());
+  bool success =
+      reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
+                            remaining_length_field_length_,
+                        bytes_to_read);
+  QUICHE_DCHECK(success);
+  remaining_length_field_length_ -= bytes_to_read;
+}
+
+void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_type_field_length_, reader->BytesRemaining());
+  bool success =
+      reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
+                            remaining_type_field_length_,
+                        bytes_to_read);
+  QUICHE_DCHECK(success);
+  remaining_type_field_length_ -= bytes_to_read;
+}
+
+void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
+  state_ = STATE_ERROR;
+  error_ = error;
+  error_detail_ = std::move(error_detail);
+  visitor_->OnError(this);
+}
+
+bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
+                                     SettingsFrame* frame) {
+  while (!reader->IsDoneReading()) {
+    uint64_t id;
+    if (!reader->ReadVarInt62(&id)) {
+      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting identifier.");
+      return false;
+    }
+    uint64_t content;
+    if (!reader->ReadVarInt62(&content)) {
+      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting value.");
+      return false;
+    }
+    auto result = frame->values.insert({id, content});
+    if (!result.second) {
+      RaiseError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER,
+                 "Duplicate setting identifier.");
+      return false;
+    }
+  }
+  return true;
+}
+
+bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader,
+                                              PriorityUpdateFrame* frame) {
+  frame->prioritized_element_type = REQUEST_STREAM;
+
+  if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
+    RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id.");
+    return false;
+  }
+
+  absl::string_view priority_field_value = reader->ReadRemainingPayload();
+  frame->priority_field_value =
+      std::string(priority_field_value.data(), priority_field_value.size());
+
+  return true;
+}
+
+bool HttpDecoder::ParseAcceptChFrame(QuicDataReader* reader,
+                                     AcceptChFrame* frame) {
+  absl::string_view origin;
+  absl::string_view value;
+  while (!reader->IsDoneReading()) {
+    if (!reader->ReadStringPieceVarInt62(&origin)) {
+      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH origin.");
+      return false;
+    }
+    if (!reader->ReadStringPieceVarInt62(&value)) {
+      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH value.");
+      return false;
+    }
+    // Copy data.
+    frame->entries.push_back({std::string(origin.data(), origin.size()),
+                              std::string(value.data(), value.size())});
+  }
+  return true;
+}
+
+QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
+  QUICHE_DCHECK(IsFrameBuffered());
+
+  switch (frame_type) {
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
+      return kPayloadLengthLimit;
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
+      return VARIABLE_LENGTH_INTEGER_LENGTH_8;
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
+      return VARIABLE_LENGTH_INTEGER_LENGTH_8;
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
+      return kPayloadLengthLimit;
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
+      return kPayloadLengthLimit;
+    default:
+      QUICHE_NOTREACHED();
+      return 0;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_decoder.h b/quiche/quic/core/http/http_decoder.h
new file mode 100644
index 0000000..59553a3
--- /dev/null
+++ b/quiche/quic/core/http/http_decoder.h
@@ -0,0 +1,278 @@
+// Copyright (c) 2018 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_HTTP_HTTP_DECODER_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+
+class HttpDecoderPeer;
+
+}  // namespace test
+
+class QuicDataReader;
+
+// A class for decoding the HTTP frames that are exchanged in an HTTP over QUIC
+// session.
+class QUIC_EXPORT_PRIVATE HttpDecoder {
+ public:
+  struct QUIC_EXPORT_PRIVATE Options {
+    // Indicates that WEBTRANSPORT_STREAM should be parsed.
+    bool allow_web_transport_stream = false;
+  };
+
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() {}
+
+    // Called if an error is detected.
+    virtual void OnError(HttpDecoder* decoder) = 0;
+
+    // All the following methods return true to continue decoding,
+    // and false to pause it.
+    // On*FrameStart() methods are called after the frame header is completely
+    // processed.  At that point it is safe to consume |header_length| bytes.
+
+    // Called when a MAX_PUSH_ID frame has been successfully parsed.
+    virtual bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) = 0;
+
+    // Called when a GOAWAY frame has been successfully parsed.
+    virtual bool OnGoAwayFrame(const GoAwayFrame& frame) = 0;
+
+    // Called when a SETTINGS frame has been received.
+    virtual bool OnSettingsFrameStart(QuicByteCount header_length) = 0;
+
+    // Called when a SETTINGS frame has been successfully parsed.
+    virtual bool OnSettingsFrame(const SettingsFrame& frame) = 0;
+
+    // Called when a DATA frame has been received.
+    // |header_length| and |payload_length| are the length of DATA frame header
+    // and payload, respectively.
+    virtual bool OnDataFrameStart(QuicByteCount header_length,
+                                  QuicByteCount payload_length) = 0;
+    // Called when part of the payload of a DATA frame has been read.  May be
+    // called multiple times for a single frame.  |payload| is guaranteed to be
+    // non-empty.
+    virtual bool OnDataFramePayload(absl::string_view payload) = 0;
+    // Called when a DATA frame has been completely processed.
+    virtual bool OnDataFrameEnd() = 0;
+
+    // Called when a HEADERS frame has been received.
+    // |header_length| and |payload_length| are the length of HEADERS frame
+    // header and payload, respectively.
+    virtual bool OnHeadersFrameStart(QuicByteCount header_length,
+                                     QuicByteCount payload_length) = 0;
+    // Called when part of the payload of a HEADERS frame has been read.  May be
+    // called multiple times for a single frame.  |payload| is guaranteed to be
+    // non-empty.
+    virtual bool OnHeadersFramePayload(absl::string_view payload) = 0;
+    // Called when a HEADERS frame has been completely processed.
+    virtual bool OnHeadersFrameEnd() = 0;
+
+    // Called when a PRIORITY_UPDATE frame has been received.
+    // |header_length| contains PRIORITY_UPDATE frame length and payload length.
+    virtual bool OnPriorityUpdateFrameStart(QuicByteCount header_length) = 0;
+
+    // Called when a PRIORITY_UPDATE frame has been successfully parsed.
+    virtual bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) = 0;
+
+    // Called when an ACCEPT_CH frame has been received.
+    // |header_length| contains ACCEPT_CH frame length and payload length.
+    virtual bool OnAcceptChFrameStart(QuicByteCount header_length) = 0;
+
+    // Called when an ACCEPT_CH frame has been successfully parsed.
+    virtual bool OnAcceptChFrame(const AcceptChFrame& frame) = 0;
+
+    // Called when a WEBTRANSPORT_STREAM frame type and the session ID varint
+    // immediately following it has been received.  Any further parsing should
+    // be done by the stream itself, and not the parser. Note that this does not
+    // return bool, because WEBTRANSPORT_STREAM always causes the parsing
+    // process to cease.
+    virtual void OnWebTransportStreamFrameType(
+        QuicByteCount header_length,
+        WebTransportSessionId session_id) = 0;
+
+    // Called when a frame of unknown type |frame_type| has been received.
+    // Frame type might be reserved, Visitor must make sure to ignore.
+    // |header_length| and |payload_length| are the length of the frame header
+    // and payload, respectively.
+    virtual bool OnUnknownFrameStart(uint64_t frame_type,
+                                     QuicByteCount header_length,
+                                     QuicByteCount payload_length) = 0;
+    // Called when part of the payload of the unknown frame has been read.  May
+    // be called multiple times for a single frame.  |payload| is guaranteed to
+    // be non-empty.
+    virtual bool OnUnknownFramePayload(absl::string_view payload) = 0;
+    // Called when the unknown frame has been completely processed.
+    virtual bool OnUnknownFrameEnd() = 0;
+  };
+
+  // |visitor| must be non-null, and must outlive HttpDecoder.
+  explicit HttpDecoder(Visitor* visitor);
+  explicit HttpDecoder(Visitor* visitor, Options options);
+
+  ~HttpDecoder();
+
+  // Processes the input and invokes the appropriate visitor methods, until a
+  // visitor method returns false or an error occurs.  Returns the number of
+  // bytes processed.  Does not process any input if called after an error.
+  // Paused processing can be resumed by calling ProcessInput() again with the
+  // unprocessed portion of data.  Must not be called after an error has
+  // occurred.
+  QuicByteCount ProcessInput(const char* data, QuicByteCount len);
+
+  // Decode settings frame from |data|.
+  // Upon successful decoding, |frame| will be populated, and returns true.
+  // This method is not used for regular processing of incoming data.
+  static bool DecodeSettings(const char* data,
+                             QuicByteCount len,
+                             SettingsFrame* frame);
+
+  // Returns an error code other than QUIC_NO_ERROR if and only if
+  // Visitor::OnError() has been called.
+  QuicErrorCode error() const { return error_; }
+
+  const std::string& error_detail() const { return error_detail_; }
+
+  // Returns true if input data processed so far ends on a frame boundary.
+  bool AtFrameBoundary() const { return state_ == STATE_READING_FRAME_TYPE; }
+
+ private:
+  friend test::HttpDecoderPeer;
+
+  // Represents the current state of the parsing state machine.
+  enum HttpDecoderState {
+    STATE_READING_FRAME_LENGTH,
+    STATE_READING_FRAME_TYPE,
+
+    // States used for buffered frame types
+    STATE_BUFFER_OR_PARSE_PAYLOAD,
+
+    // States used for non-buffered frame types
+    STATE_READING_FRAME_PAYLOAD,
+    STATE_FINISH_PARSING,
+
+    STATE_PARSING_NO_LONGER_POSSIBLE,
+    STATE_ERROR
+  };
+
+  // Reads the type of a frame from |reader|. Sets error_ and error_detail_
+  // if there are any errors.  Also calls OnDataFrameStart() or
+  // OnHeadersFrameStart() for appropriate frame types. Returns whether the
+  // processing should continue.
+  bool ReadFrameType(QuicDataReader* reader);
+
+  // Reads the length of a frame from |reader|. Sets error_ and error_detail_
+  // if there are any errors.  Returns whether processing should continue.
+  bool ReadFrameLength(QuicDataReader* reader);
+
+  // Returns whether the current frame is of a buffered type.
+  // The payload of buffered frames is buffered by HttpDecoder, and parsed by
+  // HttpDecoder after the entire frame has been received.  (Copying to the
+  // buffer is skipped if the ProcessInput() call covers the entire payload.)
+  // Frames that are not buffered have every payload fragment synchronously
+  // passed to the Visitor without buffering.
+  bool IsFrameBuffered();
+
+  // For buffered frame types, calls BufferOrParsePayload().  For other frame
+  // types, reads the payload of the current frame from |reader| and calls
+  // visitor methods.  Returns whether processing should continue.
+  bool ReadFramePayload(QuicDataReader* reader);
+
+  // For buffered frame types, this method is only called if frame payload is
+  // empty, and it calls BufferOrParsePayload().  For other frame types, this
+  // method directly calls visitor methods to signal that frame had been
+  // received completely.  Returns whether processing should continue.
+  bool FinishParsing();
+
+  // Reset internal fields to prepare for reading next frame.
+  void ResetForNextFrame();
+
+  // Read payload of unknown frame from |reader| and call
+  // Visitor::OnUnknownFramePayload().  Returns true decoding should continue,
+  // false if it should be paused.
+  bool HandleUnknownFramePayload(QuicDataReader* reader);
+
+  // Buffers any remaining frame payload from |*reader| into |buffer_| if
+  // necessary.  Parses the frame payload if complete.  Parses out of |*reader|
+  // without unnecessary copy if |*reader| contains entire payload.
+  // Returns whether processing should continue.
+  // Must only be called when current frame type is buffered.
+  bool BufferOrParsePayload(QuicDataReader* reader);
+
+  // Parses the entire payload of certain kinds of frames that are parsed in a
+  // single pass.  |reader| must have at least |current_frame_length_| bytes.
+  // Returns whether processing should continue.
+  // Must only be called when current frame type is buffered.
+  bool ParseEntirePayload(QuicDataReader* reader);
+
+  // Buffers any remaining frame length field from |reader| into
+  // |length_buffer_|.
+  void BufferFrameLength(QuicDataReader* reader);
+
+  // Buffers any remaining frame type field from |reader| into |type_buffer_|.
+  void BufferFrameType(QuicDataReader* reader);
+
+  // Sets |error_| and |error_detail_| accordingly.
+  void RaiseError(QuicErrorCode error, std::string error_detail);
+
+  // Parses the payload of a SETTINGS frame from |reader| into |frame|.
+  bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
+
+  // Parses the payload of a PRIORITY_UPDATE frame (draft-02, type 0xf0700)
+  // from |reader| into |frame|.
+  bool ParsePriorityUpdateFrame(QuicDataReader* reader,
+                                PriorityUpdateFrame* frame);
+
+  // Parses the payload of an ACCEPT_CH frame from |reader| into |frame|.
+  bool ParseAcceptChFrame(QuicDataReader* reader, AcceptChFrame* frame);
+
+  // Returns the max frame size of a given |frame_type|.
+  QuicByteCount MaxFrameLength(uint64_t frame_type);
+
+  // Visitor to invoke when messages are parsed.
+  Visitor* const visitor_;  // Unowned.
+  // Whether WEBTRANSPORT_STREAM should be parsed.
+  bool allow_web_transport_stream_;
+  // Current state of the parsing.
+  HttpDecoderState state_;
+  // Type of the frame currently being parsed.
+  uint64_t current_frame_type_;
+  // Size of the frame's length field.
+  QuicByteCount current_length_field_length_;
+  // Remaining length that's needed for the frame's length field.
+  QuicByteCount remaining_length_field_length_;
+  // Length of the payload of the frame currently being parsed.
+  QuicByteCount current_frame_length_;
+  // Remaining payload bytes to be parsed.
+  QuicByteCount remaining_frame_length_;
+  // Length of the frame's type field.
+  QuicByteCount current_type_field_length_;
+  // Remaining length that's needed for the frame's type field.
+  QuicByteCount remaining_type_field_length_;
+  // Last error.
+  QuicErrorCode error_;
+  // The issue which caused |error_|
+  std::string error_detail_;
+  // Remaining unparsed data.
+  std::string buffer_;
+  // Remaining unparsed length field data.
+  std::array<char, sizeof(uint64_t)> length_buffer_;
+  // Remaining unparsed type field data.
+  std::array<char, sizeof(uint64_t)> type_buffer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
diff --git a/quiche/quic/core/http/http_decoder_test.cc b/quiche/quic/core/http/http_decoder_test.cc
new file mode 100644
index 0000000..962f53c
--- /dev/null
+++ b/quiche/quic/core/http/http_decoder_test.cc
@@ -0,0 +1,1136 @@
+// Copyright (c) 2018 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 "quiche/quic/core/http/http_decoder.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Eq;
+using ::testing::InSequence;
+using ::testing::Return;
+
+namespace quic {
+namespace test {
+
+class HttpDecoderPeer {
+ public:
+  static uint64_t current_frame_type(HttpDecoder* decoder) {
+    return decoder->current_frame_type_;
+  }
+};
+
+namespace {
+
+class MockHttpDecoderVisitor : public HttpDecoder::Visitor {
+ public:
+  ~MockHttpDecoderVisitor() override = default;
+
+  // Called if an error is detected.
+  MOCK_METHOD(void, OnError, (HttpDecoder*), (override));
+
+  MOCK_METHOD(bool,
+              OnMaxPushIdFrame,
+              (const MaxPushIdFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnGoAwayFrame, (const GoAwayFrame& frame), (override));
+  MOCK_METHOD(bool,
+              OnSettingsFrameStart,
+              (QuicByteCount header_length),
+              (override));
+  MOCK_METHOD(bool, OnSettingsFrame, (const SettingsFrame& frame), (override));
+
+  MOCK_METHOD(bool,
+              OnDataFrameStart,
+              (QuicByteCount header_length, QuicByteCount payload_length),
+              (override));
+  MOCK_METHOD(bool,
+              OnDataFramePayload,
+              (absl::string_view payload),
+              (override));
+  MOCK_METHOD(bool, OnDataFrameEnd, (), (override));
+
+  MOCK_METHOD(bool,
+              OnHeadersFrameStart,
+              (QuicByteCount header_length, QuicByteCount payload_length),
+              (override));
+  MOCK_METHOD(bool,
+              OnHeadersFramePayload,
+              (absl::string_view payload),
+              (override));
+  MOCK_METHOD(bool, OnHeadersFrameEnd, (), (override));
+
+  MOCK_METHOD(bool,
+              OnPriorityUpdateFrameStart,
+              (QuicByteCount header_length),
+              (override));
+  MOCK_METHOD(bool,
+              OnPriorityUpdateFrame,
+              (const PriorityUpdateFrame& frame),
+              (override));
+
+  MOCK_METHOD(bool,
+              OnAcceptChFrameStart,
+              (QuicByteCount header_length),
+              (override));
+  MOCK_METHOD(bool, OnAcceptChFrame, (const AcceptChFrame& frame), (override));
+  MOCK_METHOD(void,
+              OnWebTransportStreamFrameType,
+              (QuicByteCount header_length, WebTransportSessionId session_id),
+              (override));
+
+  MOCK_METHOD(bool,
+              OnUnknownFrameStart,
+              (uint64_t frame_type,
+               QuicByteCount header_length,
+               QuicByteCount payload_length),
+              (override));
+  MOCK_METHOD(bool,
+              OnUnknownFramePayload,
+              (absl::string_view payload),
+              (override));
+  MOCK_METHOD(bool, OnUnknownFrameEnd, (), (override));
+};
+
+class HttpDecoderTest : public QuicTest {
+ public:
+  HttpDecoderTest() : decoder_(&visitor_) {
+    ON_CALL(visitor_, OnMaxPushIdFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnGoAwayFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnSettingsFrameStart(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnSettingsFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnDataFrameStart(_, _)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnDataFramePayload(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnDataFrameEnd()).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnHeadersFrameStart(_, _)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnHeadersFramePayload(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnHeadersFrameEnd()).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnPriorityUpdateFrameStart(_))
+        .WillByDefault(Return(true));
+    ON_CALL(visitor_, OnPriorityUpdateFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnAcceptChFrameStart(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnAcceptChFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnUnknownFrameStart(_, _, _)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnUnknownFramePayload(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnUnknownFrameEnd()).WillByDefault(Return(true));
+  }
+  ~HttpDecoderTest() override = default;
+
+  uint64_t current_frame_type() {
+    return HttpDecoderPeer::current_frame_type(&decoder_);
+  }
+
+  // Process |input| in a single call to HttpDecoder::ProcessInput().
+  QuicByteCount ProcessInput(absl::string_view input) {
+    return decoder_.ProcessInput(input.data(), input.size());
+  }
+
+  // Feed |input| to |decoder_| one character at a time,
+  // verifying that each character gets processed.
+  void ProcessInputCharByChar(absl::string_view input) {
+    for (char c : input) {
+      EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+    }
+  }
+
+  // Append garbage to |input|, then process it in a single call to
+  // HttpDecoder::ProcessInput().  Verify that garbage is not read.
+  QuicByteCount ProcessInputWithGarbageAppended(absl::string_view input) {
+    std::string input_with_garbage_appended = absl::StrCat(input, "blahblah");
+    QuicByteCount processed_bytes = ProcessInput(input_with_garbage_appended);
+
+    // Guaranteed by HttpDecoder::ProcessInput() contract.
+    QUICHE_DCHECK_LE(processed_bytes, input_with_garbage_appended.size());
+
+    // Caller should set up visitor to pause decoding
+    // before HttpDecoder would read garbage.
+    EXPECT_LE(processed_bytes, input.size());
+
+    return processed_bytes;
+  }
+
+  testing::StrictMock<MockHttpDecoderVisitor> visitor_;
+  HttpDecoder decoder_;
+};
+
+TEST_F(HttpDecoderTest, InitialState) {
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, UnknownFrame) {
+  std::unique_ptr<char[]> input;
+
+  const QuicByteCount payload_lengths[] = {0, 14, 100};
+  const uint64_t frame_types[] = {
+      0x21, 0x40, 0x5f, 0x7e, 0x9d,  // some reserved frame types
+      0x6f, 0x14                     // some unknown, not reserved frame types
+  };
+
+  for (auto payload_length : payload_lengths) {
+    std::string data(payload_length, 'a');
+
+    for (auto frame_type : frame_types) {
+      const QuicByteCount total_length =
+          QuicDataWriter::GetVarInt62Len(frame_type) +
+          QuicDataWriter::GetVarInt62Len(payload_length) + payload_length;
+      input = std::make_unique<char[]>(total_length);
+
+      QuicDataWriter writer(total_length, input.get());
+      writer.WriteVarInt62(frame_type);
+      writer.WriteVarInt62(payload_length);
+      const QuicByteCount header_length = writer.length();
+      if (payload_length > 0) {
+        writer.WriteStringPiece(data);
+      }
+
+      EXPECT_CALL(visitor_, OnUnknownFrameStart(frame_type, header_length,
+                                                payload_length));
+      if (payload_length > 0) {
+        EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq(data)));
+      }
+      EXPECT_CALL(visitor_, OnUnknownFrameEnd());
+
+      EXPECT_EQ(total_length, decoder_.ProcessInput(input.get(), total_length));
+
+      EXPECT_THAT(decoder_.error(), IsQuicNoError());
+      ASSERT_EQ("", decoder_.error_detail());
+      EXPECT_EQ(frame_type, current_frame_type());
+    }
+  }
+}
+
+TEST_F(HttpDecoderTest, CancelPush) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "03"    // type (CANCEL_PUSH)
+      "01"    // length
+      "01");  // Push Id
+
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(1u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+  EXPECT_EQ("CANCEL_PUSH frame received.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, PushPromiseFrame) {
+  InSequence s;
+  std::string input =
+      absl::StrCat(absl::HexStringToBytes("05"    // type (PUSH PROMISE)
+                                          "08"    // length
+                                          "1f"),  // push id 31
+                   "Headers");                    // headers
+
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(1u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+  EXPECT_EQ("PUSH_PROMISE frame received.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, MaxPushId) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "0D"    // type (MAX_PUSH_ID)
+      "01"    // length
+      "01");  // Push Id
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})))
+      .WillOnce(Return(false));
+  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, SettingsFrame) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "07"    // length
+      "01"    // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
+      "02"    // content
+      "06"    // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
+      "05"    // content
+      "4100"  // identifier, encoded on 2 bytes (0x40), value is 256 (0x100)
+      "04");  // content
+
+  SettingsFrame frame;
+  frame.values[1] = 2;
+  frame.values[6] = 5;
+  frame.values[256] = 4;
+
+  // Visitor pauses processing.
+  absl::string_view remaining_input(input);
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2)).WillOnce(Return(false));
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(2u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnSettingsFrame(frame)).WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
+  EXPECT_CALL(visitor_, OnSettingsFrame(frame));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
+  EXPECT_CALL(visitor_, OnSettingsFrame(frame));
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, CorruptSettingsFrame) {
+  const char* const kPayload =
+      "\x42\x11"                           // two-byte id
+      "\x80\x22\x33\x44"                   // four-byte value
+      "\x58\x39"                           // two-byte id
+      "\xf0\x22\x33\x44\x55\x66\x77\x88";  // eight-byte value
+  struct {
+    size_t payload_length;
+    const char* const error_message;
+  } kTestData[] = {
+      {1, "Unable to read setting identifier."},
+      {5, "Unable to read setting value."},
+      {7, "Unable to read setting identifier."},
+      {12, "Unable to read setting value."},
+  };
+
+  for (const auto& test_data : kTestData) {
+    std::string input;
+    input.push_back(4u);  // type SETTINGS
+    input.push_back(test_data.payload_length);
+    const size_t header_length = input.size();
+    input.append(kPayload, test_data.payload_length);
+
+    HttpDecoder decoder(&visitor_);
+    EXPECT_CALL(visitor_, OnSettingsFrameStart(header_length));
+    EXPECT_CALL(visitor_, OnError(&decoder));
+
+    QuicByteCount processed_bytes =
+        decoder.ProcessInput(input.data(), input.size());
+    EXPECT_EQ(input.size(), processed_bytes);
+    EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+    EXPECT_EQ(test_data.error_message, decoder.error_detail());
+  }
+}
+
+TEST_F(HttpDecoderTest, DuplicateSettingsIdentifier) {
+  std::string input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "04"    // length
+      "01"    // identifier
+      "01"    // content
+      "01"    // identifier
+      "02");  // content
+
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+
+  EXPECT_EQ(input.size(), ProcessInput(input));
+
+  EXPECT_THAT(decoder_.error(),
+              IsError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER));
+  EXPECT_EQ("Duplicate setting identifier.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, DataFrame) {
+  InSequence s;
+  std::string input = absl::StrCat(absl::HexStringToBytes("00"    // type (DATA)
+                                                          "05"),  // length
+                                   "Data!");                      // data
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5)).WillOnce(Return(false));
+  absl::string_view remaining_input(input);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(2u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")))
+      .WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+
+  EXPECT_CALL(visitor_, OnDataFrameEnd()).WillOnce(Return(false));
+  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("D")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("t")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("!")));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, FrameHeaderPartialDelivery) {
+  InSequence s;
+  // A large input that will occupy more than 1 byte in the length field.
+  std::string input(2048, 'x');
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      input.length(), quiche::SimpleBufferAllocator::Get());
+  // Partially send only 1 byte of the header to process.
+  EXPECT_EQ(1u, decoder_.ProcessInput(header.data(), 1));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Send the rest of the header.
+  EXPECT_CALL(visitor_, OnDataFrameStart(3, input.length()));
+  EXPECT_EQ(header.size() - 1,
+            decoder_.ProcessInput(header.data() + 1, header.size() - 1));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Send data.
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view(input)));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  EXPECT_EQ(2048u, decoder_.ProcessInput(input.data(), 2048));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, PartialDeliveryOfLargeFrameType) {
+  // Use a reserved type that takes four bytes as a varint.
+  const uint64_t frame_type = 0x1f * 0x222 + 0x21;
+  const QuicByteCount payload_length = 0;
+  const QuicByteCount header_length =
+      QuicDataWriter::GetVarInt62Len(frame_type) +
+      QuicDataWriter::GetVarInt62Len(payload_length);
+
+  auto input = std::make_unique<char[]>(header_length);
+  QuicDataWriter writer(header_length, input.get());
+  writer.WriteVarInt62(frame_type);
+  writer.WriteVarInt62(payload_length);
+
+  EXPECT_CALL(visitor_,
+              OnUnknownFrameStart(frame_type, header_length, payload_length));
+  EXPECT_CALL(visitor_, OnUnknownFrameEnd());
+
+  auto raw_input = input.get();
+  for (uint64_t i = 0; i < header_length; ++i) {
+    char c = raw_input[i];
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+  EXPECT_EQ(frame_type, current_frame_type());
+}
+
+TEST_F(HttpDecoderTest, GoAway) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "07"    // type (GOAWAY)
+      "01"    // length
+      "01");  // ID
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})))
+      .WillOnce(Return(false));
+  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})));
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, HeadersFrame) {
+  InSequence s;
+  std::string input =
+      absl::StrCat(absl::HexStringToBytes("01"    // type (HEADERS)
+                                          "07"),  // length
+                   "Headers");                    // headers
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7)).WillOnce(Return(false));
+  absl::string_view remaining_input(input);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(2u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")))
+      .WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
+  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("H")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("a")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("d")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("r")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("s")));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, EmptyDataFrame) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "00"    // type (DATA)
+      "00");  // length
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 0)).WillOnce(Return(false));
+  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
+
+  EXPECT_CALL(visitor_, OnDataFrameEnd()).WillOnce(Return(false));
+  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 0));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 0));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, EmptyHeadersFrame) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "01"    // type (HEADERS)
+      "00");  // length
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0)).WillOnce(Return(false));
+  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
+
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
+  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, GoawayWithOverlyLargePayload) {
+  std::string input = absl::HexStringToBytes(
+      "07"    // type (GOAWAY)
+      "10");  // length exceeding the maximum possible length for GOAWAY frame
+  // Process all data at once.
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(2u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
+  EXPECT_EQ("Frame is too large.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, MaxPushIdWithOverlyLargePayload) {
+  std::string input = absl::HexStringToBytes(
+      "0d"    // type (MAX_PUSH_ID)
+      "10");  // length exceeding the maximum possible length for MAX_PUSH_ID
+              // frame
+  // Process all data at once.
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(2u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
+  EXPECT_EQ("Frame is too large.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, FrameWithOverlyLargePayload) {
+  // Regression test for b/193919867: Ensure that reading frames with incredibly
+  // large payload lengths does not lead to allocating unbounded memory.
+  constexpr size_t max_input_length =
+      /*max frame type varint length*/ sizeof(uint64_t) +
+      /*max frame length varint length*/ sizeof(uint64_t) +
+      /*one byte of payload*/ sizeof(uint8_t);
+  char input[max_input_length];
+  for (uint64_t frame_type = 0; frame_type < 1025; frame_type++) {
+    ::testing::NiceMock<MockHttpDecoderVisitor> visitor;
+    HttpDecoder decoder(&visitor);
+    QuicDataWriter writer(max_input_length, input);
+    ASSERT_TRUE(writer.WriteVarInt62(frame_type));         // frame type.
+    ASSERT_TRUE(writer.WriteVarInt62(kVarInt62MaxValue));  // frame length.
+    ASSERT_TRUE(writer.WriteUInt8(0x00));  // one byte of payload.
+    EXPECT_NE(decoder.ProcessInput(input, writer.length()), 0u) << frame_type;
+  }
+}
+
+TEST_F(HttpDecoderTest, MalformedSettingsFrame) {
+  char input[30];
+  QuicDataWriter writer(30, input);
+  // Write type SETTINGS.
+  writer.WriteUInt8(0x04);
+  // Write length.
+  writer.WriteVarInt62(2048 * 1024);
+
+  writer.WriteStringPiece("Malformed payload");
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(5u, decoder_.ProcessInput(input, ABSL_ARRAYSIZE(input)));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
+  EXPECT_EQ("Frame is too large.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, Http2Frame) {
+  std::string input = absl::HexStringToBytes(
+      "06"    // PING in HTTP/2 but not supported in HTTP/3.
+      "05"    // length
+      "15");  // random payload
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(1u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_RECEIVE_SPDY_FRAME));
+  EXPECT_EQ("HTTP/2 frame received in a HTTP/3 connection: 6",
+            decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, HeadersPausedThenData) {
+  InSequence s;
+  std::string input =
+      absl::StrCat(absl::HexStringToBytes("01"    // type (HEADERS)
+                                          "07"),  // length
+                   "Headers",                     // headers
+                   absl::HexStringToBytes("00"    // type (DATA)
+                                          "05"),  // length
+                   "Data!");                      // data
+
+  // Visitor pauses processing, maybe because header decompression is blocked.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
+  absl::string_view remaining_input(input);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(9u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  // Process DATA frame.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+
+  processed_bytes = ProcessInput(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, CorruptFrame) {
+  InSequence s;
+
+  struct {
+    const char* const input;
+    const char* const error_message;
+  } kTestData[] = {{"\x0D"   // type (MAX_PUSH_ID)
+                    "\x01"   // length
+                    "\x40",  // first byte of two-byte varint push id
+                    "Unable to read MAX_PUSH_ID push_id."},
+                   {"\x0D"  // type (MAX_PUSH_ID)
+                    "\x04"  // length
+                    "\x05"  // valid push id
+                    "foo",  // superfluous data
+                    "Superfluous data in MAX_PUSH_ID frame."},
+                   {"\x07"   // type (GOAWAY)
+                    "\x01"   // length
+                    "\x40",  // first byte of two-byte varint stream id
+                    "Unable to read GOAWAY ID."},
+                   {"\x07"  // type (GOAWAY)
+                    "\x04"  // length
+                    "\x05"  // valid stream id
+                    "foo",  // superfluous data
+                    "Superfluous data in GOAWAY frame."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x01"      // length
+                    "\x40",     // first byte of two-byte varint origin length
+                    "Unable to read ACCEPT_CH origin."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x01"      // length
+                    "\x05",     // valid origin length but no origin string
+                    "Unable to read ACCEPT_CH origin."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x04"      // length
+                    "\x05"      // valid origin length
+                    "foo",      // payload ends before origin ends
+                    "Unable to read ACCEPT_CH origin."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x04"      // length
+                    "\x03"      // valid origin length
+                    "foo",      // payload ends at end of origin: no value
+                    "Unable to read ACCEPT_CH value."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x05"      // length
+                    "\x03"      // valid origin length
+                    "foo"       // payload ends at end of origin: no value
+                    "\x40",     // first byte of two-byte varint value length
+                    "Unable to read ACCEPT_CH value."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x08"      // length
+                    "\x03"      // valid origin length
+                    "foo"       // origin
+                    "\x05"      // valid value length
+                    "bar",      // payload ends before value ends
+                    "Unable to read ACCEPT_CH value."}};
+
+  for (const auto& test_data : kTestData) {
+    {
+      HttpDecoder decoder(&visitor_);
+      EXPECT_CALL(visitor_, OnAcceptChFrameStart(_)).Times(AnyNumber());
+      EXPECT_CALL(visitor_, OnError(&decoder));
+
+      absl::string_view input(test_data.input);
+      decoder.ProcessInput(input.data(), input.size());
+      EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+      EXPECT_EQ(test_data.error_message, decoder.error_detail());
+    }
+    {
+      HttpDecoder decoder(&visitor_);
+      EXPECT_CALL(visitor_, OnAcceptChFrameStart(_)).Times(AnyNumber());
+      EXPECT_CALL(visitor_, OnError(&decoder));
+
+      absl::string_view input(test_data.input);
+      for (auto c : input) {
+        decoder.ProcessInput(&c, 1);
+      }
+      EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+      EXPECT_EQ(test_data.error_message, decoder.error_detail());
+    }
+  }
+}
+
+TEST_F(HttpDecoderTest, EmptySettingsFrame) {
+  std::string input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "00");  // frame length
+
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
+
+  SettingsFrame empty_frame;
+  EXPECT_CALL(visitor_, OnSettingsFrame(empty_frame));
+
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, EmptyGoAwayFrame) {
+  std::string input = absl::HexStringToBytes(
+      "07"    // type (GOAWAY)
+      "00");  // frame length
+
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+  EXPECT_EQ("Unable to read GOAWAY ID.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, EmptyMaxPushIdFrame) {
+  std::string input = absl::HexStringToBytes(
+      "0d"    // type (MAX_PUSH_ID)
+      "00");  // frame length
+
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+  EXPECT_EQ("Unable to read MAX_PUSH_ID push_id.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, LargeStreamIdInGoAway) {
+  GoAwayFrame frame;
+  frame.id = 1ull << 60;
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeGoAwayFrame(frame, &buffer);
+  EXPECT_CALL(visitor_, OnGoAwayFrame(frame));
+  EXPECT_GT(length, 0u);
+  EXPECT_EQ(length, decoder_.ProcessInput(buffer.get(), length));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+// Old PRIORITY_UPDATE frame is parsed as unknown frame.
+TEST_F(HttpDecoderTest, ObsoletePriorityUpdateFrame) {
+  const QuicByteCount header_length = 2;
+  const QuicByteCount payload_length = 3;
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "0f"        // type (obsolete PRIORITY_UPDATE)
+      "03"        // length
+      "666f6f");  // payload "foo"
+
+  // Process frame as a whole.
+  EXPECT_CALL(visitor_,
+              OnUnknownFrameStart(0x0f, header_length, payload_length));
+  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("foo")));
+  EXPECT_CALL(visitor_, OnUnknownFrameEnd()).WillOnce(Return(false));
+
+  EXPECT_EQ(header_length + payload_length,
+            ProcessInputWithGarbageAppended(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process frame byte by byte.
+  EXPECT_CALL(visitor_,
+              OnUnknownFrameStart(0x0f, header_length, payload_length));
+  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("f")));
+  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("o")));
+  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("o")));
+  EXPECT_CALL(visitor_, OnUnknownFrameEnd());
+
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, PriorityUpdateFrame) {
+  InSequence s;
+  std::string input1 = absl::HexStringToBytes(
+      "800f0700"  // type (PRIORITY_UPDATE)
+      "01"        // length
+      "03");      // prioritized element id
+
+  PriorityUpdateFrame priority_update1;
+  priority_update1.prioritized_element_type = REQUEST_STREAM;
+  priority_update1.prioritized_element_id = 0x03;
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false));
+  absl::string_view remaining_input(input1);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(5u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1))
+      .WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1));
+  EXPECT_EQ(input1.size(), ProcessInput(input1));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1));
+  ProcessInputCharByChar(input1);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  std::string input2 = absl::HexStringToBytes(
+      "800f0700"  // type (PRIORITY_UPDATE)
+      "04"        // length
+      "05"        // prioritized element id
+      "666f6f");  // priority field value: "foo"
+
+  PriorityUpdateFrame priority_update2;
+  priority_update2.prioritized_element_type = REQUEST_STREAM;
+  priority_update2.prioritized_element_id = 0x05;
+  priority_update2.priority_field_value = "foo";
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false));
+  remaining_input = input2;
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(5u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2))
+      .WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2));
+  EXPECT_EQ(input2.size(), ProcessInput(input2));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2));
+  ProcessInputCharByChar(input2);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, CorruptPriorityUpdateFrame) {
+  std::string payload =
+      absl::HexStringToBytes("4005");  // prioritized element id
+  struct {
+    size_t payload_length;
+    const char* const error_message;
+  } kTestData[] = {
+      {0, "Unable to read prioritized element id."},
+      {1, "Unable to read prioritized element id."},
+  };
+
+  for (const auto& test_data : kTestData) {
+    std::string input =
+        absl::HexStringToBytes("800f0700");  // type PRIORITY_UPDATE
+    input.push_back(test_data.payload_length);
+    size_t header_length = input.size();
+    input.append(payload.data(), test_data.payload_length);
+
+    HttpDecoder decoder(&visitor_);
+    EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(header_length));
+    EXPECT_CALL(visitor_, OnError(&decoder));
+
+    QuicByteCount processed_bytes =
+        decoder.ProcessInput(input.data(), input.size());
+    EXPECT_EQ(input.size(), processed_bytes);
+    EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+    EXPECT_EQ(test_data.error_message, decoder.error_detail());
+  }
+}
+
+TEST_F(HttpDecoderTest, AcceptChFrame) {
+  InSequence s;
+  std::string input1 = absl::HexStringToBytes(
+      "4089"  // type (ACCEPT_CH)
+      "00");  // length
+
+  AcceptChFrame accept_ch1;
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3)).WillOnce(Return(false));
+  absl::string_view remaining_input(input1);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(3u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1)).WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1));
+  EXPECT_EQ(input1.size(), ProcessInput(input1));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1));
+  ProcessInputCharByChar(input1);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  std::string input2 = absl::HexStringToBytes(
+      "4089"      // type (ACCEPT_CH)
+      "08"        // length
+      "03"        // length of origin
+      "666f6f"    // origin "foo"
+      "03"        // length of value
+      "626172");  // value "bar"
+
+  AcceptChFrame accept_ch2;
+  accept_ch2.entries.push_back({"foo", "bar"});
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3)).WillOnce(Return(false));
+  remaining_input = input2;
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(3u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2)).WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2));
+  EXPECT_EQ(input2.size(), ProcessInput(input2));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2));
+  ProcessInputCharByChar(input2);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, WebTransportStreamDisabled) {
+  InSequence s;
+
+  // Unknown frame of type 0x41 and length 0x104.
+  std::string input = absl::HexStringToBytes("40414104");
+  EXPECT_CALL(visitor_, OnUnknownFrameStart(0x41, input.size(), 0x104));
+  EXPECT_EQ(ProcessInput(input), input.size());
+}
+
+TEST(HttpDecoderTestNoFixture, WebTransportStream) {
+  HttpDecoder::Options options;
+  options.allow_web_transport_stream = true;
+  testing::StrictMock<MockHttpDecoderVisitor> visitor;
+  HttpDecoder decoder(&visitor, options);
+
+  // WebTransport stream for session ID 0x104, with four bytes of extra data.
+  std::string input = absl::HexStringToBytes("40414104ffffffff");
+  EXPECT_CALL(visitor, OnWebTransportStreamFrameType(4, 0x104));
+  QuicByteCount bytes = decoder.ProcessInput(input.data(), input.size());
+  EXPECT_EQ(bytes, 4u);
+}
+
+TEST(HttpDecoderTestNoFixture, WebTransportStreamError) {
+  HttpDecoder::Options options;
+  options.allow_web_transport_stream = true;
+  testing::StrictMock<MockHttpDecoderVisitor> visitor;
+  HttpDecoder decoder(&visitor, options);
+
+  std::string input = absl::HexStringToBytes("404100");
+  EXPECT_CALL(visitor, OnWebTransportStreamFrameType(_, _));
+  decoder.ProcessInput(input.data(), input.size());
+
+  EXPECT_CALL(visitor, OnError(_));
+  EXPECT_QUIC_BUG(decoder.ProcessInput(input.data(), input.size()),
+                  "HttpDecoder called after an indefinite-length frame");
+}
+
+TEST_F(HttpDecoderTest, DecodeSettings) {
+  std::string input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "07"    // length
+      "01"    // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
+      "02"    // content
+      "06"    // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
+      "05"    // content
+      "4100"  // identifier, encoded on 2 bytes (0x40), value is 256 (0x100)
+      "04");  // content
+
+  SettingsFrame frame;
+  frame.values[1] = 2;
+  frame.values[6] = 5;
+  frame.values[256] = 4;
+
+  SettingsFrame out;
+  EXPECT_TRUE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
+  EXPECT_EQ(frame, out);
+
+  // non-settings frame.
+  input = absl::HexStringToBytes(
+      "0D"    // type (MAX_PUSH_ID)
+      "01"    // length
+      "01");  // Push Id
+
+  EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
+
+  // Corrupt SETTINGS.
+  input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "01"    // length
+      "42");  // First byte of setting identifier, indicating a 2-byte varint62.
+
+  EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_encoder.cc b/quiche/quic/core/http/http_encoder.cc
new file mode 100644
index 0000000..fa9c154
--- /dev/null
+++ b/quiche/quic/core/http/http_encoder.cc
@@ -0,0 +1,278 @@
+// Copyright (c) 2018 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 "quiche/quic/core/http/http_encoder.h"
+#include <cstdint>
+#include <memory>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+bool WriteFrameHeader(QuicByteCount length,
+                      HttpFrameType type,
+                      QuicDataWriter* writer) {
+  return writer->WriteVarInt62(static_cast<uint64_t>(type)) &&
+         writer->WriteVarInt62(length);
+}
+
+QuicByteCount GetTotalLength(QuicByteCount payload_length, HttpFrameType type) {
+  return QuicDataWriter::GetVarInt62Len(payload_length) +
+         QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(type)) +
+         payload_length;
+}
+
+}  // namespace
+
+// static
+QuicByteCount HttpEncoder::GetDataFrameHeaderLength(
+    QuicByteCount payload_length) {
+  QUICHE_DCHECK_NE(0u, payload_length);
+  return QuicDataWriter::GetVarInt62Len(payload_length) +
+         QuicDataWriter::GetVarInt62Len(
+             static_cast<uint64_t>(HttpFrameType::DATA));
+}
+
+// static
+quiche::QuicheBuffer HttpEncoder::SerializeDataFrameHeader(
+    QuicByteCount payload_length, quiche::QuicheBufferAllocator* allocator) {
+  QUICHE_DCHECK_NE(0u, payload_length);
+  QuicByteCount header_length = GetDataFrameHeaderLength(payload_length);
+
+  quiche::QuicheBuffer header(allocator, header_length);
+  QuicDataWriter writer(header.size(), header.data());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::DATA, &writer)) {
+    return header;
+  }
+  QUIC_DLOG(ERROR)
+      << "Http encoder failed when attempting to serialize data frame header.";
+  return quiche::QuicheBuffer();
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeHeadersFrameHeader(
+    QuicByteCount payload_length,
+    std::unique_ptr<char[]>* output) {
+  QUICHE_DCHECK_NE(0u, payload_length);
+  QuicByteCount header_length =
+      QuicDataWriter::GetVarInt62Len(payload_length) +
+      QuicDataWriter::GetVarInt62Len(
+          static_cast<uint64_t>(HttpFrameType::HEADERS));
+
+  output->reset(new char[header_length]);
+  QuicDataWriter writer(header_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::HEADERS, &writer)) {
+    return header_length;
+  }
+  QUIC_DLOG(ERROR)
+      << "Http encoder failed when attempting to serialize headers "
+         "frame header.";
+  return 0;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeSettingsFrame(
+    const SettingsFrame& settings,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length = 0;
+  std::vector<std::pair<uint64_t, uint64_t>> ordered_settings{
+      settings.values.begin(), settings.values.end()};
+  std::sort(ordered_settings.begin(), ordered_settings.end());
+  // Calculate the payload length.
+  for (const auto& p : ordered_settings) {
+    payload_length += QuicDataWriter::GetVarInt62Len(p.first);
+    payload_length += QuicDataWriter::GetVarInt62Len(p.second);
+  }
+
+  QuicByteCount total_length =
+      GetTotalLength(payload_length, HttpFrameType::SETTINGS);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (!WriteFrameHeader(payload_length, HttpFrameType::SETTINGS, &writer)) {
+    QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                        "settings frame header.";
+    return 0;
+  }
+
+  for (const auto& p : ordered_settings) {
+    if (!writer.WriteVarInt62(p.first) || !writer.WriteVarInt62(p.second)) {
+      QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                          "settings frame payload.";
+      return 0;
+    }
+  }
+
+  return total_length;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeGoAwayFrame(
+    const GoAwayFrame& goaway,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length = QuicDataWriter::GetVarInt62Len(goaway.id);
+  QuicByteCount total_length =
+      GetTotalLength(payload_length, HttpFrameType::GOAWAY);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::GOAWAY, &writer) &&
+      writer.WriteVarInt62(goaway.id)) {
+    return total_length;
+  }
+  QUIC_DLOG(ERROR)
+      << "Http encoder failed when attempting to serialize goaway frame.";
+  return 0;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializePriorityUpdateFrame(
+    const PriorityUpdateFrame& priority_update,
+    std::unique_ptr<char[]>* output) {
+  if (priority_update.prioritized_element_type != REQUEST_STREAM) {
+    QUIC_BUG(quic_bug_10402_1)
+        << "PRIORITY_UPDATE for push streams not implemented";
+    return 0;
+  }
+
+  QuicByteCount payload_length =
+      QuicDataWriter::GetVarInt62Len(priority_update.prioritized_element_id) +
+      priority_update.priority_field_value.size();
+  QuicByteCount total_length = GetTotalLength(
+      payload_length, HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (WriteFrameHeader(payload_length,
+                       HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM,
+                       &writer) &&
+      writer.WriteVarInt62(priority_update.prioritized_element_id) &&
+      writer.WriteBytes(priority_update.priority_field_value.data(),
+                        priority_update.priority_field_value.size())) {
+    return total_length;
+  }
+
+  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                      "PRIORITY_UPDATE frame.";
+  return 0;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeAcceptChFrame(
+    const AcceptChFrame& accept_ch,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length = 0;
+  for (const auto& entry : accept_ch.entries) {
+    payload_length += QuicDataWriter::GetVarInt62Len(entry.origin.size());
+    payload_length += entry.origin.size();
+    payload_length += QuicDataWriter::GetVarInt62Len(entry.value.size());
+    payload_length += entry.value.size();
+  }
+
+  QuicByteCount total_length =
+      GetTotalLength(payload_length, HttpFrameType::ACCEPT_CH);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (!WriteFrameHeader(payload_length, HttpFrameType::ACCEPT_CH, &writer)) {
+    QUIC_DLOG(ERROR)
+        << "Http encoder failed to serialize ACCEPT_CH frame header.";
+    return 0;
+  }
+
+  for (const auto& entry : accept_ch.entries) {
+    if (!writer.WriteStringPieceVarInt62(entry.origin) ||
+        !writer.WriteStringPieceVarInt62(entry.value)) {
+      QUIC_DLOG(ERROR)
+          << "Http encoder failed to serialize ACCEPT_CH frame payload.";
+      return 0;
+    }
+  }
+
+  return total_length;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeGreasingFrame(
+    std::unique_ptr<char[]>* output) {
+  uint64_t frame_type;
+  QuicByteCount payload_length;
+  std::string payload;
+  if (!GetQuicFlag(FLAGS_quic_enable_http3_grease_randomness)) {
+    frame_type = 0x40;
+    payload_length = 1;
+    payload = "a";
+  } else {
+    uint32_t result;
+    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
+    frame_type = 0x1fULL * static_cast<uint64_t>(result) + 0x21ULL;
+
+    // The payload length is random but within [0, 3];
+    payload_length = result % 4;
+
+    if (payload_length > 0) {
+      std::unique_ptr<char[]> buffer(new char[payload_length]);
+      QuicRandom::GetInstance()->RandBytes(buffer.get(), payload_length);
+      payload = std::string(buffer.get(), payload_length);
+    }
+  }
+  QuicByteCount total_length = QuicDataWriter::GetVarInt62Len(frame_type) +
+                               QuicDataWriter::GetVarInt62Len(payload_length) +
+                               payload_length;
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  bool success =
+      writer.WriteVarInt62(frame_type) && writer.WriteVarInt62(payload_length);
+
+  if (payload_length > 0) {
+    success &= writer.WriteBytes(payload.data(), payload_length);
+  }
+
+  if (success) {
+    return total_length;
+  }
+
+  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                      "greasing frame.";
+  return 0;
+}
+
+QuicByteCount HttpEncoder::SerializeWebTransportStreamFrameHeader(
+    WebTransportSessionId session_id,
+    std::unique_ptr<char[]>* output) {
+  uint64_t stream_type =
+      static_cast<uint64_t>(HttpFrameType::WEBTRANSPORT_STREAM);
+  QuicByteCount header_length = QuicDataWriter::GetVarInt62Len(stream_type) +
+                                QuicDataWriter::GetVarInt62Len(session_id);
+
+  *output = std::make_unique<char[]>(header_length);
+  QuicDataWriter writer(header_length, output->get());
+  bool success =
+      writer.WriteVarInt62(stream_type) && writer.WriteVarInt62(session_id);
+  if (success && writer.remaining() == 0) {
+    return header_length;
+  }
+
+  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                      "WEBTRANSPORT_STREAM frame header.";
+  return 0;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_encoder.h b/quiche/quic/core/http/http_encoder.h
new file mode 100644
index 0000000..eba0e55
--- /dev/null
+++ b/quiche/quic/core/http/http_encoder.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2018 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_HTTP_HTTP_ENCODER_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
+
+#include <memory>
+
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quic {
+
+class QuicDataWriter;
+
+// A class for encoding the HTTP frames that are exchanged in an HTTP over QUIC
+// session.
+class QUIC_EXPORT_PRIVATE HttpEncoder {
+ public:
+  HttpEncoder() = delete;
+
+  // Returns the length of the header for a DATA frame.
+  static QuicByteCount GetDataFrameHeaderLength(QuicByteCount payload_length);
+
+  // Serializes a DATA frame header into a QuicheBuffer; returns said
+  // QuicheBuffer on success, empty buffer otherwise.
+  static quiche::QuicheBuffer SerializeDataFrameHeader(
+      QuicByteCount payload_length, quiche::QuicheBufferAllocator* allocator);
+
+  // Serializes a HEADERS frame header into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializeHeadersFrameHeader(
+      QuicByteCount payload_length,
+      std::unique_ptr<char[]>* output);
+
+  // Serializes a SETTINGS frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializeSettingsFrame(const SettingsFrame& settings,
+                                              std::unique_ptr<char[]>* output);
+
+  // Serializes a GOAWAY frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializeGoAwayFrame(const GoAwayFrame& goaway,
+                                            std::unique_ptr<char[]>* output);
+
+  // Serializes a PRIORITY_UPDATE frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializePriorityUpdateFrame(
+      const PriorityUpdateFrame& priority_update,
+      std::unique_ptr<char[]>* output);
+
+  // Serializes an ACCEPT_CH frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializeAcceptChFrame(const AcceptChFrame& accept_ch,
+                                              std::unique_ptr<char[]>* output);
+
+  // Serializes a frame with reserved frame type specified in
+  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.9.
+  static QuicByteCount SerializeGreasingFrame(std::unique_ptr<char[]>* output);
+
+  // Serializes a WEBTRANSPORT_STREAM frame header as specified in
+  // https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html#name-client-initiated-bidirectio
+  static QuicByteCount SerializeWebTransportStreamFrameHeader(
+      WebTransportSessionId session_id,
+      std::unique_ptr<char[]>* output);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
diff --git a/quiche/quic/core/http/http_encoder_test.cc b/quiche/quic/core/http/http_encoder_test.cc
new file mode 100644
index 0000000..217d98a
--- /dev/null
+++ b/quiche/quic/core/http/http_encoder_test.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2018 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 "quiche/quic/core/http/http_encoder.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/simple_buffer_allocator.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+
+TEST(HttpEncoderTest, SerializeDataFrameHeader) {
+  quiche::QuicheBuffer buffer = HttpEncoder::SerializeDataFrameHeader(
+      /* payload_length = */ 5, quiche::SimpleBufferAllocator::Get());
+  char output[] = {// type (DATA)
+                   0x00,
+                   // length
+                   0x05};
+  EXPECT_EQ(ABSL_ARRAYSIZE(output), buffer.size());
+  quiche::test::CompareCharArraysWithHexError(
+      "DATA", buffer.data(), buffer.size(), output, ABSL_ARRAYSIZE(output));
+}
+
+TEST(HttpEncoderTest, SerializeHeadersFrameHeader) {
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeHeadersFrameHeader(
+      /* payload_length = */ 7, &buffer);
+  char output[] = {// type (HEADERS)
+                   0x01,
+                   // length
+                   0x07};
+  EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
+  quiche::test::CompareCharArraysWithHexError("HEADERS", buffer.get(), length,
+                                              output, ABSL_ARRAYSIZE(output));
+}
+
+TEST(HttpEncoderTest, SerializeSettingsFrame) {
+  SettingsFrame settings;
+  settings.values[1] = 2;
+  settings.values[6] = 5;
+  settings.values[256] = 4;
+  char output[] = {// type (SETTINGS)
+                   0x04,
+                   // length
+                   0x07,
+                   // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
+                   0x01,
+                   // content
+                   0x02,
+                   // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
+                   0x06,
+                   // content
+                   0x05,
+                   // identifier (256 in variable length integer)
+                   0x40 + 0x01, 0x00,
+                   // content
+                   0x04};
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeSettingsFrame(settings, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
+  quiche::test::CompareCharArraysWithHexError("SETTINGS", buffer.get(), length,
+                                              output, ABSL_ARRAYSIZE(output));
+}
+
+TEST(HttpEncoderTest, SerializeGoAwayFrame) {
+  GoAwayFrame goaway;
+  goaway.id = 0x1;
+  char output[] = {// type (GOAWAY)
+                   0x07,
+                   // length
+                   0x1,
+                   // ID
+                   0x01};
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
+  quiche::test::CompareCharArraysWithHexError("GOAWAY", buffer.get(), length,
+                                              output, ABSL_ARRAYSIZE(output));
+}
+
+TEST(HttpEncoderTest, SerializePriorityUpdateFrame) {
+  PriorityUpdateFrame priority_update1;
+  priority_update1.prioritized_element_type = REQUEST_STREAM;
+  priority_update1.prioritized_element_id = 0x03;
+  uint8_t output1[] = {0x80, 0x0f, 0x07, 0x00,  // type (PRIORITY_UPDATE)
+                       0x01,                    // length
+                       0x03};                   // prioritized element id
+
+  std::unique_ptr<char[]> buffer;
+  uint64_t length =
+      HttpEncoder::SerializePriorityUpdateFrame(priority_update1, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output1), length);
+  quiche::test::CompareCharArraysWithHexError(
+      "PRIORITY_UPDATE", buffer.get(), length, reinterpret_cast<char*>(output1),
+      ABSL_ARRAYSIZE(output1));
+}
+
+TEST(HttpEncoderTest, SerializeAcceptChFrame) {
+  AcceptChFrame accept_ch;
+  uint8_t output1[] = {0x40, 0x89,  // type (ACCEPT_CH)
+                       0x00};       // length
+
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output1), length);
+  quiche::test::CompareCharArraysWithHexError("ACCEPT_CH", buffer.get(), length,
+                                              reinterpret_cast<char*>(output1),
+                                              ABSL_ARRAYSIZE(output1));
+
+  accept_ch.entries.push_back({"foo", "bar"});
+  uint8_t output2[] = {0x40, 0x89,               // type (ACCEPT_CH)
+                       0x08,                     // payload length
+                       0x03, 0x66, 0x6f, 0x6f,   // length of "foo"; "foo"
+                       0x03, 0x62, 0x61, 0x72};  // length of "bar"; "bar"
+
+  length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output2), length);
+  quiche::test::CompareCharArraysWithHexError("ACCEPT_CH", buffer.get(), length,
+                                              reinterpret_cast<char*>(output2),
+                                              ABSL_ARRAYSIZE(output2));
+}
+
+TEST(HttpEncoderTest, SerializeWebTransportStreamFrameHeader) {
+  WebTransportSessionId session_id = 0x17;
+  char output[] = {0x40, 0x41,  // type (WEBTRANSPORT_STREAM)
+                   0x17};       // session ID
+
+  std::unique_ptr<char[]> buffer;
+  uint64_t length =
+      HttpEncoder::SerializeWebTransportStreamFrameHeader(session_id, &buffer);
+  EXPECT_EQ(sizeof(output), length);
+  quiche::test::CompareCharArraysWithHexError(
+      "WEBTRANSPORT_STREAM", buffer.get(), length, output, sizeof(output));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_frames.h b/quiche/quic/core/http/http_frames.h
new file mode 100644
index 0000000..c452a7d
--- /dev/null
+++ b/quiche/quic/core/http/http_frames.h
@@ -0,0 +1,187 @@
+// Copyright (c) 2018 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_HTTP_HTTP_FRAMES_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
+
+#include <algorithm>
+#include <cstdint>
+#include <map>
+#include <ostream>
+#include <sstream>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace quic {
+
+// TODO(b/171463363): Remove.
+using PushId = uint64_t;
+
+enum class HttpFrameType {
+  DATA = 0x0,
+  HEADERS = 0x1,
+  CANCEL_PUSH = 0X3,
+  SETTINGS = 0x4,
+  PUSH_PROMISE = 0x5,
+  GOAWAY = 0x7,
+  MAX_PUSH_ID = 0xD,
+  // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
+  ACCEPT_CH = 0x89,
+  // https://tools.ietf.org/html/draft-ietf-httpbis-priority-03
+  PRIORITY_UPDATE_REQUEST_STREAM = 0xF0700,
+  // https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html
+  WEBTRANSPORT_STREAM = 0x41,
+};
+
+// 7.2.1.  DATA
+//
+//   DATA frames (type=0x0) convey arbitrary, variable-length sequences of
+//   octets associated with an HTTP request or response payload.
+struct QUIC_EXPORT_PRIVATE DataFrame {
+  absl::string_view data;
+};
+
+// 7.2.2.  HEADERS
+//
+//   The HEADERS frame (type=0x1) is used to carry a header block,
+//   compressed using QPACK.
+struct QUIC_EXPORT_PRIVATE HeadersFrame {
+  absl::string_view headers;
+};
+
+// 7.2.4.  SETTINGS
+//
+//   The SETTINGS frame (type=0x4) conveys configuration parameters that
+//   affect how endpoints communicate, such as preferences and constraints
+//   on peer behavior
+
+using SettingsMap = absl::flat_hash_map<uint64_t, uint64_t>;
+
+struct QUIC_EXPORT_PRIVATE SettingsFrame {
+  SettingsMap values;
+
+  bool operator==(const SettingsFrame& rhs) const {
+    return values == rhs.values;
+  }
+
+  std::string ToString() const {
+    std::string s;
+    for (auto it : values) {
+      std::string setting = absl::StrCat(
+          H3SettingsToString(
+              static_cast<Http3AndQpackSettingsIdentifiers>(it.first)),
+          " = ", it.second, "; ");
+      absl::StrAppend(&s, setting);
+    }
+    return s;
+  }
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const SettingsFrame& s) {
+    os << s.ToString();
+    return os;
+  }
+};
+
+// 7.2.6.  GOAWAY
+//
+//   The GOAWAY frame (type=0x7) is used to initiate shutdown of a connection by
+//   either endpoint.
+struct QUIC_EXPORT_PRIVATE GoAwayFrame {
+  // When sent from server to client, |id| is a stream ID that should refer to
+  // a client-initiated bidirectional stream.
+  // When sent from client to server, |id| is a push ID.
+  uint64_t id;
+
+  bool operator==(const GoAwayFrame& rhs) const { return id == rhs.id; }
+};
+
+// 7.2.7.  MAX_PUSH_ID
+//
+//   The MAX_PUSH_ID frame (type=0xD) is used by clients to control the
+//   number of server pushes that the server can initiate.
+struct QUIC_EXPORT_PRIVATE MaxPushIdFrame {
+  PushId push_id;
+
+  bool operator==(const MaxPushIdFrame& rhs) const {
+    return push_id == rhs.push_id;
+  }
+};
+
+// https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html
+//
+// The PRIORITY_UPDATE frame specifies the sender-advised priority of a stream.
+// Frame type 0xf0700 (called PRIORITY_UPDATE_REQUEST_STREAM in the
+// implementation) is used for for request streams.
+// Frame type 0xf0701 is used for push streams and is not implemented.
+
+// Length of a priority frame's first byte.
+const QuicByteCount kPriorityFirstByteLength = 1;
+
+enum PrioritizedElementType : uint8_t {
+  REQUEST_STREAM = 0x00,
+  PUSH_STREAM = 0x80,
+};
+
+struct QUIC_EXPORT_PRIVATE PriorityUpdateFrame {
+  PrioritizedElementType prioritized_element_type = REQUEST_STREAM;
+  uint64_t prioritized_element_id = 0;
+  std::string priority_field_value;
+
+  bool operator==(const PriorityUpdateFrame& rhs) const {
+    return std::tie(prioritized_element_type, prioritized_element_id,
+                    priority_field_value) ==
+           std::tie(rhs.prioritized_element_type, rhs.prioritized_element_id,
+                    rhs.priority_field_value);
+  }
+  std::string ToString() const {
+    return absl::StrCat("Priority Frame : {prioritized_element_type: ",
+                        static_cast<int>(prioritized_element_type),
+                        ", prioritized_element_id: ", prioritized_element_id,
+                        ", priority_field_value: ", priority_field_value, "}");
+  }
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const PriorityUpdateFrame& s) {
+    os << s.ToString();
+    return os;
+  }
+};
+
+// ACCEPT_CH
+// https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
+//
+struct QUIC_EXPORT_PRIVATE AcceptChFrame {
+  std::vector<spdy::AcceptChOriginValuePair> entries;
+
+  bool operator==(const AcceptChFrame& rhs) const {
+    return entries.size() == rhs.entries.size() &&
+           std::equal(entries.begin(), entries.end(), rhs.entries.begin());
+  }
+
+  std::string ToString() const {
+    std::stringstream s;
+    s << *this;
+    return s.str();
+  }
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const AcceptChFrame& frame) {
+    os << "ACCEPT_CH frame with " << frame.entries.size() << " entries: ";
+    for (auto& entry : frame.entries) {
+      os << "origin: " << entry.origin << "; value: " << entry.value;
+    }
+    return os;
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
diff --git a/quiche/quic/core/http/http_frames_test.cc b/quiche/quic/core/http/http_frames_test.cc
new file mode 100644
index 0000000..1eefd7e
--- /dev/null
+++ b/quiche/quic/core/http/http_frames_test.cc
@@ -0,0 +1,105 @@
+// Copyright (c) 2020 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 "quiche/quic/core/http/http_frames.h"
+
+#include <sstream>
+
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+TEST(HttpFramesTest, SettingsFrame) {
+  SettingsFrame a;
+  EXPECT_TRUE(a == a);
+  EXPECT_EQ("", a.ToString());
+
+  SettingsFrame b;
+  b.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+  EXPECT_FALSE(a == b);
+  EXPECT_TRUE(b == b);
+
+  a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+  EXPECT_FALSE(a == b);
+  a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+  EXPECT_TRUE(a == b);
+
+  EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", b.ToString());
+  std::stringstream s;
+  s << b;
+  EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", s.str());
+}
+
+TEST(HttpFramesTest, GoAwayFrame) {
+  GoAwayFrame a{1};
+  EXPECT_TRUE(a == a);
+
+  GoAwayFrame b{2};
+  EXPECT_FALSE(a == b);
+
+  b.id = 1;
+  EXPECT_TRUE(a == b);
+}
+
+TEST(HttpFramesTest, MaxPushIdFrame) {
+  MaxPushIdFrame a{1};
+  EXPECT_TRUE(a == a);
+
+  MaxPushIdFrame b{2};
+  EXPECT_FALSE(a == b);
+
+  b.push_id = 1;
+  EXPECT_TRUE(a == b);
+}
+
+TEST(HttpFramesTest, PriorityUpdateFrame) {
+  PriorityUpdateFrame a{REQUEST_STREAM, 0, ""};
+  EXPECT_TRUE(a == a);
+  PriorityUpdateFrame b{REQUEST_STREAM, 4, ""};
+  EXPECT_FALSE(a == b);
+  a.prioritized_element_id = 4;
+  EXPECT_TRUE(a == b);
+
+  a.prioritized_element_type = PUSH_STREAM;
+  EXPECT_FALSE(a == b);
+  b.prioritized_element_type = PUSH_STREAM;
+  EXPECT_TRUE(a == b);
+
+  a.priority_field_value = "foo";
+  EXPECT_FALSE(a == b);
+
+  EXPECT_EQ(
+      "Priority Frame : {prioritized_element_type: 128, "
+      "prioritized_element_id: 4, priority_field_value: foo}",
+      a.ToString());
+  std::stringstream s;
+  s << a;
+  EXPECT_EQ(
+      "Priority Frame : {prioritized_element_type: 128, "
+      "prioritized_element_id: 4, priority_field_value: foo}",
+      s.str());
+}
+
+TEST(HttpFramesTest, AcceptChFrame) {
+  AcceptChFrame a;
+  EXPECT_TRUE(a == a);
+  EXPECT_EQ("ACCEPT_CH frame with 0 entries: ", a.ToString());
+
+  AcceptChFrame b{{{"foo", "bar"}}};
+  EXPECT_FALSE(a == b);
+
+  a.entries.push_back({"foo", "bar"});
+  EXPECT_TRUE(a == b);
+
+  EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar",
+            a.ToString());
+  std::stringstream s;
+  s << a;
+  EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar", s.str());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_client_promised_info.cc b/quiche/quic/core/http/quic_client_promised_info.cc
new file mode 100644
index 0000000..18bb5dd
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_promised_info.cc
@@ -0,0 +1,147 @@
+// Copyright (c) 2016 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 "quiche/quic/core/http/quic_client_promised_info.h"
+
+#include <string>
+#include <utility>
+
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicClientPromisedInfo::QuicClientPromisedInfo(
+    QuicSpdyClientSessionBase* session,
+    QuicStreamId id,
+    std::string url)
+    : session_(session),
+      id_(id),
+      url_(std::move(url)),
+      client_request_delegate_(nullptr) {}
+
+QuicClientPromisedInfo::~QuicClientPromisedInfo() {
+  if (cleanup_alarm_ != nullptr) {
+    cleanup_alarm_->PermanentCancel();
+  }
+}
+
+void QuicClientPromisedInfo::CleanupAlarm::OnAlarm() {
+  QUIC_DVLOG(1) << "self GC alarm for stream " << promised_->id_;
+  promised_->session()->OnPushStreamTimedOut(promised_->id_);
+  promised_->Reset(QUIC_PUSH_STREAM_TIMED_OUT);
+}
+
+void QuicClientPromisedInfo::Init() {
+  cleanup_alarm_.reset(session_->connection()->alarm_factory()->CreateAlarm(
+      new QuicClientPromisedInfo::CleanupAlarm(this)));
+  cleanup_alarm_->Set(
+      session_->connection()->helper()->GetClock()->ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kPushPromiseTimeoutSecs));
+}
+
+bool QuicClientPromisedInfo::OnPromiseHeaders(const SpdyHeaderBlock& headers) {
+  // RFC7540, Section 8.2, requests MUST be safe [RFC7231], Section
+  // 4.2.1.  GET and HEAD are the methods that are safe and required.
+  SpdyHeaderBlock::const_iterator it = headers.find(spdy::kHttp2MethodHeader);
+  if (it == headers.end()) {
+    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has no method";
+    Reset(QUIC_INVALID_PROMISE_METHOD);
+    return false;
+  }
+  if (!(it->second == "GET" || it->second == "HEAD")) {
+    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid method "
+                  << it->second;
+    Reset(QUIC_INVALID_PROMISE_METHOD);
+    return false;
+  }
+  if (!SpdyServerPushUtils::PromisedUrlIsValid(headers)) {
+    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid URL "
+                  << url_;
+    Reset(QUIC_INVALID_PROMISE_URL);
+    return false;
+  }
+  if (!session_->IsAuthorized(
+          SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers))) {
+    Reset(QUIC_UNAUTHORIZED_PROMISE_URL);
+    return false;
+  }
+  request_headers_ = headers.Clone();
+  return true;
+}
+
+void QuicClientPromisedInfo::OnResponseHeaders(const SpdyHeaderBlock& headers) {
+  response_headers_ = std::make_unique<SpdyHeaderBlock>(headers.Clone());
+  if (client_request_delegate_) {
+    // We already have a client request waiting.
+    FinalValidation();
+  }
+}
+
+void QuicClientPromisedInfo::Reset(QuicRstStreamErrorCode error_code) {
+  QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
+  session_->ResetPromised(id_, error_code);
+  session_->DeletePromised(this);
+  if (delegate) {
+    delegate->OnRendezvousResult(nullptr);
+  }
+}
+
+QuicAsyncStatus QuicClientPromisedInfo::FinalValidation() {
+  if (!client_request_delegate_->CheckVary(
+          client_request_headers_, request_headers_, *response_headers_)) {
+    Reset(QUIC_PROMISE_VARY_MISMATCH);
+    return QUIC_FAILURE;
+  }
+  QuicSpdyStream* stream = session_->GetPromisedStream(id_);
+  if (!stream) {
+    // This shouldn't be possible, as |ClientRequest| guards against
+    // closed stream for the synchronous case.  And in the
+    // asynchronous case, a RST can only be caught by |OnAlarm()|.
+    QUIC_BUG(quic_bug_10378_1) << "missing promised stream" << id_;
+  }
+  QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
+  session_->DeletePromised(this);
+  // Stream can start draining now
+  if (delegate) {
+    delegate->OnRendezvousResult(stream);
+  }
+  return QUIC_SUCCESS;
+}
+
+QuicAsyncStatus QuicClientPromisedInfo::HandleClientRequest(
+    const SpdyHeaderBlock& request_headers,
+    QuicClientPushPromiseIndex::Delegate* delegate) {
+  if (session_->IsClosedStream(id_)) {
+    // There was a RST on the response stream.
+    session_->DeletePromised(this);
+    return QUIC_FAILURE;
+  }
+
+  if (is_validating()) {
+    // The push promise has already been matched to another request though
+    // pending for validation. Returns QUIC_FAILURE to the caller as it couldn't
+    // match a new request any more. This will not affect the validation of the
+    // other request.
+    return QUIC_FAILURE;
+  }
+
+  client_request_delegate_ = delegate;
+  client_request_headers_ = request_headers.Clone();
+  if (response_headers_ == nullptr) {
+    return QUIC_PENDING;
+  }
+  return FinalValidation();
+}
+
+void QuicClientPromisedInfo::Cancel() {
+  // Don't fire OnRendezvousResult() for client initiated cancel.
+  client_request_delegate_ = nullptr;
+  Reset(QUIC_STREAM_CANCELLED);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_client_promised_info.h b/quiche/quic/core/http/quic_client_promised_info.h
new file mode 100644
index 0000000..77d32af
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_promised_info.h
@@ -0,0 +1,115 @@
+// Copyright (c) 2016 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_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
+
+#include <cstddef>
+#include <string>
+
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+#include "quiche/quic/core/http/quic_spdy_client_session_base.h"
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+namespace test {
+class QuicClientPromisedInfoPeer;
+}  // namespace test
+
+// QuicClientPromisedInfo tracks the client state of a server push
+// stream from the time a PUSH_PROMISE is received until rendezvous
+// between the promised response and the corresponding client request
+// is complete.
+class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo
+    : public QuicClientPushPromiseIndex::TryHandle {
+ public:
+  // Interface to QuicSpdyClientStream
+  QuicClientPromisedInfo(QuicSpdyClientSessionBase* session,
+                         QuicStreamId id,
+                         std::string url);
+  QuicClientPromisedInfo(const QuicClientPromisedInfo&) = delete;
+  QuicClientPromisedInfo& operator=(const QuicClientPromisedInfo&) = delete;
+  virtual ~QuicClientPromisedInfo();
+
+  void Init();
+
+  // Validate promise headers etc. Returns true if headers are valid.
+  bool OnPromiseHeaders(const spdy::SpdyHeaderBlock& headers);
+
+  // Store response, possibly proceed with final validation.
+  void OnResponseHeaders(const spdy::SpdyHeaderBlock& headers);
+
+  // Rendezvous between this promised stream and a client request that
+  // has a matching URL.
+  virtual QuicAsyncStatus HandleClientRequest(
+      const spdy::SpdyHeaderBlock& headers,
+      QuicClientPushPromiseIndex::Delegate* delegate);
+
+  void Cancel() override;
+
+  void Reset(QuicRstStreamErrorCode error_code);
+
+  // Client requests are initially associated to promises by matching
+  // URL in the client request against the URL in the promise headers,
+  // uing the |promised_by_url| map.  The push can be cross-origin, so
+  // the client should validate that the session is authoritative for
+  // the promised URL.  If not, it should call |RejectUnauthorized|.
+  QuicSpdyClientSessionBase* session() { return session_; }
+
+  // If the promised response contains Vary header, then the fields
+  // specified by Vary must match between the client request header
+  // and the promise headers (see https://crbug.com//554220).  Vary
+  // validation requires the response headers (for the actual Vary
+  // field list), the promise headers (taking the role of the "cached"
+  // request), and the client request headers.
+  spdy::SpdyHeaderBlock* request_headers() { return &request_headers_; }
+
+  spdy::SpdyHeaderBlock* response_headers() { return response_headers_.get(); }
+
+  // After validation, client will use this to access the pushed stream.
+
+  QuicStreamId id() const { return id_; }
+
+  const std::string url() const { return url_; }
+
+  // Return true if there's a request pending matching this push promise.
+  bool is_validating() const { return client_request_delegate_ != nullptr; }
+
+ private:
+  friend class test::QuicClientPromisedInfoPeer;
+
+  class QUIC_EXPORT_PRIVATE CleanupAlarm
+      : public QuicAlarm::DelegateWithoutContext {
+   public:
+    explicit CleanupAlarm(QuicClientPromisedInfo* promised)
+        : promised_(promised) {}
+
+    void OnAlarm() override;
+
+    QuicClientPromisedInfo* promised_;
+  };
+
+  QuicAsyncStatus FinalValidation();
+
+  QuicSpdyClientSessionBase* session_;
+  QuicStreamId id_;
+  std::string url_;
+  spdy::SpdyHeaderBlock request_headers_;
+  std::unique_ptr<spdy::SpdyHeaderBlock> response_headers_;
+  spdy::SpdyHeaderBlock client_request_headers_;
+  QuicClientPushPromiseIndex::Delegate* client_request_delegate_;
+
+  // The promise will commit suicide eventually if it is not claimed by a GET
+  // first.
+  std::unique_ptr<QuicAlarm> cleanup_alarm_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
diff --git a/quiche/quic/core/http/quic_client_promised_info_test.cc b/quiche/quic/core/http/quic_client_promised_info_test.cc
new file mode 100644
index 0000000..287e961
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_promised_info_test.cc
@@ -0,0 +1,356 @@
+// Copyright 2016 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 "quiche/quic/core/http/quic_client_promised_info.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_client_promised_info_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit MockQuicSpdyClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(DefaultQuicConfig(),
+                              supported_versions,
+                              connection,
+                              QuicServerId("example.com", 443, false),
+                              &crypto_config_,
+                              push_promise_index),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+        authorized_(true) {}
+  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
+  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
+      delete;
+  ~MockQuicSpdyClientSession() override {}
+
+  bool IsAuthorized(const std::string& /*authority*/) override {
+    return authorized_;
+  }
+
+  void set_authorized(bool authorized) { authorized_ = authorized; }
+
+  MOCK_METHOD(bool,
+              WriteControlFrame,
+              (const QuicFrame& frame, TransmissionType type),
+              (override));
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+
+  bool authorized_;
+};
+
+class QuicClientPromisedInfoTest : public QuicTest {
+ public:
+  class StreamVisitor;
+
+  QuicClientPromisedInfoTest()
+      : connection_(new StrictMock<MockQuicConnection>(&helper_,
+                                                       &alarm_factory_,
+                                                       Perspective::IS_CLIENT)),
+        session_(connection_->supported_versions(),
+                 connection_,
+                 &push_promise_index_),
+        body_("hello world"),
+        promise_id_(
+            QuicUtils::GetInvalidStreamId(connection_->transport_version())) {
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    session_.Initialize();
+
+    headers_[":status"] = "200";
+    headers_["content-length"] = "11";
+
+    stream_ = std::make_unique<QuicSpdyClientStream>(
+        GetNthClientInitiatedBidirectionalStreamId(
+            connection_->transport_version(), 0),
+        &session_, BIDIRECTIONAL);
+    stream_visitor_ = std::make_unique<StreamVisitor>();
+    stream_->set_visitor(stream_visitor_.get());
+
+    push_promise_[":path"] = "/bar";
+    push_promise_[":authority"] = "www.google.com";
+    push_promise_[":method"] = "GET";
+    push_promise_[":scheme"] = "https";
+
+    promise_url_ =
+        SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
+
+    client_request_ = push_promise_.Clone();
+    promise_id_ = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 0);
+  }
+
+  class StreamVisitor : public QuicSpdyClientStream::Visitor {
+    void OnClose(QuicSpdyStream* stream) override {
+      QUIC_DVLOG(1) << "stream " << stream->id();
+    }
+  };
+
+  void ReceivePromise(QuicStreamId id) {
+    auto headers = AsHeaderList(push_promise_);
+    stream_->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
+                                 headers);
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  QuicClientPushPromiseIndex push_promise_index_;
+
+  MockQuicSpdyClientSession session_;
+  std::unique_ptr<QuicSpdyClientStream> stream_;
+  std::unique_ptr<StreamVisitor> stream_visitor_;
+  std::unique_ptr<QuicSpdyClientStream> promised_stream_;
+  SpdyHeaderBlock headers_;
+  std::string body_;
+  SpdyHeaderBlock push_promise_;
+  QuicStreamId promise_id_;
+  std::string promise_url_;
+  SpdyHeaderBlock client_request_;
+};
+
+TEST_F(QuicClientPromisedInfoTest, PushPromise) {
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise is in the unclaimed streams map.
+  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseCleanupAlarm) {
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise is in the unclaimed streams map.
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  // Fire the alarm that will cancel the promised stream.
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT));
+  alarm_factory_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised));
+
+  // Verify that the promise is gone after the alarm fires.
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidMethod) {
+  // Promise with an unsafe method
+  push_promise_[":method"] = "PUT";
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise headers were ignored
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseMissingMethod) {
+  // Promise with a missing method
+  push_promise_.erase(":method");
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise headers were ignored
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidUrl) {
+  // Remove required header field to make URL invalid
+  push_promise_.erase(":authority");
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_URL));
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise headers were ignored
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseUnauthorizedUrl) {
+  session_.set_authorized(false);
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL));
+
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_EQ(promised, nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseMismatch) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  // Need to send the promised response headers and initiate the
+  // rendezvous for secondary validation to proceed.
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  TestPushPromiseDelegate delegate(/*match=*/false);
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH));
+
+  promised->HandleClientRequest(client_request_, &delegate);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryWaits) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  EXPECT_FALSE(promised->is_validating());
+  ASSERT_NE(promised, nullptr);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  promised->HandleClientRequest(client_request_, &delegate);
+  EXPECT_TRUE(promised->is_validating());
+
+  // Promise is still there, waiting for response.
+  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
+
+  // Send Response, should trigger promise validation and complete rendezvous
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  ASSERT_NE(promise_stream, nullptr);
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryNoWait) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  ASSERT_NE(promise_stream, nullptr);
+
+  // Send Response, should trigger promise validation and complete rendezvous
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  promised->HandleClientRequest(client_request_, &delegate);
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  // Have a push stream
+  EXPECT_TRUE(delegate.rendezvous_fired());
+
+  EXPECT_NE(delegate.rendezvous_stream(), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseWaitCancels) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  promised->HandleClientRequest(client_request_, &delegate);
+
+  // Promise is still there, waiting for response.
+  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
+
+  // Create response stream, but no data yet.
+  session_.GetOrCreateStream(promise_id_);
+
+  // Cancel the promised stream.
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED));
+  promised->Cancel();
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseDataClosed) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  ASSERT_NE(promise_stream, nullptr);
+
+  // Send response, rendezvous will be able to finish synchronously.
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY));
+  session_.ResetStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  EXPECT_EQ(promised->HandleClientRequest(client_request_, &delegate),
+            QUIC_FAILURE);
+
+  // Got an indication of the stream failure, client should retry
+  // request.
+  EXPECT_FALSE(delegate.rendezvous_fired());
+  EXPECT_EQ(delegate.rendezvous_stream(), nullptr);
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_client_push_promise_index.cc b/quiche/quic/core/http/quic_client_push_promise_index.cc
new file mode 100644
index 0000000..d1e0cf4
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_push_promise_index.cc
@@ -0,0 +1,48 @@
+// Copyright 2016 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 "quiche/quic/core/http/quic_client_push_promise_index.h"
+
+#include <string>
+
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicClientPushPromiseIndex::QuicClientPushPromiseIndex() {}
+
+QuicClientPushPromiseIndex::~QuicClientPushPromiseIndex() {}
+
+QuicClientPushPromiseIndex::TryHandle::~TryHandle() {}
+
+QuicClientPromisedInfo* QuicClientPushPromiseIndex::GetPromised(
+    const std::string& url) {
+  auto it = promised_by_url_.find(url);
+  if (it == promised_by_url_.end()) {
+    return nullptr;
+  }
+  return it->second;
+}
+
+QuicAsyncStatus QuicClientPushPromiseIndex::Try(
+    const spdy::SpdyHeaderBlock& request,
+    QuicClientPushPromiseIndex::Delegate* delegate,
+    TryHandle** handle) {
+  std::string url(SpdyServerPushUtils::GetPromisedUrlFromHeaders(request));
+  auto it = promised_by_url_.find(url);
+  if (it != promised_by_url_.end()) {
+    QuicClientPromisedInfo* promised = it->second;
+    QuicAsyncStatus rv = promised->HandleClientRequest(request, delegate);
+    if (rv == QUIC_PENDING) {
+      *handle = promised;
+    }
+    return rv;
+  }
+  return QUIC_FAILURE;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_client_push_promise_index.h b/quiche/quic/core/http/quic_client_push_promise_index.h
new file mode 100644
index 0000000..66570b9
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_push_promise_index.h
@@ -0,0 +1,99 @@
+// Copyright 2016 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_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
+
+#include <string>
+
+#include "quiche/quic/core/http/quic_spdy_client_session_base.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicClientPushPromiseIndex is the interface to support rendezvous
+// between client requests and resources delivered via server push.
+// The same index can be shared across multiple sessions (e.g. for the
+// same browser users profile), since cross-origin pushes are allowed
+// (subject to authority constraints).
+
+class QUIC_EXPORT_PRIVATE QuicClientPushPromiseIndex {
+ public:
+  // Delegate is used to complete the rendezvous that began with
+  // |Try()|.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // The primary lookup matched request with push promise by URL.  A
+    // secondary match is necessary to ensure Vary (RFC 2616, 14.14)
+    // is honored.  If Vary is not present, return true.  If Vary is
+    // present, return whether designated header fields of
+    // |promise_request| and |client_request| match.
+    virtual bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
+                           const spdy::SpdyHeaderBlock& promise_request,
+                           const spdy::SpdyHeaderBlock& promise_response) = 0;
+
+    // On rendezvous success, provides the promised |stream|.  Callee
+    // does not inherit ownership of |stream|.  On rendezvous failure,
+    // |stream| is |nullptr| and the client should retry the request.
+    // Rendezvous can fail due to promise validation failure or RST on
+    // promised stream.  |url| will have been removed from the index
+    // before |OnRendezvousResult()| is invoked, so a recursive call to
+    // |Try()| will return |QUIC_FAILURE|, which may be convenient for
+    // retry purposes.
+    virtual void OnRendezvousResult(QuicSpdyStream* stream) = 0;
+  };
+
+  class QUIC_EXPORT_PRIVATE TryHandle {
+   public:
+    // Cancel the request.
+    virtual void Cancel() = 0;
+
+   protected:
+    TryHandle() {}
+    TryHandle(const TryHandle&) = delete;
+    TryHandle& operator=(const TryHandle&) = delete;
+    ~TryHandle();
+  };
+
+  QuicClientPushPromiseIndex();
+  QuicClientPushPromiseIndex(const QuicClientPushPromiseIndex&) = delete;
+  QuicClientPushPromiseIndex& operator=(const QuicClientPushPromiseIndex&) =
+      delete;
+  virtual ~QuicClientPushPromiseIndex();
+
+  // Called by client code, used to enforce affinity between requests
+  // for promised streams and the session the promise came from.
+  QuicClientPromisedInfo* GetPromised(const std::string& url);
+
+  // Called by client code, to initiate rendezvous between a request
+  // and a server push stream.  If |request|'s url is in the index,
+  // rendezvous will be attempted and may complete immediately or
+  // asynchronously.  If the matching promise and response headers
+  // have already arrived, the delegate's methods will fire
+  // recursively from within |Try()|.  Returns |QUIC_SUCCESS| if the
+  // rendezvous was a success. Returns |QUIC_FAILURE| if there was no
+  // matching promise, or if there was but the rendezvous has failed.
+  // Returns QUIC_PENDING if a matching promise was found, but the
+  // rendezvous needs to complete asynchronously because the promised
+  // response headers are not yet available.  If result is
+  // QUIC_PENDING, then |*handle| will set so that the caller may
+  // cancel the request if need be.  The caller does not inherit
+  // ownership of |*handle|, and it ceases to be valid if the caller
+  // invokes |handle->Cancel()| or if |delegate->OnReponse()| fires.
+  QuicAsyncStatus Try(const spdy::SpdyHeaderBlock& request,
+                      Delegate* delegate,
+                      TryHandle** handle);
+
+  QuicPromisedByUrlMap* promised_by_url() { return &promised_by_url_; }
+
+ private:
+  QuicPromisedByUrlMap promised_by_url_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
diff --git a/quiche/quic/core/http/quic_client_push_promise_index_test.cc b/quiche/quic/core/http/quic_client_push_promise_index_test.cc
new file mode 100644
index 0000000..6f7c3ac
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_push_promise_index_test.cc
@@ -0,0 +1,113 @@
+// Copyright 2016 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 "quiche/quic/core/http/quic_client_push_promise_index.h"
+
+#include <string>
+
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_quic_client_promised_info.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit MockQuicSpdyClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(DefaultQuicConfig(),
+                              supported_versions,
+                              connection,
+                              QuicServerId("example.com", 443, false),
+                              &crypto_config_,
+                              push_promise_index),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
+  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
+  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
+      delete;
+  ~MockQuicSpdyClientSession() override {}
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+};
+
+class QuicClientPushPromiseIndexTest : public QuicTest {
+ public:
+  QuicClientPushPromiseIndexTest()
+      : connection_(new StrictMock<MockQuicConnection>(&helper_,
+                                                       &alarm_factory_,
+                                                       Perspective::IS_CLIENT)),
+        session_(connection_->supported_versions(), connection_, &index_),
+        promised_(&session_,
+                  GetNthServerInitiatedUnidirectionalStreamId(
+                      connection_->transport_version(),
+                      0),
+                  url_) {
+    request_[":path"] = "/bar";
+    request_[":authority"] = "www.google.com";
+    request_[":method"] = "GET";
+    request_[":scheme"] = "https";
+    url_ = SpdyServerPushUtils::GetPromisedUrlFromHeaders(request_);
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  MockQuicSpdyClientSession session_;
+  QuicClientPushPromiseIndex index_;
+  spdy::SpdyHeaderBlock request_;
+  std::string url_;
+  MockQuicClientPromisedInfo promised_;
+  QuicClientPushPromiseIndex::TryHandle* handle_;
+};
+
+TEST_F(QuicClientPushPromiseIndexTest, TryRequestSuccess) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_CALL(promised_, HandleClientRequest(_, _))
+      .WillOnce(Return(QUIC_SUCCESS));
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_SUCCESS);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, TryRequestPending) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_CALL(promised_, HandleClientRequest(_, _))
+      .WillOnce(Return(QUIC_PENDING));
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_PENDING);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, TryRequestFailure) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_CALL(promised_, HandleClientRequest(_, _))
+      .WillOnce(Return(QUIC_FAILURE));
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, TryNoPromise) {
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, GetNoPromise) {
+  EXPECT_EQ(index_.GetPromised(url_), nullptr);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, GetPromise) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_EQ(index_.GetPromised(url_), &promised_);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_header_list.cc b/quiche/quic/core/http/quic_header_list.cc
new file mode 100644
index 0000000..771e617
--- /dev/null
+++ b/quiche/quic/core/http/quic_header_list.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2016 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 "quiche/quic/core/http/quic_header_list.h"
+
+#include <limits>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicHeaderList::QuicHeaderList()
+    : max_header_list_size_(std::numeric_limits<size_t>::max()),
+      current_header_list_size_(0),
+      uncompressed_header_bytes_(0),
+      compressed_header_bytes_(0) {}
+
+QuicHeaderList::QuicHeaderList(QuicHeaderList&& other) = default;
+
+QuicHeaderList::QuicHeaderList(const QuicHeaderList& other) = default;
+
+QuicHeaderList& QuicHeaderList::operator=(const QuicHeaderList& other) =
+    default;
+
+QuicHeaderList& QuicHeaderList::operator=(QuicHeaderList&& other) = default;
+
+QuicHeaderList::~QuicHeaderList() {}
+
+void QuicHeaderList::OnHeaderBlockStart() {
+  QUIC_BUG_IF(quic_bug_12518_1, current_header_list_size_ != 0)
+      << "OnHeaderBlockStart called more than once!";
+}
+
+void QuicHeaderList::OnHeader(absl::string_view name, absl::string_view value) {
+  // Avoid infinite buffering of headers. No longer store headers
+  // once the current headers are over the limit.
+  if (current_header_list_size_ < max_header_list_size_) {
+    current_header_list_size_ += name.size();
+    current_header_list_size_ += value.size();
+    current_header_list_size_ += kQpackEntrySizeOverhead;
+    header_list_.emplace_back(std::string(name), std::string(value));
+  }
+}
+
+void QuicHeaderList::OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                                      size_t compressed_header_bytes) {
+  uncompressed_header_bytes_ = uncompressed_header_bytes;
+  compressed_header_bytes_ = compressed_header_bytes;
+  if (current_header_list_size_ > max_header_list_size_) {
+    Clear();
+  }
+}
+
+void QuicHeaderList::Clear() {
+  header_list_.clear();
+  current_header_list_size_ = 0;
+  uncompressed_header_bytes_ = 0;
+  compressed_header_bytes_ = 0;
+}
+
+std::string QuicHeaderList::DebugString() const {
+  std::string s = "{ ";
+  for (const auto& p : *this) {
+    s.append(p.first + "=" + p.second + ", ");
+  }
+  s.append("}");
+  return s;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_header_list.h b/quiche/quic/core/http/quic_header_list.h
new file mode 100644
index 0000000..9cccf02
--- /dev/null
+++ b/quiche/quic/core/http/quic_header_list.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2016 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_HTTP_QUIC_HEADER_LIST_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
+
+#include <algorithm>
+#include <functional>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_headers_handler_interface.h"
+
+namespace quic {
+
+// A simple class that accumulates header pairs
+class QUIC_EXPORT_PRIVATE QuicHeaderList
+    : public spdy::SpdyHeadersHandlerInterface {
+ public:
+  using ListType =
+      quiche::QuicheCircularDeque<std::pair<std::string, std::string>>;
+  using value_type = ListType::value_type;
+  using const_iterator = ListType::const_iterator;
+
+  QuicHeaderList();
+  QuicHeaderList(QuicHeaderList&& other);
+  QuicHeaderList(const QuicHeaderList& other);
+  QuicHeaderList& operator=(QuicHeaderList&& other);
+  QuicHeaderList& operator=(const QuicHeaderList& other);
+  ~QuicHeaderList() override;
+
+  // From SpdyHeadersHandlerInteface.
+  void OnHeaderBlockStart() override;
+  void OnHeader(absl::string_view name, absl::string_view value) override;
+  void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                        size_t compressed_header_bytes) override;
+
+  void Clear();
+
+  const_iterator begin() const { return header_list_.begin(); }
+  const_iterator end() const { return header_list_.end(); }
+
+  bool empty() const { return header_list_.empty(); }
+  size_t uncompressed_header_bytes() const {
+    return uncompressed_header_bytes_;
+  }
+  size_t compressed_header_bytes() const { return compressed_header_bytes_; }
+
+  // Deprecated.  TODO(b/145909215): remove.
+  void set_max_header_list_size(size_t max_header_list_size) {
+    max_header_list_size_ = max_header_list_size;
+  }
+
+  std::string DebugString() const;
+
+ private:
+  quiche::QuicheCircularDeque<std::pair<std::string, std::string>> header_list_;
+
+  // The limit on the size of the header list (defined by spec as name + value +
+  // overhead for each header field). Headers over this limit will not be
+  // buffered, and the list will be cleared upon OnHeaderBlockEnd.
+  size_t max_header_list_size_;
+
+  // Defined per the spec as the size of all header fields with an additional
+  // overhead for each field.
+  size_t current_header_list_size_;
+
+  // TODO(dahollings) Are these fields necessary?
+  size_t uncompressed_header_bytes_;
+  size_t compressed_header_bytes_;
+};
+
+inline bool operator==(const QuicHeaderList& l1, const QuicHeaderList& l2) {
+  auto pred = [](const std::pair<std::string, std::string>& p1,
+                 const std::pair<std::string, std::string>& p2) {
+    return p1.first == p2.first && p1.second == p2.second;
+  };
+  return std::equal(l1.begin(), l1.end(), l2.begin(), pred);
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
diff --git a/quiche/quic/core/http/quic_header_list_test.cc b/quiche/quic/core/http/quic_header_list_test.cc
new file mode 100644
index 0000000..6007bcc
--- /dev/null
+++ b/quiche/quic/core/http/quic_header_list_test.cc
@@ -0,0 +1,86 @@
+// Copyright (c) 2016 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 "quiche/quic/core/http/quic_header_list.h"
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using ::testing::ElementsAre;
+using ::testing::Pair;
+
+namespace quic {
+
+class QuicHeaderListTest : public QuicTest {};
+
+// This test verifies that QuicHeaderList accumulates header pairs in order.
+TEST_F(QuicHeaderListTest, OnHeader) {
+  QuicHeaderList headers;
+  headers.OnHeader("foo", "bar");
+  headers.OnHeader("april", "fools");
+  headers.OnHeader("beep", "");
+
+  EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
+                                   Pair("beep", "")));
+}
+
+TEST_F(QuicHeaderListTest, DebugString) {
+  QuicHeaderList headers;
+  headers.OnHeader("foo", "bar");
+  headers.OnHeader("april", "fools");
+  headers.OnHeader("beep", "");
+
+  EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers.DebugString());
+}
+
+TEST_F(QuicHeaderListTest, TooLarge) {
+  const size_t kMaxHeaderListSize = 256;
+
+  QuicHeaderList headers;
+  headers.set_max_header_list_size(kMaxHeaderListSize);
+  std::string key = "key";
+  std::string value(kMaxHeaderListSize, '1');
+  // Send a header that exceeds max_header_list_size.
+  headers.OnHeader(key, value);
+  // Send a second header exceeding max_header_list_size.
+  headers.OnHeader(key + "2", value);
+  // We should not allocate more memory after exceeding max_header_list_size.
+  EXPECT_LT(headers.DebugString().size(), 2 * value.size());
+  size_t total_bytes = 2 * (key.size() + value.size()) + 1;
+  headers.OnHeaderBlockEnd(total_bytes, total_bytes);
+
+  EXPECT_TRUE(headers.empty());
+  EXPECT_EQ("{ }", headers.DebugString());
+}
+
+TEST_F(QuicHeaderListTest, NotTooLarge) {
+  QuicHeaderList headers;
+  headers.set_max_header_list_size(1 << 20);
+  std::string key = "key";
+  std::string value(1 << 18, '1');
+  headers.OnHeader(key, value);
+  size_t total_bytes = key.size() + value.size();
+  headers.OnHeaderBlockEnd(total_bytes, total_bytes);
+  EXPECT_FALSE(headers.empty());
+}
+
+// This test verifies that QuicHeaderList is copyable and assignable.
+TEST_F(QuicHeaderListTest, IsCopyableAndAssignable) {
+  QuicHeaderList headers;
+  headers.OnHeader("foo", "bar");
+  headers.OnHeader("april", "fools");
+  headers.OnHeader("beep", "");
+
+  QuicHeaderList headers2(headers);
+  QuicHeaderList headers3 = headers;
+
+  EXPECT_THAT(headers2, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
+                                    Pair("beep", "")));
+  EXPECT_THAT(headers3, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
+                                    Pair("beep", "")));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_headers_stream.cc b/quiche/quic/core/http/quic_headers_stream.cc
new file mode 100644
index 0000000..81ebaef
--- /dev/null
+++ b/quiche/quic/core/http/quic_headers_stream.cc
@@ -0,0 +1,164 @@
+// Copyright 2013 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 "quiche/quic/core/http/quic_headers_stream.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
+    QuicStreamOffset headers_stream_offset, QuicStreamOffset full_length,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener)
+    : headers_stream_offset(headers_stream_offset),
+      full_length(full_length),
+      unacked_length(full_length),
+      ack_listener(std::move(ack_listener)) {}
+
+QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
+    const CompressedHeaderInfo& other) = default;
+
+QuicHeadersStream::CompressedHeaderInfo::~CompressedHeaderInfo() {}
+
+QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
+    : QuicStream(QuicUtils::GetHeadersStreamId(session->transport_version()),
+                 session,
+                 /*is_static=*/true,
+                 BIDIRECTIONAL),
+      spdy_session_(session) {
+  // The headers stream is exempt from connection level flow control.
+  DisableConnectionFlowControlForThisStream();
+}
+
+QuicHeadersStream::~QuicHeadersStream() {}
+
+void QuicHeadersStream::OnDataAvailable() {
+  struct iovec iov;
+  while (sequencer()->GetReadableRegion(&iov)) {
+    if (spdy_session_->ProcessHeaderData(iov) != iov.iov_len) {
+      // Error processing data.
+      return;
+    }
+    sequencer()->MarkConsumed(iov.iov_len);
+    MaybeReleaseSequencerBuffer();
+  }
+}
+
+void QuicHeadersStream::MaybeReleaseSequencerBuffer() {
+  if (spdy_session_->ShouldReleaseHeadersStreamSequencerBuffer()) {
+    sequencer()->ReleaseBufferIfEmpty();
+  }
+}
+
+bool QuicHeadersStream::OnStreamFrameAcked(QuicStreamOffset offset,
+                                           QuicByteCount data_length,
+                                           bool fin_acked,
+                                           QuicTime::Delta ack_delay_time,
+                                           QuicTime receive_timestamp,
+                                           QuicByteCount* newly_acked_length) {
+  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+  newly_acked.Difference(bytes_acked());
+  for (const auto& acked : newly_acked) {
+    QuicStreamOffset acked_offset = acked.min();
+    QuicByteCount acked_length = acked.max() - acked.min();
+    for (CompressedHeaderInfo& header : unacked_headers_) {
+      if (acked_offset < header.headers_stream_offset) {
+        // This header frame offset belongs to headers with smaller offset, stop
+        // processing.
+        break;
+      }
+
+      if (acked_offset >= header.headers_stream_offset + header.full_length) {
+        // This header frame belongs to headers with larger offset.
+        continue;
+      }
+
+      QuicByteCount header_offset = acked_offset - header.headers_stream_offset;
+      QuicByteCount header_length =
+          std::min(acked_length, header.full_length - header_offset);
+
+      if (header.unacked_length < header_length) {
+        QUIC_BUG(quic_bug_10416_1)
+            << "Unsent stream data is acked. unacked_length: "
+            << header.unacked_length << " acked_length: " << header_length;
+        OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                             "Unsent stream data is acked");
+        return false;
+      }
+      if (header.ack_listener != nullptr && header_length > 0) {
+        header.ack_listener->OnPacketAcked(header_length, ack_delay_time);
+      }
+      header.unacked_length -= header_length;
+      acked_offset += header_length;
+      acked_length -= header_length;
+    }
+  }
+  // Remove headers which are fully acked. Please note, header frames can be
+  // acked out of order, but unacked_headers_ is cleaned up in order.
+  while (!unacked_headers_.empty() &&
+         unacked_headers_.front().unacked_length == 0) {
+    unacked_headers_.pop_front();
+  }
+  return QuicStream::OnStreamFrameAcked(offset, data_length, fin_acked,
+                                        ack_delay_time, receive_timestamp,
+                                        newly_acked_length);
+}
+
+void QuicHeadersStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                                   QuicByteCount data_length,
+                                                   bool /*fin_retransmitted*/) {
+  QuicStream::OnStreamFrameRetransmitted(offset, data_length, false);
+  for (CompressedHeaderInfo& header : unacked_headers_) {
+    if (offset < header.headers_stream_offset) {
+      // This header frame offset belongs to headers with smaller offset, stop
+      // processing.
+      break;
+    }
+
+    if (offset >= header.headers_stream_offset + header.full_length) {
+      // This header frame belongs to headers with larger offset.
+      continue;
+    }
+
+    QuicByteCount header_offset = offset - header.headers_stream_offset;
+    QuicByteCount retransmitted_length =
+        std::min(data_length, header.full_length - header_offset);
+    if (header.ack_listener != nullptr && retransmitted_length > 0) {
+      header.ack_listener->OnPacketRetransmitted(retransmitted_length);
+    }
+    offset += retransmitted_length;
+    data_length -= retransmitted_length;
+  }
+}
+
+void QuicHeadersStream::OnDataBuffered(
+    QuicStreamOffset offset, QuicByteCount data_length,
+    const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
+        ack_listener) {
+  // Populate unacked_headers_.
+  if (!unacked_headers_.empty() &&
+      (offset == unacked_headers_.back().headers_stream_offset +
+                     unacked_headers_.back().full_length) &&
+      ack_listener == unacked_headers_.back().ack_listener) {
+    // Try to combine with latest inserted entry if they belong to the same
+    // header (i.e., having contiguous offset and the same ack listener).
+    unacked_headers_.back().full_length += data_length;
+    unacked_headers_.back().unacked_length += data_length;
+  } else {
+    unacked_headers_.push_back(
+        CompressedHeaderInfo(offset, data_length, ack_listener));
+  }
+}
+
+void QuicHeadersStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
+                                   "Attempt to reset headers stream");
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_headers_stream.h b/quiche/quic/core/http/quic_headers_stream.h
new file mode 100644
index 0000000..a5dbe38
--- /dev/null
+++ b/quiche/quic/core/http/quic_headers_stream.h
@@ -0,0 +1,99 @@
+// Copyright 2013 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_HTTP_QUIC_HEADERS_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+class QuicSpdySession;
+
+namespace test {
+class QuicHeadersStreamPeer;
+}  // namespace test
+
+// Headers in QUIC are sent as HTTP/2 HEADERS or PUSH_PROMISE frames over a
+// reserved stream with the id 3.  Each endpoint (client and server) will
+// allocate an instance of QuicHeadersStream to send and receive headers.
+class QUIC_EXPORT_PRIVATE QuicHeadersStream : public QuicStream {
+ public:
+  explicit QuicHeadersStream(QuicSpdySession* session);
+  QuicHeadersStream(const QuicHeadersStream&) = delete;
+  QuicHeadersStream& operator=(const QuicHeadersStream&) = delete;
+  ~QuicHeadersStream() override;
+
+  // QuicStream implementation
+  void OnDataAvailable() override;
+
+  // Release underlying buffer if allowed.
+  void MaybeReleaseSequencerBuffer();
+
+  bool OnStreamFrameAcked(QuicStreamOffset offset,
+                          QuicByteCount data_length,
+                          bool fin_acked,
+                          QuicTime::Delta ack_delay_time,
+                          QuicTime receive_timestamp,
+                          QuicByteCount* newly_acked_length) override;
+
+  void OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                  QuicByteCount data_length,
+                                  bool fin_retransmitted) override;
+
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+ private:
+  friend class test::QuicHeadersStreamPeer;
+
+  // CompressedHeaderInfo includes simple information of a header, including
+  // offset in headers stream, unacked length and ack listener of this header.
+  struct QUIC_EXPORT_PRIVATE CompressedHeaderInfo {
+    CompressedHeaderInfo(
+        QuicStreamOffset headers_stream_offset, QuicStreamOffset full_length,
+        quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+            ack_listener);
+    CompressedHeaderInfo(const CompressedHeaderInfo& other);
+    ~CompressedHeaderInfo();
+
+    // Offset the header was sent on the headers stream.
+    QuicStreamOffset headers_stream_offset;
+    // The full length of the header.
+    QuicByteCount full_length;
+    // The remaining bytes to be acked.
+    QuicByteCount unacked_length;
+    // Ack listener of this header, and it is notified once any of the bytes has
+    // been acked or retransmitted.
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener;
+  };
+
+  // Returns true if the session is still connected.
+  bool IsConnected();
+
+  // Override to store mapping from offset, length to ack_listener. This
+  // ack_listener is notified once data within [offset, offset + length] is
+  // acked or retransmitted.
+  void OnDataBuffered(
+      QuicStreamOffset offset, QuicByteCount data_length,
+      const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
+          ack_listener) override;
+
+  QuicSpdySession* spdy_session_;
+
+  // Headers that have not been fully acked.
+  quiche::QuicheCircularDeque<CompressedHeaderInfo> unacked_headers_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
diff --git a/quiche/quic/core/http/quic_headers_stream_test.cc b/quiche/quic/core/http/quic_headers_stream_test.cc
new file mode 100644
index 0000000..30d9147
--- /dev/null
+++ b/quiche/quic/core/http/quic_headers_stream_test.cc
@@ -0,0 +1,972 @@
+// Copyright 2013 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 "quiche/quic/core/http/quic_headers_stream.h"
+
+#include <cstdint>
+#include <ostream>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+#include "quiche/spdy/core/recording_headers_handler.h"
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+using spdy::ERROR_CODE_PROTOCOL_ERROR;
+using spdy::RecordingHeadersHandler;
+using spdy::SETTINGS_ENABLE_PUSH;
+using spdy::SETTINGS_HEADER_TABLE_SIZE;
+using spdy::SETTINGS_INITIAL_WINDOW_SIZE;
+using spdy::SETTINGS_MAX_CONCURRENT_STREAMS;
+using spdy::SETTINGS_MAX_FRAME_SIZE;
+using spdy::Spdy3PriorityToHttp2Weight;
+using spdy::SpdyAltSvcWireFormat;
+using spdy::SpdyDataIR;
+using spdy::SpdyErrorCode;
+using spdy::SpdyFramer;
+using spdy::SpdyFramerVisitorInterface;
+using spdy::SpdyGoAwayIR;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyHeadersHandlerInterface;
+using spdy::SpdyHeadersIR;
+using spdy::SpdyPingId;
+using spdy::SpdyPingIR;
+using spdy::SpdyPriority;
+using spdy::SpdyPriorityIR;
+using spdy::SpdyPushPromiseIR;
+using spdy::SpdyRstStreamIR;
+using spdy::SpdySerializedFrame;
+using spdy::SpdySettingsId;
+using spdy::SpdySettingsIR;
+using spdy::SpdyStreamId;
+using spdy::SpdyWindowUpdateIR;
+using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+using testing::WithArgs;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockVisitor : public SpdyFramerVisitorInterface {
+ public:
+  MOCK_METHOD(void,
+              OnError,
+              (http2::Http2DecoderAdapter::SpdyFramerError error,
+               std::string detailed_error),
+              (override));
+  MOCK_METHOD(void,
+              OnDataFrameHeader,
+              (SpdyStreamId stream_id, size_t length, bool fin),
+              (override));
+  MOCK_METHOD(void,
+              OnStreamFrameData,
+              (SpdyStreamId stream_id, const char*, size_t len),
+              (override));
+  MOCK_METHOD(void, OnStreamEnd, (SpdyStreamId stream_id), (override));
+  MOCK_METHOD(void,
+              OnStreamPadding,
+              (SpdyStreamId stream_id, size_t len),
+              (override));
+  MOCK_METHOD(SpdyHeadersHandlerInterface*,
+              OnHeaderFrameStart,
+              (SpdyStreamId stream_id),
+              (override));
+  MOCK_METHOD(void, OnHeaderFrameEnd, (SpdyStreamId stream_id), (override));
+  MOCK_METHOD(void,
+              OnRstStream,
+              (SpdyStreamId stream_id, SpdyErrorCode error_code),
+              (override));
+  MOCK_METHOD(void, OnSettings, (), (override));
+  MOCK_METHOD(void, OnSetting, (SpdySettingsId id, uint32_t value), (override));
+  MOCK_METHOD(void, OnSettingsAck, (), (override));
+  MOCK_METHOD(void, OnSettingsEnd, (), (override));
+  MOCK_METHOD(void, OnPing, (SpdyPingId unique_id, bool is_ack), (override));
+  MOCK_METHOD(void,
+              OnGoAway,
+              (SpdyStreamId last_accepted_stream_id, SpdyErrorCode error_code),
+              (override));
+  MOCK_METHOD(void,
+              OnHeaders,
+              (SpdyStreamId stream_id,
+               bool has_priority,
+               int weight,
+               SpdyStreamId parent_stream_id,
+               bool exclusive,
+               bool fin,
+               bool end),
+              (override));
+  MOCK_METHOD(void,
+              OnWindowUpdate,
+              (SpdyStreamId stream_id, int delta_window_size),
+              (override));
+  MOCK_METHOD(void,
+              OnPushPromise,
+              (SpdyStreamId stream_id,
+               SpdyStreamId promised_stream_id,
+               bool end),
+              (override));
+  MOCK_METHOD(void,
+              OnContinuation,
+              (SpdyStreamId stream_id, bool end),
+              (override));
+  MOCK_METHOD(
+      void,
+      OnAltSvc,
+      (SpdyStreamId stream_id,
+       absl::string_view origin,
+       const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector),
+      (override));
+  MOCK_METHOD(void,
+              OnPriority,
+              (SpdyStreamId stream_id,
+               SpdyStreamId parent_stream_id,
+               int weight,
+               bool exclusive),
+              (override));
+  MOCK_METHOD(void,
+              OnPriorityUpdate,
+              (SpdyStreamId prioritized_stream_id,
+               absl::string_view priority_field_value),
+              (override));
+  MOCK_METHOD(bool,
+              OnUnknownFrame,
+              (SpdyStreamId stream_id, uint8_t frame_type),
+              (override));
+};
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams:  " << *this;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
+    os << "{ version: " << ParsedQuicVersionToString(tp.version)
+       << ", perspective: "
+       << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
+       << "}";
+    return os;
+  }
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& tp) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(tp.version), "_",
+      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
+    if (VersionUsesHttp3(all_supported_versions[i].transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(all_supported_versions[i], p);
+    }
+  }
+  return params;
+}
+
+class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QuicHeadersStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(&helper_,
+                                                       &alarm_factory_,
+                                                       perspective(),
+                                                       GetVersion())),
+        session_(connection_),
+        body_("hello world"),
+        stream_frame_(
+            QuicUtils::GetHeadersStreamId(connection_->transport_version()),
+            /*fin=*/false,
+            /*offset=*/0,
+            ""),
+        next_promised_stream_id_(2) {
+    QuicSpdySessionPeer::SetMaxInboundHeaderListSize(&session_, 256 * 1024);
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    connection_->SetEncrypter(
+        quic::ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<quic::NullEncrypter>(connection_->perspective()));
+    headers_stream_ = QuicSpdySessionPeer::GetHeadersStream(&session_);
+    headers_[":status"] = "200 Ok";
+    headers_["content-length"] = "11";
+    framer_ = std::unique_ptr<SpdyFramer>(
+        new SpdyFramer(SpdyFramer::ENABLE_COMPRESSION));
+    deframer_ = std::unique_ptr<http2::Http2DecoderAdapter>(
+        new http2::Http2DecoderAdapter());
+    deframer_->set_visitor(&visitor_);
+    EXPECT_EQ(transport_version(), session_.transport_version());
+    EXPECT_TRUE(headers_stream_ != nullptr);
+    connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+    client_id_1_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 0);
+    client_id_2_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 1);
+    client_id_3_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 2);
+    next_stream_id_ =
+        QuicUtils::StreamIdDelta(connection_->transport_version());
+  }
+
+  QuicStreamId GetNthClientInitiatedId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), n);
+  }
+
+  QuicConsumedData SaveIov(size_t write_length) {
+    char* buf = new char[write_length];
+    QuicDataWriter writer(write_length, buf, quiche::NETWORK_BYTE_ORDER);
+    headers_stream_->WriteStreamData(headers_stream_->stream_bytes_written(),
+                                     write_length, &writer);
+    saved_data_.append(buf, write_length);
+    delete[] buf;
+    return QuicConsumedData(write_length, false);
+  }
+
+  void SavePayload(const char* data, size_t len) {
+    saved_payloads_.append(data, len);
+  }
+
+  bool SaveHeaderData(const char* data, int len) {
+    saved_header_data_.append(data, len);
+    return true;
+  }
+
+  void SaveHeaderDataStringPiece(absl::string_view data) {
+    saved_header_data_.append(data.data(), data.length());
+  }
+
+  void SavePromiseHeaderList(QuicStreamId /* stream_id */,
+                             QuicStreamId /* promised_stream_id */,
+                             size_t size,
+                             const QuicHeaderList& header_list) {
+    SaveToHandler(size, header_list);
+  }
+
+  void SaveHeaderList(QuicStreamId /* stream_id */,
+                      bool /* fin */,
+                      size_t size,
+                      const QuicHeaderList& header_list) {
+    SaveToHandler(size, header_list);
+  }
+
+  void SaveToHandler(size_t size, const QuicHeaderList& header_list) {
+    headers_handler_ = std::make_unique<RecordingHeadersHandler>();
+    headers_handler_->OnHeaderBlockStart();
+    for (const auto& p : header_list) {
+      headers_handler_->OnHeader(p.first, p.second);
+    }
+    headers_handler_->OnHeaderBlockEnd(size, size);
+  }
+
+  void WriteAndExpectRequestHeaders(QuicStreamId stream_id,
+                                    bool fin,
+                                    SpdyPriority priority) {
+    WriteHeadersAndCheckData(stream_id, fin, priority, true /*is_request*/);
+  }
+
+  void WriteAndExpectResponseHeaders(QuicStreamId stream_id, bool fin) {
+    WriteHeadersAndCheckData(stream_id, fin, 0, false /*is_request*/);
+  }
+
+  void WriteHeadersAndCheckData(QuicStreamId stream_id,
+                                bool fin,
+                                SpdyPriority priority,
+                                bool is_request) {
+    // Write the headers and capture the outgoing data
+    EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                         connection_->transport_version()),
+                                     _, _, NO_FIN, _, _))
+        .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
+    QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
+        &session_, stream_id, headers_.Clone(), fin,
+        spdy::SpdyStreamPrecedence(priority), nullptr);
+
+    // Parse the outgoing data and check that it matches was was written.
+    if (is_request) {
+      EXPECT_CALL(visitor_,
+                  OnHeaders(stream_id, kHasPriority,
+                            Spdy3PriorityToHttp2Weight(priority),
+                            /*parent_stream_id=*/0,
+                            /*exclusive=*/false, fin, kFrameComplete));
+    } else {
+      EXPECT_CALL(visitor_,
+                  OnHeaders(stream_id, !kHasPriority,
+                            /*weight=*/0,
+                            /*parent_stream_id=*/0,
+                            /*exclusive=*/false, fin, kFrameComplete));
+    }
+    headers_handler_ = std::make_unique<RecordingHeadersHandler>();
+    EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
+        .WillOnce(Return(headers_handler_.get()));
+    EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
+    if (fin) {
+      EXPECT_CALL(visitor_, OnStreamEnd(stream_id));
+    }
+    deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
+    EXPECT_FALSE(deframer_->HasError())
+        << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer_->spdy_framer_error());
+
+    CheckHeaders();
+    saved_data_.clear();
+  }
+
+  void CheckHeaders() {
+    ASSERT_TRUE(headers_handler_);
+    EXPECT_EQ(headers_, headers_handler_->decoded_block());
+    headers_handler_.reset();
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  QuicTransportVersion transport_version() const {
+    return GetParam().version.transport_version;
+  }
+
+  ParsedQuicVersionVector GetVersion() {
+    ParsedQuicVersionVector versions;
+    versions.push_back(GetParam().version);
+    return versions;
+  }
+
+  void TearDownLocalConnectionState() {
+    QuicConnectionPeer::TearDownLocalConnectionState(connection_);
+  }
+
+  QuicStreamId NextPromisedStreamId() {
+    return next_promised_stream_id_ += next_stream_id_;
+  }
+
+  static constexpr bool kFrameComplete = true;
+  static constexpr bool kHasPriority = true;
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QuicHeadersStream* headers_stream_;
+  SpdyHeaderBlock headers_;
+  std::unique_ptr<RecordingHeadersHandler> headers_handler_;
+  std::string body_;
+  std::string saved_data_;
+  std::string saved_header_data_;
+  std::string saved_payloads_;
+  std::unique_ptr<SpdyFramer> framer_;
+  std::unique_ptr<http2::Http2DecoderAdapter> deframer_;
+  StrictMock<MockVisitor> visitor_;
+  QuicStreamFrame stream_frame_;
+  QuicStreamId next_promised_stream_id_;
+  QuicStreamId client_id_1_;
+  QuicStreamId client_id_2_;
+  QuicStreamId client_id_3_;
+  QuicStreamId next_stream_id_;
+};
+
+// Run all tests with each version and perspective (client or server).
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicHeadersStreamTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicHeadersStreamTest, StreamId) {
+  EXPECT_EQ(QuicUtils::GetHeadersStreamId(connection_->transport_version()),
+            headers_stream_->id());
+}
+
+TEST_P(QuicHeadersStreamTest, WriteHeaders) {
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      if (perspective() == Perspective::IS_SERVER) {
+        WriteAndExpectResponseHeaders(stream_id, fin);
+      } else {
+        for (SpdyPriority priority = 0; priority < 7; ++priority) {
+          // TODO(rch): implement priorities correctly.
+          WriteAndExpectRequestHeaders(stream_id, fin, 0);
+        }
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, WritePushPromises) {
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    QuicStreamId promised_stream_id = NextPromisedStreamId();
+    if (perspective() == Perspective::IS_SERVER) {
+      // Write the headers and capture the outgoing data
+      EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                           connection_->transport_version()),
+                                       _, _, NO_FIN, _, _))
+          .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
+      session_.WritePushPromise(stream_id, promised_stream_id,
+                                headers_.Clone());
+
+      // Parse the outgoing data and check that it matches was was written.
+      EXPECT_CALL(visitor_,
+                  OnPushPromise(stream_id, promised_stream_id, kFrameComplete));
+      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
+      EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
+          .WillOnce(Return(headers_handler_.get()));
+      EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
+      deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
+      EXPECT_FALSE(deframer_->HasError())
+          << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
+                 deframer_->spdy_framer_error());
+      CheckHeaders();
+      saved_data_.clear();
+    } else {
+      EXPECT_QUIC_BUG(session_.WritePushPromise(stream_id, promised_stream_id,
+                                                headers_.Clone()),
+                      "Client shouldn't send PUSH_PROMISE");
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessRawData) {
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      for (SpdyPriority priority = 0; priority < 7; ++priority) {
+        // Replace with "WriteHeadersAndSaveData"
+        SpdySerializedFrame frame;
+        if (perspective() == Perspective::IS_SERVER) {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          headers_frame.set_has_priority(true);
+          headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
+          frame = framer_->SerializeFrame(headers_frame);
+          EXPECT_CALL(session_, OnStreamHeadersPriority(
+                                    stream_id, spdy::SpdyStreamPrecedence(0)));
+        } else {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          frame = framer_->SerializeFrame(headers_frame);
+        }
+        EXPECT_CALL(session_,
+                    OnStreamHeaderList(stream_id, fin, frame.size(), _))
+            .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
+        stream_frame_.data_buffer = frame.data();
+        stream_frame_.data_length = frame.size();
+        headers_stream_->OnStreamFrame(stream_frame_);
+        stream_frame_.offset += frame.size();
+        CheckHeaders();
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
+  if (perspective() == Perspective::IS_SERVER) {
+    return;
+  }
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    QuicStreamId promised_stream_id = NextPromisedStreamId();
+    SpdyPushPromiseIR push_promise(stream_id, promised_stream_id,
+                                   headers_.Clone());
+    SpdySerializedFrame frame(framer_->SerializeFrame(push_promise));
+    bool connection_closed = false;
+    if (perspective() == Perspective::IS_SERVER) {
+      EXPECT_CALL(*connection_,
+                  CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                  "PUSH_PROMISE not supported.", _))
+          .WillRepeatedly(InvokeWithoutArgs(
+              this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+    } else {
+      ON_CALL(*connection_, CloseConnection(_, _, _))
+          .WillByDefault(testing::Assign(&connection_closed, true));
+      EXPECT_CALL(session_, OnPromiseHeaderList(stream_id, promised_stream_id,
+                                                frame.size(), _))
+          .WillOnce(
+              Invoke(this, &QuicHeadersStreamTest::SavePromiseHeaderList));
+    }
+    stream_frame_.data_buffer = frame.data();
+    stream_frame_.data_length = frame.size();
+    headers_stream_->OnStreamFrame(stream_frame_);
+    if (perspective() == Perspective::IS_CLIENT) {
+      stream_frame_.offset += frame.size();
+      // CheckHeaders crashes if the connection is closed so this ensures we
+      // fail the test instead of crashing.
+      ASSERT_FALSE(connection_closed);
+      CheckHeaders();
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessPriorityFrame) {
+  QuicStreamId parent_stream_id = 0;
+  for (SpdyPriority priority = 0; priority < 7; ++priority) {
+    for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+         stream_id += next_stream_id_) {
+      int weight = Spdy3PriorityToHttp2Weight(priority);
+      SpdyPriorityIR priority_frame(stream_id, parent_stream_id, weight, true);
+      SpdySerializedFrame frame(framer_->SerializeFrame(priority_frame));
+      parent_stream_id = stream_id;
+      if (perspective() == Perspective::IS_CLIENT) {
+        EXPECT_CALL(*connection_,
+                    CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                    "Server must not send PRIORITY frames.", _))
+            .WillRepeatedly(InvokeWithoutArgs(
+                this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+      } else {
+        EXPECT_CALL(
+            session_,
+            OnPriorityFrame(stream_id, spdy::SpdyStreamPrecedence(priority)))
+            .Times(1);
+      }
+      stream_frame_.data_buffer = frame.data();
+      stream_frame_.data_length = frame.size();
+      headers_stream_->OnStreamFrame(stream_frame_);
+      stream_frame_.offset += frame.size();
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessPushPromiseDisabledSetting) {
+  if (perspective() != Perspective::IS_CLIENT) {
+    return;
+  }
+
+  session_.OnConfigNegotiated();
+  SpdySettingsIR data;
+  // Respect supported settings frames SETTINGS_ENABLE_PUSH.
+  data.AddSetting(SETTINGS_ENABLE_PUSH, 0);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                      "Unsupported field of HTTP/2 SETTINGS frame: 2", _));
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
+  // We want to create a frame that is more than the SPDY Framer's max control
+  // frame size, which is 16K, but less than the HPACK decoders max decode
+  // buffer size, which is 32K.
+  headers_["key0"] = std::string(1 << 13, '.');
+  headers_["key1"] = std::string(1 << 13, '.');
+  headers_["key2"] = std::string(1 << 13, '.');
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      for (SpdyPriority priority = 0; priority < 7; ++priority) {
+        // Replace with "WriteHeadersAndSaveData"
+        SpdySerializedFrame frame;
+        if (perspective() == Perspective::IS_SERVER) {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          headers_frame.set_has_priority(true);
+          headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
+          frame = framer_->SerializeFrame(headers_frame);
+          EXPECT_CALL(session_, OnStreamHeadersPriority(
+                                    stream_id, spdy::SpdyStreamPrecedence(0)));
+        } else {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          frame = framer_->SerializeFrame(headers_frame);
+        }
+        EXPECT_CALL(session_,
+                    OnStreamHeaderList(stream_id, fin, frame.size(), _))
+            .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
+        stream_frame_.data_buffer = frame.data();
+        stream_frame_.data_length = frame.size();
+        headers_stream_->OnStreamFrame(stream_frame_);
+        stream_frame_.offset += frame.size();
+        CheckHeaders();
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessBadData) {
+  const char kBadData[] = "blah blah blah";
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(::testing::AnyNumber());
+  stream_frame_.data_buffer = kBadData;
+  stream_frame_.data_length = strlen(kBadData);
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
+  SpdyDataIR data(/* stream_id = */ 2, "ping");
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "SPDY DATA frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
+  SpdyRstStreamIR data(/* stream_id = */ 2, ERROR_CODE_PROTOCOL_ERROR);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                              "SPDY RST_STREAM frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
+  const uint32_t kTestHeaderTableSize = 1000;
+  SpdySettingsIR data;
+  // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE,
+  // SETTINGS_MAX_HEADER_LIST_SIZE.
+  data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kTestHeaderTableSize);
+  data.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE, 2000);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+  EXPECT_EQ(kTestHeaderTableSize, QuicSpdySessionPeer::GetSpdyFramer(&session_)
+                                      ->header_encoder_table_size());
+}
+
+// Regression bug for b/208997000.
+TEST_P(QuicHeadersStreamTest, LimitEncoderDynamicTableSize) {
+  const uint32_t kVeryLargeTableSizeLimit = 1024 * 1024 * 1024;
+  SpdySettingsIR data;
+  data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kVeryLargeTableSizeLimit);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+  if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
+    EXPECT_EQ(16384u, QuicSpdySessionPeer::GetSpdyFramer(&session_)
+                          ->header_encoder_table_size());
+  } else {
+    EXPECT_EQ(kVeryLargeTableSizeLimit,
+              QuicSpdySessionPeer::GetSpdyFramer(&session_)
+                  ->header_encoder_table_size());
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
+  SpdySettingsIR data;
+  // Does not support SETTINGS_MAX_CONCURRENT_STREAMS,
+  // SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and
+  // SETTINGS_MAX_FRAME_SIZE.
+  data.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 100);
+  data.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 100);
+  data.AddSetting(SETTINGS_ENABLE_PUSH, 1);
+  data.AddSetting(SETTINGS_MAX_FRAME_SIZE, 1250);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_HEADERS_STREAM_DATA,
+                  absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                               SETTINGS_MAX_CONCURRENT_STREAMS),
+                  _));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_HEADERS_STREAM_DATA,
+                  absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                               SETTINGS_INITIAL_WINDOW_SIZE),
+                  _));
+  if (session_.perspective() == Perspective::IS_CLIENT) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(
+                    QUIC_INVALID_HEADERS_STREAM_DATA,
+                    absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                                 SETTINGS_ENABLE_PUSH),
+                    _));
+  }
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_HEADERS_STREAM_DATA,
+                  absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                               SETTINGS_MAX_FRAME_SIZE),
+                  _));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
+  SpdyPingIR data(1);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "SPDY PING frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
+  SpdyGoAwayIR data(/* last_good_stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR,
+                    "go away");
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "SPDY GOAWAY frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
+  SpdyWindowUpdateIR data(/* stream_id = */ 1, /* delta = */ 1);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                              "SPDY WINDOW_UPDATE frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) {
+  EXPECT_FALSE(QuicStreamPeer::StreamContributesToConnectionFlowControl(
+      headers_stream_));
+}
+
+TEST_P(QuicHeadersStreamTest, AckSentData) {
+  EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                       connection_->transport_version()),
+                                   _, _, NO_FIN, _, _))
+      .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  InSequence s;
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
+      new MockAckListener());
+
+  // Packet 1.
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+
+  // Packet 2.
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+
+  // Packet 3.
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+
+  // Packet 2 gets retransmitted.
+  EXPECT_CALL(*ack_listener3, OnPacketRetransmitted(7)).Times(1);
+  EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(7)).Times(1);
+  headers_stream_->OnStreamFrameRetransmitted(21, 7, false);
+  headers_stream_->OnStreamFrameRetransmitted(28, 7, false);
+
+  // Packets are acked in order: 2, 3, 1.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      21, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      28, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      35, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      0, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      7, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+  // Unsent data is acked.
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      14, 10, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+}
+
+TEST_P(QuicHeadersStreamTest, FrameContainsMultipleHeaders) {
+  // In this test, a stream frame can contain multiple headers.
+  EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                       connection_->transport_version()),
+                                   _, _, NO_FIN, _, _))
+      .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  InSequence s;
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
+      new MockAckListener());
+
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+
+  // Frame 1 is retransmitted.
+  EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(14));
+  EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(3));
+  headers_stream_->OnStreamFrameRetransmitted(0, 17, false);
+
+  // Frames are acked in order: 2, 3, 1.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(4, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(2, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      17, 13, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(13u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      30, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(12u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(14, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(3, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      0, 17, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(17u, newly_acked_length);
+}
+
+TEST_P(QuicHeadersStreamTest, HeadersGetAckedMultipleTimes) {
+  EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                       connection_->transport_version()),
+                                   _, _, NO_FIN, _, _))
+      .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  InSequence s;
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
+      new MockAckListener());
+
+  // Send [0, 42).
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+
+  // Ack [15, 20), [5, 25), [10, 17), [0, 12) and [22, 42).
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      15, 5, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(5u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(9, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(4, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      5, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(15u, newly_acked_length);
+
+  // Duplicate ack.
+  EXPECT_FALSE(headers_stream_->OnStreamFrameAcked(
+      10, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      0, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(5u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(3, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      22, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(17u, newly_acked_length);
+}
+
+TEST_P(QuicHeadersStreamTest, CloseOnPushPromiseToServer) {
+  if (perspective() == Perspective::IS_CLIENT) {
+    return;
+  }
+  QuicStreamId promised_id = 1;
+  SpdyPushPromiseIR push_promise(client_id_1_, promised_id, headers_.Clone());
+  SpdySerializedFrame frame = framer_->SerializeFrame(push_promise);
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  EXPECT_CALL(session_, OnStreamHeaderList(_, _, _, _));
+  // TODO(lassey): Check for HTTP_WRONG_STREAM error code.
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "PUSH_PROMISE not supported.", _));
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_receive_control_stream.cc b/quiche/quic/core/http/quic_receive_control_stream.cc
new file mode 100644
index 0000000..5c624b2
--- /dev/null
+++ b/quiche/quic/core/http/quic_receive_control_stream.cc
@@ -0,0 +1,274 @@
+// Copyright 2019 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 "quiche/quic/core/http/quic_receive_control_stream.h"
+
+#include <utility>
+
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+QuicReceiveControlStream::QuicReceiveControlStream(
+    PendingStream* pending,
+    QuicSpdySession* spdy_session)
+    : QuicStream(pending,
+                 spdy_session,
+                 /*is_static=*/true),
+      settings_frame_received_(false),
+      decoder_(this),
+      spdy_session_(spdy_session) {
+  sequencer()->set_level_triggered(true);
+}
+
+QuicReceiveControlStream::~QuicReceiveControlStream() {}
+
+void QuicReceiveControlStream::OnStreamReset(
+    const QuicRstStreamFrame& /*frame*/) {
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+      "RESET_STREAM received for receive control stream");
+}
+
+void QuicReceiveControlStream::OnDataAvailable() {
+  iovec iov;
+  while (!reading_stopped() && decoder_.error() == QUIC_NO_ERROR &&
+         sequencer()->GetReadableRegion(&iov)) {
+    QUICHE_DCHECK(!sequencer()->IsClosed());
+
+    QuicByteCount processed_bytes = decoder_.ProcessInput(
+        reinterpret_cast<const char*>(iov.iov_base), iov.iov_len);
+    sequencer()->MarkConsumed(processed_bytes);
+
+    if (!session()->connection()->connected()) {
+      return;
+    }
+
+    // The only reason QuicReceiveControlStream pauses HttpDecoder is an error,
+    // in which case the connection would have already been closed.
+    QUICHE_DCHECK_EQ(iov.iov_len, processed_bytes);
+  }
+}
+
+void QuicReceiveControlStream::OnError(HttpDecoder* decoder) {
+  stream_delegate()->OnStreamError(decoder->error(), decoder->error_detail());
+}
+
+bool QuicReceiveControlStream::OnMaxPushIdFrame(const MaxPushIdFrame& frame) {
+  if (GetQuicReloadableFlag(quic_ignore_max_push_id)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_ignore_max_push_id);
+    return ValidateFrameType(HttpFrameType::MAX_PUSH_ID);
+  }
+
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnMaxPushIdFrameReceived(frame);
+  }
+
+  if (!ValidateFrameType(HttpFrameType::MAX_PUSH_ID)) {
+    return false;
+  }
+
+  return spdy_session()->OnMaxPushIdFrame(frame.push_id);
+}
+
+bool QuicReceiveControlStream::OnGoAwayFrame(const GoAwayFrame& frame) {
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnGoAwayFrameReceived(frame);
+  }
+
+  if (!ValidateFrameType(HttpFrameType::GOAWAY)) {
+    return false;
+  }
+
+  spdy_session()->OnHttp3GoAway(frame.id);
+  return true;
+}
+
+bool QuicReceiveControlStream::OnSettingsFrameStart(
+    QuicByteCount /*header_length*/) {
+  return ValidateFrameType(HttpFrameType::SETTINGS);
+}
+
+bool QuicReceiveControlStream::OnSettingsFrame(const SettingsFrame& frame) {
+  QUIC_DVLOG(1) << "Control Stream " << id()
+                << " received settings frame: " << frame;
+  return spdy_session_->OnSettingsFrame(frame);
+}
+
+bool QuicReceiveControlStream::OnDataFrameStart(QuicByteCount /*header_length*/,
+                                                QuicByteCount
+                                                /*payload_length*/) {
+  return ValidateFrameType(HttpFrameType::DATA);
+}
+
+bool QuicReceiveControlStream::OnDataFramePayload(
+    absl::string_view /*payload*/) {
+  QUICHE_NOTREACHED();
+  return false;
+}
+
+bool QuicReceiveControlStream::OnDataFrameEnd() {
+  QUICHE_NOTREACHED();
+  return false;
+}
+
+bool QuicReceiveControlStream::OnHeadersFrameStart(
+    QuicByteCount /*header_length*/,
+    QuicByteCount
+    /*payload_length*/) {
+  return ValidateFrameType(HttpFrameType::HEADERS);
+}
+
+bool QuicReceiveControlStream::OnHeadersFramePayload(
+    absl::string_view /*payload*/) {
+  QUICHE_NOTREACHED();
+  return false;
+}
+
+bool QuicReceiveControlStream::OnHeadersFrameEnd() {
+  QUICHE_NOTREACHED();
+  return false;
+}
+
+bool QuicReceiveControlStream::OnPriorityUpdateFrameStart(
+    QuicByteCount /*header_length*/) {
+  return ValidateFrameType(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM);
+}
+
+bool QuicReceiveControlStream::OnPriorityUpdateFrame(
+    const PriorityUpdateFrame& frame) {
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnPriorityUpdateFrameReceived(frame);
+  }
+
+  // TODO(b/147306124): Use a proper structured headers parser instead.
+  for (absl::string_view key_value :
+       absl::StrSplit(frame.priority_field_value, ',')) {
+    std::vector<absl::string_view> key_and_value =
+        absl::StrSplit(key_value, '=');
+    if (key_and_value.size() != 2) {
+      continue;
+    }
+
+    absl::string_view key = key_and_value[0];
+    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&key);
+    if (key != "u") {
+      continue;
+    }
+
+    absl::string_view value = key_and_value[1];
+    int urgency;
+    if (!absl::SimpleAtoi(value, &urgency) || urgency < 0 || urgency > 7) {
+      stream_delegate()->OnStreamError(
+          QUIC_INVALID_PRIORITY_UPDATE,
+          "Invalid value for PRIORITY_UPDATE urgency parameter.");
+      return false;
+    }
+
+    if (frame.prioritized_element_type == REQUEST_STREAM) {
+      return spdy_session_->OnPriorityUpdateForRequestStream(
+          frame.prioritized_element_id, urgency);
+    } else {
+      return spdy_session_->OnPriorityUpdateForPushStream(
+          frame.prioritized_element_id, urgency);
+    }
+  }
+
+  // Ignore frame if no urgency parameter can be parsed.
+  return true;
+}
+
+bool QuicReceiveControlStream::OnAcceptChFrameStart(
+    QuicByteCount /* header_length */) {
+  return ValidateFrameType(HttpFrameType::ACCEPT_CH);
+}
+
+bool QuicReceiveControlStream::OnAcceptChFrame(const AcceptChFrame& frame) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, spdy_session()->perspective());
+
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnAcceptChFrameReceived(frame);
+  }
+
+  spdy_session()->OnAcceptChFrame(frame);
+  return true;
+}
+
+void QuicReceiveControlStream::OnWebTransportStreamFrameType(
+    QuicByteCount /*header_length*/,
+    WebTransportSessionId /*session_id*/) {
+  QUIC_BUG(WEBTRANSPORT_STREAM on Control Stream)
+      << "Parsed WEBTRANSPORT_STREAM on a control stream.";
+}
+
+bool QuicReceiveControlStream::OnUnknownFrameStart(
+    uint64_t frame_type,
+    QuicByteCount /*header_length*/,
+    QuicByteCount payload_length) {
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnUnknownFrameReceived(id(), frame_type,
+                                                            payload_length);
+  }
+
+  return ValidateFrameType(static_cast<HttpFrameType>(frame_type));
+}
+
+bool QuicReceiveControlStream::OnUnknownFramePayload(
+    absl::string_view /*payload*/) {
+  // Ignore unknown frame types.
+  return true;
+}
+
+bool QuicReceiveControlStream::OnUnknownFrameEnd() {
+  // Ignore unknown frame types.
+  return true;
+}
+
+bool QuicReceiveControlStream::ValidateFrameType(HttpFrameType frame_type) {
+  // Certain frame types are forbidden.
+  if (frame_type == HttpFrameType::DATA ||
+      frame_type == HttpFrameType::HEADERS ||
+      (spdy_session()->perspective() == Perspective::IS_CLIENT &&
+       frame_type == HttpFrameType::MAX_PUSH_ID) ||
+      (spdy_session()->perspective() == Perspective::IS_SERVER &&
+       frame_type == HttpFrameType::ACCEPT_CH)) {
+    stream_delegate()->OnStreamError(
+        QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
+        absl::StrCat("Invalid frame type ", static_cast<int>(frame_type),
+                     " received on control stream."));
+    return false;
+  }
+
+  if (settings_frame_received_) {
+    if (frame_type == HttpFrameType::SETTINGS) {
+      // SETTINGS frame may only be the first frame on the control stream.
+      stream_delegate()->OnStreamError(
+          QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
+          "SETTINGS frame can only be received once.");
+      return false;
+    }
+    return true;
+  }
+
+  if (frame_type == HttpFrameType::SETTINGS) {
+    settings_frame_received_ = true;
+    return true;
+  }
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_MISSING_SETTINGS_FRAME,
+      absl::StrCat("First frame received on control stream is type ",
+                   static_cast<int>(frame_type), ", but it must be SETTINGS."));
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_receive_control_stream.h b/quiche/quic/core/http/quic_receive_control_stream.h
new file mode 100644
index 0000000..70fa63a
--- /dev/null
+++ b/quiche/quic/core/http/quic_receive_control_stream.h
@@ -0,0 +1,79 @@
+// Copyright 2019 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_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
+
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicSpdySession;
+
+// 3.2.1 Control Stream.
+// The receive control stream is peer initiated and is read only.
+class QUIC_EXPORT_PRIVATE QuicReceiveControlStream
+    : public QuicStream,
+      public HttpDecoder::Visitor {
+ public:
+  explicit QuicReceiveControlStream(PendingStream* pending,
+                                    QuicSpdySession* spdy_session);
+  QuicReceiveControlStream(const QuicReceiveControlStream&) = delete;
+  QuicReceiveControlStream& operator=(const QuicReceiveControlStream&) = delete;
+  ~QuicReceiveControlStream() override;
+
+  // Overriding QuicStream::OnStreamReset to make sure control stream is never
+  // closed before connection.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+  // Implementation of QuicStream.
+  void OnDataAvailable() override;
+
+  // HttpDecoder::Visitor implementation.
+  void OnError(HttpDecoder* decoder) override;
+  bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) override;
+  bool OnGoAwayFrame(const GoAwayFrame& frame) override;
+  bool OnSettingsFrameStart(QuicByteCount header_length) override;
+  bool OnSettingsFrame(const SettingsFrame& frame) override;
+  bool OnDataFrameStart(QuicByteCount header_length,
+                        QuicByteCount payload_length) override;
+  bool OnDataFramePayload(absl::string_view payload) override;
+  bool OnDataFrameEnd() override;
+  bool OnHeadersFrameStart(QuicByteCount header_length,
+                           QuicByteCount payload_length) override;
+  bool OnHeadersFramePayload(absl::string_view payload) override;
+  bool OnHeadersFrameEnd() override;
+  bool OnPriorityUpdateFrameStart(QuicByteCount header_length) override;
+  bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) override;
+  bool OnAcceptChFrameStart(QuicByteCount header_length) override;
+  bool OnAcceptChFrame(const AcceptChFrame& frame) override;
+  void OnWebTransportStreamFrameType(QuicByteCount header_length,
+                                     WebTransportSessionId session_id) override;
+  bool OnUnknownFrameStart(uint64_t frame_type,
+                           QuicByteCount header_length,
+                           QuicByteCount payload_length) override;
+  bool OnUnknownFramePayload(absl::string_view payload) override;
+  bool OnUnknownFrameEnd() override;
+
+  QuicSpdySession* spdy_session() { return spdy_session_; }
+
+ private:
+  // Called when a frame of allowed type is received.  Returns true if the frame
+  // is allowed in this position.  Returns false and resets the stream
+  // otherwise.
+  bool ValidateFrameType(HttpFrameType frame_type);
+
+  // False until a SETTINGS frame is received.
+  bool settings_frame_received_;
+
+  HttpDecoder decoder_;
+  QuicSpdySession* const spdy_session_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
diff --git a/quiche/quic/core/http/quic_receive_control_stream_test.cc b/quiche/quic/core/http/quic_receive_control_stream_test.cc
new file mode 100644
index 0000000..4ef68c4
--- /dev/null
+++ b/quiche/quic/core/http/quic_receive_control_stream_test.cc
@@ -0,0 +1,483 @@
+// Copyright 2019 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 "quiche/quic/core/http/quic_receive_control_stream.h"
+
+#include "absl/memory/memory.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+
+class QpackEncoder;
+
+namespace test {
+
+namespace {
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::StrictMock;
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams: " << *this;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
+    os << "{ version: " << ParsedQuicVersionToString(tp.version)
+       << ", perspective: "
+       << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
+       << "}";
+    return os;
+  }
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& tp) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(tp.version), "_",
+      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (const auto& version : AllSupportedVersions()) {
+    if (!VersionUsesHttp3(version.transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(version, p);
+    }
+  }
+  return params;
+}
+
+class TestStream : public QuicSpdyStream {
+ public:
+  TestStream(QuicStreamId id, QuicSpdySession* session)
+      : QuicSpdyStream(id, session, BIDIRECTIONAL) {}
+  ~TestStream() override = default;
+
+  void OnBodyAvailable() override {}
+};
+
+class QuicReceiveControlStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QuicReceiveControlStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_,
+            &alarm_factory_,
+            perspective(),
+            SupportedVersions(GetParam().version))),
+        session_(connection_) {
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    QuicStreamId id = perspective() == Perspective::IS_SERVER
+                          ? GetNthClientInitiatedUnidirectionalStreamId(
+                                session_.transport_version(), 3)
+                          : GetNthServerInitiatedUnidirectionalStreamId(
+                                session_.transport_version(), 3);
+    char type[] = {kControlStream};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_.OnStreamFrame(data1);
+
+    receive_control_stream_ =
+        QuicSpdySessionPeer::GetReceiveControlStream(&session_);
+
+    stream_ = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
+                                 GetParam().version.transport_version, 0),
+                             &session_);
+    session_.ActivateStream(absl::WrapUnique(stream_));
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  std::string EncodeSettings(const SettingsFrame& settings) {
+    std::unique_ptr<char[]> buffer;
+    QuicByteCount settings_frame_length =
+        HttpEncoder::SerializeSettingsFrame(settings, &buffer);
+    return std::string(buffer.get(), settings_frame_length);
+  }
+
+  std::string SerializePriorityUpdateFrame(
+      const PriorityUpdateFrame& priority_update) {
+    std::unique_ptr<char[]> priority_buffer;
+    QuicByteCount priority_frame_length =
+        HttpEncoder::SerializePriorityUpdateFrame(priority_update,
+                                                  &priority_buffer);
+    return std::string(priority_buffer.get(), priority_frame_length);
+  }
+
+  QuicStreamOffset NumBytesConsumed() {
+    return QuicStreamPeer::sequencer(receive_control_stream_)
+        ->NumBytesConsumed();
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QuicReceiveControlStream* receive_control_stream_;
+  TestStream* stream_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicReceiveControlStreamTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicReceiveControlStreamTest, ResetControlStream) {
+  EXPECT_TRUE(receive_control_stream_->is_static());
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId,
+                               receive_control_stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
+  receive_control_stream_->OnStreamReset(rst_frame);
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveSettings) {
+  SettingsFrame settings;
+  settings.values[10] = 2;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 12;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 37;
+  std::string data = EncodeSettings(settings);
+  QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data);
+
+  QpackEncoder* qpack_encoder = session_.qpack_encoder();
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(qpack_encoder);
+  EXPECT_EQ(std::numeric_limits<size_t>::max(),
+            session_.max_outbound_header_list_size());
+  EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+  EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
+
+  receive_control_stream_->OnStreamFrame(frame);
+
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+  EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+  EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity());
+}
+
+// Regression test for https://crbug.com/982648.
+// QuicReceiveControlStream::OnDataAvailable() must stop processing input as
+// soon as OnSettingsFrameStart() is called by HttpDecoder for the second frame.
+TEST_P(QuicReceiveControlStreamTest, ReceiveSettingsTwice) {
+  SettingsFrame settings;
+  // Reserved identifiers, must be ignored.
+  settings.values[0x21] = 100;
+  settings.values[0x40] = 200;
+
+  std::string settings_frame = EncodeSettings(settings);
+
+  QuicStreamOffset offset = 1;
+  EXPECT_EQ(offset, NumBytesConsumed());
+
+  // Receive first SETTINGS frame.
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
+                      settings_frame));
+  offset += settings_frame.length();
+
+  // First SETTINGS frame is consumed.
+  EXPECT_EQ(offset, NumBytesConsumed());
+
+  // Second SETTINGS frame causes the connection to be closed.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
+                      "SETTINGS frame can only be received once.", _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  // Receive second SETTINGS frame.
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
+                      settings_frame));
+
+  // Frame header of second SETTINGS frame is consumed, but not frame payload.
+  QuicByteCount settings_frame_header_length = 2;
+  EXPECT_EQ(offset + settings_frame_header_length, NumBytesConsumed());
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveSettingsFragments) {
+  SettingsFrame settings;
+  settings.values[10] = 2;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  std::string data = EncodeSettings(settings);
+  std::string data1 = data.substr(0, 1);
+  std::string data2 = data.substr(1, data.length() - 1);
+
+  QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data1);
+  QuicStreamFrame frame2(receive_control_stream_->id(), false, 2, data2);
+  EXPECT_NE(5u, session_.max_outbound_header_list_size());
+  receive_control_stream_->OnStreamFrame(frame);
+  receive_control_stream_->OnStreamFrame(frame2);
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveWrongFrame) {
+  // DATA frame header without payload.
+  quiche::QuicheBuffer data = HttpEncoder::SerializeDataFrameHeader(
+      /* payload_length = */ 2, quiche::SimpleBufferAllocator::Get());
+
+  QuicStreamFrame frame(receive_control_stream_->id(), false, 1,
+                        data.AsStringView());
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM, _, _));
+  receive_control_stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicReceiveControlStreamTest,
+       ReceivePriorityUpdateFrameBeforeSettingsFrame) {
+  std::string serialized_frame = SerializePriorityUpdateFrame({});
+  QuicStreamFrame data(receive_control_stream_->id(), /* fin = */ false,
+                       /* offset = */ 1, serialized_frame);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
+                              "First frame received on control stream is type "
+                              "984832, but it must be SETTINGS.",
+                              _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  receive_control_stream_->OnStreamFrame(data);
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveGoAwayFrame) {
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  QuicStreamOffset offset = 1;
+
+  // Receive SETTINGS frame.
+  SettingsFrame settings;
+  std::string settings_frame = EncodeSettings(settings);
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
+                      settings_frame));
+  offset += settings_frame.length();
+
+  GoAwayFrame goaway{/* id = */ 0};
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
+  std::string data = std::string(buffer.get(), header_length);
+
+  QuicStreamFrame frame(receive_control_stream_->id(), false, offset, data);
+  EXPECT_FALSE(session_.goaway_received());
+
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameReceived(goaway));
+
+  receive_control_stream_->OnStreamFrame(frame);
+  EXPECT_TRUE(session_.goaway_received());
+}
+
+TEST_P(QuicReceiveControlStreamTest, PushPromiseOnControlStreamShouldClose) {
+  std::string push_promise_frame = absl::HexStringToBytes(
+      "05"    // PUSH_PROMISE
+      "01"    // length
+      "00");  // push ID
+  QuicStreamFrame frame(receive_control_stream_->id(), false, 1,
+                        push_promise_frame);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+  receive_control_stream_->OnStreamFrame(frame);
+}
+
+// Regression test for b/137554973: unknown frames should be consumed.
+TEST_P(QuicReceiveControlStreamTest, ConsumeUnknownFrame) {
+  EXPECT_EQ(1u, NumBytesConsumed());
+
+  QuicStreamOffset offset = 1;
+
+  // Receive SETTINGS frame.
+  std::string settings_frame = EncodeSettings({});
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
+                      settings_frame));
+  offset += settings_frame.length();
+
+  // SETTINGS frame is consumed.
+  EXPECT_EQ(offset, NumBytesConsumed());
+
+  // Receive unknown frame.
+  std::string unknown_frame = absl::HexStringToBytes(
+      "21"        // reserved frame type
+      "03"        // payload length
+      "666f6f");  // payload "foo"
+
+  receive_control_stream_->OnStreamFrame(QuicStreamFrame(
+      receive_control_stream_->id(), /* fin = */ false, offset, unknown_frame));
+  offset += unknown_frame.size();
+
+  // Unknown frame is consumed.
+  EXPECT_EQ(offset, NumBytesConsumed());
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveUnknownFrame) {
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  const QuicStreamId id = receive_control_stream_->id();
+  QuicStreamOffset offset = 1;
+
+  // Receive SETTINGS frame.
+  SettingsFrame settings;
+  std::string settings_frame = EncodeSettings(settings);
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(id, /* fin = */ false, offset, settings_frame));
+  offset += settings_frame.length();
+
+  // Receive unknown frame.
+  std::string unknown_frame = absl::HexStringToBytes(
+      "21"        // reserved frame type
+      "03"        // payload length
+      "666f6f");  // payload "foo"
+
+  EXPECT_CALL(debug_visitor, OnUnknownFrameReceived(id, /* frame_type = */ 0x21,
+                                                    /* payload_length = */ 3));
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(id, /* fin = */ false, offset, unknown_frame));
+}
+
+TEST_P(QuicReceiveControlStreamTest, CancelPushFrameBeforeSettings) {
+  std::string cancel_push_frame = absl::HexStringToBytes(
+      "03"    // type CANCEL_PUSH
+      "01"    // payload length
+      "01");  // push ID
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
+                                            "CANCEL_PUSH frame received.", _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
+                      /* offset = */ 1, cancel_push_frame));
+}
+
+TEST_P(QuicReceiveControlStreamTest, AcceptChFrameBeforeSettings) {
+  std::string accept_ch_frame = absl::HexStringToBytes(
+      "4089"  // type (ACCEPT_CH)
+      "00");  // length
+
+  if (perspective() == Perspective::IS_SERVER) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(
+                    QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
+                    "Invalid frame type 137 received on control stream.", _))
+        .WillOnce(
+            Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
+                                "First frame received on control stream is "
+                                "type 137, but it must be SETTINGS.",
+                                _))
+        .WillOnce(
+            Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  }
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
+                      /* offset = */ 1, accept_ch_frame));
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveAcceptChFrame) {
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  const QuicStreamId id = receive_control_stream_->id();
+  QuicStreamOffset offset = 1;
+
+  // Receive SETTINGS frame.
+  SettingsFrame settings;
+  std::string settings_frame = EncodeSettings(settings);
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(id, /* fin = */ false, offset, settings_frame));
+  offset += settings_frame.length();
+
+  // Receive ACCEPT_CH frame.
+  std::string accept_ch_frame = absl::HexStringToBytes(
+      "4089"  // type (ACCEPT_CH)
+      "00");  // length
+
+  if (perspective() == Perspective::IS_CLIENT) {
+    EXPECT_CALL(debug_visitor, OnAcceptChFrameReceived(_));
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(
+                    QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
+                    "Invalid frame type 137 received on control stream.", _))
+        .WillOnce(
+            Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+    EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+    EXPECT_CALL(session_, OnConnectionClosed(_, _));
+  }
+
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(id, /* fin = */ false, offset, accept_ch_frame));
+}
+
+TEST_P(QuicReceiveControlStreamTest, UnknownFrameBeforeSettings) {
+  std::string unknown_frame = absl::HexStringToBytes(
+      "21"        // reserved frame type
+      "03"        // payload length
+      "666f6f");  // payload "foo"
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
+                              "First frame received on control stream is type "
+                              "33, but it must be SETTINGS.",
+                              _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
+                      /* offset = */ 1, unknown_frame));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_send_control_stream.cc b/quiche/quic/core/http/quic_send_control_stream.cc
new file mode 100644
index 0000000..f021f3d
--- /dev/null
+++ b/quiche/quic/core/http/quic_send_control_stream.cc
@@ -0,0 +1,124 @@
+// Copyright 2019 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 "quiche/quic/core/http/quic_send_control_stream.h"
+#include <cstdint>
+#include <memory>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSendControlStream::QuicSendControlStream(QuicStreamId id,
+                                             QuicSpdySession* spdy_session,
+                                             const SettingsFrame& settings)
+    : QuicStream(id, spdy_session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
+      settings_sent_(false),
+      settings_(settings),
+      spdy_session_(spdy_session) {}
+
+void QuicSendControlStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  QUIC_BUG(quic_bug_10382_1)
+      << "OnStreamReset() called for write unidirectional stream.";
+}
+
+bool QuicSendControlStream::OnStopSending(QuicResetStreamError /* code */) {
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+      "STOP_SENDING received for send control stream");
+  return false;
+}
+
+void QuicSendControlStream::MaybeSendSettingsFrame() {
+  if (settings_sent_) {
+    return;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  // Send the stream type on so the peer knows about this stream.
+  char data[sizeof(kControlStream)];
+  QuicDataWriter writer(ABSL_ARRAYSIZE(data), data);
+  writer.WriteVarInt62(kControlStream);
+  WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
+                    nullptr);
+
+  SettingsFrame settings = settings_;
+  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.4.1
+  // specifies that setting identifiers of 0x1f * N + 0x21 are reserved and
+  // greasing should be attempted.
+  if (!GetQuicFlag(FLAGS_quic_enable_http3_grease_randomness)) {
+    settings.values[0x40] = 20;
+  } else {
+    uint32_t result;
+    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
+    uint64_t setting_id = 0x1fULL * static_cast<uint64_t>(result) + 0x21ULL;
+    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
+    settings.values[setting_id] = result;
+  }
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount frame_length =
+      HttpEncoder::SerializeSettingsFrame(settings, &buffer);
+  QUIC_DVLOG(1) << "Control stream " << id() << " is writing settings frame "
+                << settings;
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnSettingsFrameSent(settings);
+  }
+  WriteOrBufferData(absl::string_view(buffer.get(), frame_length),
+                    /*fin = */ false, nullptr);
+  settings_sent_ = true;
+
+  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.9
+  // specifies that a reserved frame type has no semantic meaning and should be
+  // discarded. A greasing frame is added here.
+  std::unique_ptr<char[]> grease;
+  QuicByteCount grease_length = HttpEncoder::SerializeGreasingFrame(&grease);
+  WriteOrBufferData(absl::string_view(grease.get(), grease_length),
+                    /*fin = */ false, nullptr);
+}
+
+void QuicSendControlStream::WritePriorityUpdate(
+    const PriorityUpdateFrame& priority_update) {
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  MaybeSendSettingsFrame();
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnPriorityUpdateFrameSent(priority_update);
+  }
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount frame_length =
+      HttpEncoder::SerializePriorityUpdateFrame(priority_update, &buffer);
+  QUIC_DVLOG(1) << "Control Stream " << id() << " is writing "
+                << priority_update;
+  WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false,
+                    nullptr);
+}
+
+void QuicSendControlStream::SendGoAway(QuicStreamId id) {
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  MaybeSendSettingsFrame();
+
+  GoAwayFrame frame;
+  frame.id = id;
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnGoAwayFrameSent(id);
+  }
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount frame_length =
+      HttpEncoder::SerializeGoAwayFrame(frame, &buffer);
+  WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false,
+                    nullptr);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_send_control_stream.h b/quiche/quic/core/http/quic_send_control_stream.h
new file mode 100644
index 0000000..49076bb
--- /dev/null
+++ b/quiche/quic/core/http/quic_send_control_stream.h
@@ -0,0 +1,64 @@
+// Copyright 2019 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_HTTP_QUIC_SEND_CONTROL_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
+
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+class QuicSpdySession;
+
+// 6.2.1 Control Stream.
+// The send control stream is self initiated and is write only.
+class QUIC_EXPORT_PRIVATE QuicSendControlStream : public QuicStream {
+ public:
+  // |session| can't be nullptr, and the ownership is not passed. The stream can
+  // only be accessed through the session.
+  QuicSendControlStream(QuicStreamId id,
+                        QuicSpdySession* session,
+                        const SettingsFrame& settings);
+  QuicSendControlStream(const QuicSendControlStream&) = delete;
+  QuicSendControlStream& operator=(const QuicSendControlStream&) = delete;
+  ~QuicSendControlStream() override = default;
+
+  // Overriding QuicStream::OnStopSending() to make sure control stream is never
+  // closed before connection.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+  bool OnStopSending(QuicResetStreamError code) override;
+
+  // Send SETTINGS frame if it hasn't been sent yet. Settings frame must be the
+  // first frame sent on this stream.
+  void MaybeSendSettingsFrame();
+
+  // Send a PRIORITY_UPDATE frame on this stream, and a SETTINGS frame
+  // beforehand if one has not been already sent.
+  void WritePriorityUpdate(const PriorityUpdateFrame& priority_update);
+
+  // Send a GOAWAY frame on this stream, and a SETTINGS frame beforehand if one
+  // has not been already sent.
+  void SendGoAway(QuicStreamId id);
+
+  // The send control stream is write unidirectional, so this method should
+  // never be called.
+  void OnDataAvailable() override { QUIC_NOTREACHED(); }
+
+ private:
+  // Track if a settings frame is already sent.
+  bool settings_sent_;
+
+  // SETTINGS values to send.
+  const SettingsFrame settings_;
+
+  QuicSpdySession* const spdy_session_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
diff --git a/quiche/quic/core/http/quic_send_control_stream_test.cc b/quiche/quic/core/http/quic_send_control_stream_test.cc
new file mode 100644
index 0000000..aa7606f
--- /dev/null
+++ b/quiche/quic/core/http/quic_send_control_stream_test.cc
@@ -0,0 +1,300 @@
+// Copyright 2019 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 "quiche/quic/core/http/quic_send_control_stream.h"
+
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Invoke;
+using ::testing::StrictMock;
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams: " << *this;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
+    os << "{ version: " << ParsedQuicVersionToString(tp.version)
+       << ", perspective: "
+       << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
+       << "}";
+    return os;
+  }
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& tp) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(tp.version), "_",
+      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (const auto& version : AllSupportedVersions()) {
+    if (!VersionUsesHttp3(version.transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(version, p);
+    }
+  }
+  return params;
+}
+
+class QuicSendControlStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QuicSendControlStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_, &alarm_factory_, perspective(),
+            SupportedVersions(GetParam().version))),
+        session_(connection_) {
+    ON_CALL(session_, WritevData(_, _, _, _, _, _))
+        .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  }
+
+  void Initialize() {
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    send_control_stream_ = QuicSpdySessionPeer::GetSendControlStream(&session_);
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3);
+    session_.OnConfigNegotiated();
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QuicSendControlStream* send_control_stream_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSendControlStreamTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSendControlStreamTest, WriteSettings) {
+  SetQuicFlag(FLAGS_quic_enable_http3_grease_randomness, false);
+  session_.set_qpack_maximum_dynamic_table_capacity(255);
+  session_.set_qpack_maximum_blocked_streams(16);
+  session_.set_max_inbound_header_list_size(1024);
+
+  Initialize();
+  testing::InSequence s;
+
+  std::string expected_write_data = absl::HexStringToBytes(
+      "00"    // stream type: control stream
+      "04"    // frame type: SETTINGS frame
+      "0b"    // frame length
+      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "40ff"  // 255
+      "06"    // SETTINGS_MAX_HEADER_LIST_SIZE
+      "4400"  // 1024
+      "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
+      "10"    // 16
+      "4040"  // 0x40 as the reserved settings id
+      "14"    // 20
+      "4040"  // 0x40 as the reserved frame type
+      "01"    // 1 byte frame length
+      "61");  //  payload "a"
+  if ((!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+       perspective() == Perspective::IS_CLIENT) &&
+      QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
+          HttpDatagramSupport::kDraft00And04) {
+    expected_write_data = absl::HexStringToBytes(
+        "00"         // stream type: control stream
+        "04"         // frame type: SETTINGS frame
+        "0e"         // frame length
+        "01"         // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+        "40ff"       // 255
+        "06"         // SETTINGS_MAX_HEADER_LIST_SIZE
+        "4400"       // 1024
+        "07"         // SETTINGS_QPACK_BLOCKED_STREAMS
+        "10"         // 16
+        "4040"       // 0x40 as the reserved settings id
+        "14"         // 20
+        "4276"       // SETTINGS_H3_DATAGRAM_DRAFT00
+        "01"         // 1
+        "800ffd277"  // SETTINGS_H3_DATAGRAM_DRAFT04
+        "01"         // 1
+        "4040"       // 0x40 as the reserved frame type
+        "01"         // 1 byte frame length
+        "61");       //  payload "a"
+  }
+  if (GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+      perspective() == Perspective::IS_SERVER &&
+      QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
+          HttpDatagramSupport::kNone) {
+    expected_write_data = absl::HexStringToBytes(
+        "00"    // stream type: control stream
+        "04"    // frame type: SETTINGS frame
+        "0d"    // frame length
+        "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+        "40ff"  // 255
+        "06"    // SETTINGS_MAX_HEADER_LIST_SIZE
+        "4400"  // 1024
+        "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
+        "10"    // 16
+        "08"    // SETTINGS_ENABLE_CONNECT_PROTOCOL
+        "01"    // 1
+        "4040"  // 0x40 as the reserved settings id
+        "14"    // 20
+        "4040"  // 0x40 as the reserved frame type
+        "01"    // 1 byte frame length
+        "61");  //  payload "a"
+  }
+  if (GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+      perspective() == Perspective::IS_SERVER &&
+      QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) !=
+          HttpDatagramSupport::kNone) {
+    expected_write_data = absl::HexStringToBytes(
+        "00"         // stream type: control stream
+        "04"         // frame type: SETTINGS frame
+        "11"         // frame length
+        "01"         // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+        "40ff"       // 255
+        "06"         // SETTINGS_MAX_HEADER_LIST_SIZE
+        "4400"       // 1024
+        "07"         // SETTINGS_QPACK_BLOCKED_STREAMS
+        "10"         // 16
+        "08"         // SETTINGS_ENABLE_CONNECT_PROTOCOL
+        "01"         // 1
+        "4040"       // 0x40 as the reserved settings id
+        "14"         // 20
+        "4276"       // SETTINGS_H3_DATAGRAM_DRAFT00
+        "01"         // 1
+        "800ffd277"  // SETTINGS_H3_DATAGRAM_DRAFT04
+        "01"         // 1
+        "4040"       // 0x40 as the reserved frame type
+        "01"         // 1 byte frame length
+        "61");       //  payload "a"
+  }
+
+  auto buffer = std::make_unique<char[]>(expected_write_data.size());
+  QuicDataWriter writer(expected_write_data.size(), buffer.get());
+
+  // A lambda to save and consume stream data when QuicSession::WritevData() is
+  // called.
+  auto save_write_data =
+      [&writer, this](QuicStreamId /*id*/, size_t write_length,
+                      QuicStreamOffset offset, StreamSendingState /*state*/,
+                      TransmissionType /*type*/,
+                      absl::optional<EncryptionLevel> /*level*/) {
+        send_control_stream_->WriteStreamData(offset, write_length, &writer);
+        return QuicConsumedData(/* bytes_consumed = */ write_length,
+                                /* fin_consumed = */ false);
+      };
+
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 1, _, _, _, _))
+      .WillOnce(Invoke(save_write_data));
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(),
+                                   expected_write_data.size() - 5, _, _, _, _))
+      .WillOnce(Invoke(save_write_data));
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 4, _, _, _, _))
+      .WillOnce(Invoke(save_write_data));
+
+  send_control_stream_->MaybeSendSettingsFrame();
+  quiche::test::CompareCharArraysWithHexError(
+      "settings", writer.data(), writer.length(), expected_write_data.data(),
+      expected_write_data.length());
+}
+
+TEST_P(QuicSendControlStreamTest, WriteSettingsOnlyOnce) {
+  Initialize();
+  testing::InSequence s;
+
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 1, _, _, _, _));
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
+      .Times(2);
+  send_control_stream_->MaybeSendSettingsFrame();
+
+  // No data should be written the second time MaybeSendSettingsFrame() is
+  // called.
+  send_control_stream_->MaybeSendSettingsFrame();
+}
+
+// Send stream type and SETTINGS frame if WritePriorityUpdate() is called first.
+TEST_P(QuicSendControlStreamTest, WritePriorityBeforeSettings) {
+  Initialize();
+  testing::InSequence s;
+
+  // The first write will trigger the control stream to write stream type, a
+  // SETTINGS frame, and a greased frame before the PRIORITY_UPDATE frame.
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
+      .Times(4);
+  PriorityUpdateFrame frame;
+  send_control_stream_->WritePriorityUpdate(frame);
+
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _));
+  send_control_stream_->WritePriorityUpdate(frame);
+}
+
+TEST_P(QuicSendControlStreamTest, CloseControlStream) {
+  Initialize();
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
+  send_control_stream_->OnStopSending(
+      QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED));
+}
+
+TEST_P(QuicSendControlStreamTest, ReceiveDataOnSendControlStream) {
+  Initialize();
+  QuicStreamFrame frame(send_control_stream_->id(), false, 0, "test");
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _));
+  send_control_stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSendControlStreamTest, SendGoAway) {
+  Initialize();
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  QuicStreamId stream_id = 4;
+
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(stream_id));
+
+  send_control_stream_->SendGoAway(stream_id);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_server_initiated_spdy_stream.cc b/quiche/quic/core/http/quic_server_initiated_spdy_stream.cc
new file mode 100644
index 0000000..da63760
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_initiated_spdy_stream.cc
@@ -0,0 +1,43 @@
+// Copyright 2021 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 "quiche/quic/core/http/quic_server_initiated_spdy_stream.h"
+#include "quiche/quic/core/quic_error_codes.h"
+
+namespace quic {
+
+void QuicServerInitiatedSpdyStream::OnBodyAvailable() {
+  QUIC_BUG(Body received in QuicServerInitiatedSpdyStream)
+      << "Received body data in QuicServerInitiatedSpdyStream.";
+  OnUnrecoverableError(
+      QUIC_INTERNAL_ERROR,
+      "Received HTTP/3 body data in a server-initiated bidirectional stream");
+}
+
+size_t QuicServerInitiatedSpdyStream::WriteHeaders(
+    spdy::SpdyHeaderBlock /*header_block*/, bool /*fin*/,
+    quiche::QuicheReferenceCountedPointer<
+        QuicAckListenerInterface> /*ack_listener*/) {
+  QUIC_BUG(Writing headers in QuicServerInitiatedSpdyStream)
+      << "Attempting to write headers in QuicServerInitiatedSpdyStream";
+  OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                       "Attempted to send HTTP/3 headers in a server-initiated "
+                       "bidirectional stream");
+  return 0;
+}
+
+void QuicServerInitiatedSpdyStream::OnInitialHeadersComplete(
+    bool /*fin*/,
+    size_t /*frame_len*/,
+    const QuicHeaderList& /*header_list*/) {
+  QUIC_PEER_BUG(Reading headers in QuicServerInitiatedSpdyStream)
+      << "Attempting to receive headers in QuicServerInitiatedSpdyStream";
+
+  OnUnrecoverableError(IETF_QUIC_PROTOCOL_VIOLATION,
+                       "Received HTTP/3 headers in a server-initiated "
+                       "bidirectional stream without an extension setting "
+                       "explicitly allowing those");
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_server_initiated_spdy_stream.h b/quiche/quic/core/http/quic_server_initiated_spdy_stream.h
new file mode 100644
index 0000000..d60296c
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_initiated_spdy_stream.h
@@ -0,0 +1,32 @@
+// Copyright 2021 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_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
+
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+
+namespace quic {
+
+// QuicServerInitiatedSpdyStream is a subclass of QuicSpdyStream meant to handle
+// WebTransport traffic on server-initiated bidirectional streams.  Receiving or
+// sending any other traffic on this stream will result in a CONNECTION_CLOSE.
+class QUIC_EXPORT_PRIVATE QuicServerInitiatedSpdyStream
+    : public QuicSpdyStream {
+ public:
+  using QuicSpdyStream::QuicSpdyStream;
+
+  void OnBodyAvailable() override;
+  size_t WriteHeaders(
+      spdy::SpdyHeaderBlock header_block, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener) override;
+  void OnInitialHeadersComplete(bool fin,
+                                size_t frame_len,
+                                const QuicHeaderList& header_list) override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
diff --git a/quiche/quic/core/http/quic_server_session_base.cc b/quiche/quic/core/http/quic_server_session_base.cc
new file mode 100644
index 0000000..b636e4c
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_session_base.cc
@@ -0,0 +1,374 @@
+// 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 "quiche/quic/core/http/quic_server_session_base.h"
+
+#include <string>
+
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicServerSessionBase::QuicServerSessionBase(
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection,
+    Visitor* visitor,
+    QuicCryptoServerStreamBase::Helper* helper,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache)
+    : QuicSpdySession(connection, visitor, config, supported_versions),
+      crypto_config_(crypto_config),
+      compressed_certs_cache_(compressed_certs_cache),
+      helper_(helper),
+      bandwidth_resumption_enabled_(false),
+      bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()),
+      last_scup_time_(QuicTime::Zero()) {}
+
+QuicServerSessionBase::~QuicServerSessionBase() {}
+
+void QuicServerSessionBase::Initialize() {
+  crypto_stream_ =
+      CreateQuicCryptoServerStream(crypto_config_, compressed_certs_cache_);
+  QuicSpdySession::Initialize();
+  SendSettingsToCryptoStream();
+}
+
+void QuicServerSessionBase::OnConfigNegotiated() {
+  QuicSpdySession::OnConfigNegotiated();
+
+  const bool use_lower_min_irtt =
+      connection()->sent_packet_manager().use_lower_min_irtt();
+
+  if (!use_lower_min_irtt) {
+    if (!config()->HasReceivedConnectionOptions()) {
+      return;
+    }
+  }
+
+  const CachedNetworkParameters* cached_network_params =
+      crypto_stream_->PreviousCachedNetworkParams();
+
+  // Set the initial rtt from cached_network_params.min_rtt_ms, which comes from
+  // a validated address token. This will override the initial rtt that may have
+  // been set by the transport parameters.
+  if (version().UsesTls() && cached_network_params != nullptr) {
+    if (cached_network_params->serving_region() == serving_region_) {
+      QUIC_CODE_COUNT(quic_server_received_network_params_at_same_region);
+      if ((!use_lower_min_irtt || config()->HasReceivedConnectionOptions()) &&
+          ContainsQuicTag(config()->ReceivedConnectionOptions(), kTRTT)) {
+        QUIC_DLOG(INFO)
+            << "Server: Setting initial rtt to "
+            << cached_network_params->min_rtt_ms()
+            << "ms which is received from a validated address token";
+        connection()->sent_packet_manager().SetInitialRtt(
+            QuicTime::Delta::FromMilliseconds(
+                cached_network_params->min_rtt_ms()),
+            /*trusted=*/use_lower_min_irtt);
+      }
+    } else {
+      QUIC_CODE_COUNT(quic_server_received_network_params_at_different_region);
+    }
+  }
+
+  if (use_lower_min_irtt) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_lower_min_for_trusted_irtt, 1, 2);
+    if (!config()->HasReceivedConnectionOptions()) {
+      return;
+    }
+  }
+
+  // Enable bandwidth resumption if peer sent correct connection options.
+  const bool last_bandwidth_resumption =
+      ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWRE);
+  const bool max_bandwidth_resumption =
+      ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWMX);
+  bandwidth_resumption_enabled_ =
+      last_bandwidth_resumption || max_bandwidth_resumption;
+
+  // If the client has provided a bandwidth estimate from the same serving
+  // region as this server, then decide whether to use the data for bandwidth
+  // resumption.
+  if (cached_network_params != nullptr &&
+      cached_network_params->serving_region() == serving_region_) {
+    if (!version().UsesTls()) {
+      // Log the received connection parameters, regardless of how they
+      // get used for bandwidth resumption.
+      connection()->OnReceiveConnectionState(*cached_network_params);
+    }
+
+    if (bandwidth_resumption_enabled_) {
+      // Only do bandwidth resumption if estimate is recent enough.
+      const uint64_t seconds_since_estimate =
+          connection()->clock()->WallNow().ToUNIXSeconds() -
+          cached_network_params->timestamp();
+      if (seconds_since_estimate <= kNumSecondsPerHour) {
+        connection()->ResumeConnectionState(*cached_network_params,
+                                            max_bandwidth_resumption);
+      }
+    }
+  }
+}
+
+void QuicServerSessionBase::OnConnectionClosed(
+    const QuicConnectionCloseFrame& frame,
+    ConnectionCloseSource source) {
+  QuicSession::OnConnectionClosed(frame, source);
+  // In the unlikely event we get a connection close while doing an asynchronous
+  // crypto event, make sure we cancel the callback.
+  if (crypto_stream_ != nullptr) {
+    crypto_stream_->CancelOutstandingCallbacks();
+  }
+}
+
+void QuicServerSessionBase::OnCongestionWindowChange(QuicTime now) {
+  if (!bandwidth_resumption_enabled_) {
+    return;
+  }
+  // Only send updates when the application has no data to write.
+  if (HasDataToWrite()) {
+    return;
+  }
+
+  // If not enough time has passed since the last time we sent an update to the
+  // client, or not enough packets have been sent, then return early.
+  const QuicSentPacketManager& sent_packet_manager =
+      connection()->sent_packet_manager();
+  int64_t srtt_ms =
+      sent_packet_manager.GetRttStats()->smoothed_rtt().ToMilliseconds();
+  int64_t now_ms = (now - last_scup_time_).ToMilliseconds();
+  int64_t packets_since_last_scup = 0;
+  const QuicPacketNumber largest_sent_packet =
+      connection()->sent_packet_manager().GetLargestSentPacket();
+  if (largest_sent_packet.IsInitialized()) {
+    packets_since_last_scup =
+        last_scup_packet_number_.IsInitialized()
+            ? largest_sent_packet - last_scup_packet_number_
+            : largest_sent_packet.ToUint64();
+  }
+  if (now_ms < (kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms) ||
+      now_ms < kMinIntervalBetweenServerConfigUpdatesMs ||
+      packets_since_last_scup < kMinPacketsBetweenServerConfigUpdates) {
+    return;
+  }
+
+  // If the bandwidth recorder does not have a valid estimate, return early.
+  const QuicSustainedBandwidthRecorder* bandwidth_recorder =
+      sent_packet_manager.SustainedBandwidthRecorder();
+  if (bandwidth_recorder == nullptr || !bandwidth_recorder->HasEstimate()) {
+    return;
+  }
+
+  // The bandwidth recorder has recorded at least one sustained bandwidth
+  // estimate. Check that it's substantially different from the last one that
+  // we sent to the client, and if so, send the new one.
+  QuicBandwidth new_bandwidth_estimate =
+      bandwidth_recorder->BandwidthEstimate();
+
+  int64_t bandwidth_delta =
+      std::abs(new_bandwidth_estimate.ToBitsPerSecond() -
+               bandwidth_estimate_sent_to_client_.ToBitsPerSecond());
+
+  // Define "substantial" difference as a 50% increase or decrease from the
+  // last estimate.
+  bool substantial_difference =
+      bandwidth_delta >
+      0.5 * bandwidth_estimate_sent_to_client_.ToBitsPerSecond();
+  if (!substantial_difference) {
+    return;
+  }
+
+  if (version().UsesTls()) {
+    if (version().HasIetfQuicFrames() && MaybeSendAddressToken()) {
+      bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
+    }
+  } else {
+    absl::optional<CachedNetworkParameters> cached_network_params =
+        GenerateCachedNetworkParameters();
+
+    if (cached_network_params.has_value()) {
+      bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
+      QUIC_DVLOG(1) << "Server: sending new bandwidth estimate (KBytes/s): "
+                    << bandwidth_estimate_sent_to_client_.ToKBytesPerSecond();
+
+      QUICHE_DCHECK_EQ(
+          BandwidthToCachedParameterBytesPerSecond(
+              bandwidth_estimate_sent_to_client_),
+          cached_network_params->bandwidth_estimate_bytes_per_second());
+
+      crypto_stream_->SendServerConfigUpdate(&cached_network_params.value());
+
+      connection()->OnSendConnectionState(*cached_network_params);
+    }
+  }
+
+  last_scup_time_ = now;
+  last_scup_packet_number_ =
+      connection()->sent_packet_manager().GetLargestSentPacket();
+}
+
+bool QuicServerSessionBase::ShouldCreateIncomingStream(QuicStreamId id) {
+  if (!connection()->connected()) {
+    QUIC_BUG(quic_bug_10393_2)
+        << "ShouldCreateIncomingStream called when disconnected";
+    return false;
+  }
+
+  if (QuicUtils::IsServerInitiatedStreamId(transport_version(), id)) {
+    QUIC_BUG(quic_bug_10393_3)
+        << "ShouldCreateIncomingStream called with server initiated "
+           "stream ID.";
+    return false;
+  }
+
+  if (QuicUtils::IsServerInitiatedStreamId(transport_version(), id)) {
+    QUIC_DLOG(INFO) << "Invalid incoming even stream_id:" << id;
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Client created even numbered stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  return true;
+}
+
+bool QuicServerSessionBase::ShouldCreateOutgoingBidirectionalStream() {
+  if (!connection()->connected()) {
+    QUIC_BUG(quic_bug_12513_2)
+        << "ShouldCreateOutgoingBidirectionalStream called when disconnected";
+    return false;
+  }
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_BUG(quic_bug_10393_4)
+        << "Encryption not established so no outgoing stream created.";
+    return false;
+  }
+
+  return CanOpenNextOutgoingBidirectionalStream();
+}
+
+bool QuicServerSessionBase::ShouldCreateOutgoingUnidirectionalStream() {
+  if (!connection()->connected()) {
+    QUIC_BUG(quic_bug_12513_3)
+        << "ShouldCreateOutgoingUnidirectionalStream called when disconnected";
+    return false;
+  }
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_BUG(quic_bug_10393_5)
+        << "Encryption not established so no outgoing stream created.";
+    return false;
+  }
+
+  return CanOpenNextOutgoingUnidirectionalStream();
+}
+
+QuicCryptoServerStreamBase* QuicServerSessionBase::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+const QuicCryptoServerStreamBase* QuicServerSessionBase::GetCryptoStream()
+    const {
+  return crypto_stream_.get();
+}
+
+int32_t QuicServerSessionBase::BandwidthToCachedParameterBytesPerSecond(
+    const QuicBandwidth& bandwidth) const {
+  return static_cast<int32_t>(std::min<int64_t>(
+      bandwidth.ToBytesPerSecond(), std::numeric_limits<uint32_t>::max()));
+}
+
+void QuicServerSessionBase::SendSettingsToCryptoStream() {
+  if (!version().UsesTls()) {
+    return;
+  }
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount buffer_size =
+      HttpEncoder::SerializeSettingsFrame(settings(), &buffer);
+
+  std::unique_ptr<ApplicationState> serialized_settings =
+      std::make_unique<ApplicationState>(buffer.get(),
+                                         buffer.get() + buffer_size);
+  GetMutableCryptoStream()->SetServerApplicationStateForResumption(
+      std::move(serialized_settings));
+}
+
+QuicSSLConfig QuicServerSessionBase::GetSSLConfig() const {
+  QUICHE_DCHECK(crypto_config_ && crypto_config_->proof_source());
+
+  QuicSSLConfig ssl_config = QuicSpdySession::GetSSLConfig();
+
+  ssl_config.disable_ticket_support =
+      GetQuicFlag(FLAGS_quic_disable_server_tls_resumption);
+
+  if (!crypto_config_ || !crypto_config_->proof_source()) {
+    return ssl_config;
+  }
+
+  absl::InlinedVector<uint16_t, 8> signature_algorithms =
+      crypto_config_->proof_source()->SupportedTlsSignatureAlgorithms();
+  if (!signature_algorithms.empty()) {
+    ssl_config.signing_algorithm_prefs = std::move(signature_algorithms);
+  }
+
+  return ssl_config;
+}
+
+absl::optional<CachedNetworkParameters>
+QuicServerSessionBase::GenerateCachedNetworkParameters() const {
+  const QuicSentPacketManager& sent_packet_manager =
+      connection()->sent_packet_manager();
+  const QuicSustainedBandwidthRecorder* bandwidth_recorder =
+      sent_packet_manager.SustainedBandwidthRecorder();
+
+  CachedNetworkParameters cached_network_params;
+  cached_network_params.set_timestamp(
+      connection()->clock()->WallNow().ToUNIXSeconds());
+
+  if (!sent_packet_manager.GetRttStats()->min_rtt().IsZero()) {
+    cached_network_params.set_min_rtt_ms(
+        sent_packet_manager.GetRttStats()->min_rtt().ToMilliseconds());
+  }
+
+  // Populate bandwidth estimates if any.
+  if (bandwidth_recorder != nullptr && bandwidth_recorder->HasEstimate()) {
+    const int32_t bw_estimate_bytes_per_second =
+        BandwidthToCachedParameterBytesPerSecond(
+            bandwidth_recorder->BandwidthEstimate());
+    const int32_t max_bw_estimate_bytes_per_second =
+        BandwidthToCachedParameterBytesPerSecond(
+            bandwidth_recorder->MaxBandwidthEstimate());
+    QUIC_BUG_IF(quic_bug_12513_1, max_bw_estimate_bytes_per_second < 0)
+        << max_bw_estimate_bytes_per_second;
+    QUIC_BUG_IF(quic_bug_10393_1, bw_estimate_bytes_per_second < 0)
+        << bw_estimate_bytes_per_second;
+
+    cached_network_params.set_bandwidth_estimate_bytes_per_second(
+        bw_estimate_bytes_per_second);
+    cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
+        max_bw_estimate_bytes_per_second);
+    cached_network_params.set_max_bandwidth_timestamp_seconds(
+        bandwidth_recorder->MaxBandwidthTimestamp());
+
+    cached_network_params.set_previous_connection_state(
+        bandwidth_recorder->EstimateRecordedDuringSlowStart()
+            ? CachedNetworkParameters::SLOW_START
+            : CachedNetworkParameters::CONGESTION_AVOIDANCE);
+  }
+
+  if (!serving_region_.empty()) {
+    cached_network_params.set_serving_region(serving_region_);
+  }
+
+  return cached_network_params;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_server_session_base.h b/quiche/quic/core/http/quic_server_session_base.h
new file mode 100644
index 0000000..d30b9dd
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_session_base.h
@@ -0,0 +1,151 @@
+// 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.
+
+// A server specific QuicSession subclass.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
+
+#include <cstdint>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicConfig;
+class QuicConnection;
+class QuicCryptoServerConfig;
+
+namespace test {
+class QuicServerSessionBasePeer;
+class QuicSimpleServerSessionPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
+ public:
+  // Does not take ownership of |connection|. |crypto_config| must outlive the
+  // session. |helper| must outlive any created crypto streams.
+  QuicServerSessionBase(const QuicConfig& config,
+                        const ParsedQuicVersionVector& supported_versions,
+                        QuicConnection* connection,
+                        QuicSession::Visitor* visitor,
+                        QuicCryptoServerStreamBase::Helper* helper,
+                        const QuicCryptoServerConfig* crypto_config,
+                        QuicCompressedCertsCache* compressed_certs_cache);
+  QuicServerSessionBase(const QuicServerSessionBase&) = delete;
+  QuicServerSessionBase& operator=(const QuicServerSessionBase&) = delete;
+
+  // Override the base class to cancel any ongoing asychronous crypto.
+  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                          ConnectionCloseSource source) override;
+
+  // Sends a server config update to the client, containing new bandwidth
+  // estimate.
+  void OnCongestionWindowChange(QuicTime now) override;
+
+  ~QuicServerSessionBase() override;
+
+  void Initialize() override;
+
+  const QuicCryptoServerStreamBase* crypto_stream() const {
+    return crypto_stream_.get();
+  }
+
+  // Override base class to process bandwidth related config received from
+  // client.
+  void OnConfigNegotiated() override;
+
+  void set_serving_region(const std::string& serving_region) {
+    serving_region_ = serving_region;
+  }
+
+  const std::string& serving_region() const { return serving_region_; }
+
+  QuicSSLConfig GetSSLConfig() const override;
+
+ protected:
+  // QuicSession methods(override them with return type of QuicSpdyStream*):
+  QuicCryptoServerStreamBase* GetMutableCryptoStream() override;
+
+  const QuicCryptoServerStreamBase* GetCryptoStream() const override;
+
+  absl::optional<CachedNetworkParameters> GenerateCachedNetworkParameters()
+      const override;
+
+  // If an outgoing stream can be created, return true.
+  // Return false when connection is closed or forward secure encryption hasn't
+  // established yet or number of server initiated streams already reaches the
+  // upper limit.
+  bool ShouldCreateOutgoingBidirectionalStream() override;
+  bool ShouldCreateOutgoingUnidirectionalStream() override;
+
+  // If we should create an incoming stream, returns true. Otherwise
+  // does error handling, including communicating the error to the client and
+  // possibly closing the connection, and returns false.
+  bool ShouldCreateIncomingStream(QuicStreamId id) override;
+
+  virtual std::unique_ptr<QuicCryptoServerStreamBase>
+  CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) = 0;
+
+  const QuicCryptoServerConfig* crypto_config() { return crypto_config_; }
+
+  QuicCryptoServerStreamBase::Helper* stream_helper() { return helper_; }
+
+ private:
+  friend class test::QuicServerSessionBasePeer;
+  friend class test::QuicSimpleServerSessionPeer;
+
+  // Informs the QuicCryptoStream of the SETTINGS that will be used on this
+  // connection, so that the server crypto stream knows whether to accept 0-RTT
+  // data.
+  void SendSettingsToCryptoStream();
+
+  const QuicCryptoServerConfig* crypto_config_;
+
+  // The cache which contains most recently compressed certs.
+  // Owned by QuicDispatcher.
+  QuicCompressedCertsCache* compressed_certs_cache_;
+
+  std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_;
+
+  // Pointer to the helper used to create crypto server streams. Must outlive
+  // streams created via CreateQuicCryptoServerStream.
+  QuicCryptoServerStreamBase::Helper* helper_;
+
+  // Whether bandwidth resumption is enabled for this connection.
+  bool bandwidth_resumption_enabled_;
+
+  // The most recent bandwidth estimate sent to the client.
+  QuicBandwidth bandwidth_estimate_sent_to_client_;
+
+  // Text describing server location. Sent to the client as part of the bandwith
+  // estimate in the source-address token. Optional, can be left empty.
+  std::string serving_region_;
+
+  // Time at which we send the last SCUP to the client.
+  QuicTime last_scup_time_;
+
+  // Number of packets sent to the peer, at the time we last sent a SCUP.
+  QuicPacketNumber last_scup_packet_number_;
+
+  // Converts QuicBandwidth to an int32 bytes/second that can be
+  // stored in CachedNetworkParameters.  TODO(jokulik): This function
+  // should go away once we fix http://b//27897982
+  int32_t BandwidthToCachedParameterBytesPerSecond(
+      const QuicBandwidth& bandwidth) const;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
diff --git a/quiche/quic/core/http/quic_server_session_base_test.cc b/quiche/quic/core/http/quic_server_session_base_test.cc
new file mode 100644
index 0000000..9b8dbcf
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_session_base_test.cc
@@ -0,0 +1,809 @@
+// Copyright 2013 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 "quiche/quic/core/http/quic_server_session_base.h"
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_crypto_server_stream.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/tls_server_handshaker.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/fake_proof_source.h"
+#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_server_session_base_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+using testing::_;
+using testing::StrictMock;
+
+using testing::AtLeast;
+
+namespace quic {
+namespace test {
+namespace {
+
+// Data to be sent on a request stream.  In Google QUIC, this is interpreted as
+// DATA payload (there is no framing on request streams).  In IETF QUIC, this is
+// interpreted as HEADERS frame (type 0x1) with payload length 122 ('z').  Since
+// no payload is included, QPACK decoder will not be invoked.
+const char* const kStreamData = "\1z";
+
+class TestServerSession : public QuicServerSessionBase {
+ public:
+  TestServerSession(const QuicConfig& config,
+                    QuicConnection* connection,
+                    QuicSession::Visitor* visitor,
+                    QuicCryptoServerStreamBase::Helper* helper,
+                    const QuicCryptoServerConfig* crypto_config,
+                    QuicCompressedCertsCache* compressed_certs_cache,
+                    QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicServerSessionBase(config,
+                              CurrentSupportedVersions(),
+                              connection,
+                              visitor,
+                              helper,
+                              crypto_config,
+                              compressed_certs_cache),
+        quic_simple_server_backend_(quic_simple_server_backend) {}
+
+  ~TestServerSession() override { DeleteConnection(); }
+
+  MOCK_METHOD(bool,
+              WriteControlFrame,
+              (const QuicFrame& frame, TransmissionType type),
+              (override));
+
+ protected:
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
+    if (!ShouldCreateIncomingStream(id)) {
+      return nullptr;
+    }
+    QuicSpdyStream* stream = new QuicSimpleServerStream(
+        id, this, BIDIRECTIONAL, quic_simple_server_backend_);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override {
+    QuicSpdyStream* stream =
+        new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  QuicSpdyStream* CreateOutgoingBidirectionalStream() override {
+    QUICHE_DCHECK(false);
+    return nullptr;
+  }
+
+  QuicSpdyStream* CreateOutgoingUnidirectionalStream() override {
+    if (!ShouldCreateOutgoingUnidirectionalStream()) {
+      return nullptr;
+    }
+
+    QuicSpdyStream* stream = new QuicSimpleServerStream(
+        GetNextOutgoingUnidirectionalStreamId(), this, WRITE_UNIDIRECTIONAL,
+        quic_simple_server_backend_);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) override {
+    return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
+                                    stream_helper());
+  }
+
+ private:
+  QuicSimpleServerBackend*
+      quic_simple_server_backend_;  // Owned by QuicServerSessionBaseTest
+};
+
+const size_t kMaxStreamsForTest = 10;
+
+class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicServerSessionBaseTest()
+      : QuicServerSessionBaseTest(crypto_test_utils::ProofSourceForTesting()) {}
+
+  explicit QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source)
+      : crypto_config_(QuicCryptoServerConfig::TESTING,
+                       QuicRandom::GetInstance(),
+                       std::move(proof_source),
+                       KeyExchangeSource::Default()),
+        compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
+    config_.SetMaxBidirectionalStreamsToSend(kMaxStreamsForTest);
+    config_.SetMaxUnidirectionalStreamsToSend(kMaxStreamsForTest);
+    QuicConfigPeer::SetReceivedMaxBidirectionalStreams(&config_,
+                                                       kMaxStreamsForTest);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(&config_,
+                                                        kMaxStreamsForTest);
+    config_.SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    config_.SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+
+    ParsedQuicVersionVector supported_versions = SupportedVersions(version());
+    connection_ = new StrictMock<MockQuicConnection>(
+        &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    session_ = std::make_unique<TestServerSession>(
+        config_, connection_, &owner_, &stream_helper_, &crypto_config_,
+        &compressed_certs_cache_, &memory_cache_backend_);
+    MockClock clock;
+    handshake_message_ = crypto_config_.AddDefaultConfig(
+        QuicRandom::GetInstance(), &clock,
+        QuicCryptoServerConfig::ConfigOptions());
+    session_->Initialize();
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_->config(), kMinimumFlowControlSendWindow);
+    session_->OnConfigNegotiated();
+    if (version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(connection_);
+    }
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
+  }
+
+  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
+    return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
+        transport_version(), n);
+  }
+
+  ParsedQuicVersion version() const { return GetParam(); }
+
+  QuicTransportVersion transport_version() const {
+    return version().transport_version;
+  }
+
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
+  // one-way close. This method can be used to inject a STOP_SENDING, which
+  // would cause a close in the opposite direction. This allows tests to do the
+  // extra work to get a two-way (full) close where desired. Also sets up
+  // expects needed to ensure that the STOP_SENDING worked as expected.
+  void InjectStopSendingFrame(QuicStreamId stream_id) {
+    if (!VersionHasIetfQuicFrames(transport_version())) {
+      // Only needed for version 99/IETF QUIC. Noop otherwise.
+      return;
+    }
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_id,
+                                      QUIC_ERROR_PROCESSING_STREAM);
+    EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(stream_id, QUIC_ERROR_PROCESSING_STREAM));
+    session_->OnStopSendingFrame(stop_sending);
+  }
+
+  StrictMock<MockQuicSessionVisitor> owner_;
+  StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  QuicConfig config_;
+  QuicCryptoServerConfig crypto_config_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+  QuicMemoryCacheBackend memory_cache_backend_;
+  std::unique_ptr<TestServerSession> session_;
+  std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
+};
+
+// Compares CachedNetworkParameters.
+MATCHER_P(EqualsProto, network_params, "") {
+  CachedNetworkParameters reference(network_params);
+  return (arg->bandwidth_estimate_bytes_per_second() ==
+              reference.bandwidth_estimate_bytes_per_second() &&
+          arg->bandwidth_estimate_bytes_per_second() ==
+              reference.bandwidth_estimate_bytes_per_second() &&
+          arg->max_bandwidth_estimate_bytes_per_second() ==
+              reference.max_bandwidth_estimate_bytes_per_second() &&
+          arg->max_bandwidth_timestamp_seconds() ==
+              reference.max_bandwidth_timestamp_seconds() &&
+          arg->min_rtt_ms() == reference.min_rtt_ms() &&
+          arg->previous_connection_state() ==
+              reference.previous_connection_state());
+}
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicServerSessionBaseTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) {
+  // Send some data open a stream, then reset it.
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        kStreamData);
+  session_->OnStreamFrame(data1);
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For non-version 99, the RESET_STREAM will do the full close.
+    // Set up expects accordingly.
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  session_->OnRstStream(rst1);
+
+  // For version-99 will create and receive a stop-sending, completing
+  // the full-close expected by this test.
+  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  // Send the same two bytes of payload in a new packet.
+  session_->OnStreamFrame(data1);
+
+  // The stream should not be re-opened.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) {
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For non-version 99, the RESET_STREAM will do the full close.
+    // Set up expects accordingly.
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  session_->OnRstStream(rst1);
+
+  // For version-99 will create and receive a stop-sending, completing
+  // the full-close expected by this test.
+  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        kStreamData);
+  session_->OnStreamFrame(data1);
+
+  // The stream should never be opened, now that the reset is received.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) {
+  // Send some data to open two streams.
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         kStreamData);
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
+                         kStreamData);
+  session_->OnStreamFrame(frame1);
+  session_->OnStreamFrame(frame2);
+  EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst(kInvalidControlFrameId,
+                         GetNthClientInitiatedBidirectionalId(0),
+                         QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For non-version 99, the RESET_STREAM will do the full close.
+    // Set up expects accordingly.
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  session_->OnRstStream(rst);
+
+  // For version-99 will create and receive a stop-sending, completing
+  // the full-close expected by this test.
+  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
+
+  // If we were tracking, we'd probably want to reject this because it's data
+  // past the reset point of stream 3.  As it's a closed stream we just drop the
+  // data on the floor, but accept the packet because it has data for stream 5.
+  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2,
+                         kStreamData);
+  QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2,
+                         kStreamData);
+  session_->OnStreamFrame(frame3);
+  session_->OnStreamFrame(frame4);
+  // The stream should never be opened, now that the reset is received.
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) {
+  // Test that the server refuses if a client attempts to open too many data
+  // streams.  For versions other than version 99, the server accepts slightly
+  // more than the negotiated stream limit to deal with rare cases where a
+  // client FIN/RST is lost.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // The slightly increased stream limit is set during config negotiation.  It
+    // is either an increase of 10 over negotiated limit, or a fixed percentage
+    // scaling, whichever is larger. Test both before continuing.
+    EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
+              kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
+    EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
+              session_->max_open_incoming_bidirectional_streams());
+  }
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  // Open the max configured number of streams, should be no problem.
+  for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
+    EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
+                                                             stream_id));
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Open more streams: server should accept slightly more than the limit.
+    // Excess streams are for non-version-99 only.
+    for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) {
+      EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
+                                                               stream_id));
+      stream_id += QuicUtils::StreamIdDelta(transport_version());
+    }
+  }
+  // Now violate the server's internal stream limit.
+  stream_id += QuicUtils::StreamIdDelta(transport_version());
+
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For non-version 99, QUIC responds to an attempt to exceed the stream
+    // limit by resetting the stream.
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM));
+  } else {
+    // In version 99 QUIC responds to an attempt to exceed the stream limit by
+    // closing the connection.
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  }
+  // Even if the connection remains open, the stream creation should fail.
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::GetOrCreateStream(session_.get(), stream_id));
+}
+
+TEST_P(QuicServerSessionBaseTest, MaxAvailableBidirectionalStreams) {
+  // Test that the server closes the connection if a client makes too many data
+  // streams available.  The server accepts slightly more than the negotiated
+  // stream limit to deal with rare cases where a client FIN/RST is lost.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  const size_t kAvailableStreamLimit =
+      session_->MaxAvailableBidirectionalStreams();
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
+      session_.get(), GetNthClientInitiatedBidirectionalId(0)));
+
+  // Establish available streams up to the server's limit.
+  QuicStreamId next_id = QuicUtils::StreamIdDelta(transport_version());
+  const int kLimitingStreamId =
+      GetNthClientInitiatedBidirectionalId(kAvailableStreamLimit + 1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // This exceeds the stream limit. In versions other than 99
+    // this is allowed. Version 99 hews to the IETF spec and does
+    // not allow it.
+    EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
+        session_.get(), kLimitingStreamId));
+    // A further available stream will result in connection close.
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  } else {
+    // A further available stream will result in connection close.
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  }
+
+  // This forces stream kLimitingStreamId + 2 to become available, which
+  // violates the quota.
+  EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateStream(
+      session_.get(), kLimitingStreamId + 2 * next_id));
+}
+
+TEST_P(QuicServerSessionBaseTest, GetEvenIncomingError) {
+  // Incoming streams on the server session must be odd.
+  const QuicErrorCode expected_error =
+      VersionHasIetfQuicFrames(transport_version())
+          ? QUIC_HTTP_STREAM_WRONG_DIRECTION
+          : QUIC_INVALID_STREAM_ID;
+  EXPECT_CALL(*connection_, CloseConnection(expected_error, _, _));
+  EXPECT_EQ(nullptr, QuicServerSessionBasePeer::GetOrCreateStream(
+                         session_.get(),
+                         session_->next_outgoing_unidirectional_stream_id()));
+}
+
+TEST_P(QuicServerSessionBaseTest, GetStreamDisconnected) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (version() != AllSupportedVersions()[0]) {
+    return;
+  }
+
+  // Don't create new streams if the connection is disconnected.
+  QuicConnectionPeer::TearDownLocalConnectionState(connection_);
+  EXPECT_QUIC_BUG(QuicServerSessionBasePeer::GetOrCreateStream(
+                      session_.get(), GetNthClientInitiatedBidirectionalId(0)),
+                  "ShouldCreateIncomingStream called when disconnected");
+}
+
+class MockQuicCryptoServerStream : public QuicCryptoServerStream {
+ public:
+  explicit MockQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      QuicServerSessionBase* session,
+      QuicCryptoServerStreamBase::Helper* helper)
+      : QuicCryptoServerStream(crypto_config,
+                               compressed_certs_cache,
+                               session,
+                               helper) {}
+  MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
+  MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
+      delete;
+  ~MockQuicCryptoServerStream() override {}
+
+  MOCK_METHOD(void,
+              SendServerConfigUpdate,
+              (const CachedNetworkParameters*),
+              (override));
+};
+
+class MockTlsServerHandshaker : public TlsServerHandshaker {
+ public:
+  explicit MockTlsServerHandshaker(QuicServerSessionBase* session,
+                                   const QuicCryptoServerConfig* crypto_config)
+      : TlsServerHandshaker(session, crypto_config) {}
+  MockTlsServerHandshaker(const MockTlsServerHandshaker&) = delete;
+  MockTlsServerHandshaker& operator=(const MockTlsServerHandshaker&) = delete;
+  ~MockTlsServerHandshaker() override {}
+
+  MOCK_METHOD(void, SendServerConfigUpdate, (const CachedNetworkParameters*),
+              (override));
+
+  MOCK_METHOD(std::string, GetAddressToken, (const CachedNetworkParameters*),
+              (const, override));
+};
+
+TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
+  if (version().UsesTls() && !version().HasIetfQuicFrames()) {
+    // Skip the Txxx versions.
+    return;
+  }
+
+  // Test that bandwidth estimate updates are sent to the client, only when
+  // bandwidth resumption is enabled, the bandwidth estimate has changed
+  // sufficiently, enough time has passed,
+  // and we don't have any other data to write.
+
+  // Client has sent kBWRE connection option to trigger bandwidth resumption.
+  QuicTagVector copt;
+  copt.push_back(kBWRE);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  EXPECT_TRUE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+
+  int32_t bandwidth_estimate_kbytes_per_second = 123;
+  int32_t max_bandwidth_estimate_kbytes_per_second = 134;
+  int32_t max_bandwidth_estimate_timestamp = 1122334455;
+  const std::string serving_region = "not a real region";
+  session_->set_serving_region(serving_region);
+
+  if (!VersionUsesHttp3(transport_version())) {
+    session_->UnregisterStreamPriority(
+        QuicUtils::GetHeadersStreamId(transport_version()),
+        /*is_static=*/true);
+  }
+  QuicServerSessionBasePeer::SetCryptoStream(session_.get(), nullptr);
+  MockQuicCryptoServerStream* quic_crypto_stream = nullptr;
+  MockTlsServerHandshaker* tls_server_stream = nullptr;
+  if (version().handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+    quic_crypto_stream = new MockQuicCryptoServerStream(
+        &crypto_config_, &compressed_certs_cache_, session_.get(),
+        &stream_helper_);
+    QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
+                                               quic_crypto_stream);
+  } else {
+    tls_server_stream =
+        new MockTlsServerHandshaker(session_.get(), &crypto_config_);
+    QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
+                                               tls_server_stream);
+  }
+  if (!VersionUsesHttp3(transport_version())) {
+    session_->RegisterStreamPriority(
+        QuicUtils::GetHeadersStreamId(transport_version()),
+        /*is_static=*/true,
+        spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority));
+  }
+
+  // Set some initial bandwidth values.
+  QuicSentPacketManager* sent_packet_manager =
+      QuicConnectionPeer::GetSentPacketManager(session_->connection());
+  QuicSustainedBandwidthRecorder& bandwidth_recorder =
+      QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager);
+  // Seed an rtt measurement equal to the initial default rtt.
+  RttStats* rtt_stats =
+      const_cast<RttStats*>(sent_packet_manager->GetRttStats());
+  rtt_stats->UpdateRtt(rtt_stats->initial_rtt(), QuicTime::Delta::Zero(),
+                       QuicTime::Zero());
+  QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
+      &bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
+  QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
+      &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
+      max_bandwidth_estimate_timestamp);
+  // Queue up some pending data.
+  if (!VersionUsesHttp3(transport_version())) {
+    session_->MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetHeadersStreamId(transport_version()));
+  } else {
+    session_->MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
+                                                  Perspective::IS_SERVER));
+  }
+  EXPECT_TRUE(session_->HasDataToWrite());
+
+  // There will be no update sent yet - not enough time has passed.
+  QuicTime now = QuicTime::Zero();
+  session_->OnCongestionWindowChange(now);
+
+  // Bandwidth estimate has now changed sufficiently but not enough time has
+  // passed to send a Server Config Update.
+  bandwidth_estimate_kbytes_per_second =
+      bandwidth_estimate_kbytes_per_second * 1.6;
+  session_->OnCongestionWindowChange(now);
+
+  // Bandwidth estimate has now changed sufficiently and enough time has passed,
+  // but not enough packets have been sent.
+  int64_t srtt_ms =
+      sent_packet_manager->GetRttStats()->smoothed_rtt().ToMilliseconds();
+  now = now + QuicTime::Delta::FromMilliseconds(
+                  kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms);
+  session_->OnCongestionWindowChange(now);
+
+  // The connection no longer has pending data to be written.
+  session_->OnCanWrite();
+  EXPECT_FALSE(session_->HasDataToWrite());
+  session_->OnCongestionWindowChange(now);
+
+  // Bandwidth estimate has now changed sufficiently, enough time has passed,
+  // and enough packets have been sent.
+  SerializedPacket packet(
+      QuicPacketNumber(1) + kMinPacketsBetweenServerConfigUpdates,
+      PACKET_4BYTE_PACKET_NUMBER, nullptr, 1000, false, false);
+  sent_packet_manager->OnPacketSent(&packet, now, NOT_RETRANSMISSION,
+                                    HAS_RETRANSMITTABLE_DATA, true);
+
+  // Verify that the proto has exactly the values we expect.
+  CachedNetworkParameters expected_network_params;
+  expected_network_params.set_bandwidth_estimate_bytes_per_second(
+      bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
+  expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
+      bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
+  expected_network_params.set_max_bandwidth_timestamp_seconds(
+      bandwidth_recorder.MaxBandwidthTimestamp());
+  expected_network_params.set_min_rtt_ms(session_->connection()
+                                             ->sent_packet_manager()
+                                             .GetRttStats()
+                                             ->min_rtt()
+                                             .ToMilliseconds());
+  expected_network_params.set_previous_connection_state(
+      CachedNetworkParameters::CONGESTION_AVOIDANCE);
+  expected_network_params.set_timestamp(
+      session_->connection()->clock()->WallNow().ToUNIXSeconds());
+  expected_network_params.set_serving_region(serving_region);
+
+  if (quic_crypto_stream) {
+    EXPECT_CALL(*quic_crypto_stream,
+                SendServerConfigUpdate(EqualsProto(expected_network_params)))
+        .Times(1);
+  } else {
+    EXPECT_CALL(*tls_server_stream,
+                GetAddressToken(EqualsProto(expected_network_params)))
+        .WillOnce(testing::Return("Test address token"));
+  }
+  EXPECT_CALL(*connection_, OnSendConnectionState(_)).Times(1);
+  session_->OnCongestionWindowChange(now);
+}
+
+TEST_P(QuicServerSessionBaseTest, BandwidthResumptionExperiment) {
+  if (version().UsesTls()) {
+    if (!version().HasIetfQuicFrames()) {
+      // Skip the Txxx versions.
+      return;
+    }
+    // Avoid a QUIC_BUG in QuicSession::OnConfigNegotiated.
+    connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  }
+
+  // Test that if a client provides a CachedNetworkParameters with the same
+  // serving region as the current server, and which was made within an hour of
+  // now, that this data is passed down to the send algorithm.
+
+  // Client has sent kBWRE connection option to trigger bandwidth resumption.
+  QuicTagVector copt;
+  copt.push_back(kBWRE);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+
+  const std::string kTestServingRegion = "a serving region";
+  session_->set_serving_region(kTestServingRegion);
+
+  // Set the time to be one hour + one second from the 0 baseline.
+  connection_->AdvanceTime(
+      QuicTime::Delta::FromSeconds(kNumSecondsPerHour + 1));
+
+  QuicCryptoServerStreamBase* crypto_stream =
+      static_cast<QuicCryptoServerStreamBase*>(
+          QuicSessionPeer::GetMutableCryptoStream(session_.get()));
+
+  // No effect if no CachedNetworkParameters provided.
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
+  session_->OnConfigNegotiated();
+
+  // No effect if CachedNetworkParameters provided, but different serving
+  // regions.
+  CachedNetworkParameters cached_network_params;
+  cached_network_params.set_bandwidth_estimate_bytes_per_second(1);
+  cached_network_params.set_serving_region("different serving region");
+  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
+  session_->OnConfigNegotiated();
+
+  // Same serving region, but timestamp is too old, should have no effect.
+  cached_network_params.set_serving_region(kTestServingRegion);
+  cached_network_params.set_timestamp(0);
+  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
+  session_->OnConfigNegotiated();
+
+  // Same serving region, and timestamp is recent: estimate is stored.
+  cached_network_params.set_timestamp(
+      connection_->clock()->WallNow().ToUNIXSeconds());
+  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(1);
+  session_->OnConfigNegotiated();
+}
+
+TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) {
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+
+  // Client has sent kBWMX connection option to trigger bandwidth resumption.
+  QuicTagVector copt;
+  copt.push_back(kBWMX);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  EXPECT_TRUE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+}
+
+TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+}
+
+// Tests which check the lifetime management of data members of
+// QuicCryptoServerStream objects when async GetProof is in use.
+class StreamMemberLifetimeTest : public QuicServerSessionBaseTest {
+ public:
+  StreamMemberLifetimeTest()
+      : QuicServerSessionBaseTest(
+            std::unique_ptr<FakeProofSource>(new FakeProofSource())),
+        crypto_config_peer_(&crypto_config_) {
+    GetFakeProofSource()->Activate();
+  }
+
+  FakeProofSource* GetFakeProofSource() const {
+    return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
+  }
+
+ private:
+  QuicCryptoServerConfigPeer crypto_config_peer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(StreamMemberLifetimeTests,
+                         StreamMemberLifetimeTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+// Trigger an operation which causes an async invocation of
+// ProofSource::GetProof.  Delay the completion of the operation until after the
+// stream has been destroyed, and verify that there are no memory bugs.
+TEST_P(StreamMemberLifetimeTest, Basic) {
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test depends on the QUIC crypto protocol, so it is disabled for the
+    // TLS handshake.
+    // TODO(nharper): Fix this test so it doesn't rely on QUIC crypto.
+    return;
+  }
+
+  const QuicClock* clock = helper_.GetClock();
+  CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
+      clock, transport_version(), &crypto_config_);
+  chlo.SetVector(kCOPT, QuicTagVector{kREJ});
+  std::vector<ParsedQuicVersion> packet_version_list = {version()};
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      TestConnectionId(1), EmptyQuicConnectionId(), true, false, 1,
+      std::string(chlo.GetSerialized().AsStringPiece()), CONNECTION_ID_PRESENT,
+      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &packet_version_list));
+
+  EXPECT_CALL(stream_helper_, CanAcceptClientHello(_, _, _, _, _))
+      .WillOnce(testing::Return(true));
+
+  // Set the current packet
+  QuicConnectionPeer::SetCurrentPacket(session_->connection(),
+                                       packet->AsStringPiece());
+
+  // Yes, this is horrible.  But it's the easiest way to trigger the behavior we
+  // need to exercise.
+  QuicCryptoServerStreamBase* crypto_stream =
+      const_cast<QuicCryptoServerStreamBase*>(session_->crypto_stream());
+
+  // Feed the CHLO into the crypto stream, which will trigger a call to
+  // ProofSource::GetProof
+  crypto_test_utils::SendHandshakeMessageToStream(crypto_stream, chlo,
+                                                  Perspective::IS_CLIENT);
+  ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
+
+  // Destroy the stream
+  session_.reset();
+
+  // Allow the async ProofSource::GetProof call to complete.  Verify (under
+  // memory access checkers) that this does not result in accesses to any
+  // freed memory from the session or its subobjects.
+  GetFakeProofSource()->InvokePendingCallback(0);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_session.cc b/quiche/quic/core/http/quic_spdy_client_session.cc
new file mode 100644
index 0000000..ed02803
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session.cc
@@ -0,0 +1,223 @@
+// 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 "quiche/quic/core/http/quic_spdy_client_session.h"
+
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/http/quic_server_initiated_spdy_stream.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSpdyClientSession::QuicSpdyClientSession(
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection,
+    const QuicServerId& server_id,
+    QuicCryptoClientConfig* crypto_config,
+    QuicClientPushPromiseIndex* push_promise_index)
+    : QuicSpdyClientSessionBase(connection,
+                                push_promise_index,
+                                config,
+                                supported_versions),
+      server_id_(server_id),
+      crypto_config_(crypto_config),
+      respect_goaway_(true) {}
+
+QuicSpdyClientSession::~QuicSpdyClientSession() = default;
+
+void QuicSpdyClientSession::Initialize() {
+  crypto_stream_ = CreateQuicCryptoStream();
+  if (config()->HasClientRequestedIndependentOption(kQLVE,
+                                                    Perspective::IS_CLIENT)) {
+    connection()->EnableLegacyVersionEncapsulation(server_id_.host());
+  }
+  QuicSpdyClientSessionBase::Initialize();
+}
+
+void QuicSpdyClientSession::OnProofValid(
+    const QuicCryptoClientConfig::CachedState& /*cached*/) {}
+
+void QuicSpdyClientSession::OnProofVerifyDetailsAvailable(
+    const ProofVerifyDetails& /*verify_details*/) {}
+
+bool QuicSpdyClientSession::ShouldCreateOutgoingBidirectionalStream() {
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created.";
+    return false;
+  }
+  if (goaway_received() && respect_goaway_) {
+    QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
+                    << "Already received goaway.";
+    return false;
+  }
+  return CanOpenNextOutgoingBidirectionalStream();
+}
+
+bool QuicSpdyClientSession::ShouldCreateOutgoingUnidirectionalStream() {
+  QUIC_BUG(quic_bug_10396_1)
+      << "Try to create outgoing unidirectional client data streams";
+  return false;
+}
+
+QuicSpdyClientStream*
+QuicSpdyClientSession::CreateOutgoingBidirectionalStream() {
+  if (!ShouldCreateOutgoingBidirectionalStream()) {
+    return nullptr;
+  }
+  std::unique_ptr<QuicSpdyClientStream> stream = CreateClientStream();
+  QuicSpdyClientStream* stream_ptr = stream.get();
+  ActivateStream(std::move(stream));
+  return stream_ptr;
+}
+
+QuicSpdyClientStream*
+QuicSpdyClientSession::CreateOutgoingUnidirectionalStream() {
+  QUIC_BUG(quic_bug_10396_2)
+      << "Try to create outgoing unidirectional client data streams";
+  return nullptr;
+}
+
+std::unique_ptr<QuicSpdyClientStream>
+QuicSpdyClientSession::CreateClientStream() {
+  return std::make_unique<QuicSpdyClientStream>(
+      GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
+}
+
+QuicCryptoClientStreamBase* QuicSpdyClientSession::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+const QuicCryptoClientStreamBase* QuicSpdyClientSession::GetCryptoStream()
+    const {
+  return crypto_stream_.get();
+}
+
+bool QuicSpdyClientSession::IsKnownServerAddress(
+    const QuicSocketAddress& address) const {
+  return std::find(known_server_addresses_.cbegin(),
+                   known_server_addresses_.cend(),
+                   address) != known_server_addresses_.cend();
+}
+
+void QuicSpdyClientSession::AddKnownServerAddress(
+    const QuicSocketAddress& address) {
+  known_server_addresses_.push_back(address);
+}
+
+void QuicSpdyClientSession::CryptoConnect() {
+  QUICHE_DCHECK(flow_controller());
+  crypto_stream_->CryptoConnect();
+}
+
+int QuicSpdyClientSession::GetNumSentClientHellos() const {
+  return crypto_stream_->num_sent_client_hellos();
+}
+
+bool QuicSpdyClientSession::IsResumption() const {
+  return crypto_stream_->IsResumption();
+}
+
+bool QuicSpdyClientSession::EarlyDataAccepted() const {
+  return crypto_stream_->EarlyDataAccepted();
+}
+
+bool QuicSpdyClientSession::ReceivedInchoateReject() const {
+  return crypto_stream_->ReceivedInchoateReject();
+}
+
+int QuicSpdyClientSession::GetNumReceivedServerConfigUpdates() const {
+  return crypto_stream_->num_scup_messages_received();
+}
+
+bool QuicSpdyClientSession::ShouldCreateIncomingStream(QuicStreamId id) {
+  if (!connection()->connected()) {
+    QUIC_BUG(quic_bug_10396_3)
+        << "ShouldCreateIncomingStream called when disconnected";
+    return false;
+  }
+  if (goaway_received() && respect_goaway_) {
+    QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
+                    << "Already received goaway.";
+    return false;
+  }
+
+  if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id)) {
+    QUIC_BUG(quic_bug_10396_4)
+        << "ShouldCreateIncomingStream called with client initiated "
+           "stream ID.";
+    return false;
+  }
+
+  if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id)) {
+    QUIC_LOG(WARNING) << "Received invalid push stream id " << id;
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "Server created non write unidirectional stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version()) &&
+      QuicUtils::IsBidirectionalStreamId(id, version()) &&
+      !WillNegotiateWebTransport()) {
+    connection()->CloseConnection(
+        QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM,
+        "Server created bidirectional stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  return true;
+}
+
+QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(
+    PendingStream* pending) {
+  QuicSpdyStream* stream = new QuicSpdyClientStream(pending, this);
+  ActivateStream(absl::WrapUnique(stream));
+  return stream;
+}
+
+QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(QuicStreamId id) {
+  if (!ShouldCreateIncomingStream(id)) {
+    return nullptr;
+  }
+  QuicSpdyStream* stream;
+  if (version().UsesHttp3() &&
+      QuicUtils::IsBidirectionalStreamId(id, version())) {
+    QUIC_BUG_IF(QuicServerInitiatedSpdyStream but no WebTransport support,
+                !WillNegotiateWebTransport())
+        << "QuicServerInitiatedSpdyStream created but no WebTransport support";
+    stream = new QuicServerInitiatedSpdyStream(id, this, BIDIRECTIONAL);
+  } else {
+    stream = new QuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
+  }
+  ActivateStream(absl::WrapUnique(stream));
+  return stream;
+}
+
+std::unique_ptr<QuicCryptoClientStreamBase>
+QuicSpdyClientSession::CreateQuicCryptoStream() {
+  return std::make_unique<QuicCryptoClientStream>(
+      server_id_, this,
+      crypto_config_->proof_verifier()->CreateDefaultContext(), crypto_config_,
+      this, /*has_application_state = */ version().UsesHttp3());
+}
+
+bool QuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_session.h b/quiche/quic/core/http/quic_spdy_client_session.h
new file mode 100644
index 0000000..ceab083
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session.h
@@ -0,0 +1,127 @@
+// 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.
+
+// A client specific QuicSession subclass.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
+
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/http/quic_spdy_client_session_base.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+class QuicConnection;
+class QuicServerId;
+
+class QUIC_EXPORT_PRIVATE QuicSpdyClientSession
+    : public QuicSpdyClientSessionBase {
+ public:
+  // Takes ownership of |connection|. Caller retains ownership of
+  // |promised_by_url|.
+  QuicSpdyClientSession(const QuicConfig& config,
+                        const ParsedQuicVersionVector& supported_versions,
+                        QuicConnection* connection,
+                        const QuicServerId& server_id,
+                        QuicCryptoClientConfig* crypto_config,
+                        QuicClientPushPromiseIndex* push_promise_index);
+  QuicSpdyClientSession(const QuicSpdyClientSession&) = delete;
+  QuicSpdyClientSession& operator=(const QuicSpdyClientSession&) = delete;
+  ~QuicSpdyClientSession() override;
+  // Set up the QuicSpdyClientSession. Must be called prior to use.
+  void Initialize() override;
+
+  // QuicSession methods:
+  QuicSpdyClientStream* CreateOutgoingBidirectionalStream() override;
+  QuicSpdyClientStream* CreateOutgoingUnidirectionalStream() override;
+  QuicCryptoClientStreamBase* GetMutableCryptoStream() override;
+  const QuicCryptoClientStreamBase* GetCryptoStream() const override;
+  bool IsKnownServerAddress(const QuicSocketAddress& address) const override;
+
+  void AddKnownServerAddress(const QuicSocketAddress& address);
+
+  bool IsAuthorized(const std::string& authority) override;
+
+  // QuicSpdyClientSessionBase methods:
+  void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) override;
+
+  // Performs a crypto handshake with the server.
+  virtual void CryptoConnect();
+
+  // Returns the number of client hello messages that have been sent on the
+  // crypto stream. If the handshake has completed then this is one greater
+  // than the number of round-trips needed for the handshake.
+  int GetNumSentClientHellos() const;
+
+  // Return true if the handshake performed is a TLS resumption.
+  // Always return false for QUIC Crypto.
+  bool IsResumption() const;
+
+  // Returns true if early data (0-RTT data) was sent and the server accepted
+  // it.
+  bool EarlyDataAccepted() const;
+
+  // Returns true if the handshake was delayed one round trip by the server
+  // because the server wanted proof the client controls its source address
+  // before progressing further. In Google QUIC, this would be due to an
+  // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
+  // to a Retry packet.
+  // TODO(nharper): Consider a better name for this method.
+  bool ReceivedInchoateReject() const;
+
+  int GetNumReceivedServerConfigUpdates() const;
+
+  using QuicSession::CanOpenNextOutgoingBidirectionalStream;
+
+  void set_respect_goaway(bool respect_goaway) {
+    respect_goaway_ = respect_goaway;
+  }
+
+ protected:
+  // QuicSession methods:
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
+  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override;
+  // If an outgoing stream can be created, return true.
+  bool ShouldCreateOutgoingBidirectionalStream() override;
+  bool ShouldCreateOutgoingUnidirectionalStream() override;
+
+  // If an incoming stream can be created, return true.
+  // TODO(fayang): move this up to QuicSpdyClientSessionBase.
+  bool ShouldCreateIncomingStream(QuicStreamId id) override;
+
+  // Create the crypto stream. Called by Initialize().
+  virtual std::unique_ptr<QuicCryptoClientStreamBase> CreateQuicCryptoStream();
+
+  // Unlike CreateOutgoingBidirectionalStream, which applies a bunch of
+  // sanity checks, this simply returns a new QuicSpdyClientStream. This may be
+  // used by subclasses which want to use a subclass of QuicSpdyClientStream for
+  // streams but wish to use the sanity checks in
+  // CreateOutgoingBidirectionalStream.
+  virtual std::unique_ptr<QuicSpdyClientStream> CreateClientStream();
+
+  const QuicServerId& server_id() const { return server_id_; }
+  QuicCryptoClientConfig* crypto_config() { return crypto_config_; }
+
+ private:
+  std::unique_ptr<QuicCryptoClientStreamBase> crypto_stream_;
+  QuicServerId server_id_;
+  QuicCryptoClientConfig* crypto_config_;
+  // Server addresses that are known to the client.
+  std::vector<QuicSocketAddress> known_server_addresses_;
+
+  // If this is set to false, the client will ignore server GOAWAYs and allow
+  // the creation of streams regardless of the high chance they will fail.
+  bool respect_goaway_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
diff --git a/quiche/quic/core/http/quic_spdy_client_session_base.cc b/quiche/quic/core/http/quic_spdy_client_session_base.cc
new file mode 100644
index 0000000..559764c
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session_base.cc
@@ -0,0 +1,279 @@
+// 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 "quiche/quic/core/http/quic_spdy_client_session_base.h"
+
+#include <string>
+
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicSpdyClientSessionBase::QuicSpdyClientSessionBase(
+    QuicConnection* connection,
+    QuicClientPushPromiseIndex* push_promise_index,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions)
+    : QuicSpdySession(connection, nullptr, config, supported_versions),
+      push_promise_index_(push_promise_index),
+      largest_promised_stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())) {}
+
+QuicSpdyClientSessionBase::~QuicSpdyClientSessionBase() {
+  //  all promised streams for this session
+  for (auto& it : promised_by_id_) {
+    QUIC_DVLOG(1) << "erase stream " << it.first << " url " << it.second->url();
+    push_promise_index_->promised_by_url()->erase(it.second->url());
+  }
+  DeleteConnection();
+}
+
+void QuicSpdyClientSessionBase::OnConfigNegotiated() {
+  QuicSpdySession::OnConfigNegotiated();
+}
+
+void QuicSpdyClientSessionBase::OnInitialHeadersComplete(
+    QuicStreamId stream_id,
+    const SpdyHeaderBlock& response_headers) {
+  // Note that the strong ordering of the headers stream means that
+  // QuicSpdyClientStream::OnPromiseHeadersComplete must have already
+  // been called (on the associated stream) if this is a promised
+  // stream. However, this stream may not have existed at this time,
+  // hence the need to query the session.
+  QuicClientPromisedInfo* promised = GetPromisedById(stream_id);
+  if (!promised)
+    return;
+
+  promised->OnResponseHeaders(response_headers);
+}
+
+void QuicSpdyClientSessionBase::OnPromiseHeaderList(
+    QuicStreamId stream_id,
+    QuicStreamId promised_stream_id,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  if (IsStaticStream(stream_id)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  // In HTTP3, push promises are received on individual streams, so they could
+  // be arrive out of order.
+  if (!VersionUsesHttp3(transport_version()) &&
+      promised_stream_id !=
+          QuicUtils::GetInvalidStreamId(transport_version()) &&
+      largest_promised_stream_id_ !=
+          QuicUtils::GetInvalidStreamId(transport_version()) &&
+      promised_stream_id <= largest_promised_stream_id_) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "Received push stream id lesser or equal to the"
+        " last accepted before",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (!IsIncomingStream(promised_stream_id)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received push stream id for outgoing stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    // Received push stream id is higher than MAX_PUSH_ID
+    // because no MAX_PUSH_ID frame is ever sent.
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "Received push stream id higher than MAX_PUSH_ID.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  largest_promised_stream_id_ = promised_stream_id;
+
+  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+  if (!stream) {
+    // It's quite possible to receive headers after a stream has been reset.
+    return;
+  }
+  stream->OnPromiseHeaderList(promised_stream_id, frame_len, header_list);
+}
+
+bool QuicSpdyClientSessionBase::HandlePromised(QuicStreamId /* associated_id */,
+                                               QuicStreamId promised_id,
+                                               const SpdyHeaderBlock& headers) {
+  // TODO(b/136295430): Do not treat |promised_id| as a stream ID when using
+  // IETF QUIC.
+  // Due to pathalogical packet re-ordering, it is possible that
+  // frames for the promised stream have already arrived, and the
+  // promised stream could be active or closed.
+  if (IsClosedStream(promised_id)) {
+    // There was a RST on the data stream already, perhaps
+    // QUIC_REFUSED_STREAM?
+    QUIC_DVLOG(1) << "Promise ignored for stream " << promised_id
+                  << " that is already closed";
+    return false;
+  }
+
+  if (push_promise_index_->promised_by_url()->size() >= get_max_promises()) {
+    QUIC_DVLOG(1) << "Too many promises, rejecting promise for stream "
+                  << promised_id;
+    ResetPromised(promised_id, QUIC_REFUSED_STREAM);
+    return false;
+  }
+
+  const std::string url =
+      SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers);
+  QuicClientPromisedInfo* old_promised = GetPromisedByUrl(url);
+  if (old_promised) {
+    QUIC_DVLOG(1) << "Promise for stream " << promised_id
+                  << " is duplicate URL " << url
+                  << " of previous promise for stream " << old_promised->id();
+    ResetPromised(promised_id, QUIC_DUPLICATE_PROMISE_URL);
+    return false;
+  }
+
+  if (GetPromisedById(promised_id)) {
+    // OnPromiseHeadersComplete() would have closed the connection if
+    // promised id is a duplicate.
+    QUIC_BUG(quic_bug_10412_1) << "Duplicate promise for id " << promised_id;
+    return false;
+  }
+
+  QuicClientPromisedInfo* promised =
+      new QuicClientPromisedInfo(this, promised_id, url);
+  std::unique_ptr<QuicClientPromisedInfo> promised_owner(promised);
+  promised->Init();
+  QUIC_DVLOG(1) << "stream " << promised_id << " emplace url " << url;
+  (*push_promise_index_->promised_by_url())[url] = promised;
+  promised_by_id_[promised_id] = std::move(promised_owner);
+  bool result = promised->OnPromiseHeaders(headers);
+  if (result) {
+    QUICHE_DCHECK(promised_by_id_.find(promised_id) != promised_by_id_.end());
+  }
+  return result;
+}
+
+QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedByUrl(
+    const std::string& url) {
+  auto it = push_promise_index_->promised_by_url()->find(url);
+  if (it != push_promise_index_->promised_by_url()->end()) {
+    return it->second;
+  }
+  return nullptr;
+}
+
+QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedById(
+    const QuicStreamId id) {
+  auto it = promised_by_id_.find(id);
+  if (it != promised_by_id_.end()) {
+    return it->second.get();
+  }
+  return nullptr;
+}
+
+QuicSpdyStream* QuicSpdyClientSessionBase::GetPromisedStream(
+    const QuicStreamId id) {
+  QuicStream* stream = GetActiveStream(id);
+  if (stream != nullptr) {
+    return static_cast<QuicSpdyStream*>(stream);
+  }
+  return nullptr;
+}
+
+void QuicSpdyClientSessionBase::DeletePromised(
+    QuicClientPromisedInfo* promised) {
+  push_promise_index_->promised_by_url()->erase(promised->url());
+  // Since promised_by_id_ contains the unique_ptr, this will destroy
+  // promised.
+  // ToDo: Consider implementing logic to send a new MAX_PUSH_ID frame to allow
+  // another stream to be promised.
+  promised_by_id_.erase(promised->id());
+  if (!VersionUsesHttp3(transport_version())) {
+    headers_stream()->MaybeReleaseSequencerBuffer();
+  }
+}
+
+void QuicSpdyClientSessionBase::OnPushStreamTimedOut(
+    QuicStreamId /*stream_id*/) {}
+
+void QuicSpdyClientSessionBase::ResetPromised(
+    QuicStreamId id,
+    QuicRstStreamErrorCode error_code) {
+  QUICHE_DCHECK(QuicUtils::IsServerInitiatedStreamId(transport_version(), id));
+  ResetStream(id, error_code);
+  if (!IsOpenStream(id) && !IsClosedStream(id)) {
+    MaybeIncreaseLargestPeerStreamId(id);
+  }
+}
+
+void QuicSpdyClientSessionBase::OnStreamClosed(QuicStreamId stream_id) {
+  QuicSpdySession::OnStreamClosed(stream_id);
+  if (!VersionUsesHttp3(transport_version())) {
+    headers_stream()->MaybeReleaseSequencerBuffer();
+  }
+}
+
+bool QuicSpdyClientSessionBase::ShouldReleaseHeadersStreamSequencerBuffer() {
+  return !HasActiveRequestStreams() && promised_by_id_.empty();
+}
+
+bool QuicSpdyClientSessionBase::ShouldKeepConnectionAlive() const {
+  return QuicSpdySession::ShouldKeepConnectionAlive() ||
+         num_outgoing_draining_streams() > 0;
+}
+
+bool QuicSpdyClientSessionBase::OnSettingsFrame(const SettingsFrame& frame) {
+  if (!was_zero_rtt_rejected()) {
+    if (max_outbound_header_list_size() != std::numeric_limits<size_t>::max() &&
+        frame.values.find(SETTINGS_MAX_FIELD_SECTION_SIZE) ==
+            frame.values.end()) {
+      CloseConnectionWithDetails(
+          QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+          "Server accepted 0-RTT but omitted non-default "
+          "SETTINGS_MAX_FIELD_SECTION_SIZE");
+      return false;
+    }
+
+    if (qpack_encoder()->maximum_blocked_streams() != 0 &&
+        frame.values.find(SETTINGS_QPACK_BLOCKED_STREAMS) ==
+            frame.values.end()) {
+      CloseConnectionWithDetails(
+          QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+          "Server accepted 0-RTT but omitted non-default "
+          "SETTINGS_QPACK_BLOCKED_STREAMS");
+      return false;
+    }
+
+    if (qpack_encoder()->MaximumDynamicTableCapacity() != 0 &&
+        frame.values.find(SETTINGS_QPACK_MAX_TABLE_CAPACITY) ==
+            frame.values.end()) {
+      CloseConnectionWithDetails(
+          QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+          "Server accepted 0-RTT but omitted non-default "
+          "SETTINGS_QPACK_MAX_TABLE_CAPACITY");
+      return false;
+    }
+  }
+
+  if (!QuicSpdySession::OnSettingsFrame(frame)) {
+    return false;
+  }
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount frame_length =
+      HttpEncoder::SerializeSettingsFrame(frame, &buffer);
+  auto serialized_data = std::make_unique<ApplicationState>(
+      buffer.get(), buffer.get() + frame_length);
+  GetMutableCryptoStream()->SetServerApplicationStateForResumption(
+      std::move(serialized_data));
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_session_base.h b/quiche/quic/core/http/quic_spdy_client_session_base.h
new file mode 100644
index 0000000..426d28d
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session_base.h
@@ -0,0 +1,146 @@
+// 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_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
+
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicClientPromisedInfo;
+class QuicClientPushPromiseIndex;
+class QuicSpdyClientStream;
+
+// For client/http layer code. Lookup promised streams based on
+// matching promised request url. The same map can be shared across
+// multiple sessions, since cross-origin pushes are allowed (subject
+// to authority constraints).  Clients should use this map to enforce
+// session affinity for requests corresponding to cross-origin push
+// promised streams.
+using QuicPromisedByUrlMap =
+    absl::flat_hash_map<std::string, QuicClientPromisedInfo*>;
+
+// The maximum time a promises stream can be reserved without being
+// claimed by a client request.
+const int64_t kPushPromiseTimeoutSecs = 60;
+
+// Base class for all client-specific QuicSession subclasses.
+class QUIC_EXPORT_PRIVATE QuicSpdyClientSessionBase
+    : public QuicSpdySession,
+      public QuicCryptoClientStream::ProofHandler {
+ public:
+  // Takes ownership of |connection|. Caller retains ownership of
+  // |promised_by_url|.
+  QuicSpdyClientSessionBase(QuicConnection* connection,
+                            QuicClientPushPromiseIndex* push_promise_index,
+                            const QuicConfig& config,
+                            const ParsedQuicVersionVector& supported_versions);
+  QuicSpdyClientSessionBase(const QuicSpdyClientSessionBase&) = delete;
+  QuicSpdyClientSessionBase& operator=(const QuicSpdyClientSessionBase&) =
+      delete;
+
+  ~QuicSpdyClientSessionBase() override;
+
+  void OnConfigNegotiated() override;
+
+  // Called by |headers_stream_| when push promise headers have been
+  // completely received.
+  void OnPromiseHeaderList(QuicStreamId stream_id,
+                           QuicStreamId promised_stream_id,
+                           size_t frame_len,
+                           const QuicHeaderList& header_list) override;
+
+  // Called by |QuicSpdyClientStream| on receipt of response headers,
+  // needed to detect promised server push streams, as part of
+  // client-request to push-stream rendezvous.
+  void OnInitialHeadersComplete(QuicStreamId stream_id,
+                                const spdy::SpdyHeaderBlock& response_headers);
+
+  // Called by |QuicSpdyClientStream| on receipt of PUSH_PROMISE, does
+  // some session level validation and creates the
+  // |QuicClientPromisedInfo| inserting into maps by (promised) id and
+  // url. Returns true if a new push promise is accepted. Resets the promised
+  // stream and returns false otherwise.
+  virtual bool HandlePromised(QuicStreamId associated_id,
+                              QuicStreamId promised_id,
+                              const spdy::SpdyHeaderBlock& headers);
+
+  // For cross-origin server push, this should verify the server is
+  // authoritative per [RFC2818], Section 3.  Roughly, subjectAltName
+  // list in the certificate should contain a matching DNS name, or IP
+  // address.  |hostname| is derived from the ":authority" header field of
+  // the PUSH_PROMISE frame, port if present there will be dropped.
+  virtual bool IsAuthorized(const std::string& hostname) = 0;
+
+  // Session retains ownership.
+  QuicClientPromisedInfo* GetPromisedByUrl(const std::string& url);
+  // Session retains ownership.
+  QuicClientPromisedInfo* GetPromisedById(const QuicStreamId id);
+
+  //
+  QuicSpdyStream* GetPromisedStream(const QuicStreamId id);
+
+  // Removes |promised| from the maps by url.
+  void ErasePromisedByUrl(QuicClientPromisedInfo* promised);
+
+  // Removes |promised| from the maps by url and id and destroys
+  // promised.
+  virtual void DeletePromised(QuicClientPromisedInfo* promised);
+
+  virtual void OnPushStreamTimedOut(QuicStreamId stream_id);
+
+  // Sends Rst for the stream, and makes sure that future calls to
+  // IsClosedStream(id) return true, which ensures that any subsequent
+  // frames related to this stream will be ignored (modulo flow
+  // control accounting).
+  void ResetPromised(QuicStreamId id, QuicRstStreamErrorCode error_code);
+
+  // Release headers stream's sequencer buffer if it's empty.
+  void OnStreamClosed(QuicStreamId stream_id) override;
+
+  // Returns true if there are no active requests and no promised streams.
+  bool ShouldReleaseHeadersStreamSequencerBuffer() override;
+
+  // Override to wait for all received responses to be consumed by application.
+  bool ShouldKeepConnectionAlive() const override;
+
+  size_t get_max_promises() const {
+    return max_open_incoming_unidirectional_streams() *
+           kMaxPromisedStreamsMultiplier;
+  }
+
+  QuicClientPushPromiseIndex* push_promise_index() {
+    return push_promise_index_;
+  }
+
+  // Override to serialize the settings and pass it down to the handshaker.
+  bool OnSettingsFrame(const SettingsFrame& frame) override;
+
+ private:
+  // For QuicSpdyClientStream to detect that a response corresponds to a
+  // promise.
+  using QuicPromisedByIdMap =
+      absl::flat_hash_map<QuicStreamId,
+                          std::unique_ptr<QuicClientPromisedInfo>>;
+
+  // As per rfc7540, section 10.5: track promise streams in "reserved
+  // (remote)".  The primary key is URL from the promise request
+  // headers.  The promised stream id is a secondary key used to get
+  // promise info when the response headers of the promised stream
+  // arrive.
+  QuicClientPushPromiseIndex* push_promise_index_;
+  QuicPromisedByIdMap promised_by_id_;
+  QuicStreamId largest_promised_stream_id_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
diff --git a/quiche/quic/core/http/quic_spdy_client_session_test.cc b/quiche/quic/core/http/quic_spdy_client_session_test.cc
new file mode 100644
index 0000000..346341c
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session_test.cc
@@ -0,0 +1,1345 @@
+// 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 "quiche/quic/core/http/quic_spdy_client_session.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/tls_client_handshaker.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_quic_spdy_client_stream.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_packet_creator_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+
+using spdy::SpdyHeaderBlock;
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::AtLeast;
+using ::testing::AtMost;
+using ::testing::Invoke;
+using ::testing::StrictMock;
+using ::testing::Truly;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kPort = 443;
+
+class TestQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit TestQuicSpdyClientSession(
+      const QuicConfig& config,
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      const QuicServerId& server_id,
+      QuicCryptoClientConfig* crypto_config,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(config,
+                              supported_versions,
+                              connection,
+                              server_id,
+                              crypto_config,
+                              push_promise_index) {}
+
+  std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override {
+    return std::make_unique<MockQuicSpdyClientStream>(
+        GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
+  }
+
+  MockQuicSpdyClientStream* CreateIncomingStream(QuicStreamId id) override {
+    if (!ShouldCreateIncomingStream(id)) {
+      return nullptr;
+    }
+    MockQuicSpdyClientStream* stream =
+        new MockQuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+};
+
+class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicSpdyClientSessionTest()
+      : promised_stream_id_(
+            QuicUtils::GetInvalidStreamId(GetParam().transport_version)),
+        associated_stream_id_(
+            QuicUtils::GetInvalidStreamId(GetParam().transport_version)) {
+    auto client_cache = std::make_unique<test::SimpleSessionCache>();
+    client_session_cache_ = client_cache.get();
+    client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+        crypto_test_utils::ProofVerifierForTesting(), std::move(client_cache));
+    server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
+    Initialize();
+    // Advance the time, because timers do not like uninitialized times.
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+  ~QuicSpdyClientSessionTest() override {
+    // Session must be destroyed before promised_by_url_
+    session_.reset(nullptr);
+  }
+
+  void Initialize() {
+    session_.reset();
+    connection_ = new ::testing::NiceMock<PacketSavingConnection>(
+        &helper_, &alarm_factory_, Perspective::IS_CLIENT,
+        SupportedVersions(GetParam()));
+    session_ = std::make_unique<TestQuicSpdyClientSession>(
+        DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
+        QuicServerId(kServerHostname, kPort, false),
+        client_crypto_config_.get(), &push_promise_index_);
+    session_->Initialize();
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    crypto_stream_ = static_cast<QuicCryptoClientStream*>(
+        session_->GetMutableCryptoStream());
+    push_promise_[":path"] = "/bar";
+    push_promise_[":authority"] = "www.google.com";
+    push_promise_[":method"] = "GET";
+    push_promise_[":scheme"] = "https";
+    promise_url_ =
+        SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
+    promised_stream_id_ = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 0);
+    associated_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 0);
+  }
+
+  // The function ensures that A) the MAX_STREAMS frames get properly deleted
+  // (since the test uses a 'did we leak memory' check ... if we just lose the
+  // frame, the test fails) and B) returns true (instead of the default, false)
+  // which ensures that the rest of the system thinks that the frame actually
+  // was transmitted.
+  bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
+    if (frame.type == MAX_STREAMS_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ public:
+  bool ClearStreamsBlockedControlFrame(const QuicFrame& frame) {
+    if (frame.type == STREAMS_BLOCKED_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ protected:
+  void CompleteCryptoHandshake() {
+    CompleteCryptoHandshake(kDefaultMaxStreamsPerConnection);
+  }
+
+  void CompleteCryptoHandshake(uint32_t server_max_incoming_streams) {
+    if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .Times(::testing::AnyNumber())
+          .WillRepeatedly(Invoke(
+              this, &QuicSpdyClientSessionTest::ClearMaxStreamsControlFrame));
+    }
+    session_->CryptoConnect();
+    QuicConfig config = DefaultQuicConfig();
+    if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+      config.SetMaxUnidirectionalStreamsToSend(server_max_incoming_streams);
+      config.SetMaxBidirectionalStreamsToSend(server_max_incoming_streams);
+    } else {
+      config.SetMaxBidirectionalStreamsToSend(server_max_incoming_streams);
+    }
+    crypto_test_utils::HandshakeWithFakeServer(
+        &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+        connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+  }
+
+  void CreateConnection() {
+    connection_ = new ::testing::NiceMock<PacketSavingConnection>(
+        &helper_, &alarm_factory_, Perspective::IS_CLIENT,
+        SupportedVersions(GetParam()));
+    // Advance the time, because timers do not like uninitialized times.
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    session_ = std::make_unique<TestQuicSpdyClientSession>(
+        DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
+        QuicServerId(kServerHostname, kPort, false),
+        client_crypto_config_.get(), &push_promise_index_);
+    session_->Initialize();
+    crypto_stream_ = static_cast<QuicCryptoClientStream*>(
+        session_->GetMutableCryptoStream());
+  }
+
+  void CompleteFirstConnection() {
+    CompleteCryptoHandshake();
+    EXPECT_FALSE(session_->GetCryptoStream()->IsResumption());
+    if (session_->version().UsesHttp3()) {
+      SettingsFrame settings;
+      settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+      settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+      settings.values[256] = 4;  // unknown setting
+      session_->OnSettingsFrame(settings);
+    }
+  }
+
+  // Owned by |session_|.
+  QuicCryptoClientStream* crypto_stream_;
+  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+  std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  ::testing::NiceMock<PacketSavingConnection>* connection_;
+  std::unique_ptr<TestQuicSpdyClientSession> session_;
+  QuicClientPushPromiseIndex push_promise_index_;
+  SpdyHeaderBlock push_promise_;
+  std::string promise_url_;
+  QuicStreamId promised_stream_id_;
+  QuicStreamId associated_stream_id_;
+  test::SimpleSessionCache* client_session_cache_;
+};
+
+std::string ParamNameFormatter(
+    const testing::TestParamInfo<QuicSpdyClientSessionTest::ParamType>& info) {
+  return ParsedQuicVersionToString(info.param);
+}
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSpdyClientSessionTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ParamNameFormatter);
+
+TEST_P(QuicSpdyClientSessionTest, CryptoConnect) {
+  CompleteCryptoHandshake();
+}
+
+TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test relies on resumption and is QUIC crypto specific, so it is
+    // disabled for TLS.
+    return;
+  }
+  // Complete a handshake in order to prime the crypto config for 0-RTT.
+  CompleteCryptoHandshake();
+
+  // Now create a second session using the same crypto config.
+  Initialize();
+
+  // Starting the handshake should move immediately to encryption
+  // established and will allow streams to be created.
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_FALSE(QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+                                           stream->id()));
+
+  // Process an "inchoate" REJ from the server which will cause
+  // an inchoate CHLO to be sent and will leave the encryption level
+  // at NONE.
+  CryptoHandshakeMessage rej;
+  crypto_test_utils::FillInDummyReject(&rej);
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  crypto_test_utils::SendHandshakeMessageToStream(
+      session_->GetMutableCryptoStream(), rej, Perspective::IS_CLIENT);
+  EXPECT_FALSE(session_->IsEncryptionEstablished());
+  EXPECT_EQ(ENCRYPTION_INITIAL,
+            QuicPacketCreatorPeer::GetEncryptionLevel(
+                QuicConnectionPeer::GetPacketCreator(connection_)));
+  // Verify that no new streams may be created.
+  EXPECT_TRUE(session_->CreateOutgoingBidirectionalStream() == nullptr);
+  // Verify that no data may be send on existing streams.
+  char data[] = "hello world";
+  QuicConsumedData consumed =
+      session_->WritevData(stream->id(), ABSL_ARRAYSIZE(data), 0, NO_FIN,
+                           NOT_RETRANSMISSION, ENCRYPTION_INITIAL);
+  EXPECT_EQ(0u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+}
+
+TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithNoFinOrRst) {
+  uint32_t kServerMaxIncomingStreams = 1;
+  CompleteCryptoHandshake(kServerMaxIncomingStreams);
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+  EXPECT_FALSE(session_->CreateOutgoingBidirectionalStream());
+
+  // Close the stream, but without having received a FIN or a RST_STREAM
+  // or MAX_STREAMS (IETF QUIC) and check that a new one can not be created.
+  session_->ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_FALSE(stream);
+}
+
+TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithRst) {
+  uint32_t kServerMaxIncomingStreams = 1;
+  CompleteCryptoHandshake(kServerMaxIncomingStreams);
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_NE(nullptr, stream);
+  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
+
+  // Close the stream and receive an RST frame to remove the unfinished stream
+  session_->ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
+  session_->OnRstStream(QuicRstStreamFrame(kInvalidControlFrameId, stream->id(),
+                                           QUIC_RST_ACKNOWLEDGEMENT, 0));
+  // Check that a new one can be created.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // In IETF QUIC the stream limit increases only if we get a MAX_STREAMS
+    // frame; pretend we got one.
+
+    QuicMaxStreamsFrame frame(0, 2,
+                              /*unidirectional=*/false);
+    session_->OnMaxStreamsFrame(frame);
+  }
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_NE(nullptr, stream);
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // Ensure that we have 2 total streams, 1 open and 1 closed.
+    QuicStreamCount expected_stream_count = 2;
+    EXPECT_EQ(expected_stream_count,
+              QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_)
+                  ->outgoing_stream_count());
+  }
+}
+
+TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) {
+  // Tests the situation in which the client sends a RST at the same time that
+  // the server sends trailing headers (trailers). Receipt of the trailers by
+  // the client should result in all outstanding stream state being tidied up
+  // (including flow control, and number of available outgoing streams).
+  uint32_t kServerMaxIncomingStreams = 1;
+  CompleteCryptoHandshake(kServerMaxIncomingStreams);
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_NE(nullptr, stream);
+
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // For IETF QUIC, trying to open a stream and failing due to lack
+    // of stream ids will result in a STREAMS_BLOCKED. Make
+    // sure we get one. Also clear out the frame because if it's
+    // left sitting, the later SendRstStream will not actually
+    // transmit the RST_STREAM because the connection will be in write-blocked
+    // state. This means that the SendControlFrame that is expected w.r.t. the
+    // RST_STREAM, below, will not be satisfied.
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(
+            this, &QuicSpdyClientSessionTest::ClearStreamsBlockedControlFrame));
+  }
+
+  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
+
+  QuicStreamId stream_id = stream->id();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(AtLeast(1))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
+  session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY);
+
+  // A new stream cannot be created as the reset stream still counts as an open
+  // outgoing stream until closed by the server.
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(nullptr, stream);
+
+  // The stream receives trailers with final byte offset: this is one of three
+  // ways that a peer can signal the end of a stream (the others being RST,
+  // stream data + FIN).
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
+  trailers.OnHeaderBlockEnd(0, 0);
+  session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
+
+  // The stream is now complete from the client's perspective, and it should
+  // be able to create a new outgoing stream.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    QuicMaxStreamsFrame frame(0, 2,
+                              /*unidirectional=*/false);
+
+    session_->OnMaxStreamsFrame(frame);
+  }
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_NE(nullptr, stream);
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // Ensure that we have 2 open streams.
+    QuicStreamCount expected_stream_count = 2;
+    EXPECT_EQ(expected_stream_count,
+              QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_)
+                  ->outgoing_stream_count());
+  }
+}
+
+TEST_P(QuicSpdyClientSessionTest, ReceivedMalformedTrailersAfterSendingRst) {
+  // Tests the situation where the client has sent a RST to the server, and has
+  // received trailing headers with a malformed final byte offset value.
+  CompleteCryptoHandshake();
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_NE(nullptr, stream);
+
+  // Send the RST, which results in the stream being closed locally (but some
+  // state remains while the client waits for a response from the server).
+  QuicStreamId stream_id = stream->id();
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(AtLeast(1))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
+  session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY);
+
+  // The stream receives trailers with final byte offset, but the header value
+  // is non-numeric and should be treated as malformed.
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "invalid non-numeric value");
+  trailers.OnHeaderBlockEnd(0, 0);
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnStreamHeaderListWithStaticStream) {
+  // Test situation where OnStreamHeaderList is called by stream with static id.
+  CompleteCryptoHandshake();
+
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
+  trailers.OnHeaderBlockEnd(0, 0);
+
+  // Initialize H/3 control stream.
+  QuicStreamId id;
+  if (VersionUsesHttp3(connection_->transport_version())) {
+    id = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 3);
+    char type[] = {0x00};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_->OnStreamFrame(data1);
+  } else {
+    id = QuicUtils::GetHeadersStreamId(connection_->transport_version());
+  }
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "stream is static", _))
+      .Times(1);
+  session_->OnStreamHeaderList(id,
+                               /*fin=*/false, 0, trailers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnPromiseHeaderListWithStaticStream) {
+  // Test situation where OnPromiseHeaderList is called by stream with static
+  // id.
+  CompleteCryptoHandshake();
+
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
+  trailers.OnHeaderBlockEnd(0, 0);
+
+  // Initialize H/3 control stream.
+  QuicStreamId id;
+  if (VersionUsesHttp3(connection_->transport_version())) {
+    id = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 3);
+    char type[] = {0x00};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_->OnStreamFrame(data1);
+  } else {
+    id = QuicUtils::GetHeadersStreamId(connection_->transport_version());
+  }
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "stream is static", _))
+      .Times(1);
+  session_->OnPromiseHeaderList(id, promised_stream_id_, 0, trailers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, GoAwayReceived) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+  CompleteCryptoHandshake();
+
+  // After receiving a GoAway, I should no longer be able to create outgoing
+  // streams.
+  session_->connection()->OnGoAwayFrame(QuicGoAwayFrame(
+      kInvalidControlFrameId, QUIC_PEER_GOING_AWAY, 1u, "Going away."));
+  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
+}
+
+static bool CheckForDecryptionError(QuicFramer* framer) {
+  return framer->error() == QUIC_DECRYPTION_FAILURE;
+}
+
+// Various sorts of invalid packets that should not cause a connection
+// to be closed.
+TEST_P(QuicSpdyClientSessionTest, InvalidPacketReceived) {
+  QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
+  QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
+
+  EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
+      .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
+                             &MockQuicConnection::ReallyProcessUdpPacket));
+  EXPECT_CALL(*connection_, OnCanWrite()).Times(AnyNumber());
+  EXPECT_CALL(*connection_, OnError(_)).Times(1);
+
+  // Verify that empty packets don't close the connection.
+  QuicReceivedPacket zero_length_packet(nullptr, 0, QuicTime::Zero(), false);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_->ProcessUdpPacket(client_address, server_address,
+                             zero_length_packet);
+
+  // Verifiy that small, invalid packets don't close the connection.
+  char buf[2] = {0x00, 0x01};
+  QuicConnectionId connection_id = session_->connection()->connection_id();
+  QuicReceivedPacket valid_packet(buf, 2, QuicTime::Zero(), false);
+  // Close connection shouldn't be called.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*connection_, OnError(_)).Times(AtMost(1));
+  session_->ProcessUdpPacket(client_address, server_address, valid_packet);
+
+  // Verify that a non-decryptable packet doesn't close the connection.
+  QuicFramerPeer::SetLastSerializedServerConnectionId(
+      QuicConnectionPeer::GetFramer(connection_), connection_id);
+  ParsedQuicVersionVector versions = SupportedVersions(GetParam());
+  QuicConnectionId destination_connection_id = EmptyQuicConnectionId();
+  QuicConnectionId source_connection_id = connection_id;
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      destination_connection_id, source_connection_id, false, false, 100,
+      "data", true, CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT,
+      PACKET_4BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  // Change the last byte of the encrypted data.
+  *(const_cast<char*>(received->data() + received->length() - 1)) += 1;
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*connection_, OnError(Truly(CheckForDecryptionError))).Times(1);
+  session_->ProcessUdpPacket(client_address, server_address, *received);
+}
+
+// A packet with invalid framing should cause a connection to be closed.
+TEST_P(QuicSpdyClientSessionTest, InvalidFramedPacketReceived) {
+  const ParsedQuicVersion version = GetParam();
+  QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
+  QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
+  if (version.KnowsWhichDecrypterToUse()) {
+    connection_->InstallDecrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+  } else {
+    connection_->SetDecrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+  }
+
+  EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
+      .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
+                             &MockQuicConnection::ReallyProcessUdpPacket));
+  EXPECT_CALL(*connection_, OnError(_)).Times(1);
+
+  // Verify that a decryptable packet with bad frames does close the connection.
+  QuicConnectionId destination_connection_id =
+      session_->connection()->connection_id();
+  QuicConnectionId source_connection_id = EmptyQuicConnectionId();
+  QuicFramerPeer::SetLastSerializedServerConnectionId(
+      QuicConnectionPeer::GetFramer(connection_), destination_connection_id);
+  bool version_flag = false;
+  QuicConnectionIdIncluded scid_included = CONNECTION_ID_ABSENT;
+  if (version.HasIetfInvariantHeader()) {
+    version_flag = true;
+    source_connection_id = destination_connection_id;
+    scid_included = CONNECTION_ID_PRESENT;
+  }
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
+      destination_connection_id, source_connection_id, version_flag, false, 100,
+      "data", CONNECTION_ID_ABSENT, scid_included, PACKET_4BYTE_PACKET_NUMBER,
+      version, Perspective::IS_SERVER));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  session_->ProcessUdpPacket(client_address, server_address, *received);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeaders) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
+      session_->CreateOutgoingBidirectionalStream());
+
+  EXPECT_CALL(*stream, OnPromiseHeaderList(_, _, _));
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseStreamIdTooHigh) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  QuicStreamId stream_id =
+      QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(session_.get());
+  QuicSessionPeer::ActivateStream(
+      session_.get(), std::make_unique<QuicSpdyClientStream>(
+                          stream_id, session_.get(), BIDIRECTIONAL));
+
+  QuicHeaderList headers;
+  headers.OnHeaderBlockStart();
+  headers.OnHeader(":path", "/bar");
+  headers.OnHeader(":authority", "www.google.com");
+  headers.OnHeader(":method", "GET");
+  headers.OnHeader(":scheme", "https");
+  headers.OnHeaderBlockEnd(0, 0);
+
+  const QuicStreamId promise_id = GetNthServerInitiatedUnidirectionalStreamId(
+      connection_->transport_version(), 11);
+  session_->OnPromiseHeaderList(stream_id, promise_id, 0, headers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeadersAlreadyClosed) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOutOfOrder) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
+      session_->CreateOutgoingBidirectionalStream());
+
+  EXPECT_CALL(*stream, OnPromiseHeaderList(promised_stream_id_, _, _));
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+  associated_stream_id_ +=
+      QuicUtils::StreamIdDelta(connection_->transport_version());
+  if (!VersionUsesHttp3(session_->transport_version())) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_INVALID_STREAM_ID,
+                                "Received push stream id lesser or equal to the"
+                                " last accepted before",
+                                _));
+  }
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOutgoingStreamId) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
+      session_->CreateOutgoingBidirectionalStream());
+
+  // Promise an illegal (outgoing) stream id.
+  promised_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
+      connection_->transport_version(), 0);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Received push stream id for outgoing stream.", _));
+
+  session_->OnPromiseHeaderList(stream->id(), promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseHandlePromise) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+
+  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseAlreadyClosed) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+  session_->GetOrCreateStream(promised_stream_id_);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+  SpdyHeaderBlock promise_headers;
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, promise_headers));
+
+  // Verify that the promise was not created.
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseDuplicateUrl) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+
+  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+
+  promised_stream_id_ +=
+      QuicUtils::StreamIdDelta(connection_->transport_version());
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_DUPLICATE_PROMISE_URL));
+
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, push_promise_));
+
+  // Verify that the promise was not created.
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ReceivingPromiseEnhanceYourCalm) {
+  CompleteCryptoHandshake();
+  for (size_t i = 0u; i < session_->get_max_promises(); i++) {
+    push_promise_[":path"] = absl::StrCat("/bar", i);
+
+    QuicStreamId id =
+        promised_stream_id_ +
+        i * QuicUtils::StreamIdDelta(connection_->transport_version());
+
+    EXPECT_TRUE(
+        session_->HandlePromised(associated_stream_id_, id, push_promise_));
+
+    // Verify that the promise is in the unclaimed streams map.
+    std::string promise_url(
+        SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_));
+    EXPECT_NE(session_->GetPromisedByUrl(promise_url), nullptr);
+    EXPECT_NE(session_->GetPromisedById(id), nullptr);
+  }
+
+  // One more promise, this should be refused.
+  int i = session_->get_max_promises();
+  push_promise_[":path"] = absl::StrCat("/bar", i);
+
+  QuicStreamId id =
+      promised_stream_id_ +
+      i * QuicUtils::StreamIdDelta(connection_->transport_version());
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(id, QUIC_REFUSED_STREAM));
+  EXPECT_FALSE(
+      session_->HandlePromised(associated_stream_id_, id, push_promise_));
+
+  // Verify that the promise was not created.
+  std::string promise_url(
+      SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_));
+  EXPECT_EQ(session_->GetPromisedById(id), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedAlreadyOpen) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+  EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
+}
+
+TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedNonexistant) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+  EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsPush) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+
+  session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsNotPush) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->CreateOutgoingBidirectionalStream();
+  session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
+}
+
+TEST_P(QuicSpdyClientSessionTest, DeletePromised) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+  QuicClientPromisedInfo* promised =
+      session_->GetPromisedById(promised_stream_id_);
+  EXPECT_NE(promised, nullptr);
+  EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+
+  session_->DeletePromised(promised);
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ResetPromised) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY));
+  session_->ResetStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY);
+  QuicClientPromisedInfo* promised =
+      session_->GetPromisedById(promised_stream_id_);
+  EXPECT_NE(promised, nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+  EXPECT_EQ(session_->GetPromisedStream(promised_stream_id_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidMethod) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_METHOD));
+
+  push_promise_[":method"] = "POST";
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, push_promise_));
+
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidHost) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_URL));
+
+  push_promise_[":authority"] = "";
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, push_promise_));
+
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest,
+       TryToCreateServerInitiatedBidirectionalStream) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM, _, _));
+  } else {
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  }
+  session_->GetOrCreateStream(GetNthServerInitiatedBidirectionalStreamId(
+      connection_->transport_version(), 0));
+}
+
+TEST_P(QuicSpdyClientSessionTest, TooManyPushPromises) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  QuicStreamId stream_id =
+      QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(session_.get());
+  QuicSessionPeer::ActivateStream(
+      session_.get(), std::make_unique<QuicSpdyClientStream>(
+                          stream_id, session_.get(), BIDIRECTIONAL));
+
+  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM));
+
+  for (size_t promise_count = 0; promise_count <= session_->get_max_promises();
+       promise_count++) {
+    auto promise_id = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), promise_count);
+    auto headers = QuicHeaderList();
+    headers.OnHeaderBlockStart();
+    headers.OnHeader(":path", absl::StrCat("/", promise_count));
+    headers.OnHeader(":authority", "www.google.com");
+    headers.OnHeader(":method", "GET");
+    headers.OnHeader(":scheme", "https");
+    headers.OnHeaderBlockEnd(0, 0);
+    session_->OnPromiseHeaderList(stream_id, promise_id, 0, headers);
+  }
+}
+
+// Test that upon receiving HTTP/3 SETTINGS, the settings are serialized and
+// stored into client session cache.
+TEST_P(QuicSpdyClientSessionTest, OnSettingsFrame) {
+  // This feature is HTTP/3 only
+  if (!VersionUsesHttp3(session_->transport_version())) {
+    return;
+  }
+  CompleteCryptoHandshake();
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  settings.values[256] = 4;   // unknown setting
+  char application_state[] = {// type (SETTINGS)
+                              0x04,
+                              // length
+                              0x07,
+                              // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
+                              0x01,
+                              // content
+                              0x02,
+                              // identifier (SETTINGS_MAX_FIELD_SECTION_SIZE)
+                              0x06,
+                              // content
+                              0x05,
+                              // identifier (256 in variable length integer)
+                              0x40 + 0x01, 0x00,
+                              // content
+                              0x04};
+  ApplicationState expected(std::begin(application_state),
+                            std::end(application_state));
+  session_->OnSettingsFrame(settings);
+  EXPECT_EQ(expected, *client_session_cache_
+                           ->Lookup(QuicServerId(kServerHostname, kPort, false),
+                                    session_->GetClock()->WallNow(), nullptr)
+                           ->application_state);
+}
+
+TEST_P(QuicSpdyClientSessionTest, IetfZeroRttSetup) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  CreateConnection();
+  // Session configs should be in initial state.
+  if (session_->version().UsesHttp3()) {
+    EXPECT_EQ(0u, session_->flow_controller()->send_window_offset());
+    EXPECT_EQ(std::numeric_limits<size_t>::max(),
+              session_->max_outbound_header_list_size());
+  } else {
+    EXPECT_EQ(kMinimumFlowControlSendWindow,
+              session_->flow_controller()->send_window_offset());
+  }
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
+
+  // The client session should have a basic setup ready before the handshake
+  // succeeds.
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            session_->flow_controller()->send_window_offset());
+  if (session_->version().UsesHttp3()) {
+    auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+              id_manager->max_outgoing_bidirectional_streams());
+    EXPECT_EQ(
+        kDefaultMaxStreamsPerConnection + kHttp3StaticUnidirectionalStreamCount,
+        id_manager->max_outgoing_unidirectional_streams());
+    auto* control_stream =
+        QuicSpdySessionPeer::GetSendControlStream(session_.get());
+    EXPECT_EQ(kInitialStreamFlowControlWindowForTest,
+              QuicStreamPeer::SendWindowOffset(control_stream));
+    EXPECT_EQ(5u, session_->max_outbound_header_list_size());
+  } else {
+    auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+              id_manager->max_open_outgoing_streams());
+  }
+
+  // Complete the handshake with a different config.
+  QuicConfig config = DefaultQuicConfig();
+  config.SetInitialMaxStreamDataBytesUnidirectionalToSend(
+      kInitialStreamFlowControlWindowForTest + 1);
+  config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest + 1);
+  config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
+  config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+
+  EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest + 1,
+            session_->flow_controller()->send_window_offset());
+  if (session_->version().UsesHttp3()) {
+    auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
+    auto* control_stream =
+        QuicSpdySessionPeer::GetSendControlStream(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
+              id_manager->max_outgoing_bidirectional_streams());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection +
+                  kHttp3StaticUnidirectionalStreamCount + 1,
+              id_manager->max_outgoing_unidirectional_streams());
+    EXPECT_EQ(kInitialStreamFlowControlWindowForTest + 1,
+              QuicStreamPeer::SendWindowOffset(control_stream));
+  } else {
+    auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
+              id_manager->max_open_outgoing_streams());
+  }
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  // Let the session receive a new SETTINGS frame to complete the second
+  // connection.
+  if (session_->version().UsesHttp3()) {
+    SettingsFrame settings;
+    settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+    settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+    settings.values[256] = 4;  // unknown setting
+    session_->OnSettingsFrame(settings);
+  }
+}
+
+// Regression test for b/159168475
+TEST_P(QuicSpdyClientSessionTest, RetransmitDataOnZeroRttReject) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  // Create a second connection, but disable 0-RTT on the server.
+  CreateConnection();
+  ON_CALL(*connection_, OnCanWrite())
+      .WillByDefault(
+          testing::Invoke(connection_, &MockQuicConnection::ReallyOnCanWrite));
+  EXPECT_CALL(*connection_, OnCanWrite()).Times(0);
+
+  QuicConfig config = DefaultQuicConfig();
+  config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+  config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+
+  // Packets will be written: CHLO, HTTP/3 SETTINGS (H/3 only), and request
+  // data.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION))
+      .Times(session_->version().UsesHttp3() ? 2 : 1);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+  stream->WriteOrBufferData("hello", true, nullptr);
+
+  // When handshake is done, the client sends 2 packet: HANDSHAKE FINISHED, and
+  // coalesced retransmission of HTTP/3 SETTINGS and request data.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
+  // TODO(b/158027651): change transmission type to ALL_ZERO_RTT_RETRANSMISSION.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+  EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
+}
+
+// When IETF QUIC 0-RTT is rejected, a server-sent fresh transport params is
+// available. If the new transport params reduces stream/flow control limit to
+// lower than what the client has already used, connection will be closed.
+TEST_P(QuicSpdyClientSessionTest, ZeroRttRejectReducesStreamLimitTooMuch) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  // Create a second connection, but disable 0-RTT on the server.
+  CreateConnection();
+  QuicConfig config = DefaultQuicConfig();
+  // Server doesn't allow any bidirectional streams.
+  config.SetMaxBidirectionalStreamsToSend(0);
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+
+  if (session_->version().UsesHttp3()) {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(
+            QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+            "Server rejected 0-RTT, aborting because new bidirectional initial "
+            "stream limit 0 is less than current open streams: 1",
+            _))
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection));
+  } else {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INTERNAL_ERROR,
+                        "Server rejected 0-RTT, aborting because new stream "
+                        "limit 0 is less than current open streams: 1",
+                        _))
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection));
+  }
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+}
+
+TEST_P(QuicSpdyClientSessionTest,
+       ZeroRttRejectReducesStreamFlowControlTooMuch) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  // Create a second connection, but disable 0-RTT on the server.
+  CreateConnection();
+  QuicConfig config = DefaultQuicConfig();
+  // Server doesn't allow any outgoing streams.
+  config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(2);
+  config.SetInitialMaxStreamDataBytesUnidirectionalToSend(1);
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+  // Let the stream write more than 1 byte of data.
+  stream->WriteOrBufferData("hello", true, nullptr);
+
+  if (session_->version().UsesHttp3()) {
+    // Both control stream and the request stream will report errors.
+    // Open question: should both streams be closed with the same error code?
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _))
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection));
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection))
+        .RetiresOnSaturation();
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(
+                    QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+                    "Server rejected 0-RTT, aborting because new stream max "
+                    "data 2 for stream 3 is less than currently used: 5",
+                    _))
+        .Times(1)
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection));
+  }
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+}
+
+TEST_P(QuicSpdyClientSessionTest,
+       ZeroRttRejectReducesSessionFlowControlTooMuch) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  // Create a second connection, but disable 0-RTT on the server.
+  CreateConnection();
+  QuicConfig config = DefaultQuicConfig();
+  // Server doesn't allow minimum data in session.
+  config.SetInitialSessionFlowControlWindowToSend(
+      kMinimumFlowControlSendWindow);
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+  std::string data_to_send(kMinimumFlowControlSendWindow + 1, 'x');
+  // Let the stream write some data.
+  stream->WriteOrBufferData(data_to_send, true, nullptr);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+}
+
+TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttResumption) {
+  if (!session_->version().UsesHttp3()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  CreateConnection();
+  CompleteCryptoHandshake();
+  EXPECT_TRUE(session_->GetCryptoStream()->EarlyDataAccepted());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  // Let the session receive a different SETTINGS frame.
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  settings.values[256] = 4;  // unknown setting
+  session_->OnSettingsFrame(settings);
+}
+
+TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttRejection) {
+  if (!session_->version().UsesHttp3()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  CreateConnection();
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicConfig config = DefaultQuicConfig();
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+  EXPECT_FALSE(session_->GetCryptoStream()->EarlyDataAccepted());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  // Let the session receive a different SETTINGS frame.
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+  // setting on SETTINGS_MAX_FIELD_SECTION_SIZE is reduced.
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 4;
+  settings.values[256] = 4;  // unknown setting
+  session_->OnSettingsFrame(settings);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ServerAcceptsZeroRttButOmitSetting) {
+  if (!session_->version().UsesHttp3()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  CreateConnection();
+  CompleteCryptoHandshake();
+  EXPECT_TRUE(session_->GetMutableCryptoStream()->EarlyDataAccepted());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  // Let the session receive a different SETTINGS frame.
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+  // Intentionally omit SETTINGS_MAX_FIELD_SECTION_SIZE which was previously
+  // sent with a non-zero value.
+  settings.values[256] = 4;  // unknown setting
+  session_->OnSettingsFrame(settings);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_stream.cc b/quiche/quic/core/http/quic_spdy_client_stream.cc
new file mode 100644
index 0000000..e1677fb
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_stream.cc
@@ -0,0 +1,219 @@
+// 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 "quiche/quic/core/http/quic_spdy_client_stream.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicSpdyClientStream::QuicSpdyClientStream(QuicStreamId id,
+                                           QuicSpdyClientSession* session,
+                                           StreamType type)
+    : QuicSpdyStream(id, session, type),
+      content_length_(-1),
+      response_code_(0),
+      header_bytes_read_(0),
+      header_bytes_written_(0),
+      session_(session),
+      has_preliminary_headers_(false) {}
+
+QuicSpdyClientStream::QuicSpdyClientStream(PendingStream* pending,
+                                           QuicSpdyClientSession* session)
+    : QuicSpdyStream(pending, session),
+      content_length_(-1),
+      response_code_(0),
+      header_bytes_read_(0),
+      header_bytes_written_(0),
+      session_(session),
+      has_preliminary_headers_(false) {}
+
+QuicSpdyClientStream::~QuicSpdyClientStream() = default;
+
+void QuicSpdyClientStream::OnInitialHeadersComplete(
+    bool fin,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
+
+  QUICHE_DCHECK(headers_decompressed());
+  header_bytes_read_ += frame_len;
+  if (rst_sent()) {
+    // QuicSpdyStream::OnInitialHeadersComplete already rejected invalid
+    // response header.
+    return;
+  }
+
+  if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
+                                         &response_headers_)) {
+    QUIC_DLOG(ERROR) << "Failed to parse header list: "
+                     << header_list.DebugString() << " on stream " << id();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  if (web_transport() != nullptr) {
+    web_transport()->HeadersReceived(response_headers_);
+    if (!web_transport()->ready()) {
+      // The request was rejected by WebTransport, typically due to not having a
+      // 2xx status.  The reason we're using Reset() here rather than closing
+      // cleanly is that even if the server attempts to send us any form of body
+      // with a 4xx request, we've already set up the capsule parser, and we
+      // don't have any way to process anything from the response body in
+      // question.
+      Reset(QUIC_STREAM_CANCELLED);
+      return;
+    }
+  }
+
+  if (!ParseHeaderStatusCode(response_headers_, &response_code_)) {
+    QUIC_DLOG(ERROR) << "Received invalid response code: "
+                     << response_headers_[":status"].as_string()
+                     << " on stream " << id();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  if (response_code_ == 101) {
+    // 101 "Switching Protocols" is forbidden in HTTP/3 as per the
+    // "HTTP Upgrade" section of draft-ietf-quic-http.
+    QUIC_DLOG(ERROR) << "Received forbidden 101 response code"
+                     << " on stream " << id();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  if (response_code_ >= 100 && response_code_ < 200) {
+    // These are Informational 1xx headers, not the actual response headers.
+    QUIC_DLOG(INFO) << "Received informational response code: "
+                    << response_headers_[":status"].as_string() << " on stream "
+                    << id();
+    set_headers_decompressed(false);
+    if (response_code_ == 100 && !has_preliminary_headers_) {
+      // This is 100 Continue, save it to enable "Expect: 100-continue".
+      has_preliminary_headers_ = true;
+      preliminary_headers_ = std::move(response_headers_);
+    } else {
+      response_headers_.clear();
+    }
+  }
+
+  ConsumeHeaderList();
+  QUIC_DVLOG(1) << "headers complete for stream " << id();
+
+  session_->OnInitialHeadersComplete(id(), response_headers_);
+}
+
+void QuicSpdyClientStream::OnTrailingHeadersComplete(
+    bool fin,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list);
+  MarkTrailersConsumed();
+}
+
+void QuicSpdyClientStream::OnPromiseHeaderList(
+    QuicStreamId promised_id,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  header_bytes_read_ += frame_len;
+  int64_t content_length = -1;
+  SpdyHeaderBlock promise_headers;
+  if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length,
+                                         &promise_headers)) {
+    QUIC_DLOG(ERROR) << "Failed to parse promise headers: "
+                     << header_list.DebugString();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  session_->HandlePromised(id(), promised_id, promise_headers);
+  if (visitor() != nullptr) {
+    visitor()->OnPromiseHeadersComplete(promised_id, frame_len);
+  }
+}
+
+void QuicSpdyClientStream::OnBodyAvailable() {
+  // For push streams, visitor will not be set until the rendezvous
+  // between server promise and client request is complete.
+  if (visitor() == nullptr)
+    return;
+
+  while (HasBytesToRead()) {
+    struct iovec iov;
+    if (GetReadableRegions(&iov, 1) == 0) {
+      // No more data to read.
+      break;
+    }
+    QUIC_DVLOG(1) << "Client processed " << iov.iov_len << " bytes for stream "
+                  << id();
+    data_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
+
+    if (content_length_ >= 0 &&
+        data_.size() > static_cast<uint64_t>(content_length_)) {
+      QUIC_DLOG(ERROR) << "Invalid content length (" << content_length_
+                       << ") with data of size " << data_.size();
+      Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+      return;
+    }
+    MarkConsumed(iov.iov_len);
+  }
+  if (sequencer()->IsClosed()) {
+    OnFinRead();
+  } else {
+    sequencer()->SetUnblocked();
+  }
+}
+
+size_t QuicSpdyClientStream::SendRequest(SpdyHeaderBlock headers,
+                                         absl::string_view body,
+                                         bool fin) {
+  QuicConnection::ScopedPacketFlusher flusher(session_->connection());
+  bool send_fin_with_headers = fin && body.empty();
+  size_t bytes_sent = body.size();
+  header_bytes_written_ =
+      WriteHeaders(std::move(headers), send_fin_with_headers, nullptr);
+  bytes_sent += header_bytes_written_;
+
+  if (!body.empty()) {
+    WriteOrBufferBody(body, fin);
+  }
+
+  return bytes_sent;
+}
+
+bool QuicSpdyClientStream::AreHeadersValid(
+    const QuicHeaderList& header_list) const {
+  if (!GetQuicReloadableFlag(quic_verify_request_headers_2)) {
+    return true;
+  }
+  if (!QuicSpdyStream::AreHeadersValid(header_list)) {
+    return false;
+  }
+  // Verify the presence of :status header.
+  bool saw_status = false;
+  for (const std::pair<std::string, std::string>& pair : header_list) {
+    if (pair.first == ":status") {
+      saw_status = true;
+    } else if (absl::StrContains(pair.first, ":")) {
+      QUIC_DLOG(ERROR) << "Unexpected ':' in header " << pair.first << ".";
+      return false;
+    }
+  }
+  return saw_status;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_stream.h b/quiche/quic/core/http/quic_spdy_client_stream.h
new file mode 100644
index 0000000..ebda141
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_stream.h
@@ -0,0 +1,102 @@
+// 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_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
+
+#include <cstddef>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+class QuicSpdyClientSession;
+
+// All this does right now is send an SPDY request, and aggregate the
+// SPDY response.
+class QUIC_EXPORT_PRIVATE QuicSpdyClientStream : public QuicSpdyStream {
+ public:
+  QuicSpdyClientStream(QuicStreamId id,
+                       QuicSpdyClientSession* session,
+                       StreamType type);
+  QuicSpdyClientStream(PendingStream* pending,
+                       QuicSpdyClientSession* spdy_session);
+  QuicSpdyClientStream(const QuicSpdyClientStream&) = delete;
+  QuicSpdyClientStream& operator=(const QuicSpdyClientStream&) = delete;
+  ~QuicSpdyClientStream() override;
+
+  // Override the base class to parse and store headers.
+  void OnInitialHeadersComplete(bool fin,
+                                size_t frame_len,
+                                const QuicHeaderList& header_list) override;
+
+  // Override the base class to parse and store trailers.
+  void OnTrailingHeadersComplete(bool fin,
+                                 size_t frame_len,
+                                 const QuicHeaderList& header_list) override;
+
+  // Override the base class to handle creation of the push stream.
+  void OnPromiseHeaderList(QuicStreamId promised_id,
+                           size_t frame_len,
+                           const QuicHeaderList& header_list) override;
+
+  // QuicStream implementation called by the session when there's data for us.
+  void OnBodyAvailable() override;
+
+  // Serializes the headers and body, sends it to the server, and
+  // returns the number of bytes sent.
+  size_t SendRequest(spdy::SpdyHeaderBlock headers,
+                     absl::string_view body,
+                     bool fin);
+
+  // Returns the response data.
+  const std::string& data() { return data_; }
+
+  // Returns whatever headers have been received for this stream.
+  const spdy::SpdyHeaderBlock& response_headers() { return response_headers_; }
+
+  const spdy::SpdyHeaderBlock& preliminary_headers() {
+    return preliminary_headers_;
+  }
+
+  size_t header_bytes_read() const { return header_bytes_read_; }
+
+  size_t header_bytes_written() const { return header_bytes_written_; }
+
+  int response_code() const { return response_code_; }
+
+  // While the server's SetPriority shouldn't be called externally, the creator
+  // of client-side streams should be able to set the priority.
+  using QuicSpdyStream::SetPriority;
+
+ protected:
+  bool AreHeadersValid(const QuicHeaderList& header_list) const override;
+
+ private:
+  // The parsed headers received from the server.
+  spdy::SpdyHeaderBlock response_headers_;
+
+  // The parsed content-length, or -1 if none is specified.
+  int64_t content_length_;
+  int response_code_;
+  std::string data_;
+  size_t header_bytes_read_;
+  size_t header_bytes_written_;
+
+  QuicSpdyClientSession* session_;
+
+  // These preliminary headers are used for the 100 Continue headers
+  // that may arrive before the response headers when the request has
+  // Expect: 100-continue.
+  bool has_preliminary_headers_;
+  spdy::SpdyHeaderBlock preliminary_headers_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/quiche/quic/core/http/quic_spdy_client_stream_test.cc b/quiche/quic/core/http/quic_spdy_client_stream_test.cc
new file mode 100644
index 0000000..0470f41
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_stream_test.cc
@@ -0,0 +1,324 @@
+// Copyright 2013 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 "quiche/quic/core/http/quic_spdy_client_stream.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+
+namespace {
+
+class MockQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit MockQuicSpdyClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(DefaultQuicConfig(),
+                              supported_versions,
+                              connection,
+                              QuicServerId("example.com", 443, false),
+                              &crypto_config_,
+                              push_promise_index),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
+  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
+  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
+      delete;
+  ~MockQuicSpdyClientSession() override = default;
+
+  MOCK_METHOD(bool,
+              WriteControlFrame,
+              (const QuicFrame& frame, TransmissionType type),
+              (override));
+
+  using QuicSession::ActivateStream;
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+};
+
+class QuicSpdyClientStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  class StreamVisitor;
+
+  QuicSpdyClientStreamTest()
+      : connection_(
+            new StrictMock<MockQuicConnection>(&helper_,
+                                               &alarm_factory_,
+                                               Perspective::IS_CLIENT,
+                                               SupportedVersions(GetParam()))),
+        session_(connection_->supported_versions(),
+                 connection_,
+                 &push_promise_index_),
+        body_("hello world") {
+    session_.Initialize();
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    headers_[":status"] = "200";
+    headers_["content-length"] = "11";
+
+    auto stream = std::make_unique<QuicSpdyClientStream>(
+        GetNthClientInitiatedBidirectionalStreamId(
+            connection_->transport_version(), 0),
+        &session_, BIDIRECTIONAL);
+    stream_ = stream.get();
+    session_.ActivateStream(std::move(stream));
+
+    stream_visitor_ = std::make_unique<StreamVisitor>();
+    stream_->set_visitor(stream_visitor_.get());
+  }
+
+  class StreamVisitor : public QuicSpdyClientStream::Visitor {
+    void OnClose(QuicSpdyStream* stream) override {
+      QUIC_DVLOG(1) << "stream " << stream->id();
+    }
+  };
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  QuicClientPushPromiseIndex push_promise_index_;
+
+  MockQuicSpdyClientSession session_;
+  QuicSpdyClientStream* stream_;
+  std::unique_ptr<StreamVisitor> stream_visitor_;
+  SpdyHeaderBlock headers_;
+  std::string body_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSpdyClientStreamTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) {
+  headers_[":status"] = "200 ok";
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_THAT(stream_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(QuicSpdyClientStreamTest, InvalidResponseHeader) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  auto headers = AsHeaderList(std::vector<std::pair<std::string, std::string>>{
+      {":status", "200"}, {":path", "/foo"}});
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_THAT(stream_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(QuicSpdyClientStreamTest, MissingStatusCode) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  auto headers = AsHeaderList(
+      std::vector<std::pair<std::string, std::string>>{{"key", "value"}});
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_THAT(stream_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestFraming) {
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+}
+
+TEST_P(QuicSpdyClientStreamTest, Test100ContinueBeforeSuccessful) {
+  // First send 100 Continue.
+  headers_[":status"] = "100";
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
+  EXPECT_EQ(0u, stream_->response_headers().size());
+  EXPECT_EQ(100, stream_->response_code());
+  EXPECT_EQ("", stream_->data());
+  // Then send 200 OK.
+  headers_[":status"] = "200";
+  headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  // Make sure the 200 response got parsed correctly.
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+  // Make sure the 100 response is still available.
+  EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestUnknownInformationalBeforeSuccessful) {
+  // First send 199, an unknown Informational (1XX).
+  headers_[":status"] = "199";
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_EQ(0u, stream_->response_headers().size());
+  EXPECT_EQ(199, stream_->response_code());
+  EXPECT_EQ("", stream_->data());
+  // Then send 200 OK.
+  headers_[":status"] = "200";
+  headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  // Make sure the 200 response got parsed correctly.
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestReceiving101) {
+  // 101 "Switching Protocols" is forbidden in HTTP/3 as per the
+  // "HTTP Upgrade" section of draft-ietf-quic-http.
+  headers_[":status"] = "101";
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_THAT(stream_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestFramingOnePacket) {
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+}
+
+TEST_P(QuicSpdyClientStreamTest,
+       QUIC_TEST_DISABLED_IN_CHROME(TestFramingExtraData)) {
+  std::string large_body = "hello world!!!!!!";
+
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  // The headers should parse successfully.
+  EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      large_body.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), large_body)
+                         : large_body;
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+
+  EXPECT_NE(QUIC_STREAM_NO_ERROR, stream_->stream_error());
+}
+
+// Test that receiving trailing headers (on the headers stream), containing a
+// final offset, results in the stream being closed at that byte offset.
+TEST_P(QuicSpdyClientStreamTest, ReceivingTrailers) {
+  // There is no kFinalOffsetHeaderKey if trailers are sent on the
+  // request/response stream.
+  if (VersionUsesHttp3(connection_->transport_version())) {
+    return;
+  }
+
+  // Send headers as usual.
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+
+  // Send trailers before sending the body. Even though a FIN has been received
+  // the stream should not be closed, as it does not yet have all the data bytes
+  // promised by the final offset field.
+  SpdyHeaderBlock trailer_block;
+  trailer_block["trailer key"] = "trailer value";
+  trailer_block[kFinalOffsetHeaderKey] = absl::StrCat(body_.size());
+  auto trailers = AsHeaderList(trailer_block);
+  stream_->OnStreamHeaderList(true, trailers.uncompressed_header_bytes(),
+                              trailers);
+
+  // Now send the body, which should close the stream as the FIN has been
+  // received, as well as all data.
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_TRUE(stream_->reading_stopped());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_server_stream_base.cc b/quiche/quic/core/http/quic_spdy_server_stream_base.cc
new file mode 100644
index 0000000..9852302
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_server_stream_base.cc
@@ -0,0 +1,134 @@
+// Copyright (c) 2016 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 "quiche/quic/core/http/quic_spdy_server_stream_base.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(QuicStreamId id,
+                                                   QuicSpdySession* session,
+                                                   StreamType type)
+    : QuicSpdyStream(id, session, type) {}
+
+QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(PendingStream* pending,
+                                                   QuicSpdySession* session)
+    : QuicSpdyStream(pending, session) {}
+
+void QuicSpdyServerStreamBase::CloseWriteSide() {
+  if (!fin_received() && !rst_received() && sequencer()->ignore_read_data() &&
+      !rst_sent()) {
+    // Early cancel the stream if it has stopped reading before receiving FIN
+    // or RST.
+    QUICHE_DCHECK(fin_sent() || !session()->connection()->connected());
+    // Tell the peer to stop sending further data.
+    QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
+    MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
+  }
+
+  QuicSpdyStream::CloseWriteSide();
+}
+
+void QuicSpdyServerStreamBase::StopReading() {
+  if (!fin_received() && !rst_received() && write_side_closed() &&
+      !rst_sent()) {
+    QUICHE_DCHECK(fin_sent());
+    // Tell the peer to stop sending further data.
+    QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
+    MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
+  }
+  QuicSpdyStream::StopReading();
+}
+
+bool QuicSpdyServerStreamBase::AreHeadersValid(
+    const QuicHeaderList& header_list) const {
+  if (!GetQuicReloadableFlag(quic_verify_request_headers_2)) {
+    return true;
+  }
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 2, 3);
+  if (!QuicSpdyStream::AreHeadersValid(header_list)) {
+    return false;
+  }
+
+  bool saw_connect = false;
+  bool saw_protocol = false;
+  bool saw_path = false;
+  bool saw_scheme = false;
+  bool saw_method = false;
+  bool saw_authority = false;
+  bool is_extended_connect = false;
+  // Check if it is missing any required headers and if there is any disallowed
+  // ones.
+  for (const std::pair<std::string, std::string>& pair : header_list) {
+    if (pair.first == ":method") {
+      saw_method = true;
+      if (pair.second == "CONNECT") {
+        saw_connect = true;
+        if (saw_protocol) {
+          is_extended_connect = true;
+        }
+      }
+    } else if (pair.first == ":protocol") {
+      saw_protocol = true;
+      if (saw_connect) {
+        is_extended_connect = true;
+      }
+    } else if (pair.first == ":scheme") {
+      saw_scheme = true;
+    } else if (pair.first == ":path") {
+      saw_path = true;
+    } else if (pair.first == ":authority") {
+      saw_authority = true;
+    } else if (absl::StrContains(pair.first, ":")) {
+      QUIC_DLOG(ERROR) << "Unexpected ':' in header " << pair.first << ".";
+      return false;
+    }
+    if (is_extended_connect) {
+      if (!spdy_session()->allow_extended_connect()) {
+        QUIC_DLOG(ERROR)
+            << "Received extended-CONNECT request while it is disabled.";
+        return false;
+      }
+    } else if (saw_method && !saw_connect) {
+      if (saw_protocol) {
+        QUIC_DLOG(ERROR) << "Receive non-CONNECT request with :protocol.";
+        return false;
+      }
+    }
+  }
+
+  if (is_extended_connect) {
+    if (saw_scheme && saw_path && saw_authority) {
+      // Saw all the required pseudo headers.
+      return true;
+    }
+    QUIC_DLOG(ERROR) << "Missing required pseudo headers for extended-CONNECT.";
+    return false;
+  }
+  // This is a vanilla CONNECT or non-CONNECT request.
+  if (saw_connect) {
+    // Check vanilla CONNECT.
+    if (saw_path || saw_scheme) {
+      QUIC_DLOG(ERROR)
+          << "Received invalid CONNECT request with disallowed pseudo header.";
+      return false;
+    }
+    return true;
+  }
+  // Check non-CONNECT request.
+  if (saw_method && saw_authority && saw_path && saw_scheme) {
+    return true;
+  }
+  QUIC_LOG(ERROR) << "Missing required pseudo headers.";
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_server_stream_base.h b/quiche/quic/core/http/quic_spdy_server_stream_base.h
new file mode 100644
index 0000000..22fb65d
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_server_stream_base.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2016 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_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
+
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+
+namespace quic {
+
+class QUIC_NO_EXPORT QuicSpdyServerStreamBase : public QuicSpdyStream {
+ public:
+  QuicSpdyServerStreamBase(QuicStreamId id,
+                           QuicSpdySession* session,
+                           StreamType type);
+  QuicSpdyServerStreamBase(PendingStream* pending, QuicSpdySession* session);
+  QuicSpdyServerStreamBase(const QuicSpdyServerStreamBase&) = delete;
+  QuicSpdyServerStreamBase& operator=(const QuicSpdyServerStreamBase&) = delete;
+
+  // Override the base class to send QUIC_STREAM_NO_ERROR to the peer
+  // when the stream has not received all the data.
+  void CloseWriteSide() override;
+  void StopReading() override;
+
+ protected:
+  bool AreHeadersValid(const QuicHeaderList& header_list) const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
diff --git a/quiche/quic/core/http/quic_spdy_server_stream_base_test.cc b/quiche/quic/core/http/quic_spdy_server_stream_base_test.cc
new file mode 100644
index 0000000..ff14bb7
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_server_stream_base_test.cc
@@ -0,0 +1,339 @@
+// Copyright (c) 2016 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 "quiche/quic/core/http/quic_spdy_server_stream_base.h"
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestQuicSpdyServerStream : public QuicSpdyServerStreamBase {
+ public:
+  TestQuicSpdyServerStream(QuicStreamId id, QuicSpdySession* session,
+                           StreamType type)
+      : QuicSpdyServerStreamBase(id, session, type) {}
+
+  void OnBodyAvailable() override {}
+};
+
+class QuicSpdyServerStreamBaseTest : public QuicTest {
+ protected:
+  QuicSpdyServerStreamBaseTest()
+      : session_(new MockQuicConnection(&helper_, &alarm_factory_,
+                                        Perspective::IS_SERVER)) {
+    session_.Initialize();
+    session_.connection()->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(session_.perspective()));
+    stream_ =
+        new TestQuicSpdyServerStream(GetNthClientInitiatedBidirectionalStreamId(
+                                         session_.transport_version(), 0),
+                                     &session_, BIDIRECTIONAL);
+    session_.ActivateStream(absl::WrapUnique(stream_));
+    helper_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+  QuicSpdyServerStreamBase* stream_ = nullptr;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicSpdySession session_;
+};
+
+TEST_F(QuicSpdyServerStreamBaseTest,
+       SendQuicRstStreamNoErrorWithEarlyResponse) {
+  stream_->StopReading();
+
+  if (session_.version().UsesHttp3()) {
+    EXPECT_CALL(session_,
+                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
+                                                 QUIC_STREAM_NO_ERROR)))
+        .Times(1);
+  } else {
+    EXPECT_CALL(
+        session_,
+        MaybeSendRstStreamFrame(
+            _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
+        .Times(1);
+  }
+  QuicStreamPeer::SetFinSent(stream_);
+  stream_->CloseWriteSide();
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest,
+       DoNotSendQuicRstStreamNoErrorWithRstReceived) {
+  EXPECT_FALSE(stream_->reading_stopped());
+
+  EXPECT_CALL(session_,
+              MaybeSendRstStreamFrame(
+                  _,
+                  QuicResetStreamError::FromInternal(
+                      VersionHasIetfQuicFrames(session_.transport_version())
+                          ? QUIC_STREAM_CANCELLED
+                          : QUIC_RST_ACKNOWLEDGEMENT),
+                  _))
+      .Times(1);
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (VersionHasIetfQuicFrames(session_.transport_version())) {
+    // Create and inject a STOP SENDING frame to complete the close
+    // of the stream. This is only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
+                                      QUIC_STREAM_CANCELLED);
+    session_.OnStopSendingFrame(stop_sending);
+  }
+
+  EXPECT_TRUE(stream_->reading_stopped());
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, AllowExtendedConnect) {
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeader(":protocol", "webtransport");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeaderBlockEnd(128, 128);
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_EQ(GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+                GetQuicReloadableFlag(quic_act_upon_invalid_header) &&
+                !session_.allow_extended_connect(),
+            stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, AllowExtendedConnectProtocolFirst) {
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":protocol", "webtransport");
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeaderBlockEnd(128, 128);
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_EQ(GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+                GetQuicReloadableFlag(quic_act_upon_invalid_header) &&
+                !session_.allow_extended_connect(),
+            stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidExtendedConnect) {
+  if (!session_.version().UsesHttp3()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeader(":protocol", "webtransport");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, VanillaConnectAllowed) {
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeaderBlockEnd(128, 128);
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_FALSE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidVanillaConnect) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidNonConnectWithProtocol) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "GET");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeader(":protocol", "webtransport");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutScheme) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :scheme should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "GET");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutAuthority) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :authority should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":method", "GET");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutMethod) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :method should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutPath) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :path should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":method", "POST");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestHeader) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :path should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":method", "POST");
+  header_list.OnHeader("invalid:header", "value");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, EmptyHeaders) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  spdy::SpdyHeaderBlock empty_header;
+  quic::test::NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
+  quic::test::NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
+  auto qpack_encoder =
+      std::make_unique<quic::QpackEncoder>(&decoder_stream_error_delegate);
+  qpack_encoder->set_qpack_stream_sender_delegate(
+      &encoder_stream_sender_delegate);
+  std::string payload =
+      qpack_encoder->EncodeHeaderList(stream_->id(), empty_header, nullptr);
+  std::unique_ptr<char[]> headers_buffer;
+  quic::QuicByteCount headers_frame_header_length =
+      quic::HttpEncoder::SerializeHeadersFrameHeader(payload.length(),
+                                                     &headers_buffer);
+  absl::string_view headers_frame_header(headers_buffer.get(),
+                                         headers_frame_header_length);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamFrame(QuicStreamFrame(
+      stream_->id(), true, 0, absl::StrCat(headers_frame_header, payload)));
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_session.cc b/quiche/quic/core/http/quic_spdy_session.cc
new file mode 100644
index 0000000..14550db
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_session.cc
@@ -0,0 +1,1949 @@
+// Copyright (c) 2015 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 "quiche/quic/core/http/quic_spdy_session.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/http/quic_headers_stream.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+
+using http2::Http2DecoderAdapter;
+using spdy::Http2WeightToSpdy3Priority;
+using spdy::Spdy3PriorityToHttp2Weight;
+using spdy::SpdyErrorCode;
+using spdy::SpdyFramer;
+using spdy::SpdyFramerDebugVisitorInterface;
+using spdy::SpdyFramerVisitorInterface;
+using spdy::SpdyFrameType;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyHeadersHandlerInterface;
+using spdy::SpdyHeadersIR;
+using spdy::SpdyPingId;
+using spdy::SpdyPriority;
+using spdy::SpdyPriorityIR;
+using spdy::SpdyPushPromiseIR;
+using spdy::SpdySerializedFrame;
+using spdy::SpdySettingsId;
+using spdy::SpdyStreamId;
+
+namespace quic {
+
+ABSL_CONST_INIT const size_t kMaxUnassociatedWebTransportStreams = 24;
+
+namespace {
+
+// Limit on HPACK encoder dynamic table size.
+// Only used for Google QUIC, not IETF QUIC.
+constexpr uint64_t kHpackEncoderDynamicTableSizeLimit = 16384;
+
+#define ENDPOINT \
+  (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+// Class to forward ACCEPT_CH frame to QuicSpdySession,
+// and ignore every other frame.
+class AlpsFrameDecoder : public HttpDecoder::Visitor {
+ public:
+  explicit AlpsFrameDecoder(QuicSpdySession* session) : session_(session) {}
+  ~AlpsFrameDecoder() override = default;
+
+  // HttpDecoder::Visitor implementation.
+  void OnError(HttpDecoder* /*decoder*/) override {}
+  bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
+    error_detail_ = "MAX_PUSH_ID frame forbidden";
+    return false;
+  }
+  bool OnGoAwayFrame(const GoAwayFrame& /*frame*/) override {
+    error_detail_ = "GOAWAY frame forbidden";
+    return false;
+  }
+  bool OnSettingsFrameStart(QuicByteCount /*header_length*/) override {
+    return true;
+  }
+  bool OnSettingsFrame(const SettingsFrame& frame) override {
+    if (settings_frame_received_via_alps_) {
+      error_detail_ = "multiple SETTINGS frames";
+      return false;
+    }
+
+    settings_frame_received_via_alps_ = true;
+
+    error_detail_ = session_->OnSettingsFrameViaAlps(frame);
+    return !error_detail_;
+  }
+  bool OnDataFrameStart(QuicByteCount /*header_length*/, QuicByteCount
+                        /*payload_length*/) override {
+    error_detail_ = "DATA frame forbidden";
+    return false;
+  }
+  bool OnDataFramePayload(absl::string_view /*payload*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnDataFrameEnd() override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnHeadersFrameStart(QuicByteCount /*header_length*/,
+                           QuicByteCount /*payload_length*/) override {
+    error_detail_ = "HEADERS frame forbidden";
+    return false;
+  }
+  bool OnHeadersFramePayload(absl::string_view /*payload*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnHeadersFrameEnd() override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnPriorityUpdateFrameStart(QuicByteCount /*header_length*/) override {
+    error_detail_ = "PRIORITY_UPDATE frame forbidden";
+    return false;
+  }
+  bool OnPriorityUpdateFrame(const PriorityUpdateFrame& /*frame*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnAcceptChFrameStart(QuicByteCount /*header_length*/) override {
+    return true;
+  }
+  bool OnAcceptChFrame(const AcceptChFrame& frame) override {
+    session_->OnAcceptChFrameReceivedViaAlps(frame);
+    return true;
+  }
+  void OnWebTransportStreamFrameType(
+      QuicByteCount /*header_length*/,
+      WebTransportSessionId /*session_id*/) override {
+    QUICHE_NOTREACHED();
+  }
+  bool OnUnknownFrameStart(uint64_t /*frame_type*/,
+                           QuicByteCount
+                           /*header_length*/,
+                           QuicByteCount /*payload_length*/) override {
+    return true;
+  }
+  bool OnUnknownFramePayload(absl::string_view /*payload*/) override {
+    return true;
+  }
+  bool OnUnknownFrameEnd() override { return true; }
+
+  const absl::optional<std::string>& error_detail() const {
+    return error_detail_;
+  }
+
+ private:
+  QuicSpdySession* const session_;
+  absl::optional<std::string> error_detail_;
+
+  // True if SETTINGS frame has been received via ALPS.
+  bool settings_frame_received_via_alps_ = false;
+};
+
+}  // namespace
+
+// A SpdyFramerVisitor that passes HEADERS frames to the QuicSpdyStream, and
+// closes the connection if any unexpected frames are received.
+class QuicSpdySession::SpdyFramerVisitor
+    : public SpdyFramerVisitorInterface,
+      public SpdyFramerDebugVisitorInterface {
+ public:
+  explicit SpdyFramerVisitor(QuicSpdySession* session) : session_(session) {}
+  SpdyFramerVisitor(const SpdyFramerVisitor&) = delete;
+  SpdyFramerVisitor& operator=(const SpdyFramerVisitor&) = delete;
+
+  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+      SpdyStreamId /* stream_id */) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    return &header_list_;
+  }
+
+  void OnHeaderFrameEnd(SpdyStreamId /* stream_id */) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+
+    LogHeaderCompressionRatioHistogram(
+        /* using_qpack = */ false,
+        /* is_sent = */ false, header_list_.compressed_header_bytes(),
+        header_list_.uncompressed_header_bytes());
+
+    if (session_->IsConnected()) {
+      session_->OnHeaderList(header_list_);
+    }
+    header_list_.Clear();
+  }
+
+  void OnStreamFrameData(SpdyStreamId /*stream_id*/, const char* /*data*/,
+                         size_t /*len*/) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    CloseConnection("SPDY DATA frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnStreamEnd(SpdyStreamId /*stream_id*/) override {
+    // The framer invokes OnStreamEnd after processing a frame that had the fin
+    // bit set.
+  }
+
+  void OnStreamPadding(SpdyStreamId /*stream_id*/, size_t /*len*/) override {
+    CloseConnection("SPDY frame padding received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnError(Http2DecoderAdapter::SpdyFramerError error,
+               std::string detailed_error) override {
+    QuicErrorCode code;
+    switch (error) {
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INDEX_VARINT_ERROR:
+        code = QUIC_HPACK_INDEX_VARINT_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_NAME_LENGTH_VARINT_ERROR:
+        code = QUIC_HPACK_NAME_LENGTH_VARINT_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR:
+        code = QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_TOO_LONG:
+        code = QUIC_HPACK_NAME_TOO_LONG;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_TOO_LONG:
+        code = QUIC_HPACK_VALUE_TOO_LONG;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_HUFFMAN_ERROR:
+        code = QUIC_HPACK_NAME_HUFFMAN_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_HUFFMAN_ERROR:
+        code = QUIC_HPACK_VALUE_HUFFMAN_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
+        code = QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_INDEX:
+        code = QUIC_HPACK_INVALID_INDEX;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_NAME_INDEX:
+        code = QUIC_HPACK_INVALID_NAME_INDEX;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
+        code = QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
+        code = QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
+        code = QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_TRUNCATED_BLOCK:
+        code = QUIC_HPACK_TRUNCATED_BLOCK;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_FRAGMENT_TOO_LONG:
+        code = QUIC_HPACK_FRAGMENT_TOO_LONG;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
+        code = QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE:
+        code = QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE;
+        break;
+      default:
+        code = QUIC_INVALID_HEADERS_STREAM_DATA;
+    }
+    CloseConnection(
+        absl::StrCat("SPDY framing error: ", detailed_error,
+                     Http2DecoderAdapter::SpdyFramerErrorToString(error)),
+        code);
+  }
+
+  void OnDataFrameHeader(SpdyStreamId /*stream_id*/, size_t /*length*/,
+                         bool /*fin*/) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    CloseConnection("SPDY DATA frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnRstStream(SpdyStreamId /*stream_id*/,
+                   SpdyErrorCode /*error_code*/) override {
+    CloseConnection("SPDY RST_STREAM frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnSetting(SpdySettingsId id, uint32_t value) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    session_->OnSetting(id, value);
+  }
+
+  void OnSettingsEnd() override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+  }
+
+  void OnPing(SpdyPingId /*unique_id*/, bool /*is_ack*/) override {
+    CloseConnection("SPDY PING frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnGoAway(SpdyStreamId /*last_accepted_stream_id*/,
+                SpdyErrorCode /*error_code*/) override {
+    CloseConnection("SPDY GOAWAY frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnHeaders(SpdyStreamId stream_id, bool has_priority, int weight,
+                 SpdyStreamId /* parent_stream_id */, bool /* exclusive */,
+                 bool fin, bool /*end*/) override {
+    if (!session_->IsConnected()) {
+      return;
+    }
+
+    if (VersionUsesHttp3(session_->transport_version())) {
+      CloseConnection("HEADERS frame not allowed on headers stream.",
+                      QUIC_INVALID_HEADERS_STREAM_DATA);
+      return;
+    }
+
+    QUIC_BUG_IF(quic_bug_12477_1,
+                session_->destruction_indicator() != 123456789)
+        << "QuicSpdyStream use after free. "
+        << session_->destruction_indicator() << QuicStackTrace();
+
+    SpdyPriority priority =
+        has_priority ? Http2WeightToSpdy3Priority(weight) : 0;
+    session_->OnHeaders(stream_id, has_priority,
+                        spdy::SpdyStreamPrecedence(priority), fin);
+  }
+
+  void OnWindowUpdate(SpdyStreamId /*stream_id*/,
+                      int /*delta_window_size*/) override {
+    CloseConnection("SPDY WINDOW_UPDATE frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
+                     bool /*end*/) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    if (session_->perspective() != Perspective::IS_CLIENT) {
+      CloseConnection("PUSH_PROMISE not supported.",
+                      QUIC_INVALID_HEADERS_STREAM_DATA);
+      return;
+    }
+    if (!session_->IsConnected()) {
+      return;
+    }
+    session_->OnPushPromise(stream_id, promised_stream_id);
+  }
+
+  void OnContinuation(SpdyStreamId /*stream_id*/, bool /*end*/) override {}
+
+  void OnPriority(SpdyStreamId stream_id, SpdyStreamId /* parent_id */,
+                  int weight, bool /* exclusive */) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    if (!session_->IsConnected()) {
+      return;
+    }
+    SpdyPriority priority = Http2WeightToSpdy3Priority(weight);
+    session_->OnPriority(stream_id, spdy::SpdyStreamPrecedence(priority));
+  }
+
+  void OnPriorityUpdate(SpdyStreamId /*prioritized_stream_id*/,
+                        absl::string_view /*priority_field_value*/) override {
+    // TODO(b/171470299): Parse and call
+    // QuicSpdySession::OnPriorityUpdateForRequestStream().
+  }
+
+  bool OnUnknownFrame(SpdyStreamId /*stream_id*/,
+                      uint8_t /*frame_type*/) override {
+    CloseConnection("Unknown frame type received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+    return false;
+  }
+
+  // SpdyFramerDebugVisitorInterface implementation
+  void OnSendCompressedFrame(SpdyStreamId /*stream_id*/, SpdyFrameType /*type*/,
+                             size_t payload_len, size_t frame_len) override {
+    if (payload_len == 0) {
+      QUIC_BUG(quic_bug_10360_1) << "Zero payload length.";
+      return;
+    }
+    int compression_pct = 100 - (100 * frame_len) / payload_len;
+    QUIC_DVLOG(1) << "Net.QuicHpackCompressionPercentage: " << compression_pct;
+  }
+
+  void OnReceiveCompressedFrame(SpdyStreamId /*stream_id*/,
+                                SpdyFrameType /*type*/,
+                                size_t frame_len) override {
+    if (session_->IsConnected()) {
+      session_->OnCompressedFrameSize(frame_len);
+    }
+  }
+
+  void set_max_header_list_size(size_t max_header_list_size) {
+    header_list_.set_max_header_list_size(max_header_list_size);
+  }
+
+ private:
+  void CloseConnection(const std::string& details, QuicErrorCode code) {
+    if (session_->IsConnected()) {
+      session_->CloseConnectionWithDetails(code, details);
+    }
+  }
+
+  QuicSpdySession* session_;
+  QuicHeaderList header_list_;
+};
+
+Http3DebugVisitor::Http3DebugVisitor() {}
+
+Http3DebugVisitor::~Http3DebugVisitor() {}
+
+// Expected unidirectional static streams Requirement can be found at
+// https://tools.ietf.org/html/draft-ietf-quic-http-22#section-6.2.
+QuicSpdySession::QuicSpdySession(
+    QuicConnection* connection, QuicSession::Visitor* visitor,
+    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions)
+    : QuicSession(connection, visitor, config, supported_versions,
+                  /*num_expected_unidirectional_static_streams = */
+                  VersionUsesHttp3(connection->transport_version())
+                      ? static_cast<QuicStreamCount>(
+                            kHttp3StaticUnidirectionalStreamCount)
+                      : 0u,
+                  std::make_unique<DatagramObserver>(this)),
+      send_control_stream_(nullptr),
+      receive_control_stream_(nullptr),
+      qpack_encoder_receive_stream_(nullptr),
+      qpack_decoder_receive_stream_(nullptr),
+      qpack_encoder_send_stream_(nullptr),
+      qpack_decoder_send_stream_(nullptr),
+      qpack_maximum_dynamic_table_capacity_(
+          kDefaultQpackMaxDynamicTableCapacity),
+      qpack_maximum_blocked_streams_(kDefaultMaximumBlockedStreams),
+      max_inbound_header_list_size_(kDefaultMaxUncompressedHeaderSize),
+      max_outbound_header_list_size_(std::numeric_limits<size_t>::max()),
+      stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())),
+      promised_stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())),
+      frame_len_(0),
+      fin_(false),
+      spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
+      spdy_framer_visitor_(new SpdyFramerVisitor(this)),
+      debug_visitor_(nullptr),
+      destruction_indicator_(123456789),
+      allow_extended_connect_(
+          GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+          perspective() == Perspective::IS_SERVER &&
+          VersionUsesHttp3(transport_version())) {
+  h2_deframer_.set_visitor(spdy_framer_visitor_.get());
+  h2_deframer_.set_debug_visitor(spdy_framer_visitor_.get());
+  spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get());
+}
+
+QuicSpdySession::~QuicSpdySession() {
+  QUIC_BUG_IF(quic_bug_12477_2, destruction_indicator_ != 123456789)
+      << "QuicSpdySession use after free. " << destruction_indicator_
+      << QuicStackTrace();
+  destruction_indicator_ = 987654321;
+}
+
+void QuicSpdySession::Initialize() {
+  QuicSession::Initialize();
+
+  FillSettingsFrame();
+  if (!VersionUsesHttp3(transport_version())) {
+    if (perspective() == Perspective::IS_SERVER) {
+      set_largest_peer_created_stream_id(
+          QuicUtils::GetHeadersStreamId(transport_version()));
+    } else {
+      QuicStreamId headers_stream_id = GetNextOutgoingBidirectionalStreamId();
+      QUICHE_DCHECK_EQ(headers_stream_id,
+                       QuicUtils::GetHeadersStreamId(transport_version()));
+    }
+    auto headers_stream = std::make_unique<QuicHeadersStream>((this));
+    QUICHE_DCHECK_EQ(QuicUtils::GetHeadersStreamId(transport_version()),
+                     headers_stream->id());
+
+    headers_stream_ = headers_stream.get();
+    ActivateStream(std::move(headers_stream));
+  } else {
+    qpack_encoder_ = std::make_unique<QpackEncoder>(this);
+    qpack_decoder_ =
+        std::make_unique<QpackDecoder>(qpack_maximum_dynamic_table_capacity_,
+                                       qpack_maximum_blocked_streams_, this);
+    MaybeInitializeHttp3UnidirectionalStreams();
+  }
+
+  spdy_framer_visitor_->set_max_header_list_size(max_inbound_header_list_size_);
+
+  // Limit HPACK buffering to 2x header list size limit.
+  h2_deframer_.GetHpackDecoder()->set_max_decode_buffer_size_bytes(
+      2 * max_inbound_header_list_size_);
+}
+
+void QuicSpdySession::FillSettingsFrame() {
+  settings_.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
+      qpack_maximum_dynamic_table_capacity_;
+  settings_.values[SETTINGS_QPACK_BLOCKED_STREAMS] =
+      qpack_maximum_blocked_streams_;
+  settings_.values[SETTINGS_MAX_FIELD_SECTION_SIZE] =
+      max_inbound_header_list_size_;
+  if (version().UsesHttp3()) {
+    HttpDatagramSupport local_http_datagram_support =
+        LocalHttpDatagramSupport();
+    if (local_http_datagram_support == HttpDatagramSupport::kDraft00 ||
+        local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
+      settings_.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
+    }
+    if (local_http_datagram_support == HttpDatagramSupport::kDraft04 ||
+        local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
+      settings_.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+    }
+  }
+  if (WillNegotiateWebTransport()) {
+    settings_.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
+  }
+  if (allow_extended_connect()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 1, 3);
+    settings_.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
+  }
+}
+
+void QuicSpdySession::OnDecoderStreamError(QuicErrorCode error_code,
+                                           absl::string_view error_message) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  CloseConnectionWithDetails(
+      error_code, absl::StrCat("Decoder stream error: ", error_message));
+}
+
+void QuicSpdySession::OnEncoderStreamError(QuicErrorCode error_code,
+                                           absl::string_view error_message) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  CloseConnectionWithDetails(
+      error_code, absl::StrCat("Encoder stream error: ", error_message));
+}
+
+void QuicSpdySession::OnStreamHeadersPriority(
+    QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
+  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+  if (!stream) {
+    // It's quite possible to receive headers after a stream has been reset.
+    return;
+  }
+  stream->OnStreamHeadersPriority(precedence);
+}
+
+void QuicSpdySession::OnStreamHeaderList(QuicStreamId stream_id, bool fin,
+                                         size_t frame_len,
+                                         const QuicHeaderList& header_list) {
+  if (IsStaticStream(stream_id)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+  if (stream == nullptr) {
+    // The stream no longer exists, but trailing headers may contain the final
+    // byte offset necessary for flow control and open stream accounting.
+    size_t final_byte_offset = 0;
+    for (const auto& header : header_list) {
+      const std::string& header_key = header.first;
+      const std::string& header_value = header.second;
+      if (header_key == kFinalOffsetHeaderKey) {
+        if (!absl::SimpleAtoi(header_value, &final_byte_offset)) {
+          connection()->CloseConnection(
+              QUIC_INVALID_HEADERS_STREAM_DATA,
+              "Trailers are malformed (no final offset)",
+              ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+          return;
+        }
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "Received final byte offset in trailers for stream "
+                      << stream_id << ", which no longer exists.";
+        OnFinalByteOffsetReceived(stream_id, final_byte_offset);
+      }
+    }
+
+    // It's quite possible to receive headers after a stream has been reset.
+    return;
+  }
+  stream->OnStreamHeaderList(fin, frame_len, header_list);
+}
+
+void QuicSpdySession::OnPriorityFrame(
+    QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
+  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+  if (!stream) {
+    // It's quite possible to receive a PRIORITY frame after a stream has been
+    // reset.
+    return;
+  }
+  stream->OnPriorityFrame(precedence);
+}
+
+bool QuicSpdySession::OnPriorityUpdateForRequestStream(QuicStreamId stream_id,
+                                                       int urgency) {
+  if (perspective() == Perspective::IS_CLIENT ||
+      !QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
+      !QuicUtils::IsClientInitiatedStreamId(transport_version(), stream_id)) {
+    return true;
+  }
+
+  QuicStreamCount advertised_max_incoming_bidirectional_streams =
+      GetAdvertisedMaxIncomingBidirectionalStreams();
+  if (advertised_max_incoming_bidirectional_streams == 0 ||
+      stream_id > QuicUtils::GetFirstBidirectionalStreamId(
+                      transport_version(), Perspective::IS_CLIENT) +
+                      QuicUtils::StreamIdDelta(transport_version()) *
+                          (advertised_max_incoming_bidirectional_streams - 1)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "PRIORITY_UPDATE frame received for invalid stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  if (MaybeSetStreamPriority(stream_id, spdy::SpdyStreamPrecedence(urgency))) {
+    return true;
+  }
+
+  if (IsClosedStream(stream_id)) {
+    return true;
+  }
+
+  buffered_stream_priorities_[stream_id] = urgency;
+
+  if (buffered_stream_priorities_.size() >
+      10 * max_open_incoming_bidirectional_streams()) {
+    // This should never happen, because |buffered_stream_priorities_| should
+    // only contain entries for streams that are allowed to be open by the peer
+    // but have not been opened yet.
+    std::string error_message =
+        absl::StrCat("Too many stream priority values buffered: ",
+                     buffered_stream_priorities_.size(),
+                     ", which should not exceed the incoming stream limit of ",
+                     max_open_incoming_bidirectional_streams());
+    QUIC_BUG(quic_bug_10360_2) << error_message;
+    connection()->CloseConnection(
+        QUIC_INTERNAL_ERROR, error_message,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicSpdySession::OnPriorityUpdateForPushStream(QuicStreamId /*push_id*/,
+                                                    int /*urgency*/) {
+  // TODO(b/147306124): Implement PRIORITY_UPDATE frames for pushed streams.
+  return true;
+}
+
+size_t QuicSpdySession::ProcessHeaderData(const struct iovec& iov) {
+  QUIC_BUG_IF(quic_bug_12477_4, destruction_indicator_ != 123456789)
+      << "QuicSpdyStream use after free. " << destruction_indicator_
+      << QuicStackTrace();
+  return h2_deframer_.ProcessInput(static_cast<char*>(iov.iov_base),
+                                   iov.iov_len);
+}
+
+size_t QuicSpdySession::WriteHeadersOnHeadersStream(
+    QuicStreamId id, SpdyHeaderBlock headers, bool fin,
+    const spdy::SpdyStreamPrecedence& precedence,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
+
+  return WriteHeadersOnHeadersStreamImpl(
+      id, std::move(headers), fin,
+      /* parent_stream_id = */ 0,
+      Spdy3PriorityToHttp2Weight(precedence.spdy3_priority()),
+      /* exclusive = */ false, std::move(ack_listener));
+}
+
+size_t QuicSpdySession::WritePriority(QuicStreamId id,
+                                      QuicStreamId parent_stream_id, int weight,
+                                      bool exclusive) {
+  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
+  SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive);
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(priority_frame));
+  headers_stream()->WriteOrBufferData(
+      absl::string_view(frame.data(), frame.size()), false, nullptr);
+  return frame.size();
+}
+
+void QuicSpdySession::WriteHttp3PriorityUpdate(
+    const PriorityUpdateFrame& priority_update) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  send_control_stream_->WritePriorityUpdate(priority_update);
+}
+
+void QuicSpdySession::OnHttp3GoAway(uint64_t id) {
+  QUIC_BUG_IF(quic_bug_12477_5, !version().UsesHttp3())
+      << "HTTP/3 GOAWAY received on version " << version();
+
+  if (last_received_http3_goaway_id_.has_value() &&
+      id > last_received_http3_goaway_id_.value()) {
+    CloseConnectionWithDetails(
+        QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
+        absl::StrCat("GOAWAY received with ID ", id,
+                     " greater than previously received ID ",
+                     last_received_http3_goaway_id_.value()));
+    return;
+  }
+  last_received_http3_goaway_id_ = id;
+
+  if (perspective() == Perspective::IS_SERVER) {
+    // TODO(b/151749109): Cancel server pushes with push ID larger than |id|.
+    return;
+  }
+
+  // QuicStreamId is uint32_t.  Casting to this narrower type is well-defined
+  // and preserves the lower 32 bits.  Both IsBidirectionalStreamId() and
+  // IsIncomingStream() give correct results, because their return value is
+  // determined by the least significant two bits.
+  QuicStreamId stream_id = static_cast<QuicStreamId>(id);
+  if (!QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
+      IsIncomingStream(stream_id)) {
+    CloseConnectionWithDetails(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
+                               "GOAWAY with invalid stream ID");
+    return;
+  }
+
+  // TODO(b/161252736): Cancel client requests with ID larger than |id|.
+  // If |id| is larger than numeric_limits<QuicStreamId>::max(), then use
+  // max() instead of downcast value.
+}
+
+bool QuicSpdySession::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& frame) {
+  if (!QuicSession::OnStreamsBlockedFrame(frame)) {
+    return false;
+  }
+
+  // The peer asked for stream space more than this implementation has. Send
+  // goaway.
+  if (perspective() == Perspective::IS_SERVER &&
+      frame.stream_count >= QuicUtils::GetMaxStreamCount()) {
+    QUICHE_DCHECK_EQ(frame.stream_count, QuicUtils::GetMaxStreamCount());
+    SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "stream count too large");
+  }
+  return true;
+}
+
+void QuicSpdySession::SendHttp3GoAway(QuicErrorCode error_code,
+                                      const std::string& reason) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  if (!IsEncryptionEstablished()) {
+    QUIC_CODE_COUNT(quic_h3_goaway_before_encryption_established);
+    connection()->CloseConnection(
+        error_code, reason,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  QuicStreamId stream_id;
+
+  stream_id = QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
+      transport_version());
+  if (last_sent_http3_goaway_id_.has_value()) {
+    if (last_sent_http3_goaway_id_.value() == stream_id) {
+      // Do not send GOAWAY twice.
+      return;
+    }
+    if (last_sent_http3_goaway_id_.value() < stream_id) {
+      // A previous GOAWAY frame was sent with smaller stream ID.  This is not
+      // possible, because the only time a GOAWAY frame with non-maximal
+      // stream ID is sent is right before closing connection.
+      QUIC_BUG(quic_bug_10360_3)
+          << "Not sending GOAWAY frame with " << stream_id
+          << " because one with " << last_sent_http3_goaway_id_.value()
+          << " already sent on connection " << connection()->connection_id();
+      return;
+    }
+  }
+
+  send_control_stream_->SendGoAway(stream_id);
+  last_sent_http3_goaway_id_ = stream_id;
+}
+
+void QuicSpdySession::WritePushPromise(QuicStreamId original_stream_id,
+                                       QuicStreamId promised_stream_id,
+                                       SpdyHeaderBlock headers) {
+  if (perspective() == Perspective::IS_CLIENT) {
+    QUIC_BUG(quic_bug_10360_4) << "Client shouldn't send PUSH_PROMISE";
+    return;
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    QUIC_BUG(quic_bug_12477_6)
+        << "Support for server push over HTTP/3 has been removed.";
+    return;
+  }
+
+  SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id,
+                                 std::move(headers));
+  // PUSH_PROMISE must not be the last frame sent out, at least followed by
+  // response headers.
+  push_promise.set_fin(false);
+
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise));
+  headers_stream()->WriteOrBufferData(
+      absl::string_view(frame.data(), frame.size()), false, nullptr);
+}
+
+void QuicSpdySession::SendInitialData() {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  QuicConnection::ScopedPacketFlusher flusher(connection());
+  send_control_stream_->MaybeSendSettingsFrame();
+}
+
+QpackEncoder* QuicSpdySession::qpack_encoder() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  return qpack_encoder_.get();
+}
+
+QpackDecoder* QuicSpdySession::qpack_decoder() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  return qpack_decoder_.get();
+}
+
+void QuicSpdySession::OnStreamCreated(QuicSpdyStream* stream) {
+  auto it = buffered_stream_priorities_.find(stream->id());
+  if (it == buffered_stream_priorities_.end()) {
+    return;
+  }
+
+  stream->SetPriority(spdy::SpdyStreamPrecedence(it->second));
+  buffered_stream_priorities_.erase(it);
+}
+
+QuicSpdyStream* QuicSpdySession::GetOrCreateSpdyDataStream(
+    const QuicStreamId stream_id) {
+  QuicStream* stream = GetOrCreateStream(stream_id);
+  if (stream && stream->is_static()) {
+    QUIC_BUG(quic_bug_10360_5)
+        << "GetOrCreateSpdyDataStream returns static stream " << stream_id
+        << " in version " << transport_version() << "\n"
+        << QuicStackTrace();
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        absl::StrCat("stream ", stream_id, " is static"),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return nullptr;
+  }
+  return static_cast<QuicSpdyStream*>(stream);
+}
+
+void QuicSpdySession::OnNewEncryptionKeyAvailable(
+    EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
+  QuicSession::OnNewEncryptionKeyAvailable(level, std::move(encrypter));
+  if (IsEncryptionEstablished()) {
+    // Send H3 SETTINGs once encryption is established.
+    SendInitialData();
+  }
+}
+
+bool QuicSpdySession::ShouldNegotiateWebTransport() { return false; }
+
+bool QuicSpdySession::ShouldNegotiateDatagramContexts() { return false; }
+
+bool QuicSpdySession::ShouldValidateWebTransportVersion() const { return true; }
+
+bool QuicSpdySession::WillNegotiateWebTransport() {
+  return LocalHttpDatagramSupport() != HttpDatagramSupport::kNone &&
+         version().UsesHttp3() && ShouldNegotiateWebTransport();
+}
+
+// True if there are open HTTP requests.
+bool QuicSpdySession::ShouldKeepConnectionAlive() const {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()) ||
+                0u == pending_streams_size());
+  return GetNumActiveStreams() + pending_streams_size() > 0;
+}
+
+bool QuicSpdySession::UsesPendingStreamForFrame(QuicFrameType type,
+                                                QuicStreamId stream_id) const {
+  // Pending streams can only be used to handle unidirectional stream with
+  // STREAM & RESET_STREAM frames in IETF QUIC.
+  return VersionUsesHttp3(transport_version()) &&
+         (type == STREAM_FRAME || type == RST_STREAM_FRAME) &&
+         QuicUtils::GetStreamType(stream_id, perspective(),
+                                  IsIncomingStream(stream_id),
+                                  version()) == READ_UNIDIRECTIONAL;
+}
+
+size_t QuicSpdySession::WriteHeadersOnHeadersStreamImpl(
+    QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
+    QuicStreamId parent_stream_id, int weight, bool exclusive,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
+
+  const QuicByteCount uncompressed_size = headers.TotalBytesUsed();
+  SpdyHeadersIR headers_frame(id, std::move(headers));
+  headers_frame.set_fin(fin);
+  if (perspective() == Perspective::IS_CLIENT) {
+    headers_frame.set_has_priority(true);
+    headers_frame.set_parent_stream_id(parent_stream_id);
+    headers_frame.set_weight(weight);
+    headers_frame.set_exclusive(exclusive);
+  }
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame));
+  headers_stream()->WriteOrBufferData(
+      absl::string_view(frame.data(), frame.size()), false,
+      std::move(ack_listener));
+
+  // Calculate compressed header block size without framing overhead.
+  QuicByteCount compressed_size = frame.size();
+  compressed_size -= spdy::kFrameHeaderSize;
+  if (perspective() == Perspective::IS_CLIENT) {
+    // Exclusive bit and Stream Dependency are four bytes, weight is one more.
+    compressed_size -= 5;
+  }
+
+  LogHeaderCompressionRatioHistogram(
+      /* using_qpack = */ false,
+      /* is_sent = */ true, compressed_size, uncompressed_size);
+
+  return frame.size();
+}
+
+void QuicSpdySession::OnPromiseHeaderList(
+    QuicStreamId /*stream_id*/, QuicStreamId /*promised_stream_id*/,
+    size_t /*frame_len*/, const QuicHeaderList& /*header_list*/) {
+  std::string error =
+      "OnPromiseHeaderList should be overridden in client code.";
+  QUIC_BUG(quic_bug_10360_6) << error;
+  connection()->CloseConnection(QUIC_INTERNAL_ERROR, error,
+                                ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+bool QuicSpdySession::ResumeApplicationState(ApplicationState* cached_state) {
+  QUICHE_DCHECK_EQ(perspective(), Perspective::IS_CLIENT);
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  SettingsFrame out;
+  if (!HttpDecoder::DecodeSettings(
+          reinterpret_cast<char*>(cached_state->data()), cached_state->size(),
+          &out)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSettingsFrameResumed(out);
+  }
+  QUICHE_DCHECK(streams_waiting_for_settings_.empty());
+  for (const auto& setting : out.values) {
+    OnSetting(setting.first, setting.second);
+  }
+  return true;
+}
+
+absl::optional<std::string> QuicSpdySession::OnAlpsData(
+    const uint8_t* alps_data, size_t alps_length) {
+  AlpsFrameDecoder alps_frame_decoder(this);
+  HttpDecoder decoder(&alps_frame_decoder);
+  decoder.ProcessInput(reinterpret_cast<const char*>(alps_data), alps_length);
+  if (alps_frame_decoder.error_detail()) {
+    return alps_frame_decoder.error_detail();
+  }
+
+  if (decoder.error() != QUIC_NO_ERROR) {
+    return decoder.error_detail();
+  }
+
+  if (!decoder.AtFrameBoundary()) {
+    return "incomplete HTTP/3 frame";
+  }
+
+  return absl::nullopt;
+}
+
+void QuicSpdySession::OnAcceptChFrameReceivedViaAlps(
+    const AcceptChFrame& frame) {
+  if (debug_visitor_) {
+    debug_visitor_->OnAcceptChFrameReceivedViaAlps(frame);
+  }
+}
+
+bool QuicSpdySession::OnSettingsFrame(const SettingsFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSettingsFrameReceived(frame);
+  }
+  for (const auto& setting : frame.values) {
+    if (!OnSetting(setting.first, setting.second)) {
+      return false;
+    }
+  }
+  for (QuicStreamId stream_id : streams_waiting_for_settings_) {
+    QUICHE_DCHECK(ShouldBufferRequestsUntilSettings());
+    QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+    if (stream == nullptr) {
+      // The stream may no longer exist, since it is possible for a stream to
+      // get reset while waiting for the SETTINGS frame.
+      continue;
+    }
+    stream->OnDataAvailable();
+  }
+  streams_waiting_for_settings_.clear();
+  return true;
+}
+
+absl::optional<std::string> QuicSpdySession::OnSettingsFrameViaAlps(
+    const SettingsFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSettingsFrameReceivedViaAlps(frame);
+  }
+  for (const auto& setting : frame.values) {
+    if (!OnSetting(setting.first, setting.second)) {
+      // Do not bother adding the setting identifier or value to the error
+      // message, because OnSetting() already closed the connection, therefore
+      // the error message will be ignored.
+      return "error parsing setting";
+    }
+  }
+  return absl::nullopt;
+}
+
+bool QuicSpdySession::VerifySettingIsZeroOrOne(uint64_t id, uint64_t value) {
+  if (value == 0 || value == 1) {
+    return true;
+  }
+  std::string error_details = absl::StrCat(
+      "Received ",
+      H3SettingsToString(static_cast<Http3AndQpackSettingsIdentifiers>(id)),
+      " with invalid value ", value);
+  QUIC_PEER_BUG(bad received setting) << ENDPOINT << error_details;
+  CloseConnectionWithDetails(QUIC_HTTP_INVALID_SETTING_VALUE, error_details);
+  return false;
+}
+
+bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
+  any_settings_received_ = true;
+
+  if (VersionUsesHttp3(transport_version())) {
+    // SETTINGS frame received on the control stream.
+    switch (id) {
+      case SETTINGS_QPACK_MAX_TABLE_CAPACITY: {
+        QUIC_DVLOG(1)
+            << ENDPOINT
+            << "SETTINGS_QPACK_MAX_TABLE_CAPACITY received with value "
+            << value;
+        // Communicate |value| to encoder, because it is used for encoding
+        // Required Insert Count.
+        if (!qpack_encoder_->SetMaximumDynamicTableCapacity(value)) {
+          CloseConnectionWithDetails(
+              was_zero_rtt_rejected()
+                  ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
+                  : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+              absl::StrCat(was_zero_rtt_rejected()
+                               ? "Server rejected 0-RTT, aborting because "
+                               : "",
+                           "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: ",
+                           value, " while current value is: ",
+                           qpack_encoder_->MaximumDynamicTableCapacity()));
+          return false;
+        }
+        // However, limit the dynamic table capacity to
+        // |qpack_maximum_dynamic_table_capacity_|.
+        qpack_encoder_->SetDynamicTableCapacity(
+            std::min(value, qpack_maximum_dynamic_table_capacity_));
+        break;
+      }
+      case SETTINGS_MAX_FIELD_SECTION_SIZE:
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_MAX_FIELD_SECTION_SIZE received with value "
+                      << value;
+        if (max_outbound_header_list_size_ !=
+                std::numeric_limits<size_t>::max() &&
+            max_outbound_header_list_size_ > value) {
+          CloseConnectionWithDetails(
+              was_zero_rtt_rejected()
+                  ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
+                  : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+              absl::StrCat(was_zero_rtt_rejected()
+                               ? "Server rejected 0-RTT, aborting because "
+                               : "",
+                           "Server sent an SETTINGS_MAX_FIELD_SECTION_SIZE: ",
+                           value, " which reduces current value: ",
+                           max_outbound_header_list_size_));
+          return false;
+        }
+        max_outbound_header_list_size_ = value;
+        break;
+      case SETTINGS_QPACK_BLOCKED_STREAMS: {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_QPACK_BLOCKED_STREAMS received with value "
+                      << value;
+        if (!qpack_encoder_->SetMaximumBlockedStreams(value)) {
+          CloseConnectionWithDetails(
+              was_zero_rtt_rejected()
+                  ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
+                  : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+              absl::StrCat(was_zero_rtt_rejected()
+                               ? "Server rejected 0-RTT, aborting because "
+                               : "",
+                           "Server sent an SETTINGS_QPACK_BLOCKED_STREAMS: ",
+                           value, " which reduces current value: ",
+                           qpack_encoder_->maximum_blocked_streams()));
+          return false;
+        }
+        break;
+      }
+      case SETTINGS_ENABLE_CONNECT_PROTOCOL: {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_ENABLE_CONNECT_PROTOCOL received with value "
+                      << value;
+        if (!VerifySettingIsZeroOrOne(id, value)) {
+          return false;
+        }
+        if (perspective() == Perspective::IS_CLIENT) {
+          allow_extended_connect_ = value != 0;
+        }
+        break;
+      }
+      case spdy::SETTINGS_ENABLE_PUSH:
+        ABSL_FALLTHROUGH_INTENDED;
+      case spdy::SETTINGS_MAX_CONCURRENT_STREAMS:
+        ABSL_FALLTHROUGH_INTENDED;
+      case spdy::SETTINGS_INITIAL_WINDOW_SIZE:
+        ABSL_FALLTHROUGH_INTENDED;
+      case spdy::SETTINGS_MAX_FRAME_SIZE:
+        CloseConnectionWithDetails(
+            QUIC_HTTP_RECEIVE_SPDY_SETTING,
+            absl::StrCat("received HTTP/2 specific setting in HTTP/3 session: ",
+                         id));
+        return false;
+      case SETTINGS_H3_DATAGRAM_DRAFT00: {
+        HttpDatagramSupport local_http_datagram_support =
+            LocalHttpDatagramSupport();
+        if (local_http_datagram_support != HttpDatagramSupport::kDraft00 &&
+            local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
+          break;
+        }
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_H3_DATAGRAM_DRAFT00 received with value "
+                      << value;
+        if (!version().UsesHttp3()) {
+          break;
+        }
+        if (!VerifySettingIsZeroOrOne(id, value)) {
+          return false;
+        }
+        if (value && http_datagram_support_ != HttpDatagramSupport::kDraft04) {
+          // If both draft-00 and draft-04 are supported, use draft-04.
+          http_datagram_support_ = HttpDatagramSupport::kDraft00;
+        }
+        break;
+      }
+      case SETTINGS_H3_DATAGRAM_DRAFT04: {
+        HttpDatagramSupport local_http_datagram_support =
+            LocalHttpDatagramSupport();
+        if (local_http_datagram_support != HttpDatagramSupport::kDraft04 &&
+            local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
+          break;
+        }
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_H3_DATAGRAM_DRAFT04 received with value "
+                      << value;
+        if (!version().UsesHttp3()) {
+          break;
+        }
+        if (!VerifySettingIsZeroOrOne(id, value)) {
+          return false;
+        }
+        if (value) {
+          http_datagram_support_ = HttpDatagramSupport::kDraft04;
+        }
+        break;
+      }
+      case SETTINGS_WEBTRANS_DRAFT00:
+        if (!WillNegotiateWebTransport()) {
+          break;
+        }
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_ENABLE_WEBTRANSPORT received with value "
+                      << value;
+        if (!VerifySettingIsZeroOrOne(id, value)) {
+          return false;
+        }
+        peer_supports_webtransport_ = (value == 1);
+        if (perspective() == Perspective::IS_CLIENT && value == 1) {
+          allow_extended_connect_ = true;
+        }
+        break;
+      default:
+        QUIC_DVLOG(1) << ENDPOINT << "Unknown setting identifier " << id
+                      << " received with value " << value;
+        // Ignore unknown settings.
+        break;
+    }
+    return true;
+  }
+
+  // SETTINGS frame received on the headers stream.
+  switch (id) {
+    case spdy::SETTINGS_HEADER_TABLE_SIZE:
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "SETTINGS_HEADER_TABLE_SIZE received with value "
+                    << value;
+      if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
+        QUIC_RELOADABLE_FLAG_COUNT(quic_limit_encoder_dynamic_table_size);
+        spdy_framer_.UpdateHeaderEncoderTableSize(
+            std::min<uint64_t>(value, kHpackEncoderDynamicTableSizeLimit));
+        break;
+      }
+      spdy_framer_.UpdateHeaderEncoderTableSize(value);
+      break;
+    case spdy::SETTINGS_ENABLE_PUSH:
+      if (perspective() == Perspective::IS_SERVER) {
+        // See rfc7540, Section 6.5.2.
+        if (value > 1) {
+          QUIC_DLOG(ERROR) << ENDPOINT << "Invalid value " << value
+                           << " received for SETTINGS_ENABLE_PUSH.";
+          if (IsConnected()) {
+            CloseConnectionWithDetails(
+                QUIC_INVALID_HEADERS_STREAM_DATA,
+                absl::StrCat("Invalid value for SETTINGS_ENABLE_PUSH: ",
+                             value));
+          }
+          return true;
+        }
+        QUIC_DVLOG(1) << ENDPOINT << "SETTINGS_ENABLE_PUSH received with value "
+                      << value << ", ignoring.";
+        break;
+      } else {
+        QUIC_DLOG(ERROR)
+            << ENDPOINT
+            << "Invalid SETTINGS_ENABLE_PUSH received by client with value "
+            << value;
+        if (IsConnected()) {
+          CloseConnectionWithDetails(
+              QUIC_INVALID_HEADERS_STREAM_DATA,
+              absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id));
+        }
+      }
+      break;
+    case spdy::SETTINGS_MAX_HEADER_LIST_SIZE:
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "SETTINGS_MAX_HEADER_LIST_SIZE received with value "
+                    << value;
+      max_outbound_header_list_size_ = value;
+      break;
+    default:
+      QUIC_DLOG(ERROR) << ENDPOINT << "Unknown setting identifier " << id
+                       << " received with value " << value;
+      if (IsConnected()) {
+        CloseConnectionWithDetails(
+            QUIC_INVALID_HEADERS_STREAM_DATA,
+            absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id));
+      }
+  }
+  return true;
+}
+
+bool QuicSpdySession::ShouldReleaseHeadersStreamSequencerBuffer() {
+  return false;
+}
+
+void QuicSpdySession::OnHeaders(SpdyStreamId stream_id, bool has_priority,
+                                const spdy::SpdyStreamPrecedence& precedence,
+                                bool fin) {
+  if (has_priority) {
+    if (perspective() == Perspective::IS_CLIENT) {
+      CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                 "Server must not send priorities.");
+      return;
+    }
+    OnStreamHeadersPriority(stream_id, precedence);
+  } else {
+    if (perspective() == Perspective::IS_SERVER) {
+      CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                 "Client must send priorities.");
+      return;
+    }
+  }
+  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
+                   stream_id_);
+  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
+                   promised_stream_id_);
+  stream_id_ = stream_id;
+  fin_ = fin;
+}
+
+void QuicSpdySession::OnPushPromise(SpdyStreamId stream_id,
+                                    SpdyStreamId promised_stream_id) {
+  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
+                   stream_id_);
+  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
+                   promised_stream_id_);
+  stream_id_ = stream_id;
+  promised_stream_id_ = promised_stream_id;
+}
+
+// TODO (wangyix): Why is SpdyStreamId used instead of QuicStreamId?
+// This occurs in many places in this file.
+void QuicSpdySession::OnPriority(SpdyStreamId stream_id,
+                                 const spdy::SpdyStreamPrecedence& precedence) {
+  if (perspective() == Perspective::IS_CLIENT) {
+    CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+                               "Server must not send PRIORITY frames.");
+    return;
+  }
+  OnPriorityFrame(stream_id, precedence);
+}
+
+void QuicSpdySession::OnHeaderList(const QuicHeaderList& header_list) {
+  QUIC_DVLOG(1) << ENDPOINT << "Received header list for stream " << stream_id_
+                << ": " << header_list.DebugString();
+  // This code path is only executed for push promise in IETF QUIC.
+  if (VersionUsesHttp3(transport_version())) {
+    QUICHE_DCHECK(promised_stream_id_ !=
+                  QuicUtils::GetInvalidStreamId(transport_version()));
+  }
+  if (promised_stream_id_ ==
+      QuicUtils::GetInvalidStreamId(transport_version())) {
+    OnStreamHeaderList(stream_id_, fin_, frame_len_, header_list);
+  } else {
+    OnPromiseHeaderList(stream_id_, promised_stream_id_, frame_len_,
+                        header_list);
+  }
+  // Reset state for the next frame.
+  promised_stream_id_ = QuicUtils::GetInvalidStreamId(transport_version());
+  stream_id_ = QuicUtils::GetInvalidStreamId(transport_version());
+  fin_ = false;
+  frame_len_ = 0;
+}
+
+void QuicSpdySession::OnCompressedFrameSize(size_t frame_len) {
+  frame_len_ += frame_len;
+}
+
+void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error,
+                                                 const std::string& details) {
+  connection()->CloseConnection(
+      error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+bool QuicSpdySession::HasActiveRequestStreams() const {
+  return GetNumActiveStreams() + num_draining_streams() > 0;
+}
+
+QuicStream* QuicSpdySession::ProcessPendingStream(PendingStream* pending) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QUICHE_DCHECK(connection()->connected());
+  struct iovec iov;
+  if (!pending->sequencer()->GetReadableRegion(&iov)) {
+    // The first byte hasn't been received yet.
+    return nullptr;
+  }
+
+  QuicDataReader reader(static_cast<char*>(iov.iov_base), iov.iov_len);
+  uint8_t stream_type_length = reader.PeekVarInt62Length();
+  uint64_t stream_type = 0;
+  if (!reader.ReadVarInt62(&stream_type)) {
+    if (pending->sequencer()->NumBytesBuffered() ==
+        pending->sequencer()->close_offset()) {
+      // Stream received FIN but there are not enough bytes for stream type.
+      // Mark all bytes consumed in order to close stream.
+      pending->MarkConsumed(pending->sequencer()->close_offset());
+    }
+    return nullptr;
+  }
+  pending->MarkConsumed(stream_type_length);
+
+  switch (stream_type) {
+    case kControlStream: {  // HTTP/3 control stream.
+      if (receive_control_stream_) {
+        CloseConnectionOnDuplicateHttp3UnidirectionalStreams("Control");
+        return nullptr;
+      }
+      auto receive_stream =
+          std::make_unique<QuicReceiveControlStream>(pending, this);
+      receive_control_stream_ = receive_stream.get();
+      ActivateStream(std::move(receive_stream));
+      QUIC_DVLOG(1) << ENDPOINT << "Receive Control stream is created";
+      if (debug_visitor_ != nullptr) {
+        debug_visitor_->OnPeerControlStreamCreated(
+            receive_control_stream_->id());
+      }
+      return receive_control_stream_;
+    }
+    case kServerPushStream: {  // Push Stream.
+      CloseConnectionWithDetails(QUIC_HTTP_RECEIVE_SERVER_PUSH,
+                                 "Received server push stream");
+      return nullptr;
+    }
+    case kQpackEncoderStream: {  // QPACK encoder stream.
+      if (qpack_encoder_receive_stream_) {
+        CloseConnectionOnDuplicateHttp3UnidirectionalStreams("QPACK encoder");
+        return nullptr;
+      }
+      auto encoder_receive = std::make_unique<QpackReceiveStream>(
+          pending, this, qpack_decoder_->encoder_stream_receiver());
+      qpack_encoder_receive_stream_ = encoder_receive.get();
+      ActivateStream(std::move(encoder_receive));
+      QUIC_DVLOG(1) << ENDPOINT << "Receive QPACK Encoder stream is created";
+      if (debug_visitor_ != nullptr) {
+        debug_visitor_->OnPeerQpackEncoderStreamCreated(
+            qpack_encoder_receive_stream_->id());
+      }
+      return qpack_encoder_receive_stream_;
+    }
+    case kQpackDecoderStream: {  // QPACK decoder stream.
+      if (qpack_decoder_receive_stream_) {
+        CloseConnectionOnDuplicateHttp3UnidirectionalStreams("QPACK decoder");
+        return nullptr;
+      }
+      auto decoder_receive = std::make_unique<QpackReceiveStream>(
+          pending, this, qpack_encoder_->decoder_stream_receiver());
+      qpack_decoder_receive_stream_ = decoder_receive.get();
+      ActivateStream(std::move(decoder_receive));
+      QUIC_DVLOG(1) << ENDPOINT << "Receive QPACK Decoder stream is created";
+      if (debug_visitor_ != nullptr) {
+        debug_visitor_->OnPeerQpackDecoderStreamCreated(
+            qpack_decoder_receive_stream_->id());
+      }
+      return qpack_decoder_receive_stream_;
+    }
+    case kWebTransportUnidirectionalStream: {
+      // Note that this checks whether WebTransport is enabled on the receiver
+      // side, as we may receive WebTransport streams before peer's SETTINGS are
+      // received.
+      // TODO(b/184156476): consider whether this means we should drop buffered
+      // streams if we don't receive indication of WebTransport support.
+      if (!WillNegotiateWebTransport()) {
+        // Treat as unknown stream type.
+        break;
+      }
+      QUIC_DVLOG(1) << ENDPOINT << "Created an incoming WebTransport stream "
+                    << pending->id();
+      auto stream_owned =
+          std::make_unique<WebTransportHttp3UnidirectionalStream>(pending,
+                                                                  this);
+      WebTransportHttp3UnidirectionalStream* stream = stream_owned.get();
+      ActivateStream(std::move(stream_owned));
+      return stream;
+    }
+    default:
+      break;
+  }
+  MaybeSendStopSendingFrame(
+      pending->id(),
+      QuicResetStreamError::FromInternal(QUIC_STREAM_STREAM_CREATION_ERROR));
+  pending->StopReading();
+  return nullptr;
+}
+
+void QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  if (!send_control_stream_ && CanOpenNextOutgoingUnidirectionalStream()) {
+    auto send_control = std::make_unique<QuicSendControlStream>(
+        GetNextOutgoingUnidirectionalStreamId(), this, settings_);
+    send_control_stream_ = send_control.get();
+    ActivateStream(std::move(send_control));
+    if (debug_visitor_) {
+      debug_visitor_->OnControlStreamCreated(send_control_stream_->id());
+    }
+  }
+
+  if (!qpack_decoder_send_stream_ &&
+      CanOpenNextOutgoingUnidirectionalStream()) {
+    auto decoder_send = std::make_unique<QpackSendStream>(
+        GetNextOutgoingUnidirectionalStreamId(), this, kQpackDecoderStream);
+    qpack_decoder_send_stream_ = decoder_send.get();
+    ActivateStream(std::move(decoder_send));
+    qpack_decoder_->set_qpack_stream_sender_delegate(
+        qpack_decoder_send_stream_);
+    if (debug_visitor_) {
+      debug_visitor_->OnQpackDecoderStreamCreated(
+          qpack_decoder_send_stream_->id());
+    }
+  }
+
+  if (!qpack_encoder_send_stream_ &&
+      CanOpenNextOutgoingUnidirectionalStream()) {
+    auto encoder_send = std::make_unique<QpackSendStream>(
+        GetNextOutgoingUnidirectionalStreamId(), this, kQpackEncoderStream);
+    qpack_encoder_send_stream_ = encoder_send.get();
+    ActivateStream(std::move(encoder_send));
+    qpack_encoder_->set_qpack_stream_sender_delegate(
+        qpack_encoder_send_stream_);
+    if (debug_visitor_) {
+      debug_visitor_->OnQpackEncoderStreamCreated(
+          qpack_encoder_send_stream_->id());
+    }
+  }
+}
+
+void QuicSpdySession::BeforeConnectionCloseSent() {
+  if (!VersionUsesHttp3(transport_version()) || !IsEncryptionEstablished()) {
+    return;
+  }
+
+  QUICHE_DCHECK_EQ(perspective(), Perspective::IS_SERVER);
+
+  QuicStreamId stream_id =
+      GetLargestPeerCreatedStreamId(/*unidirectional = */ false);
+
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    // No client-initiated bidirectional streams received yet.
+    // Send 0 to let client know that all requests can be retried.
+    stream_id = 0;
+  } else {
+    // Tell client that streams starting with the next after the largest
+    // received one can be retried.
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+  if (last_sent_http3_goaway_id_.has_value() &&
+      last_sent_http3_goaway_id_.value() <= stream_id) {
+    // A previous GOAWAY frame was sent with smaller stream ID.  This is not
+    // possible, because this is the only method sending a GOAWAY frame with
+    // non-maximal stream ID, and this must only be called once, right
+    // before closing connection.
+    QUIC_BUG(QuicGoawayFrameAlreadySent)
+        << "Not sending GOAWAY frame with " << stream_id << " because one with "
+        << last_sent_http3_goaway_id_.value() << " already sent on connection "
+        << connection()->connection_id();
+
+    // MUST not send GOAWAY with identifier larger than previously sent.
+    // Do not bother sending one with same identifier as before, since GOAWAY
+    // frames on the control stream are guaranteed to be processed in order.
+    return;
+  }
+
+  send_control_stream_->SendGoAway(stream_id);
+  last_sent_http3_goaway_id_ = stream_id;
+}
+
+void QuicSpdySession::OnCanCreateNewOutgoingStream(bool unidirectional) {
+  if (unidirectional && VersionUsesHttp3(transport_version())) {
+    MaybeInitializeHttp3UnidirectionalStreams();
+  }
+}
+
+bool QuicSpdySession::OnMaxPushIdFrame(PushId max_push_id) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective());
+
+  if (max_push_id_.has_value()) {
+    QUIC_DVLOG(1) << "Setting max_push_id to:  " << max_push_id
+                  << " from: " << max_push_id_.value();
+  } else {
+    QUIC_DVLOG(1) << "Setting max_push_id to:  " << max_push_id
+                  << " from unset";
+  }
+  absl::optional<PushId> old_max_push_id = max_push_id_;
+  max_push_id_ = max_push_id;
+
+  if (!old_max_push_id.has_value() || max_push_id > old_max_push_id.value()) {
+    OnCanCreateNewOutgoingStream(true);
+    return true;
+  }
+
+  // Equal value is not considered an error.
+  if (max_push_id < old_max_push_id.value()) {
+    CloseConnectionWithDetails(
+        QUIC_HTTP_INVALID_MAX_PUSH_ID,
+        absl::StrCat("MAX_PUSH_ID received with value ", max_push_id,
+                     " which is smaller that previously received value ",
+                     old_max_push_id.value()));
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicSpdySession::goaway_received() const {
+  return VersionUsesHttp3(transport_version())
+             ? last_received_http3_goaway_id_.has_value()
+             : transport_goaway_received();
+}
+
+bool QuicSpdySession::goaway_sent() const {
+  return VersionUsesHttp3(transport_version())
+             ? last_sent_http3_goaway_id_.has_value()
+             : transport_goaway_sent();
+}
+
+void QuicSpdySession::CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
+    absl::string_view type) {
+  QUIC_PEER_BUG(quic_peer_bug_10360_9) << absl::StrCat(
+      "Received a duplicate ", type, " stream: Closing connection.");
+  CloseConnectionWithDetails(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+                             absl::StrCat(type, " stream is received twice."));
+}
+
+// static
+void QuicSpdySession::LogHeaderCompressionRatioHistogram(
+    bool using_qpack, bool is_sent, QuicByteCount compressed,
+    QuicByteCount uncompressed) {
+  if (compressed <= 0 || uncompressed <= 0) {
+    return;
+  }
+
+  int ratio = 100 * (compressed) / (uncompressed);
+  if (ratio < 1) {
+    ratio = 1;
+  } else if (ratio > 200) {
+    ratio = 200;
+  }
+
+  // Note that when using histogram macros in Chromium, the histogram name must
+  // be the same across calls for any given call site.
+  if (using_qpack) {
+    if (is_sent) {
+      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioQpackSent",
+                            ratio, 1, 200, 200,
+                            "Header compression ratio as percentage for sent "
+                            "headers using QPACK.");
+    } else {
+      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioQpackReceived",
+                            ratio, 1, 200, 200,
+                            "Header compression ratio as percentage for "
+                            "received headers using QPACK.");
+    }
+  } else {
+    if (is_sent) {
+      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioHpackSent",
+                            ratio, 1, 200, 200,
+                            "Header compression ratio as percentage for sent "
+                            "headers using HPACK.");
+    } else {
+      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioHpackReceived",
+                            ratio, 1, 200, 200,
+                            "Header compression ratio as percentage for "
+                            "received headers using HPACK.");
+    }
+  }
+}
+
+MessageStatus QuicSpdySession::SendHttp3Datagram(
+    QuicDatagramStreamId stream_id,
+    absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  if (!SupportsH3Datagram()) {
+    QUIC_BUG(send http datagram too early)
+        << "Refusing to send HTTP Datagram before SETTINGS received";
+    return MESSAGE_STATUS_INTERNAL_ERROR;
+  }
+  uint64_t stream_id_to_write = stream_id;
+  if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
+    // Stream ID is sent divided by four as per the specification.
+    stream_id_to_write /= kHttpDatagramStreamIdDivisor;
+  }
+  size_t slice_length =
+      QuicDataWriter::GetVarInt62Len(stream_id_to_write) + payload.length();
+  if (context_id.has_value()) {
+    slice_length += QuicDataWriter::GetVarInt62Len(context_id.value());
+  }
+  quiche::QuicheBuffer buffer(
+      connection()->helper()->GetStreamSendBufferAllocator(), slice_length);
+  QuicDataWriter writer(slice_length, buffer.data());
+  if (!writer.WriteVarInt62(stream_id_to_write)) {
+    QUIC_BUG(h3 datagram stream ID write fail)
+        << "Failed to write HTTP/3 datagram stream ID";
+    return MESSAGE_STATUS_INTERNAL_ERROR;
+  }
+  if (context_id.has_value()) {
+    if (!writer.WriteVarInt62(context_id.value())) {
+      QUIC_BUG(h3 datagram context ID write fail)
+          << "Failed to write HTTP/3 datagram context ID";
+      return MESSAGE_STATUS_INTERNAL_ERROR;
+    }
+  }
+  if (!writer.WriteBytes(payload.data(), payload.length())) {
+    QUIC_BUG(h3 datagram payload write fail)
+        << "Failed to write HTTP/3 datagram payload";
+    return MESSAGE_STATUS_INTERNAL_ERROR;
+  }
+
+  quiche::QuicheMemSlice slice(std::move(buffer));
+  return datagram_queue()->SendOrQueueDatagram(std::move(slice));
+}
+
+void QuicSpdySession::SetMaxDatagramTimeInQueueForStreamId(
+    QuicStreamId /*stream_id*/, QuicTime::Delta max_time_in_queue) {
+  // TODO(b/184598230): implement this in a way that works for multiple sessions
+  // on a same connection.
+  datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
+}
+
+void QuicSpdySession::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
+                                                  QuicStreamId stream_id) {
+  h3_datagram_flow_id_to_stream_id_map_[flow_id] = stream_id;
+}
+
+void QuicSpdySession::UnregisterHttp3DatagramFlowId(
+    QuicDatagramStreamId flow_id) {
+  h3_datagram_flow_id_to_stream_id_map_.erase(flow_id);
+}
+
+void QuicSpdySession::OnMessageReceived(absl::string_view message) {
+  QuicSession::OnMessageReceived(message);
+  if (!SupportsH3Datagram()) {
+    QUIC_DLOG(INFO) << "Ignoring unexpected received HTTP/3 datagram";
+    return;
+  }
+  QuicDataReader reader(message);
+  uint64_t stream_id64;
+  if (!reader.ReadVarInt62(&stream_id64)) {
+    QUIC_DLOG(ERROR) << "Failed to parse stream ID in received HTTP/3 datagram";
+    return;
+  }
+  if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
+    // Stream ID is sent divided by four as per the specification.
+    stream_id64 *= kHttpDatagramStreamIdDivisor;
+  }
+  if (perspective() == Perspective::IS_SERVER &&
+      http_datagram_support_ == HttpDatagramSupport::kDraft00) {
+    auto it = h3_datagram_flow_id_to_stream_id_map_.find(stream_id64);
+    if (it == h3_datagram_flow_id_to_stream_id_map_.end()) {
+      QUIC_DLOG(INFO) << "Received unknown HTTP/3 datagram flow ID "
+                      << stream_id64;
+      return;
+    }
+    stream_id64 = it->second;
+  }
+  if (stream_id64 > std::numeric_limits<QuicStreamId>::max()) {
+    // TODO(b/181256914) make this a connection close once we deprecate
+    // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+    QUIC_DLOG(ERROR) << "Received unexpectedly high HTTP/3 datagram stream ID "
+                     << stream_id64;
+    return;
+  }
+  QuicStreamId stream_id = static_cast<QuicStreamId>(stream_id64);
+  QuicSpdyStream* stream =
+      static_cast<QuicSpdyStream*>(GetActiveStream(stream_id));
+  if (stream == nullptr) {
+    QUIC_DLOG(INFO) << "Received HTTP/3 datagram for unknown stream ID "
+                    << stream_id;
+    // TODO(b/181256914) buffer unknown HTTP/3 datagram flow IDs for a short
+    // period of time in case they were reordered.
+    return;
+  }
+  stream->OnDatagramReceived(&reader);
+}
+
+bool QuicSpdySession::SupportsWebTransport() {
+  return WillNegotiateWebTransport() && SupportsH3Datagram() &&
+         peer_supports_webtransport_ &&
+         (!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+          allow_extended_connect_);
+}
+
+bool QuicSpdySession::SupportsH3Datagram() const {
+  return http_datagram_support_ != HttpDatagramSupport::kNone;
+}
+
+WebTransportHttp3* QuicSpdySession::GetWebTransportSession(
+    WebTransportSessionId id) {
+  if (!SupportsWebTransport()) {
+    return nullptr;
+  }
+  if (!IsValidWebTransportSessionId(id, version())) {
+    return nullptr;
+  }
+  QuicSpdyStream* connect_stream = GetOrCreateSpdyDataStream(id);
+  if (connect_stream == nullptr) {
+    return nullptr;
+  }
+  return connect_stream->web_transport();
+}
+
+bool QuicSpdySession::ShouldProcessIncomingRequests() {
+  if (!ShouldBufferRequestsUntilSettings()) {
+    return true;
+  }
+
+  return any_settings_received_;
+}
+
+void QuicSpdySession::OnStreamWaitingForClientSettings(QuicStreamId id) {
+  QUICHE_DCHECK(ShouldBufferRequestsUntilSettings());
+  QUICHE_DCHECK(QuicUtils::IsBidirectionalStreamId(id, version()));
+  streams_waiting_for_settings_.insert(id);
+}
+
+void QuicSpdySession::AssociateIncomingWebTransportStreamWithSession(
+    WebTransportSessionId session_id, QuicStreamId stream_id) {
+  if (QuicUtils::IsOutgoingStreamId(version(), stream_id, perspective())) {
+    QUIC_BUG(AssociateIncomingWebTransportStreamWithSession got outgoing stream)
+        << ENDPOINT
+        << "AssociateIncomingWebTransportStreamWithSession() got an outgoing "
+           "stream ID: "
+        << stream_id;
+    return;
+  }
+  WebTransportHttp3* session = GetWebTransportSession(session_id);
+  if (session != nullptr) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Successfully associated incoming WebTransport stream "
+                  << stream_id << " with session ID " << session_id;
+
+    session->AssociateStream(stream_id);
+    return;
+  }
+  // Evict the oldest streams until we are under the limit.
+  while (buffered_streams_.size() >= kMaxUnassociatedWebTransportStreams) {
+    QUIC_DVLOG(1) << ENDPOINT << "Removing stream "
+                  << buffered_streams_.front().stream_id
+                  << " from buffered streams as the queue is full.";
+    ResetStream(buffered_streams_.front().stream_id,
+                QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED);
+    buffered_streams_.pop_front();
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Received a WebTransport stream " << stream_id
+                << " for session ID " << session_id
+                << " but cannot associate it; buffering instead.";
+  buffered_streams_.push_back(
+      BufferedWebTransportStream{session_id, stream_id});
+}
+
+void QuicSpdySession::ProcessBufferedWebTransportStreamsForSession(
+    WebTransportHttp3* session) {
+  const WebTransportSessionId session_id = session->id();
+  QUIC_DVLOG(1) << "Processing buffered WebTransport streams for "
+                << session_id;
+  auto it = buffered_streams_.begin();
+  while (it != buffered_streams_.end()) {
+    if (it->session_id == session_id) {
+      QUIC_DVLOG(1) << "Unbuffered and associated WebTransport stream "
+                    << it->stream_id << " with session " << it->session_id;
+      session->AssociateStream(it->stream_id);
+      it = buffered_streams_.erase(it);
+    } else {
+      it++;
+    }
+  }
+}
+
+WebTransportHttp3UnidirectionalStream*
+QuicSpdySession::CreateOutgoingUnidirectionalWebTransportStream(
+    WebTransportHttp3* session) {
+  if (!CanOpenNextOutgoingUnidirectionalStream()) {
+    return nullptr;
+  }
+
+  QuicStreamId stream_id = GetNextOutgoingUnidirectionalStreamId();
+  auto stream_owned = std::make_unique<WebTransportHttp3UnidirectionalStream>(
+      stream_id, this, session->id());
+  WebTransportHttp3UnidirectionalStream* stream = stream_owned.get();
+  ActivateStream(std::move(stream_owned));
+  stream->WritePreamble();
+  session->AssociateStream(stream_id);
+  return stream;
+}
+
+QuicSpdyStream* QuicSpdySession::CreateOutgoingBidirectionalWebTransportStream(
+    WebTransportHttp3* session) {
+  QuicSpdyStream* stream = CreateOutgoingBidirectionalStream();
+  if (stream == nullptr) {
+    return nullptr;
+  }
+  QuicStreamId stream_id = stream->id();
+  stream->ConvertToWebTransportDataStream(session->id());
+  if (stream->web_transport_stream() == nullptr) {
+    // An error in ConvertToWebTransportDataStream() would result in
+    // CONNECTION_CLOSE, thus we don't need to do anything here.
+    return nullptr;
+  }
+  session->AssociateStream(stream_id);
+  return stream;
+}
+
+void QuicSpdySession::OnDatagramProcessed(
+    absl::optional<MessageStatus> /*status*/) {
+  // TODO(b/184598230): make this work with multiple datagram flows.
+}
+
+void QuicSpdySession::DatagramObserver::OnDatagramProcessed(
+    absl::optional<MessageStatus> status) {
+  session_->OnDatagramProcessed(status);
+}
+
+HttpDatagramSupport QuicSpdySession::LocalHttpDatagramSupport() {
+  return HttpDatagramSupport::kNone;
+}
+
+std::string HttpDatagramSupportToString(
+    HttpDatagramSupport http_datagram_support) {
+  switch (http_datagram_support) {
+    case HttpDatagramSupport::kNone:
+      return "None";
+    case HttpDatagramSupport::kDraft00:
+      return "Draft00";
+    case HttpDatagramSupport::kDraft04:
+      return "Draft04";
+    case HttpDatagramSupport::kDraft00And04:
+      return "Draft00And04";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(http_datagram_support), ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const HttpDatagramSupport& http_datagram_support) {
+  os << HttpDatagramSupportToString(http_datagram_support);
+  return os;
+}
+
+// Must not be called after Initialize().
+void QuicSpdySession::set_allow_extended_connect(bool allow_extended_connect) {
+  QUIC_BUG_IF(extended connect wrong version,
+              !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+                  !VersionUsesHttp3(transport_version()))
+      << "Try to enable/disable extended CONNECT in Google QUIC";
+  QUIC_BUG_IF(extended connect on client,
+              !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+                  perspective() == Perspective::IS_CLIENT)
+      << "Enabling/disabling extended CONNECT on the client side has no effect";
+  if (ShouldNegotiateWebTransport()) {
+    QUIC_BUG_IF(disable extended connect, !allow_extended_connect)
+        << "Disabling extended CONNECT with web transport enabled has no "
+           "effect.";
+    return;
+  }
+  allow_extended_connect_ = allow_extended_connect;
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_session.h b/quiche/quic/core/http/quic_spdy_session.h
new file mode 100644
index 0000000..b603803
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_session.h
@@ -0,0 +1,706 @@
+// Copyright (c) 2015 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_HTTP_QUIC_SPDY_SESSION_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+#include <memory>
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/http/quic_headers_stream.h"
+#include "quiche/quic/core/http/quic_receive_control_stream.h"
+#include "quiche/quic/core/http/quic_send_control_stream.h"
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+#include "quiche/quic/core/qpack/qpack_receive_stream.h"
+#include "quiche/quic/core/qpack/qpack_send_stream.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+
+namespace quic {
+
+namespace test {
+class QuicSpdySessionPeer;
+}  // namespace test
+
+class WebTransportHttp3UnidirectionalStream;
+
+QUIC_EXPORT_PRIVATE extern const size_t kMaxUnassociatedWebTransportStreams;
+
+class QUIC_EXPORT_PRIVATE Http3DebugVisitor {
+ public:
+  Http3DebugVisitor();
+  Http3DebugVisitor(const Http3DebugVisitor&) = delete;
+  Http3DebugVisitor& operator=(const Http3DebugVisitor&) = delete;
+
+  virtual ~Http3DebugVisitor();
+
+  // TODO(https://crbug.com/1062700): Remove default implementation of all
+  // methods after Chrome's QuicHttp3Logger has overrides.  This is to make sure
+  // QUICHE merge is not blocked on having to add those overrides, they can
+  // happen asynchronously.
+
+  // Creation of unidirectional streams.
+
+  // Called when locally-initiated control stream is created.
+  virtual void OnControlStreamCreated(QuicStreamId /*stream_id*/) {}
+  // Called when locally-initiated QPACK encoder stream is created.
+  virtual void OnQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) {}
+  // Called when locally-initiated QPACK decoder stream is created.
+  virtual void OnQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) {}
+  // Called when peer's control stream type is received.
+  virtual void OnPeerControlStreamCreated(QuicStreamId /*stream_id*/) = 0;
+  // Called when peer's QPACK encoder stream type is received.
+  virtual void OnPeerQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
+  // Called when peer's QPACK decoder stream type is received.
+  virtual void OnPeerQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
+
+  // Incoming HTTP/3 frames in ALPS TLS extension.
+  virtual void OnSettingsFrameReceivedViaAlps(const SettingsFrame& /*frame*/) {}
+  virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/) {}
+
+  // Incoming HTTP/3 frames on the control stream.
+  virtual void OnSettingsFrameReceived(const SettingsFrame& /*frame*/) = 0;
+  virtual void OnGoAwayFrameReceived(const GoAwayFrame& /*frame*/) {}
+  // TODO(b/171463363): Remove.
+  virtual void OnMaxPushIdFrameReceived(const MaxPushIdFrame& /*frame*/) {}
+  virtual void OnPriorityUpdateFrameReceived(
+      const PriorityUpdateFrame& /*frame*/) {}
+  virtual void OnAcceptChFrameReceived(const AcceptChFrame& /*frame*/) {}
+
+  // Incoming HTTP/3 frames on request or push streams.
+  virtual void OnDataFrameReceived(QuicStreamId /*stream_id*/,
+                                   QuicByteCount /*payload_length*/) {}
+  virtual void OnHeadersFrameReceived(
+      QuicStreamId /*stream_id*/, QuicByteCount /*compressed_headers_length*/) {
+  }
+  virtual void OnHeadersDecoded(QuicStreamId /*stream_id*/,
+                                QuicHeaderList /*headers*/) {}
+
+  // Incoming HTTP/3 frames of unknown type on any stream.
+  virtual void OnUnknownFrameReceived(QuicStreamId /*stream_id*/,
+                                      uint64_t /*frame_type*/,
+                                      QuicByteCount /*payload_length*/) {}
+
+  // Outgoing HTTP/3 frames on the control stream.
+  virtual void OnSettingsFrameSent(const SettingsFrame& /*frame*/) = 0;
+  virtual void OnGoAwayFrameSent(QuicStreamId /*stream_id*/) {}
+  virtual void OnPriorityUpdateFrameSent(const PriorityUpdateFrame& /*frame*/) {
+  }
+
+  // Outgoing HTTP/3 frames on request or push streams.
+  virtual void OnDataFrameSent(QuicStreamId /*stream_id*/,
+                               QuicByteCount /*payload_length*/) {}
+  virtual void OnHeadersFrameSent(
+      QuicStreamId /*stream_id*/,
+      const spdy::SpdyHeaderBlock& /*header_block*/) {}
+
+  // 0-RTT related events.
+  virtual void OnSettingsFrameResumed(const SettingsFrame& /*frame*/) {}
+};
+
+// Whether draft-ietf-masque-h3-datagram is supported on this session and if so
+// which draft is currently in use.
+enum class HttpDatagramSupport : uint8_t {
+  kNone = 0,  // HTTP Datagrams are not supported for this session.
+  kDraft00 = 1,
+  kDraft04 = 2,
+  kDraft00And04 = 3,  // only used locally, we only negotiate one draft.
+};
+
+QUIC_EXPORT_PRIVATE std::string HttpDatagramSupportToString(
+    HttpDatagramSupport http_datagram_support);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const HttpDatagramSupport& http_datagram_support);
+
+// A QUIC session for HTTP.
+class QUIC_EXPORT_PRIVATE QuicSpdySession
+    : public QuicSession,
+      public QpackEncoder::DecoderStreamErrorDelegate,
+      public QpackDecoder::EncoderStreamErrorDelegate {
+ public:
+  // Does not take ownership of |connection| or |visitor|.
+  QuicSpdySession(QuicConnection* connection, QuicSession::Visitor* visitor,
+                  const QuicConfig& config,
+                  const ParsedQuicVersionVector& supported_versions);
+  QuicSpdySession(const QuicSpdySession&) = delete;
+  QuicSpdySession& operator=(const QuicSpdySession&) = delete;
+
+  ~QuicSpdySession() override;
+
+  void Initialize() override;
+
+  // QpackEncoder::DecoderStreamErrorDelegate implementation.
+  void OnDecoderStreamError(QuicErrorCode error_code,
+                            absl::string_view error_message) override;
+
+  // QpackDecoder::EncoderStreamErrorDelegate implementation.
+  void OnEncoderStreamError(QuicErrorCode error_code,
+                            absl::string_view error_message) override;
+
+  // Called by |headers_stream_| when headers with a priority have been
+  // received for a stream.  This method will only be called for server streams.
+  virtual void OnStreamHeadersPriority(
+      QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence);
+
+  // Called by |headers_stream_| when headers have been completely received
+  // for a stream.  |fin| will be true if the fin flag was set in the headers
+  // frame.
+  virtual void OnStreamHeaderList(QuicStreamId stream_id, bool fin,
+                                  size_t frame_len,
+                                  const QuicHeaderList& header_list);
+
+  // Called by |headers_stream_| when push promise headers have been
+  // completely received.  |fin| will be true if the fin flag was set
+  // in the headers.
+  virtual void OnPromiseHeaderList(QuicStreamId stream_id,
+                                   QuicStreamId promised_stream_id,
+                                   size_t frame_len,
+                                   const QuicHeaderList& header_list);
+
+  // Called by |headers_stream_| when a PRIORITY frame has been received for a
+  // stream. This method will only be called for server streams.
+  virtual void OnPriorityFrame(QuicStreamId stream_id,
+                               const spdy::SpdyStreamPrecedence& precedence);
+
+  // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a request
+  // stream.  Returns false and closes connection if |stream_id| is invalid.
+  bool OnPriorityUpdateForRequestStream(QuicStreamId stream_id, int urgency);
+
+  // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a push
+  // stream.  Returns false and closes connection if |push_id| is invalid.
+  bool OnPriorityUpdateForPushStream(QuicStreamId push_id, int urgency);
+
+  // Called when an HTTP/3 ACCEPT_CH frame has been received.
+  // This method will only be called for client sessions.
+  virtual void OnAcceptChFrame(const AcceptChFrame& /*frame*/) {}
+
+  // Sends contents of |iov| to h2_deframer_, returns number of bytes processed.
+  size_t ProcessHeaderData(const struct iovec& iov);
+
+  // Writes |headers| for the stream |id| to the dedicated headers stream.
+  // If |fin| is true, then no more data will be sent for the stream |id|.
+  // If provided, |ack_notifier_delegate| will be registered to be notified when
+  // we have seen ACKs for all packets resulting from this call.
+  virtual size_t WriteHeadersOnHeadersStream(
+      QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
+      const spdy::SpdyStreamPrecedence& precedence,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Writes an HTTP/2 PRIORITY frame the to peer. Returns the size in bytes of
+  // the resulting PRIORITY frame.
+  size_t WritePriority(QuicStreamId id, QuicStreamId parent_stream_id,
+                       int weight, bool exclusive);
+
+  // Writes an HTTP/3 PRIORITY_UPDATE frame to the peer.
+  void WriteHttp3PriorityUpdate(const PriorityUpdateFrame& priority_update);
+
+  // Process received HTTP/3 GOAWAY frame.  When sent from server to client,
+  // |id| is a stream ID.  When sent from client to server, |id| is a push ID.
+  virtual void OnHttp3GoAway(uint64_t id);
+
+  // Send GOAWAY if the peer is blocked on the implementation max.
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
+
+  // Write GOAWAY frame with maximum stream ID on the control stream.  Called to
+  // initite graceful connection shutdown.  Do not use smaller stream ID, in
+  // case client does not implement retry on GOAWAY.  Do not send GOAWAY if one
+  // has already been sent. Send connection close with |error_code| and |reason|
+  // before encryption gets established.
+  void SendHttp3GoAway(QuicErrorCode error_code, const std::string& reason);
+
+  // Write |headers| for |promised_stream_id| on |original_stream_id| in a
+  // PUSH_PROMISE frame to peer.
+  virtual void WritePushPromise(QuicStreamId original_stream_id,
+                                QuicStreamId promised_stream_id,
+                                spdy::SpdyHeaderBlock headers);
+
+  QpackEncoder* qpack_encoder();
+  QpackDecoder* qpack_decoder();
+  QuicHeadersStream* headers_stream() { return headers_stream_; }
+
+  const QuicHeadersStream* headers_stream() const { return headers_stream_; }
+
+  // Called when the control stream receives HTTP/3 SETTINGS.
+  // Returns false in case of 0-RTT if received settings are incompatible with
+  // cached values, true otherwise.
+  virtual bool OnSettingsFrame(const SettingsFrame& frame);
+
+  // Called when an HTTP/3 SETTINGS frame is received via ALPS.
+  // Returns an error message if an error has occurred, or nullopt otherwise.
+  // May or may not close the connection on error.
+  absl::optional<std::string> OnSettingsFrameViaAlps(
+      const SettingsFrame& frame);
+
+  // Called when a setting is parsed from a SETTINGS frame received on the
+  // control stream or from cached application state.
+  // Returns true on success.
+  // Returns false if received setting is incompatible with cached value (in
+  // case of 0-RTT) or with previously received value (in case of ALPS).
+  // Also closes the connection on error.
+  bool OnSetting(uint64_t id, uint64_t value);
+
+  // Return true if this session wants to release headers stream's buffer
+  // aggressively.
+  virtual bool ShouldReleaseHeadersStreamSequencerBuffer();
+
+  void CloseConnectionWithDetails(QuicErrorCode error,
+                                  const std::string& details);
+
+  // Must not be called after Initialize().
+  // TODO(bnc): Move to constructor argument.
+  void set_qpack_maximum_dynamic_table_capacity(
+      uint64_t qpack_maximum_dynamic_table_capacity) {
+    qpack_maximum_dynamic_table_capacity_ =
+        qpack_maximum_dynamic_table_capacity;
+  }
+
+  // Must not be called after Initialize().
+  // TODO(bnc): Move to constructor argument.
+  void set_qpack_maximum_blocked_streams(
+      uint64_t qpack_maximum_blocked_streams) {
+    qpack_maximum_blocked_streams_ = qpack_maximum_blocked_streams;
+  }
+
+  // Should only be used by IETF QUIC server side.
+  // Must not be called after Initialize().
+  // TODO(bnc): Move to constructor argument.
+  void set_max_inbound_header_list_size(size_t max_inbound_header_list_size) {
+    max_inbound_header_list_size_ = max_inbound_header_list_size;
+  }
+
+  // Must not be called after Initialize().
+  void set_allow_extended_connect(bool allow_extended_connect);
+
+  size_t max_outbound_header_list_size() const {
+    return max_outbound_header_list_size_;
+  }
+
+  size_t max_inbound_header_list_size() const {
+    return max_inbound_header_list_size_;
+  }
+
+  bool allow_extended_connect() const { return allow_extended_connect_; }
+
+  // Returns true if the session has active request streams.
+  bool HasActiveRequestStreams() const;
+
+  // Called when the size of the compressed frame payload is available.
+  void OnCompressedFrameSize(size_t frame_len);
+
+  // Called when a PUSH_PROMISE frame has been received.
+  // TODO(b/171463363): Remove.
+  void OnPushPromise(spdy::SpdyStreamId stream_id,
+                     spdy::SpdyStreamId promised_stream_id);
+
+  // Called when the complete list of headers is available.
+  void OnHeaderList(const QuicHeaderList& header_list);
+
+  QuicStreamId promised_stream_id() const { return promised_stream_id_; }
+
+  // Initialze HTTP/3 unidirectional streams if |unidirectional| is true and
+  // those streams are not initialized yet.
+  void OnCanCreateNewOutgoingStream(bool unidirectional) override;
+
+  // Sets |max_push_id_|.
+  // This method must only be called if protocol is IETF QUIC and perspective is
+  // server.  It must only be called if a MAX_PUSH_ID frame is received.
+  // Returns whether |max_push_id| is greater than or equal to current
+  // |max_push_id_|.
+  // TODO(b/171463363): Remove.
+  bool OnMaxPushIdFrame(PushId max_push_id);
+
+  int32_t destruction_indicator() const { return destruction_indicator_; }
+
+  void set_debug_visitor(Http3DebugVisitor* debug_visitor) {
+    debug_visitor_ = debug_visitor;
+  }
+
+  Http3DebugVisitor* debug_visitor() { return debug_visitor_; }
+
+  // When using Google QUIC, return whether a transport layer GOAWAY frame has
+  // been received or sent.
+  // When using IETF QUIC, return whether an HTTP/3 GOAWAY frame has been
+  // received or sent.
+  bool goaway_received() const;
+  bool goaway_sent() const;
+
+  // Log header compression ratio histogram.
+  // |using_qpack| is true for QPACK, false for HPACK.
+  // |is_sent| is true for sent headers, false for received ones.
+  // Ratio is recorded as percentage.  Smaller value means more efficient
+  // compression.  Compressed size might be larger than uncompressed size, but
+  // recorded ratio is trunckated at 200%.
+  // Uncompressed size can be zero for an empty header list, and compressed size
+  // can be zero for an empty header list when using HPACK.  (QPACK always emits
+  // a header block prefix of at least two bytes.)  This method records nothing
+  // if either |compressed| or |uncompressed| is not positive.
+  // In order for measurements for different protocol to be comparable, the
+  // caller must ensure that uncompressed size is the total length of header
+  // names and values without any overhead.
+  static void LogHeaderCompressionRatioHistogram(bool using_qpack, bool is_sent,
+                                                 QuicByteCount compressed,
+                                                 QuicByteCount uncompressed);
+
+  // True if any dynamic table entries have been referenced from either a sent
+  // or received header block.  Used for stats.
+  bool dynamic_table_entry_referenced() const {
+    return (qpack_encoder_ &&
+            qpack_encoder_->dynamic_table_entry_referenced()) ||
+           (qpack_decoder_ && qpack_decoder_->dynamic_table_entry_referenced());
+  }
+
+  void OnStreamCreated(QuicSpdyStream* stream);
+
+  // Decode SETTINGS from |cached_state| and apply it to the session.
+  bool ResumeApplicationState(ApplicationState* cached_state) override;
+
+  absl::optional<std::string> OnAlpsData(const uint8_t* alps_data,
+                                         size_t alps_length) override;
+
+  // Called when ACCEPT_CH frame is parsed out of data received in TLS ALPS
+  // extension.
+  virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/);
+
+  // Whether HTTP datagrams are supported on this session and which draft is in
+  // use, based on received SETTINGS.
+  HttpDatagramSupport http_datagram_support() const {
+    return http_datagram_support_;
+  }
+
+  // This must not be used except by QuicSpdyStream::SendHttp3Datagram.
+  MessageStatus SendHttp3Datagram(
+      QuicDatagramStreamId stream_id,
+      absl::optional<QuicDatagramContextId> context_id,
+      absl::string_view payload);
+  // This must not be used except by QuicSpdyStream::SetMaxDatagramTimeInQueue.
+  void SetMaxDatagramTimeInQueueForStreamId(QuicStreamId stream_id,
+                                            QuicTime::Delta max_time_in_queue);
+  // This must not be used except by
+  // QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders.
+  void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
+                                   QuicStreamId stream_id);
+  // This must not be used except by QuicSpdyStream::OnClose.
+  void UnregisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
+
+  // Override from QuicSession to support HTTP/3 datagrams.
+  void OnMessageReceived(absl::string_view message) override;
+
+  // Indicates whether the HTTP/3 session supports WebTransport.
+  bool SupportsWebTransport();
+
+  // Indicates whether both the peer and us support HTTP/3 Datagrams.
+  bool SupportsH3Datagram() const;
+
+  // Indicates whether the HTTP/3 session will indicate WebTransport support to
+  // the peer.
+  bool WillNegotiateWebTransport();
+
+  // Returns a WebTransport session by its session ID.  Returns nullptr if no
+  // session is associated with the given ID.
+  WebTransportHttp3* GetWebTransportSession(WebTransportSessionId id);
+
+  // If true, no data on bidirectional streams will be processed by the server
+  // until the SETTINGS are received.  Only works for HTTP/3.
+  bool ShouldBufferRequestsUntilSettings() {
+    return version().UsesHttp3() && perspective() == Perspective::IS_SERVER &&
+           LocalHttpDatagramSupport() != HttpDatagramSupport::kNone;
+  }
+
+  // Returns if the incoming bidirectional streams should process data.  This is
+  // usually true, but in certain cases we would want to wait until the settings
+  // are received.
+  bool ShouldProcessIncomingRequests();
+
+  void OnStreamWaitingForClientSettings(QuicStreamId id);
+
+  // Links the specified stream with a WebTransport session.  If the session is
+  // not present, it is buffered until a corresponding stream is found.
+  void AssociateIncomingWebTransportStreamWithSession(
+      WebTransportSessionId session_id, QuicStreamId stream_id);
+
+  void ProcessBufferedWebTransportStreamsForSession(WebTransportHttp3* session);
+
+  bool CanOpenOutgoingUnidirectionalWebTransportStream(
+      WebTransportSessionId /*id*/) {
+    return CanOpenNextOutgoingUnidirectionalStream();
+  }
+  bool CanOpenOutgoingBidirectionalWebTransportStream(
+      WebTransportSessionId /*id*/) {
+    return CanOpenNextOutgoingBidirectionalStream();
+  }
+
+  // Creates an outgoing unidirectional WebTransport stream.  Returns nullptr if
+  // the stream cannot be created due to flow control or some other reason.
+  WebTransportHttp3UnidirectionalStream*
+  CreateOutgoingUnidirectionalWebTransportStream(WebTransportHttp3* session);
+
+  // Creates an outgoing bidirectional WebTransport stream.  Returns nullptr if
+  // the stream cannot be created due to flow control or some other reason.
+  QuicSpdyStream* CreateOutgoingBidirectionalWebTransportStream(
+      WebTransportHttp3* session);
+
+  QuicSpdyStream* GetOrCreateSpdyDataStream(const QuicStreamId stream_id);
+
+  // Indicates whether we will try to negotiate datagram contexts on newly
+  // created WebTransport sessions over HTTP/3.
+  virtual bool ShouldNegotiateDatagramContexts();
+
+  // Indicates whether the client should check that the
+  // `Sec-Webtransport-Http3-Draft` header is valid.
+  // TODO(vasilvv): remove this once this is enabled in Chromium.
+  virtual bool ShouldValidateWebTransportVersion() const;
+
+ protected:
+  // Override CreateIncomingStream(), CreateOutgoingBidirectionalStream() and
+  // CreateOutgoingUnidirectionalStream() with QuicSpdyStream return type to
+  // make sure that all data streams are QuicSpdyStreams.
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override = 0;
+  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override = 0;
+  virtual QuicSpdyStream* CreateOutgoingBidirectionalStream() = 0;
+  virtual QuicSpdyStream* CreateOutgoingUnidirectionalStream() = 0;
+
+  // If an incoming stream can be created, return true.
+  virtual bool ShouldCreateIncomingStream(QuicStreamId id) = 0;
+
+  // If an outgoing bidirectional/unidirectional stream can be created, return
+  // true.
+  virtual bool ShouldCreateOutgoingBidirectionalStream() = 0;
+  virtual bool ShouldCreateOutgoingUnidirectionalStream() = 0;
+
+  // Indicates whether the underlying backend can accept and process
+  // WebTransport sessions over HTTP/3.
+  virtual bool ShouldNegotiateWebTransport();
+
+  // Returns true if there are open HTTP requests.
+  bool ShouldKeepConnectionAlive() const override;
+
+  // Overridden to buffer incoming unidirectional streams for version 99.
+  bool UsesPendingStreamForFrame(QuicFrameType type,
+                                 QuicStreamId stream_id) const override;
+
+  // Processes incoming unidirectional streams; parses the stream type, and
+  // creates a new stream of the corresponding type.  Returns the pointer to the
+  // newly created stream, or nullptr if the stream type is not yet available.
+  QuicStream* ProcessPendingStream(PendingStream* pending) override;
+
+  size_t WriteHeadersOnHeadersStreamImpl(
+      QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
+      QuicStreamId parent_stream_id, int weight, bool exclusive,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  void OnNewEncryptionKeyAvailable(
+      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override;
+
+  // Sets the maximum size of the header compression table spdy_framer_ is
+  // willing to use to encode header blocks.
+  void UpdateHeaderEncoderTableSize(uint32_t value);
+
+  bool IsConnected() { return connection()->connected(); }
+
+  const QuicReceiveControlStream* receive_control_stream() const {
+    return receive_control_stream_;
+  }
+
+  const SettingsFrame& settings() const { return settings_; }
+
+  // Initializes HTTP/3 unidirectional streams if not yet initialzed.
+  virtual void MaybeInitializeHttp3UnidirectionalStreams();
+
+  // QuicConnectionVisitorInterface method.
+  void BeforeConnectionCloseSent() override;
+
+  // Called whenever a datagram is dequeued or dropped from datagram_queue().
+  virtual void OnDatagramProcessed(absl::optional<MessageStatus> status);
+
+  // Returns which version of the HTTP/3 datagram extension we should advertise
+  // in settings and accept remote settings for.
+  virtual HttpDatagramSupport LocalHttpDatagramSupport();
+
+ private:
+  friend class test::QuicSpdySessionPeer;
+
+  class SpdyFramerVisitor;
+
+  // Proxies OnDatagramProcessed() calls to the session.
+  class QUIC_EXPORT_PRIVATE DatagramObserver
+      : public QuicDatagramQueue::Observer {
+   public:
+    explicit DatagramObserver(QuicSpdySession* session) : session_(session) {}
+    void OnDatagramProcessed(absl::optional<MessageStatus> status) override;
+
+   private:
+    QuicSpdySession* session_;  // not owned
+  };
+
+  struct QUIC_EXPORT_PRIVATE BufferedWebTransportStream {
+    WebTransportSessionId session_id;
+    QuicStreamId stream_id;
+  };
+
+  // The following methods are called by the SimpleVisitor.
+
+  // Called when a HEADERS frame has been received.
+  void OnHeaders(spdy::SpdyStreamId stream_id, bool has_priority,
+                 const spdy::SpdyStreamPrecedence& precedence, bool fin);
+
+  // Called when a PRIORITY frame has been received.
+  void OnPriority(spdy::SpdyStreamId stream_id,
+                  const spdy::SpdyStreamPrecedence& precedence);
+
+  void CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
+      absl::string_view type);
+
+  // Sends any data which should be sent at the start of a connection, including
+  // the initial SETTINGS frame, and (when IETF QUIC is used) also a MAX_PUSH_ID
+  // frame if SetMaxPushId() had been called before encryption was established.
+  // When using 0-RTT, this method is called twice: once when encryption is
+  // established, and again when 1-RTT keys are available.
+  void SendInitialData();
+
+  void FillSettingsFrame();
+
+  bool VerifySettingIsZeroOrOne(uint64_t id, uint64_t value);
+
+  std::unique_ptr<QpackEncoder> qpack_encoder_;
+  std::unique_ptr<QpackDecoder> qpack_decoder_;
+
+  // Pointer to the header stream in stream_map_.
+  QuicHeadersStream* headers_stream_;
+
+  // HTTP/3 control streams. They are owned by QuicSession inside
+  // stream map, and can be accessed by those unowned pointers below.
+  QuicSendControlStream* send_control_stream_;
+  QuicReceiveControlStream* receive_control_stream_;
+
+  // Pointers to HTTP/3 QPACK streams in stream map.
+  QpackReceiveStream* qpack_encoder_receive_stream_;
+  QpackReceiveStream* qpack_decoder_receive_stream_;
+  QpackSendStream* qpack_encoder_send_stream_;
+  QpackSendStream* qpack_decoder_send_stream_;
+
+  SettingsFrame settings_;
+
+  // Maximum dynamic table capacity as defined at
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#maximum-dynamic-table-capacity
+  // for the decoding context.  Value will be sent via
+  // SETTINGS_QPACK_MAX_TABLE_CAPACITY.
+  // |qpack_maximum_dynamic_table_capacity_| also serves as an upper bound for
+  // the dynamic table capacity of the encoding context, to limit memory usage
+  // if a larger SETTINGS_QPACK_MAX_TABLE_CAPACITY value is received.
+  uint64_t qpack_maximum_dynamic_table_capacity_;
+
+  // Maximum number of blocked streams as defined at
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams
+  // for the decoding context.  Value will be sent via
+  // SETTINGS_QPACK_BLOCKED_STREAMS.
+  uint64_t qpack_maximum_blocked_streams_;
+
+  // The maximum size of a header block that will be accepted from the peer,
+  // defined per spec as key + value + overhead per field (uncompressed).
+  // Value will be sent via SETTINGS_MAX_HEADER_LIST_SIZE.
+  size_t max_inbound_header_list_size_;
+
+  // The maximum size of a header block that can be sent to the peer. This field
+  // is informed and set by the peer via SETTINGS frame.
+  // TODO(b/148616439): Honor this field when sending headers.
+  size_t max_outbound_header_list_size_;
+
+  // Data about the stream whose headers are being processed.
+  QuicStreamId stream_id_;
+  QuicStreamId promised_stream_id_;
+  size_t frame_len_;
+  bool fin_;
+
+  spdy::SpdyFramer spdy_framer_;
+  http2::Http2DecoderAdapter h2_deframer_;
+  std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_;
+
+  // Used in IETF QUIC only.
+  // For a server:
+  //   the push ID in the most recently received MAX_PUSH_ID frame,
+  //   or unset if no MAX_PUSH_ID frame has been received.
+  // For a client:
+  //   unset until SetMaxPushId() is called;
+  //   before encryption is established, the push ID to be sent in the initial
+  //   MAX_PUSH_ID frame;
+  //   after encryption is established, the push ID in the most recently sent
+  //   MAX_PUSH_ID frame.
+  // Once set, never goes back to unset.
+  // TODO(b/171463363): Remove.
+  absl::optional<PushId> max_push_id_;
+
+  // Not owned by the session.
+  Http3DebugVisitor* debug_visitor_;
+
+  // Priority values received in PRIORITY_UPDATE frames for streams that are not
+  // open yet.
+  absl::flat_hash_map<QuicStreamId, int> buffered_stream_priorities_;
+
+  // An integer used for live check. The indicator is assigned a value in
+  // constructor. As long as it is not the assigned value, that would indicate
+  // an use-after-free.
+  int32_t destruction_indicator_;
+
+  // The identifier in the most recently received GOAWAY frame.  Unset if no
+  // GOAWAY frame has been received yet.
+  absl::optional<uint64_t> last_received_http3_goaway_id_;
+  // The identifier in the most recently sent GOAWAY frame.  Unset if no GOAWAY
+  // frame has been sent yet.
+  absl::optional<uint64_t> last_sent_http3_goaway_id_;
+
+  // Whether both this endpoint and our peer support HTTP datagrams and which
+  // draft is in use for this session.
+  HttpDatagramSupport http_datagram_support_ = HttpDatagramSupport::kNone;
+
+  // Whether the peer has indicated WebTransport support.
+  bool peer_supports_webtransport_ = false;
+
+  // This maps from draft-ietf-masque-h3-datagram-00 flow IDs to stream IDs.
+  // TODO(b/181256914) remove this when we deprecate support for that draft in
+  // favor of more recent ones.
+  absl::flat_hash_map<uint64_t, QuicStreamId>
+      h3_datagram_flow_id_to_stream_id_map_;
+
+  // Whether any settings have been received, either from the peer or from a
+  // session ticket.
+  bool any_settings_received_ = false;
+
+  // If ShouldBufferRequestsUntilSettings() is true, all streams that are
+  // blocked by that are tracked here.
+  absl::flat_hash_set<QuicStreamId> streams_waiting_for_settings_;
+
+  // WebTransport streams that do not have a session associated with them.
+  // Limited to kMaxUnassociatedWebTransportStreams; when the list is full,
+  // oldest streams are evicated first.
+  std::list<BufferedWebTransportStream> buffered_streams_;
+
+  // On the server side, if true, advertise and accept extended CONNECT method.
+  // On the client side, true if the peer advertised extended CONNECT.
+  bool allow_extended_connect_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
diff --git a/quiche/quic/core/http/quic_spdy_session_test.cc b/quiche/quic/core/http/quic_spdy_session_test.cc
new file mode 100644
index 0000000..0a767c1
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_session_test.cc
@@ -0,0 +1,3890 @@
+// 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 "quiche/quic/core/http/quic_spdy_session.h"
+
+#include <cstdint>
+#include <limits>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/frames/quic_streams_blocked_frame.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+using spdy::kV3HighestPriority;
+using spdy::Spdy3PriorityToHttp2Weight;
+using spdy::SpdyFramer;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyPriority;
+using spdy::SpdyPriorityIR;
+using spdy::SpdySerializedFrame;
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::AtLeast;
+using ::testing::ElementsAre;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+bool VerifyAndClearStopSendingFrame(const QuicFrame& frame) {
+  EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
+  return ClearControlFrame(frame);
+}
+
+class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
+ public:
+  explicit TestCryptoStream(QuicSession* session)
+      : QuicCryptoStream(session),
+        QuicCryptoHandshaker(this, session),
+        encryption_established_(false),
+        one_rtt_keys_available_(false),
+        params_(new QuicCryptoNegotiatedParameters) {
+    // Simulate a negotiated cipher_suite with a fake value.
+    params_->cipher_suite = 1;
+  }
+
+  void EstablishZeroRttEncryption() {
+    encryption_established_ = true;
+    session()->connection()->SetEncrypter(
+        ENCRYPTION_ZERO_RTT,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+  }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
+    encryption_established_ = true;
+    one_rtt_keys_available_ = true;
+    QuicErrorCode error;
+    std::string error_details;
+    session()->config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session()->config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    if (session()->version().UsesTls()) {
+      if (session()->perspective() == Perspective::IS_CLIENT) {
+        session()->config()->SetOriginalConnectionIdToSend(
+            session()->connection()->connection_id());
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->connection_id());
+      } else {
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->client_connection_id());
+      }
+      TransportParameters transport_parameters;
+      EXPECT_TRUE(
+          session()->config()->FillTransportParameters(&transport_parameters));
+      error = session()->config()->ProcessTransportParameters(
+          transport_parameters, /* is_resumption = */ false, &error_details);
+    } else {
+      CryptoHandshakeMessage msg;
+      session()->config()->ToHandshakeMessage(&msg, transport_version());
+      error =
+          session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
+    }
+    EXPECT_THAT(error, IsQuicNoError());
+    session()->OnNewEncryptionKeyAvailable(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+    session()->OnConfigNegotiated();
+    if (session()->connection()->version().handshake_protocol ==
+        PROTOCOL_TLS1_3) {
+      session()->OnTlsHandshakeComplete();
+    } else {
+      session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  }
+
+  // QuicCryptoStream implementation
+  ssl_early_data_reason_t EarlyDataReason() const override {
+    return ssl_early_data_unknown;
+  }
+  bool encryption_established() const override {
+    return encryption_established_;
+  }
+  bool one_rtt_keys_available() const override {
+    return one_rtt_keys_available_;
+  }
+  HandshakeState GetHandshakeState() const override {
+    return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+  }
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override {
+    return *params_;
+  }
+  CryptoMessageParser* crypto_message_parser() override {
+    return QuicCryptoHandshaker::crypto_message_parser();
+  }
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_params*/) const override {
+    return "";
+  }
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    return true;
+  }
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    return nullptr;
+  }
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+
+  bool HasPendingCryptoRetransmission() const override { return false; }
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override {}
+  SSL* GetSsl() const override { return nullptr; }
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    return false;
+  }
+
+ private:
+  using QuicCryptoStream::session;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+};
+
+class TestHeadersStream : public QuicHeadersStream {
+ public:
+  explicit TestHeadersStream(QuicSpdySession* session)
+      : QuicHeadersStream(session) {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+};
+
+class TestStream : public QuicSpdyStream {
+ public:
+  TestStream(QuicStreamId id, QuicSpdySession* session, StreamType type)
+      : QuicSpdyStream(id, session, type) {}
+
+  TestStream(PendingStream* pending, QuicSpdySession* session)
+      : QuicSpdyStream(pending, session) {}
+
+  using QuicStream::CloseWriteSide;
+
+  void OnBodyAvailable() override {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  MOCK_METHOD(bool, RetransmitStreamData,
+              (QuicStreamOffset, QuicByteCount, bool, TransmissionType),
+              (override));
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+
+ protected:
+  bool AreHeadersValid(const QuicHeaderList& /*header_list*/) const override {
+    return true;
+  }
+};
+
+class TestSession : public QuicSpdySession {
+ public:
+  explicit TestSession(QuicConnection* connection)
+      : QuicSpdySession(connection, nullptr, DefaultQuicConfig(),
+                        CurrentSupportedVersions()),
+        crypto_stream_(this),
+        writev_consumes_all_data_(false) {
+    this->connection()->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection->perspective()));
+    if (this->connection()->version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(this->connection());
+    }
+  }
+
+  ~TestSession() override { DeleteConnection(); }
+
+  TestCryptoStream* GetMutableCryptoStream() override {
+    return &crypto_stream_;
+  }
+
+  const TestCryptoStream* GetCryptoStream() const override {
+    return &crypto_stream_;
+  }
+
+  TestStream* CreateOutgoingBidirectionalStream() override {
+    TestStream* stream = new TestStream(GetNextOutgoingBidirectionalStreamId(),
+                                        this, BIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateOutgoingUnidirectionalStream() override {
+    TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
+                                        this, WRITE_UNIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateIncomingStream(QuicStreamId id) override {
+    // Enforce the limit on the number of open streams.
+    if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
+        stream_id_manager().num_open_incoming_streams() + 1 >
+            max_open_incoming_bidirectional_streams()) {
+      connection()->CloseConnection(
+          QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return nullptr;
+    } else {
+      TestStream* stream = new TestStream(
+          id, this,
+          DetermineStreamType(id, connection()->version(), perspective(),
+                              /*is_incoming=*/true, BIDIRECTIONAL));
+      ActivateStream(absl::WrapUnique(stream));
+      return stream;
+    }
+  }
+
+  TestStream* CreateIncomingStream(PendingStream* pending) override {
+    TestStream* stream = new TestStream(pending, this);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  bool ShouldCreateIncomingStream(QuicStreamId /*id*/) override { return true; }
+
+  bool ShouldCreateOutgoingBidirectionalStream() override { return true; }
+  bool ShouldCreateOutgoingUnidirectionalStream() override { return true; }
+
+  bool IsClosedStream(QuicStreamId id) {
+    return QuicSession::IsClosedStream(id);
+  }
+
+  QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
+    return QuicSpdySession::GetOrCreateStream(stream_id);
+  }
+
+  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
+                              QuicStreamOffset offset, StreamSendingState state,
+                              TransmissionType type,
+                              EncryptionLevel level) override {
+    bool fin = state != NO_FIN;
+    QuicConsumedData consumed(write_length, fin);
+    if (!writev_consumes_all_data_) {
+      consumed =
+          QuicSession::WritevData(id, write_length, offset, state, type, level);
+    }
+    QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
+        id, consumed.bytes_consumed);
+    return consumed;
+  }
+
+  void set_writev_consumes_all_data(bool val) {
+    writev_consumes_all_data_ = val;
+  }
+
+  QuicConsumedData SendStreamData(QuicStream* stream) {
+    if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
+                                     stream->id()) &&
+        connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
+      this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    QuicStreamPeer::SendBuffer(stream).SaveStreamData("not empty");
+    QuicConsumedData consumed =
+        WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION,
+                   GetEncryptionLevelToSendApplicationData());
+    QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
+        consumed.bytes_consumed);
+    return consumed;
+  }
+
+  QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
+    QUICHE_DCHECK(writev_consumes_all_data_);
+    return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
+                      GetEncryptionLevelToSendApplicationData());
+  }
+
+  bool ShouldNegotiateWebTransport() override { return supports_webtransport_; }
+  void set_supports_webtransport(bool value) { supports_webtransport_ = value; }
+
+  HttpDatagramSupport LocalHttpDatagramSupport() override {
+    return local_http_datagram_support_;
+  }
+  void set_local_http_datagram_support(HttpDatagramSupport value) {
+    local_http_datagram_support_ = value;
+  }
+
+  MOCK_METHOD(void, OnAcceptChFrame, (const AcceptChFrame&), (override));
+
+  using QuicSession::closed_streams;
+  using QuicSession::ShouldKeepConnectionAlive;
+  using QuicSpdySession::ProcessPendingStream;
+  using QuicSpdySession::UsesPendingStreamForFrame;
+
+ private:
+  StrictMock<TestCryptoStream> crypto_stream_;
+
+  bool writev_consumes_all_data_;
+  bool supports_webtransport_ = false;
+  HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
+};
+
+class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
+    if (frame.type == MAX_STREAMS_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ protected:
+  explicit QuicSpdySessionTestBase(Perspective perspective,
+                                   bool allow_extended_connect)
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_, &alarm_factory_, perspective,
+            SupportedVersions(GetParam()))),
+        session_(connection_) {
+    if (perspective == Perspective::IS_SERVER &&
+        VersionUsesHttp3(transport_version()) &&
+        GetQuicReloadableFlag(quic_verify_request_headers_2)) {
+      session_.set_allow_extended_connect(allow_extended_connect);
+    }
+    session_.Initialize();
+    session_.config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session_.config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    if (VersionUsesHttp3(transport_version())) {
+      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
+          session_.config(), kHttp3StaticUnidirectionalStreamCount);
+    }
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    session_.OnConfigNegotiated();
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .Times(testing::AnyNumber());
+    writer_ = static_cast<MockPacketWriter*>(
+        QuicConnectionPeer::GetWriter(session_.connection()));
+  }
+
+  void CheckClosedStreams() {
+    QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        transport_version(), Perspective::IS_CLIENT);
+    if (!QuicVersionUsesCryptoFrames(transport_version())) {
+      first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
+    }
+    for (QuicStreamId i = first_stream_id; i < 100; i++) {
+      if (closed_streams_.find(i) == closed_streams_.end()) {
+        EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
+      } else {
+        EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
+      }
+    }
+  }
+
+  void CloseStream(QuicStreamId id) {
+    if (!VersionHasIetfQuicFrames(transport_version())) {
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+    } else {
+      // IETF QUIC has two frames, RST_STREAM and STOP_SENDING
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .Times(2)
+          .WillRepeatedly(Invoke(&ClearControlFrame));
+    }
+    EXPECT_CALL(*connection_, OnStreamReset(id, _));
+
+    // QPACK streams might write data upon stream reset. Let the test session
+    // handle the data.
+    session_.set_writev_consumes_all_data(true);
+
+    session_.ResetStream(id, QUIC_STREAM_CANCELLED);
+    closed_streams_.insert(id);
+  }
+
+  ParsedQuicVersion version() const { return connection_->version(); }
+
+  QuicTransportVersion transport_version() const {
+    return connection_->transport_version();
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return GetNthServerInitiatedBidirectionalStreamId(transport_version(), n);
+  }
+
+  QuicStreamId IdDelta() {
+    return QuicUtils::StreamIdDelta(transport_version());
+  }
+
+  std::string EncodeSettings(const SettingsFrame& settings) {
+    std::unique_ptr<char[]> buffer;
+    auto header_length = HttpEncoder::SerializeSettingsFrame(settings, &buffer);
+    return std::string(buffer.get(), header_length);
+  }
+
+  std::string SerializePriorityUpdateFrame(
+      const PriorityUpdateFrame& priority_update) {
+    std::unique_ptr<char[]> priority_buffer;
+    QuicByteCount priority_frame_length =
+        HttpEncoder::SerializePriorityUpdateFrame(priority_update,
+                                                  &priority_buffer);
+    return std::string(priority_buffer.get(), priority_frame_length);
+  }
+
+  // TODO(b/171463363): Remove.
+  std::string SerializeMaxPushIdFrame(PushId push_id) {
+    const QuicByteCount payload_length =
+        QuicDataWriter::GetVarInt62Len(push_id);
+
+    const QuicByteCount total_length =
+        QuicDataWriter::GetVarInt62Len(
+            static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID)) +
+        QuicDataWriter::GetVarInt62Len(payload_length) +
+        QuicDataWriter::GetVarInt62Len(push_id);
+
+    std::string max_push_id_frame(total_length, '\0');
+    QuicDataWriter writer(total_length, &*max_push_id_frame.begin());
+
+    QUICHE_CHECK(writer.WriteVarInt62(
+        static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID)));
+    QUICHE_CHECK(writer.WriteVarInt62(payload_length));
+    QUICHE_CHECK(writer.WriteVarInt62(push_id));
+    QUICHE_CHECK_EQ(0u, writer.remaining());
+
+    return max_push_id_frame;
+  }
+
+  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
+                               Perspective perspective, bool bidirectional) {
+    // Calculate and build up stream ID rather than use
+    // GetFirst... because the test that relies on this method
+    // needs to do the stream count where #1 is 0/1/2/3, and not
+    // take into account that stream 0 is special.
+    QuicStreamId id =
+        ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
+    if (!bidirectional) {
+      id |= 0x2;
+    }
+    if (perspective == Perspective::IS_SERVER) {
+      id |= 0x1;
+    }
+    return id;
+  }
+
+  void CompleteHandshake() {
+    if (VersionHasIetfQuicFrames(transport_version())) {
+      EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+          .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+    }
+    if (connection_->version().UsesTls() &&
+        connection_->perspective() == Perspective::IS_SERVER) {
+      // HANDSHAKE_DONE frame.
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+    }
+
+    CryptoHandshakeMessage message;
+    session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
+    testing::Mock::VerifyAndClearExpectations(writer_);
+    testing::Mock::VerifyAndClearExpectations(connection_);
+  }
+
+  void ReceiveWebTransportSettings() {
+    SettingsFrame settings;
+    settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+    settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
+    settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
+    std::string data =
+        std::string(1, kControlStream) + EncodeSettings(settings);
+    QuicStreamId control_stream_id =
+        session_.perspective() == Perspective::IS_SERVER
+            ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(),
+                                                          3)
+            : GetNthServerInitiatedUnidirectionalStreamId(transport_version(),
+                                                          3);
+    QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
+    session_.OnStreamFrame(frame);
+  }
+
+  void ReceiveWebTransportSession(WebTransportSessionId session_id) {
+    QuicStreamFrame frame(session_id, /*fin=*/false, /*offset=*/0,
+                          absl::string_view());
+    session_.OnStreamFrame(frame);
+    QuicSpdyStream* stream =
+        static_cast<QuicSpdyStream*>(session_.GetOrCreateStream(session_id));
+    QuicHeaderList headers;
+    headers.OnHeaderBlockStart();
+    headers.OnHeader(":method", "CONNECT");
+    headers.OnHeader(":protocol", "webtransport");
+    if (session_.http_datagram_support() == HttpDatagramSupport::kDraft00) {
+      headers.OnHeader("datagram-flow-id", absl::StrCat(session_id));
+    } else {
+      headers.OnHeader("sec-webtransport-http3-draft02", "1");
+    }
+    stream->OnStreamHeaderList(/*fin=*/true, 0, headers);
+    if (session_.http_datagram_support() != HttpDatagramSupport::kDraft00) {
+      stream->OnCapsule(
+          Capsule::RegisterDatagramNoContext(DatagramFormatType::WEBTRANSPORT));
+    }
+    WebTransportHttp3* web_transport =
+        session_.GetWebTransportSession(session_id);
+    ASSERT_TRUE(web_transport != nullptr);
+    spdy::SpdyHeaderBlock header_block;
+    web_transport->HeadersReceived(header_block);
+  }
+
+  void ReceiveWebTransportUnidirectionalStream(WebTransportSessionId session_id,
+                                               QuicStreamId stream_id) {
+    char buffer[256];
+    QuicDataWriter data_writer(sizeof(buffer), buffer);
+    ASSERT_TRUE(data_writer.WriteVarInt62(kWebTransportUnidirectionalStream));
+    ASSERT_TRUE(data_writer.WriteVarInt62(session_id));
+    ASSERT_TRUE(data_writer.WriteStringPiece("test data"));
+    std::string data(buffer, data_writer.length());
+    QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
+    session_.OnStreamFrame(frame);
+  }
+
+  void TestHttpDatagramSetting(HttpDatagramSupport local_support,
+                               HttpDatagramSupport remote_support,
+                               HttpDatagramSupport expected_support,
+                               bool expected_datagram_supported);
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  TestSession session_;
+  std::set<QuicStreamId> closed_streams_;
+  MockPacketWriter* writer_;
+};
+
+class QuicSpdySessionTestServer : public QuicSpdySessionTestBase {
+ protected:
+  QuicSpdySessionTestServer()
+      : QuicSpdySessionTestBase(Perspective::IS_SERVER, true) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServer,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSpdySessionTestServer, UsesPendingStreamsForFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
+      STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                        transport_version(), Perspective::IS_CLIENT)));
+  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                            transport_version(), Perspective::IS_CLIENT)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                            transport_version(), Perspective::IS_SERVER)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                              transport_version(), Perspective::IS_CLIENT)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
+                            transport_version(), Perspective::IS_CLIENT)));
+}
+
+TEST_P(QuicSpdySessionTestServer, PeerAddress) {
+  EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
+            session_.peer_address());
+}
+
+TEST_P(QuicSpdySessionTestServer, SelfAddress) {
+  EXPECT_TRUE(session_.self_address().IsInitialized());
+}
+
+TEST_P(QuicSpdySessionTestServer, OneRttKeysAvailable) {
+  EXPECT_FALSE(session_.OneRttKeysAvailable());
+  CompleteHandshake();
+  EXPECT_TRUE(session_.OneRttKeysAvailable());
+}
+
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamDefault) {
+  // Ensure that no streams are initially closed.
+  QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
+  }
+  for (QuicStreamId i = first_stream_id; i < 100; i++) {
+    EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, AvailableStreams) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(2)) != nullptr);
+  // Both client initiated streams with smaller stream IDs are available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(1)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(0)) != nullptr);
+}
+
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
+  QuicSpdyStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
+
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(0));
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(1));
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamPeerCreated) {
+  CompleteHandshake();
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
+  session_.GetOrCreateStream(stream_id1);
+  session_.GetOrCreateStream(stream_id2);
+
+  CheckClosedStreams();
+  CloseStream(stream_id1);
+  CheckClosedStreams();
+  CloseStream(stream_id2);
+  // Create a stream, and make another available.
+  QuicStream* stream3 = session_.GetOrCreateStream(stream_id2 + 4);
+  CheckClosedStreams();
+  // Close one, but make sure the other is still not closed
+  CloseStream(stream3->id());
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSpdySessionTestServer, MaximumAvailableOpenedStreams) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // For IETF QUIC, we should be able to obtain the max allowed
+    // stream ID, the next ID should fail. Since the actual limit
+    // is not the number of open streams, we allocate the max and the max+2.
+    // Get the max allowed stream ID, this should succeed.
+    QuicStreamId stream_id = StreamCountToId(
+        QuicSessionPeer::ietf_streamid_manager(&session_)
+            ->max_incoming_bidirectional_streams(),
+        Perspective::IS_CLIENT,  // Client initates stream, allocs stream id.
+        /*bidirectional=*/true);
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+    stream_id =
+        StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                            ->max_incoming_unidirectional_streams(),
+                        Perspective::IS_CLIENT,
+                        /*bidirectional=*/false);
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(2);
+    // Get the (max allowed stream ID)++. These should all fail.
+    stream_id =
+        StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                                ->max_incoming_bidirectional_streams() +
+                            1,
+                        Perspective::IS_CLIENT,
+                        /*bidirectional=*/true);
+    EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id));
+
+    stream_id =
+        StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                                ->max_incoming_unidirectional_streams() +
+                            1,
+                        Perspective::IS_CLIENT,
+                        /*bidirectional=*/false);
+    EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id));
+  } else {
+    QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+    session_.GetOrCreateStream(stream_id);
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    EXPECT_NE(
+        nullptr,
+        session_.GetOrCreateStream(
+            stream_id +
+            IdDelta() *
+                (session_.max_open_incoming_bidirectional_streams() - 1)));
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, TooManyAvailableStreams) {
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2;
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
+  // A stream ID which is too large to create.
+  stream_id2 = GetNthClientInitiatedBidirectionalId(
+      2 * session_.MaxAvailableBidirectionalStreams() + 4);
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  }
+  EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
+}
+
+TEST_P(QuicSpdySessionTestServer, ManyAvailableStreams) {
+  // When max_open_streams_ is 200, should be able to create 200 streams
+  // out-of-order, that is, creating the one with the largest stream ID first.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 200);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
+  }
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  // Create one stream.
+  session_.GetOrCreateStream(stream_id);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  // Stream count is 200, GetNth... starts counting at 0, so the 200'th stream
+  // is 199. BUT actually we need to do 198 because the crypto stream (Stream
+  // ID 0) has not been registered, but GetNth... assumes that it has.
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                         GetNthClientInitiatedBidirectionalId(198)));
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       DebugDFatalIfMarkingClosedStreamWriteBlocked) {
+  CompleteHandshake();
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId closed_stream_id = stream2->id();
+  // Close the stream.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
+  stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+  std::string msg =
+      absl::StrCat("Marking unknown stream ", closed_stream_id, " blocked.");
+  EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
+                  msg);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWrite) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  InSequence s;
+
+  // Reregister, to test the loop limit.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  // 2 will get called a second time as it didn't finish its block
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  // 4 will not get called, as we exceeded the loop limit.
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, TooLargeStreamBlocked) {
+  // STREAMS_BLOCKED frame is IETF QUIC only.
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  CompleteHandshake();
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Simualte the situation where the incoming stream count is at its limit and
+  // the peer is blocked.
+  QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
+      static_cast<QuicSession*>(&session_), QuicUtils::GetMaxStreamCount());
+  QuicStreamsBlockedFrame frame;
+  frame.stream_count = QuicUtils::GetMaxStreamCount();
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(_));
+  session_.OnStreamsBlockedFrame(frame);
+}
+
+TEST_P(QuicSpdySessionTestServer, TestBatchedWrites) {
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.set_writev_consumes_all_data(true);
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // With two sessions blocked, we should get two write calls.  They should both
+  // go to the first stream as it will only write 6k and mark itself blocked
+  // again.
+  InSequence s;
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+
+  // We should get one more call for stream2, at which point it has used its
+  // write quota and we move over to stream 4.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  session_.OnCanWrite();
+
+  // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
+  // priority stream 6.  4 should be preempted.  6 will write but *not* block so
+  // will cede back to 4.
+  stream6->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_CALL(*stream4, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendLargeFakeData(stream4, 6000);
+        session_.MarkConnectionLevelWriteBlocked(stream4->id());
+        session_.MarkConnectionLevelWriteBlocked(stream6->id());
+      }));
+  EXPECT_CALL(*stream6, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendStreamData(stream6);
+        session_.SendLargeFakeData(stream4, 6000);
+      }));
+  session_.OnCanWrite();
+
+  // Stream4 alread did 6k worth of writes, so after doing another 12k it should
+  // cede and 2 should resume.
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 12000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteBundlesStreams) {
+  // Encryption needs to be established before data can be sent.
+  CompleteHandshake();
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm, GetCongestionWindow())
+      .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
+  EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+
+  // Expect that we only send one packet, the writes from different streams
+  // should be bundled together.
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteCongestionControlBlocks) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*send_algorithm, GetCongestionWindow()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  // stream4->OnCanWrite is not called.
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Still congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // stream4->OnCanWrite is called once the connection stops being
+  // congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteWriterBlocks) {
+  CompleteHandshake();
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Drive packet writer manually.
+  EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)).Times(0);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, BufferedHandshake) {
+  // This tests prioritization of the crypto stream when flow control limits are
+  // reached. When CRYPTO frames are in use, there is no flow control for the
+  // crypto handshake, so this test is irrelevant.
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    return;
+  }
+  session_.set_writev_consumes_all_data(true);
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Default value.
+
+  // Test that blocking other streams does not change our status.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream3->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  // Blocking (due to buffering of) the Crypto stream is detected.
+  session_.MarkConnectionLevelWriteBlocked(
+      QuicUtils::GetCryptoStreamId(transport_version()));
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  InSequence s;
+  // Force most streams to re-register, which is common scenario when we block
+  // the Crypto stream, and only the crypto stream can "really" write.
+
+  // Due to prioritization, we *should* be asked to write the crypto stream
+  // first.
+  // Don't re-register the crypto stream (which signals complete writing).
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_CALL(*crypto_stream, OnCanWrite());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
+    session_.SendStreamData(stream3);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Crypto stream wrote.
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  CloseStream(stream6->id());
+
+  InSequence s;
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
+  CompleteHandshake();
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Ensure connection level flow control blockage.
+  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
+  EXPECT_TRUE(session_.flow_controller()->IsBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+
+  // Mark the crypto and headers streams as write blocked, we expect them to be
+  // allowed to write later.
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    session_.MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetCryptoStreamId(transport_version()));
+  }
+
+  // Create a data stream, and although it is write blocked we never expect it
+  // to be allowed to write as we are connection level flow control blocked.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream->id());
+  EXPECT_CALL(*stream, OnCanWrite()).Times(0);
+
+  // The crypto and headers streams should be called even though we are
+  // connection flow control blocked.
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, OnCanWrite());
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    TestHeadersStream* headers_stream;
+    QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
+    headers_stream = new TestHeadersStream(&session_);
+    QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
+    session_.MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetHeadersStreamId(transport_version()));
+    EXPECT_CALL(*headers_stream, OnCanWrite());
+  }
+
+  // After the crypto and header streams perform a write, the connection will be
+  // blocked by the flow control, hence it should become application-limited.
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, SendGoAway) {
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // HTTP/3 GOAWAY has different semantic and thus has its own test.
+    return;
+  }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.goaway_sent());
+
+  const QuicStreamId kTestStreamId = 5u;
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  EXPECT_CALL(*connection_,
+              OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
+      .Times(0);
+  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
+}
+
+TEST_P(QuicSpdySessionTestServer, SendGoAwayWithoutEncryption) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // HTTP/3 GOAWAY has different semantic and thus has its own test.
+    return;
+  }
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_PEER_GOING_AWAY, "Going Away.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_FALSE(session_.goaway_sent());
+}
+
+TEST_P(QuicSpdySessionTestServer, SendHttp3GoAway) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  CompleteHandshake();
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  // Send max stream id (currently 32 bits).
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+  EXPECT_TRUE(session_.goaway_sent());
+
+  // New incoming stream is not reset.
+  const QuicStreamId kTestStreamId =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
+  EXPECT_CALL(*connection_, OnStreamReset(kTestStreamId, _)).Times(0);
+  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
+
+  // No more GOAWAY frames are sent because they could not convey new
+  // information to the client.
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+}
+
+TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayWithoutEncryption) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_PEER_GOING_AWAY, "Goaway",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+  EXPECT_FALSE(session_.goaway_sent());
+}
+
+TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterStreamIsCreated) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  CompleteHandshake();
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  const QuicStreamId kTestStreamId =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
+  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
+
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  // Send max stream id (currently 32 bits).
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+  EXPECT_TRUE(session_.goaway_sent());
+
+  // No more GOAWAY frames are sent because they could not convey new
+  // information to the client.
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+}
+
+TEST_P(QuicSpdySessionTestServer, DoNotSendGoAwayTwice) {
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // HTTP/3 GOAWAY doesn't have such restriction.
+    return;
+  }
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.goaway_sent());
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+}
+
+TEST_P(QuicSpdySessionTestServer, InvalidGoAway) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // HTTP/3 GOAWAY has different semantics and thus has its own test.
+    return;
+  }
+  QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
+                          session_.next_outgoing_bidirectional_stream_id(), "");
+  session_.OnGoAway(go_away);
+}
+
+TEST_P(QuicSpdySessionTestServer, Http3GoAwayLargerIdThanBefore) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_FALSE(session_.goaway_received());
+  PushId push_id1 = 0;
+  session_.OnHttp3GoAway(push_id1);
+  EXPECT_TRUE(session_.goaway_received());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
+          "GOAWAY received with ID 1 greater than previously received ID 0",
+          _));
+  PushId push_id2 = 1;
+  session_.OnHttp3GoAway(push_id2);
+}
+
+// Test that server session will send a connectivity probe in response to a
+// connectivity probe on the same path.
+TEST_P(QuicSpdySessionTestServer, ServerReplyToConnecitivityProbe) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicSocketAddress old_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+
+  QuicSocketAddress new_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
+
+    EXPECT_CALL(*connection_,
+                SendConnectivityProbingPacket(nullptr, new_peer_address));
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Need to explicitly do this to emulate the reception of a PathChallenge,
+    // which stores its payload for use in generating the response.
+    connection_->OnPathChallengeFrame(
+        QuicPathChallengeFrame(0, {{0, 1, 2, 3, 4, 5, 6, 7}}));
+  }
+  session_.OnPacketReceived(session_.self_address(), new_peer_address,
+                            /*is_connectivity_probe=*/true);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+}
+
+TEST_P(QuicSpdySessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
+  EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+  CompleteHandshake();
+  EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+}
+
+TEST_P(QuicSpdySessionTestServer, RstStreamBeforeHeadersDecompressed) {
+  CompleteHandshake();
+  // Send two bytes of payload.
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For version99, OnStreamReset gets called because of the STOP_SENDING,
+    // below. EXPECT the call there.
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0), _));
+  }
+
+  // In HTTP/3, Qpack stream will send data on stream reset and cause packet to
+  // be flushed.
+  if (VersionUsesHttp3(transport_version())) {
+    EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+        .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  }
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  session_.OnRstStream(rst1);
+
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
+  // one-way close.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId,
+                                      GetNthClientInitiatedBidirectionalId(0),
+                                      QUIC_ERROR_PROCESSING_STREAM);
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_ERROR_PROCESSING_STREAM));
+    session_.OnStopSendingFrame(stop_sending);
+  }
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  // Connection should remain alive.
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameFinStaticStreamId) {
+  QuicStreamId id;
+  // Initialize HTTP/3 control stream.
+  if (VersionUsesHttp3(transport_version())) {
+    id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+    char type[] = {kControlStream};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_.OnStreamFrame(data1);
+  } else {
+    id = QuicUtils::GetHeadersStreamId(transport_version());
+  }
+
+  // Send two bytes of payload.
+  QuicStreamFrame data1(id, true, 0, absl::string_view("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) {
+  QuicStreamId id;
+  QuicErrorCode expected_error;
+  std::string error_message;
+  // Initialize HTTP/3 control stream.
+  if (VersionUsesHttp3(transport_version())) {
+    id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+    char type[] = {kControlStream};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_.OnStreamFrame(data1);
+    expected_error = QUIC_HTTP_CLOSED_CRITICAL_STREAM;
+    error_message = "RESET_STREAM received for receive control stream";
+  } else {
+    id = QuicUtils::GetHeadersStreamId(transport_version());
+    expected_error = QUIC_INVALID_STREAM_ID;
+    error_message = "Attempt to reset headers stream";
+  }
+
+  // Send two bytes of payload.
+  QuicRstStreamFrame rst1(kInvalidControlFrameId, id,
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(expected_error, error_message,
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicStreamFrame data1(QuicUtils::GetInvalidStreamId(transport_version()),
+                        true, 0, absl::string_view("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnRstStreamInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          QuicUtils::GetInvalidStreamId(transport_version()),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
+  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test requires Google QUIC crypto because it assumes streams start
+    // off unblocked.
+    return;
+  }
+  // Test that if a stream is flow control blocked, then on receipt of the SHLO
+  // containing a suitable send window offset, the stream becomes unblocked.
+
+  // Ensure that Writev consumes all the data it is given (simulate no socket
+  // blocking).
+  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
+  session_.set_writev_consumes_all_data(true);
+
+  // Create a stream, and send enough data to make it flow control blocked.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  std::string body(kMinimumFlowControlSendWindow, '.');
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
+  stream2->WriteOrBufferBody(body, false);
+  EXPECT_TRUE(stream2->IsFlowControlBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Now complete the crypto handshake, resulting in an increased flow control
+  // send window.
+  CompleteHandshake();
+  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
+  // Stream is now unblocked.
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+#if !defined(OS_IOS)
+// This test is failing flakily for iOS bots.
+// http://crbug.com/425050
+// NOTE: It's not possible to use the standard MAYBE_ convention to disable
+// this test on iOS because when this test gets instantiated it ends up with
+// various names that are dependent on the parameters passed.
+TEST_P(QuicSpdySessionTestServer,
+       HandshakeUnblocksFlowControlBlockedHeadersStream) {
+  // This test depends on stream-level flow control for the crypto stream, which
+  // doesn't exist when CRYPTO frames are used.
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    return;
+  }
+
+  // This test depends on the headers stream, which does not exist when QPACK is
+  // used.
+  if (VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  // Test that if the header stream is flow control blocked, then if the SHLO
+  // contains a larger send window offset, the stream becomes unblocked.
+  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
+  session_.set_writev_consumes_all_data(true);
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(&session_);
+  EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  QuicStreamId stream_id = 5;
+  // Write until the header stream is flow control blocked.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  SpdyHeaderBlock headers;
+  SimpleRandom random;
+  while (!headers_stream->IsFlowControlBlocked() && stream_id < 2000) {
+    EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+    EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+    headers["header"] = absl::StrCat(random.RandUint64(), random.RandUint64(),
+                                     random.RandUint64());
+    session_.WriteHeadersOnHeadersStream(stream_id, headers.Clone(), true,
+                                         spdy::SpdyStreamPrecedence(0),
+                                         nullptr);
+    stream_id += IdDelta();
+  }
+  // Write once more to ensure that the headers stream has buffered data. The
+  // random headers may have exactly filled the flow control window.
+  session_.WriteHeadersOnHeadersStream(stream_id, std::move(headers), true,
+                                       spdy::SpdyStreamPrecedence(0), nullptr);
+  EXPECT_TRUE(headers_stream->HasBufferedData());
+
+  EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+  EXPECT_FALSE(session_.HasDataToWrite());
+
+  // Now complete the crypto handshake, resulting in an increased flow control
+  // send window.
+  CompleteHandshake();
+
+  // Stream is now unblocked and will no longer have buffered data.
+  EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  EXPECT_TRUE(headers_stream->HasBufferedData());
+  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
+      &session_, QuicUtils::GetHeadersStreamId(transport_version())));
+}
+#endif  // !defined(OS_IOS)
+
+TEST_P(QuicSpdySessionTestServer,
+       ConnectionFlowControlAccountingRstOutOfOrder) {
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  CompleteHandshake();
+  // Test that when we receive an out of order stream RST we correctly adjust
+  // our connection level flow control receive window.
+  // On close, the stream should mark as consumed all bytes between the highest
+  // byte consumed so far and the final byte offset from the RST frame.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  const QuicStreamOffset kByteOffset =
+      1 + kInitialSessionFlowControlWindowForTest / 2;
+
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For version99 the call to OnStreamReset happens as a result of receiving
+    // the STOP_SENDING, so set up the EXPECT there.
+    EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+    EXPECT_CALL(*connection_, SendControlFrame(_));
+  } else {
+    EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+        .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  }
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kByteOffset);
+  session_.OnRstStream(rst_frame);
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
+  // one-way close.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream->id(),
+                                      QUIC_STREAM_CANCELLED);
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*connection_,
+                OnStreamReset(stream->id(), QUIC_STREAM_CANCELLED));
+    EXPECT_CALL(*connection_, SendControlFrame(_));
+    session_.OnStopSendingFrame(stop_sending);
+  }
+
+  EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSpdySessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // IETF Quic doesn't require a minimum flow control window.
+    return;
+  }
+  // Test that receipt of an invalid (< default) stream flow control window from
+  // the peer results in the connection being torn down.
+  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
+                                                            kInvalidWindow);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSpdySessionTestServer, TooLowUnidirectionalStreamLimitHttp3) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
+  QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 2u);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          _, "new unidirectional limit 2 decreases the current limit: 3", _));
+  session_.OnConfigNegotiated();
+}
+
+// Test negotiation of custom server initial flow control window.
+TEST_P(QuicSpdySessionTestServer, CustomFlowControlWindow) {
+  QuicTagVector copt;
+  copt.push_back(kIFW7);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+  EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
+                             session_.flow_controller()));
+}
+
+TEST_P(QuicSpdySessionTestServer, WindowUpdateUnblocksHeadersStream) {
+  if (VersionUsesHttp3(transport_version())) {
+    // The test relies on headers stream, which no longer exists in IETF QUIC.
+    return;
+  }
+
+  // Test that a flow control blocked headers stream gets unblocked on recipt of
+  // a WINDOW_UPDATE frame.
+
+  // Set the headers stream to be flow control blocked.
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(&session_);
+  QuicStreamPeer::SetSendWindowOffset(headers_stream, 0);
+  EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Unblock the headers stream by supplying a WINDOW_UPDATE.
+  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId,
+                                            headers_stream->id(),
+                                            2 * kMinimumFlowControlSendWindow);
+  session_.OnWindowUpdateFrame(window_update_frame);
+  EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       TooManyUnfinishedStreamsCauseServerRejectStream) {
+  // If a buggy/malicious peer creates too many streams that are not ended
+  // with a FIN or RST then we send an RST to refuse streams for versions other
+  // than version 99. In version 99 the connection gets closed.
+  CompleteHandshake();
+  const QuicStreamId kMaxStreams = 5;
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
+                                                            kMaxStreams);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+  }
+  // GetNth assumes that both the crypto and header streams have been
+  // open, but the stream id manager, using GetFirstBidirectional... only
+  // assumes that the crypto stream is open. This means that GetNth...(0)
+  // Will return stream ID == 8 (with id ==0 for crypto and id==4 for headers).
+  // It also means that GetNth(kMax..=5) returns 28 (streams 0/1/2/3/4 are ids
+  // 8, 12, 16, 20, 24, respectively, so stream#5 is stream id 28).
+  // However, the stream ID manager does not assume stream 4 is for headers.
+  // The ID manager would assume that stream#5 is streamid 24.
+  // In order to make this all work out properly, kFinalStreamId will
+  // be set to GetNth...(kMaxStreams-1)... but only for IETF QUIC
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(kMaxStreams);
+  // Create kMaxStreams data streams, and close them all without receiving a
+  // FIN or a RST_STREAM from the client.
+  const QuicStreamId kNextId = QuicUtils::StreamIdDelta(transport_version());
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += kNextId) {
+    QuicStreamFrame data1(i, false, 0, absl::string_view("HT"));
+    session_.OnStreamFrame(data1);
+    CloseStream(i);
+  }
+  // Try and open a stream that exceeds the limit.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // On versions other than 99, opening such a stream results in a
+    // RST_STREAM.
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+    EXPECT_CALL(*connection_,
+                OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
+        .Times(1);
+  } else {
+    // On version 99 opening such a stream results in a connection close.
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INVALID_STREAM_ID,
+                        testing::MatchesRegex(
+                            "Stream id \\d+ would exceed stream count limit 5"),
+                        _));
+  }
+  // Create one more data streams to exceed limit of open stream.
+  QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) {
+  // Verify that a draining stream (which has received a FIN but not consumed
+  // it) does not count against the open quota (because it is closed from the
+  // protocol point of view).
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Simulate receiving a config. so that MAX_STREAMS/etc frames may
+    // be transmitted
+    QuicSessionPeer::set_is_configured(&session_, true);
+    // Version 99 will result in a MAX_STREAMS frame as streams are consumed
+    // (via the OnStreamFrame call) and then released (via
+    // StreamDraining). Eventually this node will believe that the peer is
+    // running low on available stream ids and then send a MAX_STREAMS frame,
+    // caught by this EXPECT_CALL.
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  }
+  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
+  const QuicStreamId kMaxStreams = 5;
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
+                                                            kMaxStreams);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+  }
+
+  // Create kMaxStreams + 1 data streams, and mark them draining.
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(kMaxStreams + 1);
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += IdDelta()) {
+    QuicStreamFrame data1(i, true, 0, absl::string_view("HT"));
+    session_.OnStreamFrame(data1);
+    EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+    session_.StreamDraining(i, /*unidirectional=*/false);
+    EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  }
+}
+
+// TODO(b/171463363): Remove.
+TEST_P(QuicSpdySessionTestServer, ReduceMaxPushId) {
+  if (GetQuicReloadableFlag(quic_ignore_max_push_id)) {
+    return;
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Use an arbitrary stream id for incoming control stream.
+  QuicStreamId stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(stream_id, false, offset, stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  SettingsFrame settings;
+  std::string settings_frame = EncodeSettings(settings);
+  QuicStreamFrame data2(stream_id, false, offset, settings_frame);
+  offset += settings_frame.length();
+
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  session_.OnStreamFrame(data2);
+
+  std::string max_push_id_frame1 = SerializeMaxPushIdFrame(/* push_id = */ 3);
+  QuicStreamFrame data3(stream_id, false, offset, max_push_id_frame1);
+  offset += max_push_id_frame1.length();
+
+  EXPECT_CALL(debug_visitor, OnMaxPushIdFrameReceived(_));
+  session_.OnStreamFrame(data3);
+
+  std::string max_push_id_frame2 = SerializeMaxPushIdFrame(/* push_id = */ 1);
+  QuicStreamFrame data4(stream_id, false, offset, max_push_id_frame2);
+
+  EXPECT_CALL(debug_visitor, OnMaxPushIdFrameReceived(_));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_INVALID_MAX_PUSH_ID,
+                              "MAX_PUSH_ID received with value 1 which is "
+                              "smaller that previously received value 3",
+                              _));
+  session_.OnStreamFrame(data4);
+}
+
+class QuicSpdySessionTestClient : public QuicSpdySessionTestBase {
+ protected:
+  QuicSpdySessionTestClient()
+      : QuicSpdySessionTestBase(Perspective::IS_CLIENT, false) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestClient,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSpdySessionTestClient, UsesPendingStreamsForFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
+      STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                        transport_version(), Perspective::IS_SERVER)));
+  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                            transport_version(), Perspective::IS_SERVER)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                            transport_version(), Perspective::IS_CLIENT)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                              transport_version(), Perspective::IS_SERVER)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
+                            transport_version(), Perspective::IS_SERVER)));
+}
+
+// Regression test for crbug.com/977581.
+TEST_P(QuicSpdySessionTestClient, BadStreamFramePendingStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  QuicStreamId stream_id1 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  // A bad stream frame with no data and no fin.
+  QuicStreamFrame data1(stream_id1, false, 0, 0);
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestClient, PendingStreamKeepsConnectionAlive) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_SERVER);
+
+  QuicStreamFrame frame(stream_id, false, 1, "test");
+  EXPECT_FALSE(session_.ShouldKeepConnectionAlive());
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_TRUE(session_.ShouldKeepConnectionAlive());
+}
+
+TEST_P(QuicSpdySessionTestClient, AvailableStreamsClient) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(2)) != nullptr);
+  // Both server initiated streams with smaller stream IDs should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(0)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(1)) != nullptr);
+  // And client initiated stream ID should be not available.
+  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(0)));
+}
+
+// Regression test for b/130740258 and https://crbug.com/971779.
+// If headers that are too large or empty are received (these cases are handled
+// the same way, as QuicHeaderList clears itself when headers exceed the limit),
+// then the stream is reset.  No more frames must be sent in this case.
+TEST_P(QuicSpdySessionTestClient, TooLargeHeadersMustNotCauseWriteAfterReset) {
+  // In IETF QUIC, HEADERS do not carry FIN flag, and OnStreamHeaderList() is
+  // never called after an error, including too large headers.
+  if (VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  // Write headers with FIN set to close write side of stream.
+  // Header block does not matter.
+  stream->WriteHeaders(SpdyHeaderBlock(), /* fin = */ true, nullptr);
+
+  // Receive headers that are too large or empty, with FIN set.
+  // This causes the stream to be reset.  No frames must be written after this.
+  QuicHeaderList headers;
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream->id(), QUIC_HEADERS_TOO_LARGE));
+  stream->OnStreamHeaderList(/* fin = */ true,
+                             headers.uncompressed_header_bytes(), headers);
+}
+
+TEST_P(QuicSpdySessionTestClient, RecordFinAfterReadSideClosed) {
+  // Verify that an incoming FIN is recorded in a stream object even if the read
+  // side has been closed.  This prevents an entry from being made in
+  // locally_closed_streams_highest_offset_ (which will never be deleted).
+  CompleteHandshake();
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+
+  // Close the read side manually.
+  QuicStreamPeer::CloseReadSide(stream);
+
+  // Receive a stream data frame with FIN.
+  QuicStreamFrame frame(stream_id, true, 0, absl::string_view());
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(stream->fin_received());
+
+  // Reset stream locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+  EXPECT_TRUE(connection_->connected());
+  EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
+  EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
+
+  // The stream is not waiting for the arrival of the peer's final offset as it
+  // was received with the FIN earlier.
+  EXPECT_EQ(
+      0u,
+      QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
+}
+
+TEST_P(QuicSpdySessionTestClient, WritePriority) {
+  if (VersionUsesHttp3(transport_version())) {
+    // IETF QUIC currently doesn't support PRIORITY.
+    return;
+  }
+  CompleteHandshake();
+
+  TestHeadersStream* headers_stream;
+  QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
+  headers_stream = new TestHeadersStream(&session_);
+  QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
+
+  // Make packet writer blocked so |headers_stream| will buffer its write data.
+  EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
+
+  const QuicStreamId id = 4;
+  const QuicStreamId parent_stream_id = 9;
+  const SpdyPriority priority = kV3HighestPriority;
+  const bool exclusive = true;
+  session_.WritePriority(id, parent_stream_id,
+                         Spdy3PriorityToHttp2Weight(priority), exclusive);
+
+  QuicStreamSendBuffer& send_buffer =
+      QuicStreamPeer::SendBuffer(headers_stream);
+  ASSERT_EQ(1u, send_buffer.size());
+
+  SpdyPriorityIR priority_frame(
+      id, parent_stream_id, Spdy3PriorityToHttp2Weight(priority), exclusive);
+  SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
+  SpdySerializedFrame frame = spdy_framer.SerializeFrame(priority_frame);
+
+  const quiche::QuicheMemSlice& slice =
+      QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
+  EXPECT_EQ(absl::string_view(frame.data(), frame.size()),
+            absl::string_view(slice.data(), slice.length()));
+}
+
+TEST_P(QuicSpdySessionTestClient, Http3ServerPush) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  // Push unidirectional stream is type 0x01.
+  std::string frame_type1 = absl::HexStringToBytes("01");
+  QuicStreamId stream_id1 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
+      .Times(1);
+  session_.OnStreamFrame(QuicStreamFrame(stream_id1, /* fin = */ false,
+                                         /* offset = */ 0, frame_type1));
+}
+
+TEST_P(QuicSpdySessionTestClient, Http3ServerPushOutofOrderFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  // Push unidirectional stream is type 0x01.
+  std::string frame_type = absl::HexStringToBytes("01");
+  // The first field of a push stream is the Push ID.
+  std::string push_id = absl::HexStringToBytes("4000");
+
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+
+  QuicStreamFrame data1(stream_id,
+                        /* fin = */ false, /* offset = */ 0, frame_type);
+  QuicStreamFrame data2(stream_id,
+                        /* fin = */ false, /* offset = */ frame_type.size(),
+                        push_id);
+
+  // Receiving some stream data without stream type does not open the stream.
+  session_.OnStreamFrame(data2);
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
+      .Times(1);
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) {
+  CompleteHandshake();
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame2(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream4->id(), false, 0, 9);
+
+  // Lost data on cryption stream, streams 2 and 4.
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(true));
+  }
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    QuicStreamFrame frame1(QuicUtils::GetCryptoStreamId(transport_version()),
+                           false, 0, 1300);
+    session_.OnFrameLost(QuicFrame(frame1));
+  } else {
+    QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
+    session_.OnFrameLost(QuicFrame(&crypto_frame));
+  }
+  session_.OnFrameLost(QuicFrame(frame2));
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Mark streams 2 and 4 write blocked.
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // Lost data is retransmitted before new data, and retransmissions for crypto
+  // stream go first.
+  // Do not check congestion window when crypto stream has lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    EXPECT_CALL(*crypto_stream, OnCanWrite());
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(false));
+  }
+  // Check congestion window for non crypto streams.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
+  // Connection is blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Unblock connection.
+  // Stream 2 retransmits lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  // Stream 2 sends new data.
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) {
+  // Resetting a stream will send a QPACK Stream Cancellation instruction on the
+  // decoder stream.  For simplicity, ignore writes on this stream.
+  CompleteHandshake();
+  NoopQpackStreamSenderDelegate qpack_stream_sender_delegate;
+  if (VersionUsesHttp3(transport_version())) {
+    session_.qpack_decoder()->set_qpack_stream_sender_delegate(
+        &qpack_stream_sender_delegate);
+  }
+
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  session_.OnFrameLost(QuicFrame(frame2));
+  session_.OnFrameLost(QuicFrame(frame1));
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+  // Reset stream 4 locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
+  stream4->Reset(QUIC_STREAM_CANCELLED);
+
+  // Verify stream 4 is removed from streams with lost data list.
+  EXPECT_CALL(*stream6, OnCanWrite());
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream6, OnCanWrite());
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSpdySessionTestServer, RetransmitFrames) {
+  CompleteHandshake();
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  session_.SendWindowUpdate(stream2->id(), 9);
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+  QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1));
+  frames.push_back(QuicFrame(window_update));
+  frames.push_back(QuicFrame(frame2));
+  frames.push_back(QuicFrame(frame3));
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+
+  EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnPriorityFrame) {
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  TestStream* stream = session_.CreateIncomingStream(stream_id);
+  session_.OnPriorityFrame(stream_id,
+                           spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
+            stream->precedence());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnPriorityUpdateFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Create control stream.
+  QuicStreamId receive_control_stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(receive_control_stream_id, false, offset, stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor,
+              OnPeerControlStreamCreated(receive_control_stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(receive_control_stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  // Send SETTINGS frame.
+  std::string serialized_settings = EncodeSettings({});
+  QuicStreamFrame data2(receive_control_stream_id, false, offset,
+                        serialized_settings);
+  offset += serialized_settings.length();
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+  session_.OnStreamFrame(data2);
+
+  // PRIORITY_UPDATE frame for first request stream.
+  const QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  struct PriorityUpdateFrame priority_update1;
+  priority_update1.prioritized_element_type = REQUEST_STREAM;
+  priority_update1.prioritized_element_id = stream_id1;
+  priority_update1.priority_field_value = "u=2";
+  std::string serialized_priority_update1 =
+      SerializePriorityUpdateFrame(priority_update1);
+  QuicStreamFrame data3(receive_control_stream_id,
+                        /* fin = */ false, offset, serialized_priority_update1);
+  offset += serialized_priority_update1.size();
+
+  // PRIORITY_UPDATE frame arrives after stream creation.
+  TestStream* stream1 = session_.CreateIncomingStream(stream_id1);
+  EXPECT_EQ(QuicStream::kDefaultUrgency,
+            stream1->precedence().spdy3_priority());
+  EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update1));
+  session_.OnStreamFrame(data3);
+  EXPECT_EQ(2u, stream1->precedence().spdy3_priority());
+
+  // PRIORITY_UPDATE frame for second request stream.
+  const QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
+  struct PriorityUpdateFrame priority_update2;
+  priority_update2.prioritized_element_type = REQUEST_STREAM;
+  priority_update2.prioritized_element_id = stream_id2;
+  priority_update2.priority_field_value = "u=2";
+  std::string serialized_priority_update2 =
+      SerializePriorityUpdateFrame(priority_update2);
+  QuicStreamFrame stream_frame3(receive_control_stream_id,
+                                /* fin = */ false, offset,
+                                serialized_priority_update2);
+
+  // PRIORITY_UPDATE frame arrives before stream creation,
+  // priority value is buffered.
+  EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update2));
+  session_.OnStreamFrame(stream_frame3);
+  // Priority is applied upon stream construction.
+  TestStream* stream2 = session_.CreateIncomingStream(stream_id2);
+  EXPECT_EQ(2u, stream2->precedence().spdy3_priority());
+}
+
+TEST_P(QuicSpdySessionTestServer, SimplePendingStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  char input[] = {0x04,            // type
+                  'a', 'b', 'c'};  // data
+  absl::string_view payload(input, ABSL_ARRAYSIZE(input));
+
+  // This is a server test with a client-initiated unidirectional stream.
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+
+  for (bool fin : {true, false}) {
+    QuicStreamFrame frame(stream_id, fin, /* offset = */ 0, payload);
+
+    // A STOP_SENDING frame is sent in response to the unknown stream type.
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke([stream_id](const QuicFrame& frame) {
+          EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
+
+          const QuicStopSendingFrame& stop_sending = frame.stop_sending_frame;
+          EXPECT_EQ(stream_id, stop_sending.stream_id);
+          EXPECT_EQ(QUIC_STREAM_STREAM_CREATION_ERROR, stop_sending.error_code);
+          EXPECT_EQ(
+              static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
+              stop_sending.ietf_error_code);
+
+          return ClearControlFrame(frame);
+        }));
+    session_.OnStreamFrame(frame);
+
+    PendingStream* pending =
+        QuicSessionPeer::GetPendingStream(&session_, stream_id);
+    if (fin) {
+      // Stream is closed if FIN is received.
+      EXPECT_FALSE(pending);
+    } else {
+      ASSERT_TRUE(pending);
+      // The pending stream must ignore read data.
+      EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+    }
+
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, SimplePendingStreamTypeOutOfOrderDelivery) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  char input[] = {0x04,            // type
+                  'a', 'b', 'c'};  // data
+  absl::string_view payload(input, ABSL_ARRAYSIZE(input));
+
+  // This is a server test with a client-initiated unidirectional stream.
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+
+  for (bool fin : {true, false}) {
+    QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
+                           payload.substr(0, 1));
+    QuicStreamFrame frame2(stream_id, fin, /* offset = */ 1, payload.substr(1));
+
+    // Deliver frames out of order.
+    session_.OnStreamFrame(frame2);
+    // A STOP_SENDING frame is sent in response to the unknown stream type.
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
+    session_.OnStreamFrame(frame1);
+
+    PendingStream* pending =
+        QuicSessionPeer::GetPendingStream(&session_, stream_id);
+    if (fin) {
+      // Stream is closed if FIN is received.
+      EXPECT_FALSE(pending);
+    } else {
+      ASSERT_TRUE(pending);
+      // The pending stream must ignore read data.
+      EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+    }
+
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       MultipleBytesPendingStreamTypeOutOfOrderDelivery) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  char input[] = {0x41, 0x00,      // type (256)
+                  'a', 'b', 'c'};  // data
+  absl::string_view payload(input, ABSL_ARRAYSIZE(input));
+
+  // This is a server test with a client-initiated unidirectional stream.
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+
+  for (bool fin : {true, false}) {
+    QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
+                           payload.substr(0, 1));
+    QuicStreamFrame frame2(stream_id, /* fin = */ false, /* offset = */ 1,
+                           payload.substr(1, 1));
+    QuicStreamFrame frame3(stream_id, fin, /* offset = */ 2, payload.substr(2));
+
+    // Deliver frames out of order.
+    session_.OnStreamFrame(frame3);
+    // The first byte does not contain the entire type varint.
+    session_.OnStreamFrame(frame1);
+    // A STOP_SENDING frame is sent in response to the unknown stream type.
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
+    session_.OnStreamFrame(frame2);
+
+    PendingStream* pending =
+        QuicSessionPeer::GetPendingStream(&session_, stream_id);
+    if (fin) {
+      // Stream is closed if FIN is received.
+      EXPECT_FALSE(pending);
+    } else {
+      ASSERT_TRUE(pending);
+      // The pending stream must ignore read data.
+      EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+    }
+
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, ReceiveControlStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  CompleteHandshake();
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Use an arbitrary stream id.
+  QuicStreamId stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+
+  QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1));
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 512;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 42;
+  std::string data = EncodeSettings(settings);
+  QuicStreamFrame frame(stream_id, false, 1, absl::string_view(data));
+
+  QpackEncoder* qpack_encoder = session_.qpack_encoder();
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(qpack_encoder);
+
+  EXPECT_NE(512u, header_table->maximum_dynamic_table_capacity());
+  EXPECT_NE(5u, session_.max_outbound_header_list_size());
+  EXPECT_NE(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  session_.OnStreamFrame(frame);
+
+  EXPECT_EQ(512u, header_table->maximum_dynamic_table_capacity());
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+  EXPECT_EQ(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+}
+
+TEST_P(QuicSpdySessionTestServer, ReceiveControlStreamOutOfOrderDelivery) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  // Use an arbitrary stream id.
+  QuicStreamId stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  SettingsFrame settings;
+  settings.values[10] = 2;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  std::string data = EncodeSettings(settings);
+
+  QuicStreamFrame data1(stream_id, false, 1, absl::string_view(data));
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view(type, 1));
+
+  session_.OnStreamFrame(data1);
+  EXPECT_NE(5u, session_.max_outbound_header_list_size());
+  session_.OnStreamFrame(data2);
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+}
+
+// Regression test for https://crbug.com/1009551.
+TEST_P(QuicSpdySessionTestServer, StreamClosedWhileHeaderDecodingBlocked) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  session_.qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  TestStream* stream = session_.CreateIncomingStream(stream_id);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string headers_payload = absl::HexStringToBytes("020080");
+  std::unique_ptr<char[]> headers_buffer;
+  QuicByteCount headers_frame_header_length =
+      HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
+                                               &headers_buffer);
+  absl::string_view headers_frame_header(headers_buffer.get(),
+                                         headers_frame_header_length);
+  std::string headers = absl::StrCat(headers_frame_header, headers_payload);
+  stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream->headers_decompressed());
+
+  // Stream is closed and destroyed.
+  CloseStream(stream_id);
+  session_.CleanUpClosedStreams();
+
+  // Dynamic table entry arrived on the decoder stream.
+  // The destroyed stream object must not be referenced.
+  session_.qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+}
+
+// Regression test for https://crbug.com/1011294.
+TEST_P(QuicSpdySessionTestServer, SessionDestroyedWhileHeaderDecodingBlocked) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  TestStream* stream = session_.CreateIncomingStream(stream_id);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string headers_payload = absl::HexStringToBytes("020080");
+  std::unique_ptr<char[]> headers_buffer;
+  QuicByteCount headers_frame_header_length =
+      HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
+                                               &headers_buffer);
+  absl::string_view headers_frame_header(headers_buffer.get(),
+                                         headers_frame_header_length);
+  std::string headers = absl::StrCat(headers_frame_header, headers_payload);
+  stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream->headers_decompressed());
+
+  // |session_| gets destoyed.  That destroys QpackDecoder, a member of
+  // QuicSpdySession (derived class), which destroys QpackDecoderHeaderTable.
+  // Then |*stream|, owned by QuicSession (base class) get destroyed, which
+  // destroys QpackProgessiveDecoder, a registered Observer of
+  // QpackDecoderHeaderTable.  This must not cause a crash.
+}
+
+TEST_P(QuicSpdySessionTestClient, ResetAfterInvalidIncomingStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+
+  const QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
+
+  // Payload consists of two bytes.  The first byte is an unknown unidirectional
+  // stream type.  The second one would be the type of a push stream, but it
+  // must not be interpreted as stream type.
+  std::string payload = absl::HexStringToBytes("3f01");
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
+                        payload);
+
+  // A STOP_SENDING frame is sent in response to the unknown stream type.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
+  session_.OnStreamFrame(frame);
+
+  // There are no active streams.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  // The pending stream is still around, because it did not receive a FIN.
+  PendingStream* pending =
+      QuicSessionPeer::GetPendingStream(&session_, stream_id);
+  ASSERT_TRUE(pending);
+
+  // The pending stream must ignore read data.
+  EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+
+  // If the stream frame is received again, it should be ignored.
+  session_.OnStreamFrame(frame);
+
+  // Receive RESET_STREAM.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
+                               QUIC_STREAM_CANCELLED,
+                               /* bytes_written = */ payload.size());
+
+  session_.OnRstStream(rst_frame);
+
+  // The stream is closed.
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+}
+
+TEST_P(QuicSpdySessionTestClient, FinAfterInvalidIncomingStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+
+  const QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
+
+  // Payload consists of two bytes.  The first byte is an unknown unidirectional
+  // stream type.  The second one would be the type of a push stream, but it
+  // must not be interpreted as stream type.
+  std::string payload = absl::HexStringToBytes("3f01");
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
+                        payload);
+
+  // A STOP_SENDING frame is sent in response to the unknown stream type.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
+  session_.OnStreamFrame(frame);
+
+  // The pending stream is still around, because it did not receive a FIN.
+  PendingStream* pending =
+      QuicSessionPeer::GetPendingStream(&session_, stream_id);
+  EXPECT_TRUE(pending);
+
+  // The pending stream must ignore read data.
+  EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+
+  // If the stream frame is received again, it should be ignored.
+  session_.OnStreamFrame(frame);
+
+  // Receive FIN.
+  session_.OnStreamFrame(QuicStreamFrame(stream_id, /* fin = */ true,
+                                         /* offset = */ payload.size(), ""));
+
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+}
+
+TEST_P(QuicSpdySessionTestClient, ResetInMiddleOfStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  const QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
+
+  // Payload is the first byte of a two byte varint encoding.
+  std::string payload = absl::HexStringToBytes("40");
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
+                        payload);
+
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+
+  // Receive RESET_STREAM.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
+                               QUIC_STREAM_CANCELLED,
+                               /* bytes_written = */ payload.size());
+
+  session_.OnRstStream(rst_frame);
+
+  // The stream is closed.
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+}
+
+TEST_P(QuicSpdySessionTestClient, FinInMiddleOfStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  const QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
+
+  // Payload is the first byte of a two byte varint encoding with a FIN.
+  std::string payload = absl::HexStringToBytes("40");
+  QuicStreamFrame frame(stream_id, /* fin = */ true, /* offset = */ 0, payload);
+
+  session_.OnStreamFrame(frame);
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+}
+
+TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  QuicStreamId id1 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  char type1[] = {kControlStream};
+
+  QuicStreamFrame data1(id1, false, 0, absl::string_view(type1, 1));
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id1));
+  session_.OnStreamFrame(data1);
+  QuicStreamId id2 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 1);
+  QuicStreamFrame data2(id2, false, 0, absl::string_view(type1, 1));
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id2)).Times(0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+                              "Control stream is received twice.", _));
+  EXPECT_QUIC_PEER_BUG(
+      session_.OnStreamFrame(data2),
+      "Received a duplicate Control stream: Closing connection.");
+
+  QuicStreamId id3 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 2);
+  char type2[]{kQpackEncoderStream};
+
+  QuicStreamFrame data3(id3, false, 0, absl::string_view(type2, 1));
+  EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id3));
+  session_.OnStreamFrame(data3);
+
+  QuicStreamId id4 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame data4(id4, false, 0, absl::string_view(type2, 1));
+  EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id4)).Times(0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+                              "QPACK encoder stream is received twice.", _));
+  EXPECT_QUIC_PEER_BUG(
+      session_.OnStreamFrame(data4),
+      "Received a duplicate QPACK encoder stream: Closing connection.");
+
+  QuicStreamId id5 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 4);
+  char type3[]{kQpackDecoderStream};
+
+  QuicStreamFrame data5(id5, false, 0, absl::string_view(type3, 1));
+  EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id5));
+  session_.OnStreamFrame(data5);
+
+  QuicStreamId id6 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 5);
+  QuicStreamFrame data6(id6, false, 0, absl::string_view(type3, 1));
+  EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id6)).Times(0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+                              "QPACK decoder stream is received twice.", _));
+  EXPECT_QUIC_PEER_BUG(
+      session_.OnStreamFrame(data6),
+      "Received a duplicate QPACK decoder stream: Closing connection.");
+}
+
+TEST_P(QuicSpdySessionTestClient, EncoderStreamError) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string data = absl::HexStringToBytes(
+      "02"    // Encoder stream.
+      "00");  // Duplicate entry 0, but no entries exist.
+
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
+                  "Encoder stream error: Invalid relative index.", _));
+  session_.OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdySessionTestClient, DecoderStreamError) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string data = absl::HexStringToBytes(
+      "03"    // Decoder stream.
+      "00");  // Insert Count Increment with forbidden increment value of zero.
+
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
+                      "Decoder stream error: Invalid increment value 0.", _));
+  session_.OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdySessionTestClient, InvalidHttp3GoAway) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
+                              "GOAWAY with invalid stream ID", _));
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  session_.OnHttp3GoAway(stream_id);
+}
+
+TEST_P(QuicSpdySessionTestClient, Http3GoAwayLargerIdThanBefore) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_FALSE(session_.goaway_received());
+  QuicStreamId stream_id1 =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
+  session_.OnHttp3GoAway(stream_id1);
+  EXPECT_TRUE(session_.goaway_received());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
+          "GOAWAY received with ID 4 greater than previously received ID 0",
+          _));
+  QuicStreamId stream_id2 =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
+  session_.OnHttp3GoAway(stream_id2);
+}
+
+TEST_P(QuicSpdySessionTestClient, CloseConnectionOnCancelPush) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Create control stream.
+  QuicStreamId receive_control_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
+                        stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor,
+              OnPeerControlStreamCreated(receive_control_stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(receive_control_stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  // First frame has to be SETTINGS.
+  std::string serialized_settings = EncodeSettings({});
+  QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
+                        serialized_settings);
+  offset += serialized_settings.length();
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+  session_.OnStreamFrame(data2);
+
+  std::string cancel_push_frame = absl::HexStringToBytes(
+      "03"    // CANCEL_PUSH
+      "01"    // length
+      "00");  // push ID
+  QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
+                        cancel_push_frame);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
+                                            "CANCEL_PUSH frame received.", _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_,
+              SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
+                                        "CANCEL_PUSH frame received."));
+  session_.OnStreamFrame(data3);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnSetting) {
+  CompleteHandshake();
+  if (VersionUsesHttp3(transport_version())) {
+    EXPECT_EQ(std::numeric_limits<size_t>::max(),
+              session_.max_outbound_header_list_size());
+    session_.OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
+    EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+
+    EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+        .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
+    QpackEncoder* qpack_encoder = session_.qpack_encoder();
+    EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+    session_.OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 12);
+    EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+
+    QpackEncoderHeaderTable* header_table =
+        QpackEncoderPeer::header_table(qpack_encoder);
+    EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
+    session_.OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 37);
+    EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity());
+
+    return;
+  }
+
+  EXPECT_EQ(std::numeric_limits<size_t>::max(),
+            session_.max_outbound_header_list_size());
+  session_.OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+
+  spdy::HpackEncoder* hpack_encoder =
+      QuicSpdySessionPeer::GetSpdyFramer(&session_)->GetHpackEncoder();
+  EXPECT_EQ(4096u, hpack_encoder->CurrentHeaderTableSizeSetting());
+  session_.OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 59);
+  EXPECT_EQ(59u, hpack_encoder->CurrentHeaderTableSizeSetting());
+}
+
+TEST_P(QuicSpdySessionTestServer, FineGrainedHpackErrorCodes) {
+  if (VersionUsesHttp3(transport_version())) {
+    // HPACK is not used in HTTP/3.
+    return;
+  }
+
+  QuicStreamId request_stream_id = 5;
+  session_.CreateIncomingStream(request_stream_id);
+
+  // Index 126 does not exist (static table has 61 entries and dynamic table is
+  // empty).
+  std::string headers_frame = absl::HexStringToBytes(
+      "000006"    // length
+      "01"        // type
+      "24"        // flags: PRIORITY | END_HEADERS
+      "00000005"  // stream_id
+      "00000000"  // stream dependency
+      "10"        // weight
+      "fe");      // payload: reference to index 126.
+  QuicStreamId headers_stream_id =
+      QuicUtils::GetHeadersStreamId(transport_version());
+  QuicStreamFrame data(headers_stream_id, false, 0, headers_frame);
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HPACK_INVALID_INDEX,
+                      "SPDY framing error: HPACK_INVALID_INDEX",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data);
+}
+
+TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalReceiveStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  struct {
+    char type;
+    const char* error_details;
+  } kTestData[] = {
+      {kControlStream, "RESET_STREAM received for receive control stream"},
+      {kQpackEncoderStream, "RESET_STREAM received for QPACK receive stream"},
+      {kQpackDecoderStream, "RESET_STREAM received for QPACK receive stream"},
+  };
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
+    QuicStreamId stream_id =
+        GetNthClientInitiatedUnidirectionalStreamId(transport_version(), i + 1);
+    const QuicByteCount data_length = 1;
+    QuicStreamFrame data(stream_id, false, 0,
+                         absl::string_view(&kTestData[i].type, data_length));
+    session_.OnStreamFrame(data);
+
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+                                              kTestData[i].error_details, _));
+
+    QuicRstStreamFrame rst(kInvalidControlFrameId, stream_id,
+                           QUIC_STREAM_CANCELLED, data_length);
+    session_.OnRstStream(rst);
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       H3ControlStreamsLimitedByConnectionFlowControl) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  // Ensure connection level flow control blockage.
+  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+
+  QuicSendControlStream* send_control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(&session_);
+  // Mark send_control stream write blocked.
+  session_.MarkConnectionLevelWriteBlocked(send_control_stream->id());
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalSendStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  QuicSendControlStream* control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(&session_);
+  ASSERT_TRUE(control_stream);
+
+  QuicStopSendingFrame stop_sending_control_stream(
+      kInvalidControlFrameId, control_stream->id(), QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+                      "STOP_SENDING received for send control stream", _));
+  session_.OnStopSendingFrame(stop_sending_control_stream);
+
+  QpackSendStream* decoder_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
+  ASSERT_TRUE(decoder_stream);
+
+  QuicStopSendingFrame stop_sending_decoder_stream(
+      kInvalidControlFrameId, decoder_stream->id(), QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+                      "STOP_SENDING received for QPACK send stream", _));
+  session_.OnStopSendingFrame(stop_sending_decoder_stream);
+
+  QpackSendStream* encoder_stream =
+      QuicSpdySessionPeer::GetQpackEncoderSendStream(&session_);
+  ASSERT_TRUE(encoder_stream);
+
+  QuicStopSendingFrame stop_sending_encoder_stream(
+      kInvalidControlFrameId, encoder_stream->id(), QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+                      "STOP_SENDING received for QPACK send stream", _));
+  session_.OnStopSendingFrame(stop_sending_encoder_stream);
+}
+
+TEST_P(QuicSpdySessionTestServer, CloseConnectionOnCancelPush) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Create control stream.
+  QuicStreamId receive_control_stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
+                        stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor,
+              OnPeerControlStreamCreated(receive_control_stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(receive_control_stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  // First frame has to be SETTINGS.
+  std::string serialized_settings = EncodeSettings({});
+  QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
+                        serialized_settings);
+  offset += serialized_settings.length();
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+  session_.OnStreamFrame(data2);
+
+  std::string cancel_push_frame = absl::HexStringToBytes(
+      "03"    // CANCEL_PUSH
+      "01"    // length
+      "00");  // push ID
+  QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
+                        cancel_push_frame);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
+                                            "CANCEL_PUSH frame received.", _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_,
+              SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
+                                        "CANCEL_PUSH frame received."));
+  session_.OnStreamFrame(data3);
+}
+
+TEST_P(QuicSpdySessionTestServer, Http3GoAwayWhenClosingConnection) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+  CompleteHandshake();
+
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+
+  // Create stream by receiving some data (CreateIncomingStream() would not
+  // update the session's largest peer created stream ID).
+  const size_t headers_payload_length = 10;
+  std::unique_ptr<char[]> headers_buffer;
+  QuicByteCount headers_frame_header_length =
+      HttpEncoder::SerializeHeadersFrameHeader(headers_payload_length,
+                                               &headers_buffer);
+  absl::string_view headers_frame_header(headers_buffer.get(),
+                                         headers_frame_header_length);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_id, headers_payload_length));
+  session_.OnStreamFrame(
+      QuicStreamFrame(stream_id, false, 0, headers_frame_header));
+
+  EXPECT_EQ(stream_id, QuicSessionPeer::GetLargestPeerCreatedStreamId(
+                           &session_, /*unidirectional = */ false));
+
+  // Stream with stream_id is already received and potentially processed,
+  // therefore a GOAWAY frame is sent with the next stream ID.
+  EXPECT_CALL(debug_visitor,
+              OnGoAwayFrameSent(stream_id +
+                                QuicUtils::StreamIdDelta(transport_version())));
+
+  // Close connection.
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_NO_ERROR, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(QUIC_NO_ERROR, _, _))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::ReallySendConnectionClosePacket));
+  connection_->CloseConnection(
+      QUIC_NO_ERROR, "closing connection",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+TEST_P(QuicSpdySessionTestClient, DoNotSendInitialMaxPushIdIfNotSet) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  InSequence s;
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+
+  CompleteHandshake();
+}
+
+TEST_P(QuicSpdySessionTestClient, ReceiveSpdySettingInHttp3) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  SettingsFrame frame;
+  frame.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  // https://datatracker.ietf.org/doc/html/draft-ietf-quic-http-30#section-7.2.4.1
+  // specifies the presence of HTTP/2 setting as error.
+  frame.values[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 100;
+
+  CompleteHandshake();
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_RECEIVE_SPDY_SETTING, _, _));
+  session_.OnSettingsFrame(frame);
+}
+
+TEST_P(QuicSpdySessionTestClient, ReceiveAcceptChFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Create control stream.
+  QuicStreamId receive_control_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
+                        stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor,
+              OnPeerControlStreamCreated(receive_control_stream_id));
+
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(receive_control_stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  // First frame has to be SETTINGS.
+  std::string serialized_settings = EncodeSettings({});
+  QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
+                        serialized_settings);
+  offset += serialized_settings.length();
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+
+  session_.OnStreamFrame(data2);
+
+  // Receive ACCEPT_CH frame.
+  AcceptChFrame accept_ch;
+  accept_ch.entries.push_back({"foo", "bar"});
+  std::unique_ptr<char[]> buffer;
+  auto frame_length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
+  QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
+                        absl::string_view(buffer.get(), frame_length));
+
+  EXPECT_CALL(debug_visitor, OnAcceptChFrameReceived(accept_ch));
+  EXPECT_CALL(session_, OnAcceptChFrame(accept_ch));
+
+  session_.OnStreamFrame(data3);
+}
+
+TEST_P(QuicSpdySessionTestClient, AcceptChViaAlps) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  std::string serialized_accept_ch_frame = absl::HexStringToBytes(
+      "4089"      // type (ACCEPT_CH)
+      "08"        // length
+      "03"        // length of origin
+      "666f6f"    // origin "foo"
+      "03"        // length of value
+      "626172");  // value "bar"
+
+  AcceptChFrame expected_accept_ch_frame{{{"foo", "bar"}}};
+  EXPECT_CALL(debug_visitor,
+              OnAcceptChFrameReceivedViaAlps(expected_accept_ch_frame));
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(serialized_accept_ch_frame.data()),
+      serialized_accept_ch_frame.size());
+  EXPECT_FALSE(error);
+}
+
+TEST_P(QuicSpdySessionTestClient, AlpsForbiddenFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string forbidden_frame = absl::HexStringToBytes(
+      "00"        // type (DATA)
+      "03"        // length
+      "66666f");  // "foo"
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(forbidden_frame.data()),
+      forbidden_frame.size());
+  ASSERT_TRUE(error);
+  EXPECT_EQ("DATA frame forbidden", error.value());
+}
+
+TEST_P(QuicSpdySessionTestClient, AlpsIncompleteFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string incomplete_frame = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "03");  // non-zero length but empty payload
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(incomplete_frame.data()),
+      incomplete_frame.size());
+  ASSERT_TRUE(error);
+  EXPECT_EQ("incomplete HTTP/3 frame", error.value());
+}
+
+// After receiving a SETTINGS frame via ALPS,
+// another SETTINGS frame is still allowed on control frame.
+TEST_P(QuicSpdySessionTestClient, SettingsViaAlpsThenOnControlStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  QpackEncoder* qpack_encoder = session_.qpack_encoder();
+  EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
+  EXPECT_EQ(0u, qpack_encoder->maximum_blocked_streams());
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  std::string serialized_settings_frame1 = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "05"    // length
+      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "4400"  // 0x0400 = 1024
+      "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
+      "20");  // 0x20 = 32
+
+  SettingsFrame expected_settings_frame1{
+      {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
+       {SETTINGS_QPACK_BLOCKED_STREAMS, 32}}};
+  EXPECT_CALL(debug_visitor,
+              OnSettingsFrameReceivedViaAlps(expected_settings_frame1));
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
+      serialized_settings_frame1.size());
+  EXPECT_FALSE(error);
+
+  EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
+  EXPECT_EQ(32u, qpack_encoder->maximum_blocked_streams());
+
+  const QuicStreamId control_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(control_stream_id));
+
+  std::string stream_type = absl::HexStringToBytes("00");
+  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
+                                         /* offset = */ 0, stream_type));
+
+  // SETTINGS_QPACK_MAX_TABLE_CAPACITY, if advertised again, MUST have identical
+  // value.
+  // SETTINGS_QPACK_BLOCKED_STREAMS is a limit.  Limits MUST NOT be reduced, but
+  // increasing is okay.
+  SettingsFrame expected_settings_frame2{
+      {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
+       {SETTINGS_QPACK_BLOCKED_STREAMS, 48}}};
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(expected_settings_frame2));
+  std::string serialized_settings_frame2 = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "05"    // length
+      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "4400"  // 0x0400 = 1024
+      "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
+      "30");  // 0x30 = 48
+  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
+                                         /* offset = */ stream_type.length(),
+                                         serialized_settings_frame2));
+
+  EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
+  EXPECT_EQ(48u, qpack_encoder->maximum_blocked_streams());
+}
+
+// A SETTINGS frame received via ALPS and another one on the control stream
+// cannot have conflicting values.
+TEST_P(QuicSpdySessionTestClient,
+       SettingsViaAlpsConflictsSettingsViaControlStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  QpackEncoder* qpack_encoder = session_.qpack_encoder();
+  EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
+
+  std::string serialized_settings_frame1 = absl::HexStringToBytes(
+      "04"      // type (SETTINGS)
+      "03"      // length
+      "01"      // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "4400");  // 0x0400 = 1024
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
+      serialized_settings_frame1.size());
+  EXPECT_FALSE(error);
+
+  EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
+
+  const QuicStreamId control_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+
+  std::string stream_type = absl::HexStringToBytes("00");
+  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
+                                         /* offset = */ 0, stream_type));
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+                      "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: "
+                      "32 while current value is: 1024",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  std::string serialized_settings_frame2 = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "02"    // length
+      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "20");  // 0x20 = 32
+  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
+                                         /* offset = */ stream_type.length(),
+                                         serialized_settings_frame2));
+}
+
+TEST_P(QuicSpdySessionTestClient, AlpsTwoSettingsFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string banned_frame = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "00"    // length
+      "04"    // type (SETTINGS)
+      "00");  // length
+
+  auto error =
+      session_.OnAlpsData(reinterpret_cast<const uint8_t*>(banned_frame.data()),
+                          banned_frame.size());
+  ASSERT_TRUE(error);
+  EXPECT_EQ("multiple SETTINGS frames", error.value());
+}
+
+void QuicSpdySessionTestBase::TestHttpDatagramSetting(
+    HttpDatagramSupport local_support, HttpDatagramSupport remote_support,
+    HttpDatagramSupport expected_support, bool expected_datagram_supported) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(local_support);
+  // HTTP/3 datagrams aren't supported before SETTINGS are received.
+  EXPECT_FALSE(session_.SupportsH3Datagram());
+  EXPECT_EQ(session_.http_datagram_support(), HttpDatagramSupport::kNone);
+  // Receive SETTINGS.
+  SettingsFrame settings;
+  switch (remote_support) {
+    case HttpDatagramSupport::kNone:
+      break;
+    case HttpDatagramSupport::kDraft00:
+      settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
+      break;
+    case HttpDatagramSupport::kDraft04:
+      settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+      break;
+    case HttpDatagramSupport::kDraft00And04:
+      settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
+      settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+      break;
+  }
+  std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  session_.OnStreamFrame(frame);
+  EXPECT_EQ(session_.http_datagram_support(), expected_support);
+  EXPECT_EQ(session_.SupportsH3Datagram(), expected_datagram_supported);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00,
+      /*remote_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00,
+      /*remote_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_support=*/HttpDatagramSupport::kNone,
+      /*expected_datagram_supported=*/false);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00And04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00,
+      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
+      /*expected_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft04,
+      /*remote_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_support=*/HttpDatagramSupport::kNone,
+      /*expected_datagram_supported=*/false);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft04,
+      /*remote_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00And04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft04,
+      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
+      /*expected_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote00) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00And04,
+      /*remote_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00And04,
+      /*remote_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient,
+       HttpDatagramSettingLocal00And04Remote00And04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00And04,
+      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
+      /*expected_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, WebTransportSetting) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  // Note that this does not actually fill out correct settings because the
+  // settings are filled in at the construction time.
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+  session_.set_debug_visitor(&debug_visitor);
+  CompleteHandshake();
+
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(_));
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+  ReceiveWebTransportSettings();
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+  EXPECT_TRUE(session_.SupportsWebTransport());
+}
+
+TEST_P(QuicSpdySessionTestClient, WebTransportSettingSetToZero) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  // Note that this does not actually fill out correct settings because the
+  // settings are filled in at the construction time.
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+  session_.set_debug_visitor(&debug_visitor);
+  CompleteHandshake();
+
+  SettingsFrame server_settings;
+  server_settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+  server_settings.values[SETTINGS_WEBTRANS_DRAFT00] = 0;
+  std::string data =
+      std::string(1, kControlStream) + EncodeSettings(server_settings);
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(server_settings));
+  session_.OnStreamFrame(frame);
+  EXPECT_FALSE(session_.SupportsWebTransport());
+}
+
+TEST_P(QuicSpdySessionTestServer, WebTransportSetting) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  EXPECT_FALSE(session_.ShouldProcessIncomingRequests());
+
+  CompleteHandshake();
+
+  ReceiveWebTransportSettings();
+  EXPECT_TRUE(session_.SupportsWebTransport());
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+}
+
+TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreams) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  CompleteHandshake();
+  QuicStreamId session_id =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
+
+  QuicStreamId data_stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4);
+  ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
+
+  ReceiveWebTransportSettings();
+
+  ReceiveWebTransportSession(session_id);
+  WebTransportHttp3* web_transport =
+      session_.GetWebTransportSession(session_id);
+  ASSERT_TRUE(web_transport != nullptr);
+
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
+  EXPECT_CALL(
+      *connection_,
+      OnStreamReset(data_stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
+  session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
+}
+
+TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreamsLimit) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  CompleteHandshake();
+  QuicStreamId session_id =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
+
+  const int streams_to_send = kMaxUnassociatedWebTransportStreams + 4;
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(
+                  _, QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED))
+      .Times(4);
+  for (int i = 0; i < streams_to_send; i++) {
+    QuicStreamId data_stream_id =
+        GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4 + i);
+    ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
+  }
+
+  ReceiveWebTransportSettings();
+
+  ReceiveWebTransportSession(session_id);
+  WebTransportHttp3* web_transport =
+      session_.GetWebTransportSession(session_id);
+  ASSERT_TRUE(web_transport != nullptr);
+
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(),
+            kMaxUnassociatedWebTransportStreams);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(_, _))
+      .Times(kMaxUnassociatedWebTransportStreams + 1);
+  session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
+}
+
+TEST_P(QuicSpdySessionTestServer, ResetOutgoingWebTransportStreams) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  CompleteHandshake();
+  QuicStreamId session_id =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
+
+  ReceiveWebTransportSettings();
+  ReceiveWebTransportSession(session_id);
+  WebTransportHttp3* web_transport =
+      session_.GetWebTransportSession(session_id);
+  ASSERT_TRUE(web_transport != nullptr);
+
+  session_.set_writev_consumes_all_data(true);
+  EXPECT_TRUE(web_transport->CanOpenNextOutgoingUnidirectionalStream());
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
+  WebTransportStream* stream =
+      web_transport->OpenOutgoingUnidirectionalStream();
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamId stream_id = stream->GetStreamId();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
+  session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
+}
+
+TEST_P(QuicSpdySessionTestClient, WebTransportWithoutExtendedConnect) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  CompleteHandshake();
+
+  SettingsFrame settings;
+  settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+  settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
+  // No SETTINGS_ENABLE_CONNECT_PROTOCOL here.
+  std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
+  QuicStreamId control_stream_id =
+      session_.perspective() == Perspective::IS_SERVER
+          ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
+          : GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
+  session_.OnStreamFrame(frame);
+
+  EXPECT_TRUE(session_.SupportsWebTransport());
+}
+
+// Regression bug for b/208997000.
+TEST_P(QuicSpdySessionTestClient, LimitEncoderDynamicTableSize) {
+  if (version().UsesHttp3()) {
+    return;
+  }
+  CompleteHandshake();
+
+  QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
+  TestHeadersStream* headers_stream =
+      new StrictMock<TestHeadersStream>(&session_);
+  QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
+  session_.MarkConnectionLevelWriteBlocked(headers_stream->id());
+
+  // Peer sends very large value.
+  session_.OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 1024 * 1024 * 1024);
+
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";  // entry with index 2 in HPACK static table
+  stream->WriteHeaders(std::move(headers), /* fin = */ true, nullptr);
+
+  EXPECT_TRUE(headers_stream->HasBufferedData());
+  QuicStreamSendBuffer& send_buffer =
+      QuicStreamPeer::SendBuffer(headers_stream);
+  ASSERT_EQ(1u, send_buffer.size());
+
+  const quiche::QuicheMemSlice& slice =
+      QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
+  absl::string_view stream_data(slice.data(), slice.length());
+
+  if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
+    EXPECT_EQ(absl::HexStringToBytes(
+                  "000009"  // frame length
+                  "01"      // frame type HEADERS
+                  "25"),    // flags END_STREAM | END_HEADERS | PRIORITY
+              stream_data.substr(0, 5));
+    stream_data.remove_prefix(5);
+  } else {
+    EXPECT_EQ(absl::HexStringToBytes(
+                  "00000c"  // frame length
+                  "01"      // frame type HEADERS
+                  "25"),    // flags END_STREAM | END_HEADERS | PRIORITY
+              stream_data.substr(0, 5));
+    stream_data.remove_prefix(5);
+  }
+
+  // Ignore stream ID as it might differ between QUIC versions.
+  stream_data.remove_prefix(4);
+
+  // Ignore stream dependency and weight.
+  EXPECT_EQ(absl::HexStringToBytes("00000000"  // stream dependency
+                                   "92"),      // stream weight
+            stream_data.substr(0, 5));
+  stream_data.remove_prefix(5);
+
+  if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
+    EXPECT_EQ(absl::HexStringToBytes(
+                  "3fe17f"  // Dynamic Table Size Update to 16384
+                  "82"),    // Indexed Header Field Representation with index 2
+              stream_data);
+  } else {
+    EXPECT_EQ(
+        absl::HexStringToBytes(
+            "3fe1ffffff03"  // Dynamic Table Size Update to 1024 * 1024 * 1024
+            "82"),          // Indexed Header Field Representation with index 2
+        stream_data);
+  }
+}
+
+class QuicSpdySessionTestServerNoExtendedConnect
+    : public QuicSpdySessionTestBase {
+ public:
+  QuicSpdySessionTestServerNoExtendedConnect()
+      : QuicSpdySessionTestBase(Perspective::IS_SERVER, false) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServerNoExtendedConnect,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+// Tests that receiving SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 doesn't enable
+// server session to support extended CONNECT.
+TEST_P(QuicSpdySessionTestServerNoExtendedConnect,
+       WebTransportSettingNoEffect) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+
+  CompleteHandshake();
+
+  ReceiveWebTransportSettings();
+  EXPECT_FALSE(session_.allow_extended_connect());
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+}
+
+TEST_P(QuicSpdySessionTestServerNoExtendedConnect, BadExtendedConnectSetting) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+
+  CompleteHandshake();
+
+  // ENABLE_CONNECT_PROTOCOL setting value has to be 1 or 0;
+  SettingsFrame settings;
+  settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 2;
+  std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
+  QuicStreamId control_stream_id =
+      session_.perspective() == Perspective::IS_SERVER
+          ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
+          : GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_INVALID_SETTING_VALUE, _, _));
+  EXPECT_QUIC_PEER_BUG(
+      session_.OnStreamFrame(frame),
+      "Received SETTINGS_ENABLE_CONNECT_PROTOCOL with invalid value");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_stream.cc b/quiche/quic/core/http/quic_spdy_stream.cc
new file mode 100644
index 0000000..82077cd
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream.cc
@@ -0,0 +1,1942 @@
+// Copyright 2013 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 "quiche/quic/core/http/quic_spdy_stream.h"
+
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/quic/core/http/capsule.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_mem_slice_storage.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyPriority;
+
+namespace quic {
+
+// Visitor of HttpDecoder that passes data frame to QuicSpdyStream and closes
+// the connection on unexpected frames.
+class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor {
+ public:
+  explicit HttpDecoderVisitor(QuicSpdyStream* stream) : stream_(stream) {}
+  HttpDecoderVisitor(const HttpDecoderVisitor&) = delete;
+  HttpDecoderVisitor& operator=(const HttpDecoderVisitor&) = delete;
+
+  void OnError(HttpDecoder* decoder) override {
+    stream_->OnUnrecoverableError(decoder->error(), decoder->error_detail());
+  }
+
+  bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("Max Push Id");
+    return false;
+  }
+
+  bool OnGoAwayFrame(const GoAwayFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("Goaway");
+    return false;
+  }
+
+  bool OnSettingsFrameStart(QuicByteCount /*header_length*/) override {
+    CloseConnectionOnWrongFrame("Settings");
+    return false;
+  }
+
+  bool OnSettingsFrame(const SettingsFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("Settings");
+    return false;
+  }
+
+  bool OnDataFrameStart(QuicByteCount header_length,
+                        QuicByteCount payload_length) override {
+    return stream_->OnDataFrameStart(header_length, payload_length);
+  }
+
+  bool OnDataFramePayload(absl::string_view payload) override {
+    QUICHE_DCHECK(!payload.empty());
+    return stream_->OnDataFramePayload(payload);
+  }
+
+  bool OnDataFrameEnd() override { return stream_->OnDataFrameEnd(); }
+
+  bool OnHeadersFrameStart(QuicByteCount header_length,
+                           QuicByteCount payload_length) override {
+    if (!VersionUsesHttp3(stream_->transport_version())) {
+      CloseConnectionOnWrongFrame("Headers");
+      return false;
+    }
+    return stream_->OnHeadersFrameStart(header_length, payload_length);
+  }
+
+  bool OnHeadersFramePayload(absl::string_view payload) override {
+    QUICHE_DCHECK(!payload.empty());
+    if (!VersionUsesHttp3(stream_->transport_version())) {
+      CloseConnectionOnWrongFrame("Headers");
+      return false;
+    }
+    return stream_->OnHeadersFramePayload(payload);
+  }
+
+  bool OnHeadersFrameEnd() override {
+    if (!VersionUsesHttp3(stream_->transport_version())) {
+      CloseConnectionOnWrongFrame("Headers");
+      return false;
+    }
+    return stream_->OnHeadersFrameEnd();
+  }
+
+  bool OnPriorityUpdateFrameStart(QuicByteCount /*header_length*/) override {
+    CloseConnectionOnWrongFrame("Priority update");
+    return false;
+  }
+
+  bool OnPriorityUpdateFrame(const PriorityUpdateFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("Priority update");
+    return false;
+  }
+
+  bool OnAcceptChFrameStart(QuicByteCount /*header_length*/) override {
+    CloseConnectionOnWrongFrame("ACCEPT_CH");
+    return false;
+  }
+
+  bool OnAcceptChFrame(const AcceptChFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("ACCEPT_CH");
+    return false;
+  }
+
+  void OnWebTransportStreamFrameType(
+      QuicByteCount header_length, WebTransportSessionId session_id) override {
+    stream_->OnWebTransportStreamFrameType(header_length, session_id);
+  }
+
+  bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length,
+                           QuicByteCount payload_length) override {
+    return stream_->OnUnknownFrameStart(frame_type, header_length,
+                                        payload_length);
+  }
+
+  bool OnUnknownFramePayload(absl::string_view payload) override {
+    return stream_->OnUnknownFramePayload(payload);
+  }
+
+  bool OnUnknownFrameEnd() override { return stream_->OnUnknownFrameEnd(); }
+
+ private:
+  void CloseConnectionOnWrongFrame(absl::string_view frame_type) {
+    stream_->OnUnrecoverableError(
+        QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM,
+        absl::StrCat(frame_type, " frame received on data stream"));
+  }
+
+  QuicSpdyStream* stream_;
+};
+
+#define ENDPOINT                                                   \
+  (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
+                                                      : "Client:"  \
+                                                        " ")
+
+namespace {
+HttpDecoder::Options HttpDecoderOptionsForBidiStream(
+    QuicSpdySession* spdy_session) {
+  HttpDecoder::Options options;
+  options.allow_web_transport_stream =
+      spdy_session->WillNegotiateWebTransport();
+  return options;
+}
+}  // namespace
+
+QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
+                               StreamType type)
+    : QuicStream(id, spdy_session, /*is_static=*/false, type),
+      spdy_session_(spdy_session),
+      on_body_available_called_because_sequencer_is_closed_(false),
+      visitor_(nullptr),
+      blocked_on_decoding_headers_(false),
+      headers_decompressed_(false),
+      header_list_size_limit_exceeded_(false),
+      headers_payload_length_(0),
+      trailers_decompressed_(false),
+      trailers_consumed_(false),
+      qpack_decoded_headers_accumulator_reset_reason_(
+          QpackDecodedHeadersAccumulatorResetReason::kUnSet),
+      http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
+      decoder_(http_decoder_visitor_.get(),
+               HttpDecoderOptionsForBidiStream(spdy_session)),
+      sequencer_offset_(0),
+      is_decoder_processing_input_(false),
+      ack_listener_(nullptr),
+      last_sent_urgency_(kDefaultUrgency),
+      datagram_next_available_context_id_(spdy_session->perspective() ==
+                                                  Perspective::IS_SERVER
+                                              ? kFirstDatagramContextIdServer
+                                              : kFirstDatagramContextIdClient) {
+  QUICHE_DCHECK_EQ(session()->connection(), spdy_session->connection());
+  QUICHE_DCHECK_EQ(transport_version(), spdy_session->transport_version());
+  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
+  QUICHE_DCHECK_EQ(0u, sequencer()->NumBytesConsumed());
+  // If headers are sent on the headers stream, then do not receive any
+  // callbacks from the sequencer until headers are complete.
+  if (!VersionUsesHttp3(transport_version())) {
+    sequencer()->SetBlockedUntilFlush();
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    sequencer()->set_level_triggered(true);
+  }
+
+  spdy_session_->OnStreamCreated(this);
+}
+
+QuicSpdyStream::QuicSpdyStream(PendingStream* pending,
+                               QuicSpdySession* spdy_session)
+    : QuicStream(pending, spdy_session, /*is_static=*/false),
+      spdy_session_(spdy_session),
+      on_body_available_called_because_sequencer_is_closed_(false),
+      visitor_(nullptr),
+      blocked_on_decoding_headers_(false),
+      headers_decompressed_(false),
+      header_list_size_limit_exceeded_(false),
+      headers_payload_length_(0),
+      trailers_decompressed_(false),
+      trailers_consumed_(false),
+      qpack_decoded_headers_accumulator_reset_reason_(
+          QpackDecodedHeadersAccumulatorResetReason::kUnSet),
+      http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
+      decoder_(http_decoder_visitor_.get()),
+      sequencer_offset_(sequencer()->NumBytesConsumed()),
+      is_decoder_processing_input_(false),
+      ack_listener_(nullptr),
+      last_sent_urgency_(kDefaultUrgency) {
+  QUICHE_DCHECK_EQ(session()->connection(), spdy_session->connection());
+  QUICHE_DCHECK_EQ(transport_version(), spdy_session->transport_version());
+  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id()));
+  // If headers are sent on the headers stream, then do not receive any
+  // callbacks from the sequencer until headers are complete.
+  if (!VersionUsesHttp3(transport_version())) {
+    sequencer()->SetBlockedUntilFlush();
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    sequencer()->set_level_triggered(true);
+  }
+
+  spdy_session_->OnStreamCreated(this);
+}
+
+QuicSpdyStream::~QuicSpdyStream() {}
+
+bool QuicSpdyStream::ShouldUseDatagramContexts() const {
+  return spdy_session_->SupportsH3Datagram() &&
+         spdy_session_->http_datagram_support() !=
+             HttpDatagramSupport::kDraft00 &&
+         use_datagram_contexts_;
+}
+
+size_t QuicSpdyStream::WriteHeaders(
+    SpdyHeaderBlock header_block, bool fin,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  if (!AssertNotWebTransportDataStream("writing headers")) {
+    return 0;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
+  // Send stream type for server push stream
+  if (VersionUsesHttp3(transport_version()) && type() == WRITE_UNIDIRECTIONAL &&
+      send_buffer().stream_offset() == 0) {
+    char data[sizeof(kServerPushStream)];
+    QuicDataWriter writer(ABSL_ARRAYSIZE(data), data);
+    writer.WriteVarInt62(kServerPushStream);
+
+    // Similar to frame headers, stream type byte shouldn't be exposed to upper
+    // layer applications.
+    unacked_frame_headers_offsets_.Add(0, writer.length());
+
+    QUIC_LOG(INFO) << ENDPOINT << "Stream " << id()
+                   << " is writing type as server push";
+    WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
+                      nullptr);
+  }
+
+  MaybeProcessSentWebTransportHeaders(header_block);
+
+  if (ShouldUseDatagramContexts()) {
+    // RegisterHttp3DatagramRegistrationVisitor caller wishes to use contexts,
+    // inform the peer.
+    header_block["sec-use-datagram-contexts"] = "?1";
+  }
+
+  if (web_transport_ != nullptr &&
+      spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
+      spdy_session_->perspective() == Perspective::IS_SERVER) {
+    header_block["sec-webtransport-http3-draft"] = "draft02";
+  }
+
+  size_t bytes_written =
+      WriteHeadersImpl(std::move(header_block), fin, std::move(ack_listener));
+  if (!VersionUsesHttp3(transport_version()) && fin) {
+    // If HEADERS are sent on the headers stream, then |fin_sent_| needs to be
+    // set and write side needs to be closed without actually sending a FIN on
+    // this stream.
+    // TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent.
+    SetFinSent();
+    CloseWriteSide();
+  }
+
+  if (web_transport_ != nullptr &&
+      session()->perspective() == Perspective::IS_CLIENT) {
+    // This will send a capsule and therefore needs to happen after headers have
+    // been sent.
+    RegisterHttp3DatagramContextId(
+        web_transport_->context_id(), DatagramFormatType::WEBTRANSPORT,
+        /*format_additional_data=*/absl::string_view(), web_transport_.get());
+  }
+
+  return bytes_written;
+}
+
+void QuicSpdyStream::WriteOrBufferBody(absl::string_view data, bool fin) {
+  if (!AssertNotWebTransportDataStream("writing body data")) {
+    return;
+  }
+  if (!VersionUsesHttp3(transport_version()) || data.length() == 0) {
+    WriteOrBufferData(data, fin, nullptr);
+    return;
+  }
+  QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnDataFrameSent(id(), data.length());
+  }
+
+  const bool success =
+      WriteDataFrameHeader(data.length(), /*force_write=*/true);
+  QUICHE_DCHECK(success);
+
+  // Write body.
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing DATA frame payload of length "
+                  << data.length() << " with fin " << fin;
+  WriteOrBufferData(data, fin, nullptr);
+}
+
+size_t QuicSpdyStream::WriteTrailers(
+    SpdyHeaderBlock trailer_block,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  if (fin_sent()) {
+    QUIC_BUG(quic_bug_10410_1)
+        << "Trailers cannot be sent after a FIN, on stream " << id();
+    return 0;
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    // The header block must contain the final offset for this stream, as the
+    // trailers may be processed out of order at the peer.
+    const QuicStreamOffset final_offset =
+        stream_bytes_written() + BufferedDataBytes();
+    QUIC_DLOG(INFO) << ENDPOINT << "Inserting trailer: ("
+                    << kFinalOffsetHeaderKey << ", " << final_offset << ")";
+    trailer_block.insert(
+        std::make_pair(kFinalOffsetHeaderKey, absl::StrCat(final_offset)));
+  }
+
+  // Write the trailing headers with a FIN, and close stream for writing:
+  // trailers are the last thing to be sent on a stream.
+  const bool kFin = true;
+  size_t bytes_written =
+      WriteHeadersImpl(std::move(trailer_block), kFin, std::move(ack_listener));
+
+  // If trailers are sent on the headers stream, then |fin_sent_| needs to be
+  // set without actually sending a FIN on this stream.
+  if (!VersionUsesHttp3(transport_version())) {
+    SetFinSent();
+
+    // Also, write side of this stream needs to be closed.  However, only do
+    // this if there is no more buffered data, otherwise it will never be sent.
+    if (BufferedDataBytes() == 0) {
+      CloseWriteSide();
+    }
+  }
+
+  return bytes_written;
+}
+
+QuicConsumedData QuicSpdyStream::WritevBody(const struct iovec* iov, int count,
+                                            bool fin) {
+  quiche::QuicheMemSliceStorage storage(
+      iov, count,
+      session()->connection()->helper()->GetStreamSendBufferAllocator(),
+      GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size));
+  return WriteBodySlices(storage.ToSpan(), fin);
+}
+
+bool QuicSpdyStream::WriteDataFrameHeader(QuicByteCount data_length,
+                                          bool force_write) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QUICHE_DCHECK_GT(data_length, 0u);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      data_length,
+      spdy_session_->connection()->helper()->GetStreamSendBufferAllocator());
+  const bool can_write = CanWriteNewDataAfterData(header.size());
+  if (!can_write && !force_write) {
+    return false;
+  }
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnDataFrameSent(id(), data_length);
+  }
+
+  unacked_frame_headers_offsets_.Add(
+      send_buffer().stream_offset(),
+      send_buffer().stream_offset() + header.size());
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing DATA frame header of length "
+                  << header.size();
+  if (can_write) {
+    // Save one copy and allocation if send buffer can accomodate the header.
+    quiche::QuicheMemSlice header_slice(std::move(header));
+    WriteMemSlices(absl::MakeSpan(&header_slice, 1), false);
+  } else {
+    QUICHE_DCHECK(force_write);
+    WriteOrBufferData(header.AsStringView(), false, nullptr);
+  }
+  return true;
+}
+
+QuicConsumedData QuicSpdyStream::WriteBodySlices(
+    absl::Span<quiche::QuicheMemSlice> slices, bool fin) {
+  if (!VersionUsesHttp3(transport_version()) || slices.empty()) {
+    return WriteMemSlices(slices, fin);
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
+  const QuicByteCount data_size = MemSliceSpanTotalSize(slices);
+  if (!WriteDataFrameHeader(data_size, /*force_write=*/false)) {
+    return {0, false};
+  }
+
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing DATA frame payload of length " << data_size;
+  return WriteMemSlices(slices, fin);
+}
+
+size_t QuicSpdyStream::Readv(const struct iovec* iov, size_t iov_len) {
+  QUICHE_DCHECK(FinishedReadingHeaders());
+  if (!VersionUsesHttp3(transport_version())) {
+    return sequencer()->Readv(iov, iov_len);
+  }
+  size_t bytes_read = 0;
+  sequencer()->MarkConsumed(body_manager_.ReadBody(iov, iov_len, &bytes_read));
+
+  return bytes_read;
+}
+
+int QuicSpdyStream::GetReadableRegions(iovec* iov, size_t iov_len) const {
+  QUICHE_DCHECK(FinishedReadingHeaders());
+  if (!VersionUsesHttp3(transport_version())) {
+    return sequencer()->GetReadableRegions(iov, iov_len);
+  }
+  return body_manager_.PeekBody(iov, iov_len);
+}
+
+void QuicSpdyStream::MarkConsumed(size_t num_bytes) {
+  QUICHE_DCHECK(FinishedReadingHeaders());
+  if (!VersionUsesHttp3(transport_version())) {
+    sequencer()->MarkConsumed(num_bytes);
+    return;
+  }
+
+  sequencer()->MarkConsumed(body_manager_.OnBodyConsumed(num_bytes));
+}
+
+bool QuicSpdyStream::IsDoneReading() const {
+  bool done_reading_headers = FinishedReadingHeaders();
+  bool done_reading_body = sequencer()->IsClosed();
+  bool done_reading_trailers = FinishedReadingTrailers();
+  return done_reading_headers && done_reading_body && done_reading_trailers;
+}
+
+bool QuicSpdyStream::HasBytesToRead() const {
+  if (!VersionUsesHttp3(transport_version())) {
+    return sequencer()->HasBytesToRead();
+  }
+  return body_manager_.HasBytesToRead();
+}
+
+void QuicSpdyStream::MarkTrailersConsumed() { trailers_consumed_ = true; }
+
+uint64_t QuicSpdyStream::total_body_bytes_read() const {
+  if (VersionUsesHttp3(transport_version())) {
+    return body_manager_.total_body_bytes_received();
+  }
+  return sequencer()->NumBytesConsumed();
+}
+
+void QuicSpdyStream::ConsumeHeaderList() {
+  header_list_.Clear();
+
+  if (!FinishedReadingHeaders()) {
+    return;
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    sequencer()->SetUnblocked();
+    return;
+  }
+
+  if (body_manager_.HasBytesToRead()) {
+    HandleBodyAvailable();
+    return;
+  }
+
+  if (sequencer()->IsClosed() &&
+      !on_body_available_called_because_sequencer_is_closed_) {
+    on_body_available_called_because_sequencer_is_closed_ = true;
+    HandleBodyAvailable();
+  }
+}
+
+void QuicSpdyStream::OnStreamHeadersPriority(
+    const spdy::SpdyStreamPrecedence& precedence) {
+  QUICHE_DCHECK_EQ(Perspective::IS_SERVER,
+                   session()->connection()->perspective());
+  SetPriority(precedence);
+}
+
+void QuicSpdyStream::OnStreamHeaderList(bool fin, size_t frame_len,
+                                        const QuicHeaderList& header_list) {
+  if (!spdy_session()->user_agent_id().has_value()) {
+    std::string uaid;
+    for (const auto& kv : header_list) {
+      if (quiche::QuicheTextUtils::ToLower(kv.first) == kUserAgentHeaderName) {
+        uaid = kv.second;
+        break;
+      }
+    }
+    spdy_session()->SetUserAgentId(std::move(uaid));
+  }
+
+  // TODO(b/134706391): remove |fin| argument.
+  // When using Google QUIC, an empty header list indicates that the size limit
+  // has been exceeded.
+  // When using IETF QUIC, there is an explicit signal from
+  // QpackDecodedHeadersAccumulator.
+  if ((VersionUsesHttp3(transport_version()) &&
+       header_list_size_limit_exceeded_) ||
+      (!VersionUsesHttp3(transport_version()) && header_list.empty())) {
+    OnHeadersTooLarge();
+    if (IsDoneReading()) {
+      return;
+    }
+  }
+  if (!headers_decompressed_) {
+    OnInitialHeadersComplete(fin, frame_len, header_list);
+  } else {
+    OnTrailingHeadersComplete(fin, frame_len, header_list);
+  }
+}
+
+void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers,
+                                      bool header_list_size_limit_exceeded) {
+  header_list_size_limit_exceeded_ = header_list_size_limit_exceeded;
+  qpack_decoded_headers_accumulator_.reset();
+  qpack_decoded_headers_accumulator_reset_reason_ =
+      QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeadersDecoded;
+
+  QuicSpdySession::LogHeaderCompressionRatioHistogram(
+      /* using_qpack = */ true,
+      /* is_sent = */ false, headers.compressed_header_bytes(),
+      headers.uncompressed_header_bytes());
+
+  const QuicStreamId promised_stream_id = spdy_session()->promised_stream_id();
+  Http3DebugVisitor* const debug_visitor = spdy_session()->debug_visitor();
+  if (promised_stream_id ==
+      QuicUtils::GetInvalidStreamId(transport_version())) {
+    if (debug_visitor) {
+      debug_visitor->OnHeadersDecoded(id(), headers);
+    }
+
+    OnStreamHeaderList(/* fin = */ false, headers_payload_length_, headers);
+  } else {
+    spdy_session_->OnHeaderList(headers);
+  }
+
+  if (blocked_on_decoding_headers_) {
+    blocked_on_decoding_headers_ = false;
+    // Continue decoding HTTP/3 frames.
+    OnDataAvailable();
+  }
+}
+
+void QuicSpdyStream::OnHeaderDecodingError(QuicErrorCode error_code,
+                                           absl::string_view error_message) {
+  qpack_decoded_headers_accumulator_.reset();
+  qpack_decoded_headers_accumulator_reset_reason_ =
+      QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeaderDecodingError;
+
+  std::string connection_close_error_message = absl::StrCat(
+      "Error decoding ", headers_decompressed_ ? "trailers" : "headers",
+      " on stream ", id(), ": ", error_message);
+  OnUnrecoverableError(error_code, connection_close_error_message);
+}
+
+void QuicSpdyStream::MaybeSendPriorityUpdateFrame() {
+  if (!VersionUsesHttp3(transport_version()) ||
+      session()->perspective() != Perspective::IS_CLIENT) {
+    return;
+  }
+
+  // Value between 0 and 7, inclusive.  Lower value means higher priority.
+  int urgency = precedence().spdy3_priority();
+  if (last_sent_urgency_ == urgency) {
+    return;
+  }
+  last_sent_urgency_ = urgency;
+
+  PriorityUpdateFrame priority_update;
+  priority_update.prioritized_element_type = REQUEST_STREAM;
+  priority_update.prioritized_element_id = id();
+  priority_update.priority_field_value = absl::StrCat("u=", urgency);
+  spdy_session_->WriteHttp3PriorityUpdate(priority_update);
+}
+
+void QuicSpdyStream::OnHeadersTooLarge() { Reset(QUIC_HEADERS_TOO_LARGE); }
+
+void QuicSpdyStream::OnInitialHeadersComplete(
+    bool fin, size_t /*frame_len*/, const QuicHeaderList& header_list) {
+  // TODO(b/134706391): remove |fin| argument.
+  headers_decompressed_ = true;
+  header_list_ = header_list;
+  bool header_too_large = VersionUsesHttp3(transport_version())
+                              ? header_list_size_limit_exceeded_
+                              : header_list.empty();
+  // Validate request headers if it did not exceed size limit. If it did,
+  // OnHeadersTooLarge() should have already handled it previously.
+  if (!header_too_large && !AreHeadersValid(header_list)) {
+    QUIC_CODE_COUNT_N(quic_validate_request_header, 1, 2);
+    if (GetQuicReloadableFlag(quic_act_upon_invalid_header)) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_act_upon_invalid_header);
+      OnInvalidHeaders();
+      return;
+    }
+  }
+  QUIC_CODE_COUNT_N(quic_validate_request_header, 2, 2);
+
+  if (!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+      !header_too_large) {
+    MaybeProcessReceivedWebTransportHeaders();
+    if (ShouldUseDatagramContexts()) {
+      bool peer_wishes_to_use_datagram_contexts = false;
+      for (const auto& header : header_list_) {
+        if (header.first == "sec-use-datagram-contexts" &&
+            header.second == "?1") {
+          peer_wishes_to_use_datagram_contexts = true;
+          break;
+        }
+      }
+      if (!peer_wishes_to_use_datagram_contexts) {
+        use_datagram_contexts_ = false;
+      }
+    }
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    if (fin) {
+      OnStreamFrame(QuicStreamFrame(id(), /* fin = */ true,
+                                    highest_received_byte_offset(),
+                                    absl::string_view()));
+    }
+    return;
+  }
+
+  if (fin && !rst_sent()) {
+    OnStreamFrame(
+        QuicStreamFrame(id(), fin, /* offset = */ 0, absl::string_view()));
+  }
+  if (FinishedReadingHeaders()) {
+    sequencer()->SetUnblocked();
+  }
+}
+
+void QuicSpdyStream::OnPromiseHeaderList(
+    QuicStreamId /* promised_id */, size_t /* frame_len */,
+    const QuicHeaderList& /*header_list */) {
+  // To be overridden in QuicSpdyClientStream.  Not supported on
+  // server side.
+  stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                   "Promise headers received by server");
+}
+
+void QuicSpdyStream::OnTrailingHeadersComplete(
+    bool fin, size_t /*frame_len*/, const QuicHeaderList& header_list) {
+  // TODO(b/134706391): remove |fin| argument.
+  QUICHE_DCHECK(!trailers_decompressed_);
+  if (!VersionUsesHttp3(transport_version()) && fin_received()) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Received Trailers after FIN, on stream: " << id();
+    stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                     "Trailers after fin");
+    return;
+  }
+
+  if (!VersionUsesHttp3(transport_version()) && !fin) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Trailers must have FIN set, on stream: " << id();
+    stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                     "Fin missing from trailers");
+    return;
+  }
+
+  size_t final_byte_offset = 0;
+  const bool expect_final_byte_offset = !VersionUsesHttp3(transport_version());
+  if (!SpdyUtils::CopyAndValidateTrailers(header_list, expect_final_byte_offset,
+                                          &final_byte_offset,
+                                          &received_trailers_)) {
+    QUIC_DLOG(ERROR) << ENDPOINT << "Trailers for stream " << id()
+                     << " are malformed.";
+    stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                     "Trailers are malformed");
+    return;
+  }
+  trailers_decompressed_ = true;
+  if (fin) {
+    const QuicStreamOffset offset = VersionUsesHttp3(transport_version())
+                                        ? highest_received_byte_offset()
+                                        : final_byte_offset;
+    OnStreamFrame(QuicStreamFrame(id(), fin, offset, absl::string_view()));
+  }
+}
+
+void QuicSpdyStream::OnPriorityFrame(
+    const spdy::SpdyStreamPrecedence& precedence) {
+  QUICHE_DCHECK_EQ(Perspective::IS_SERVER,
+                   session()->connection()->perspective());
+  SetPriority(precedence);
+}
+
+void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
+  if (web_transport_data_ != nullptr) {
+    WebTransportStreamVisitor* webtransport_visitor =
+        web_transport_data_->adapter.visitor();
+    if (webtransport_visitor != nullptr) {
+      webtransport_visitor->OnResetStreamReceived(
+          Http3ErrorToWebTransportOrDefault(frame.ietf_error_code));
+    }
+    QuicStream::OnStreamReset(frame);
+    return;
+  }
+
+  // TODO(bnc): Merge the two blocks below when both
+  // quic_abort_qpack_on_stream_reset and quic_fix_on_stream_reset are
+  // deprecated.
+  if (frame.error_code != QUIC_STREAM_NO_ERROR) {
+    if (VersionUsesHttp3(transport_version()) && !fin_received() &&
+        spdy_session_->qpack_decoder()) {
+      QUIC_CODE_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
+      spdy_session_->qpack_decoder()->OnStreamReset(id());
+      if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
+        QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
+        qpack_decoded_headers_accumulator_.reset();
+        qpack_decoded_headers_accumulator_reset_reason_ =
+            QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset1;
+      }
+    }
+
+    QuicStream::OnStreamReset(frame);
+    return;
+  }
+
+  if (GetQuicReloadableFlag(quic_fix_on_stream_reset) &&
+      VersionUsesHttp3(transport_version())) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_fix_on_stream_reset);
+    if (!fin_received() && spdy_session_->qpack_decoder()) {
+      spdy_session_->qpack_decoder()->OnStreamReset(id());
+      qpack_decoded_headers_accumulator_.reset();
+      qpack_decoded_headers_accumulator_reset_reason_ =
+          QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset2;
+    }
+
+    QuicStream::OnStreamReset(frame);
+    return;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT
+                << "Received QUIC_STREAM_NO_ERROR, not discarding response";
+  set_rst_received(true);
+  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
+  set_stream_error(frame.error());
+  CloseWriteSide();
+}
+
+void QuicSpdyStream::ResetWithError(QuicResetStreamError error) {
+  if (VersionUsesHttp3(transport_version()) && !fin_received() &&
+      spdy_session_->qpack_decoder() && web_transport_data_ == nullptr) {
+    QUIC_CODE_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
+    spdy_session_->qpack_decoder()->OnStreamReset(id());
+    if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
+      qpack_decoded_headers_accumulator_.reset();
+      qpack_decoded_headers_accumulator_reset_reason_ =
+          QpackDecodedHeadersAccumulatorResetReason::kResetInResetWithError;
+    }
+  }
+
+  QuicStream::ResetWithError(error);
+}
+
+bool QuicSpdyStream::OnStopSending(QuicResetStreamError error) {
+  if (web_transport_data_ != nullptr) {
+    WebTransportStreamVisitor* visitor = web_transport_data_->adapter.visitor();
+    if (visitor != nullptr) {
+      visitor->OnStopSendingReceived(
+          Http3ErrorToWebTransportOrDefault(error.ietf_application_code()));
+    }
+  }
+
+  return QuicStream::OnStopSending(error);
+}
+
+void QuicSpdyStream::OnWriteSideInDataRecvdState() {
+  if (web_transport_data_ != nullptr) {
+    WebTransportStreamVisitor* visitor = web_transport_data_->adapter.visitor();
+    if (visitor != nullptr) {
+      visitor->OnWriteSideInDataRecvdState();
+    }
+  }
+
+  QuicStream::OnWriteSideInDataRecvdState();
+}
+
+void QuicSpdyStream::OnDataAvailable() {
+  if (!VersionUsesHttp3(transport_version())) {
+    // Sequencer must be blocked until headers are consumed.
+    QUICHE_DCHECK(FinishedReadingHeaders());
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    HandleBodyAvailable();
+    return;
+  }
+
+  if (web_transport_data_ != nullptr) {
+    web_transport_data_->adapter.OnDataAvailable();
+    return;
+  }
+
+  if (!spdy_session()->ShouldProcessIncomingRequests()) {
+    spdy_session()->OnStreamWaitingForClientSettings(id());
+    return;
+  }
+
+  if (is_decoder_processing_input_) {
+    // Let the outermost nested OnDataAvailable() call do the work.
+    return;
+  }
+
+  if (blocked_on_decoding_headers_) {
+    return;
+  }
+
+  iovec iov;
+  while (session()->connection()->connected() && !reading_stopped() &&
+         decoder_.error() == QUIC_NO_ERROR) {
+    QUICHE_DCHECK_GE(sequencer_offset_, sequencer()->NumBytesConsumed());
+    if (!sequencer()->PeekRegion(sequencer_offset_, &iov)) {
+      break;
+    }
+
+    QUICHE_DCHECK(!sequencer()->IsClosed());
+    is_decoder_processing_input_ = true;
+    QuicByteCount processed_bytes = decoder_.ProcessInput(
+        reinterpret_cast<const char*>(iov.iov_base), iov.iov_len);
+    is_decoder_processing_input_ = false;
+    sequencer_offset_ += processed_bytes;
+    if (blocked_on_decoding_headers_) {
+      return;
+    }
+    if (web_transport_data_ != nullptr) {
+      return;
+    }
+  }
+
+  // Do not call HandleBodyAvailable() until headers are consumed.
+  if (!FinishedReadingHeaders()) {
+    return;
+  }
+
+  if (body_manager_.HasBytesToRead()) {
+    HandleBodyAvailable();
+    return;
+  }
+
+  if (sequencer()->IsClosed() &&
+      !on_body_available_called_because_sequencer_is_closed_) {
+    on_body_available_called_because_sequencer_is_closed_ = true;
+    HandleBodyAvailable();
+  }
+}
+
+void QuicSpdyStream::OnClose() {
+  QuicStream::OnClose();
+
+  qpack_decoded_headers_accumulator_.reset();
+  qpack_decoded_headers_accumulator_reset_reason_ =
+      QpackDecodedHeadersAccumulatorResetReason::kResetInOnClose;
+
+  if (visitor_) {
+    Visitor* visitor = visitor_;
+    // Calling Visitor::OnClose() may result the destruction of the visitor,
+    // so we need to ensure we don't call it again.
+    visitor_ = nullptr;
+    visitor->OnClose(this);
+  }
+
+  if (datagram_flow_id_.has_value()) {
+    spdy_session_->UnregisterHttp3DatagramFlowId(datagram_flow_id_.value());
+  }
+
+  if (web_transport_ != nullptr) {
+    web_transport_->OnConnectStreamClosing();
+  }
+  if (web_transport_data_ != nullptr) {
+    WebTransportHttp3* web_transport =
+        spdy_session_->GetWebTransportSession(web_transport_data_->session_id);
+    if (web_transport == nullptr) {
+      // Since there is no guaranteed destruction order for streams, the session
+      // could be already removed from the stream map by the time we reach here.
+      QUIC_DLOG(WARNING) << ENDPOINT << "WebTransport stream " << id()
+                         << " attempted to notify parent session "
+                         << web_transport_data_->session_id
+                         << ", but the session could not be found.";
+      return;
+    }
+    web_transport->OnStreamClosed(id());
+  }
+}
+
+void QuicSpdyStream::OnCanWrite() {
+  QuicStream::OnCanWrite();
+
+  // Trailers (and hence a FIN) may have been sent ahead of queued body bytes.
+  if (!HasBufferedData() && fin_sent()) {
+    CloseWriteSide();
+  }
+}
+
+bool QuicSpdyStream::FinishedReadingHeaders() const {
+  return headers_decompressed_ && header_list_.empty();
+}
+
+// static
+bool QuicSpdyStream::ParseHeaderStatusCode(const SpdyHeaderBlock& header,
+                                           int* status_code) {
+  SpdyHeaderBlock::const_iterator it = header.find(spdy::kHttp2StatusHeader);
+  if (it == header.end()) {
+    return false;
+  }
+  const absl::string_view status(it->second);
+  if (status.size() != 3) {
+    return false;
+  }
+  // First character must be an integer in range [1,5].
+  if (status[0] < '1' || status[0] > '5') {
+    return false;
+  }
+  // The remaining two characters must be integers.
+  if (!isdigit(status[1]) || !isdigit(status[2])) {
+    return false;
+  }
+  return absl::SimpleAtoi(status, status_code);
+}
+
+bool QuicSpdyStream::FinishedReadingTrailers() const {
+  // If no further trailing headers are expected, and the decompressed trailers
+  // (if any) have been consumed, then reading of trailers is finished.
+  if (!fin_received()) {
+    return false;
+  } else if (!trailers_decompressed_) {
+    return true;
+  } else {
+    return trailers_consumed_;
+  }
+}
+
+bool QuicSpdyStream::OnDataFrameStart(QuicByteCount header_length,
+                                      QuicByteCount payload_length) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnDataFrameReceived(id(), payload_length);
+  }
+
+  if (!headers_decompressed_ || trailers_decompressed_) {
+    stream_delegate()->OnStreamError(
+        QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+        "Unexpected DATA frame received.");
+    return false;
+  }
+
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
+
+  return true;
+}
+
+bool QuicSpdyStream::OnDataFramePayload(absl::string_view payload) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  body_manager_.OnBody(payload);
+
+  return true;
+}
+
+bool QuicSpdyStream::OnDataFrameEnd() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  QUIC_DVLOG(1) << ENDPOINT
+                << "Reaches the end of a data frame. Total bytes received are "
+                << body_manager_.total_body_bytes_received();
+  return true;
+}
+
+bool QuicSpdyStream::OnStreamFrameAcked(QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        bool fin_acked,
+                                        QuicTime::Delta ack_delay_time,
+                                        QuicTime receive_timestamp,
+                                        QuicByteCount* newly_acked_length) {
+  const bool new_data_acked = QuicStream::OnStreamFrameAcked(
+      offset, data_length, fin_acked, ack_delay_time, receive_timestamp,
+      newly_acked_length);
+
+  const QuicByteCount newly_acked_header_length =
+      GetNumFrameHeadersInInterval(offset, data_length);
+  QUICHE_DCHECK_LE(newly_acked_header_length, *newly_acked_length);
+  unacked_frame_headers_offsets_.Difference(offset, offset + data_length);
+  if (ack_listener_ != nullptr && new_data_acked) {
+    ack_listener_->OnPacketAcked(
+        *newly_acked_length - newly_acked_header_length, ack_delay_time);
+  }
+  return new_data_acked;
+}
+
+void QuicSpdyStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                                QuicByteCount data_length,
+                                                bool fin_retransmitted) {
+  QuicStream::OnStreamFrameRetransmitted(offset, data_length,
+                                         fin_retransmitted);
+
+  const QuicByteCount retransmitted_header_length =
+      GetNumFrameHeadersInInterval(offset, data_length);
+  QUICHE_DCHECK_LE(retransmitted_header_length, data_length);
+
+  if (ack_listener_ != nullptr) {
+    ack_listener_->OnPacketRetransmitted(data_length -
+                                         retransmitted_header_length);
+  }
+}
+
+QuicByteCount QuicSpdyStream::GetNumFrameHeadersInInterval(
+    QuicStreamOffset offset, QuicByteCount data_length) const {
+  QuicByteCount header_acked_length = 0;
+  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+  newly_acked.Intersection(unacked_frame_headers_offsets_);
+  for (const auto& interval : newly_acked) {
+    header_acked_length += interval.Length();
+  }
+  return header_acked_length;
+}
+
+bool QuicSpdyStream::OnHeadersFrameStart(QuicByteCount header_length,
+                                         QuicByteCount payload_length) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QUICHE_DCHECK(!qpack_decoded_headers_accumulator_);
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnHeadersFrameReceived(id(),
+                                                           payload_length);
+  }
+
+  headers_payload_length_ = payload_length;
+
+  if (trailers_decompressed_) {
+    stream_delegate()->OnStreamError(
+        QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+        "HEADERS frame received after trailing HEADERS.");
+    return false;
+  }
+
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
+
+  qpack_decoded_headers_accumulator_ =
+      std::make_unique<QpackDecodedHeadersAccumulator>(
+          id(), spdy_session_->qpack_decoder(), this,
+          spdy_session_->max_inbound_header_list_size());
+
+  return true;
+}
+
+bool QuicSpdyStream::OnHeadersFramePayload(absl::string_view payload) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  if (!qpack_decoded_headers_accumulator_) {
+    QUIC_BUG(b215142466_OnHeadersFramePayload)
+        << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
+    OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
+                          "qpack_decoded_headers_accumulator_ is nullptr");
+    return false;
+  }
+
+  qpack_decoded_headers_accumulator_->Decode(payload);
+
+  // |qpack_decoded_headers_accumulator_| is reset if an error is detected.
+  if (!qpack_decoded_headers_accumulator_) {
+    return false;
+  }
+
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(payload.size()));
+  return true;
+}
+
+bool QuicSpdyStream::OnHeadersFrameEnd() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  if (!qpack_decoded_headers_accumulator_) {
+    QUIC_BUG(b215142466_OnHeadersFrameEnd)
+        << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
+    OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
+                          "qpack_decoded_headers_accumulator_ is nullptr");
+    return false;
+  }
+
+  qpack_decoded_headers_accumulator_->EndHeaderBlock();
+
+  // If decoding is complete or an error is detected, then
+  // |qpack_decoded_headers_accumulator_| is already reset.
+  if (qpack_decoded_headers_accumulator_) {
+    blocked_on_decoding_headers_ = true;
+    return false;
+  }
+
+  return !sequencer()->IsClosed() && !reading_stopped();
+}
+
+void QuicSpdyStream::OnWebTransportStreamFrameType(
+    QuicByteCount header_length, WebTransportSessionId session_id) {
+  QUIC_DVLOG(1) << ENDPOINT << " Received WEBTRANSPORT_STREAM on stream "
+                << id() << " for session " << session_id;
+  sequencer()->MarkConsumed(header_length);
+
+  if (headers_payload_length_ > 0 || headers_decompressed_) {
+    QUIC_PEER_BUG(WEBTRANSPORT_STREAM received on HTTP request)
+        << ENDPOINT << "Stream " << id()
+        << " tried to convert to WebTransport, but it already "
+           "has HTTP data on it";
+    Reset(QUIC_STREAM_FRAME_UNEXPECTED);
+  }
+  if (QuicUtils::IsOutgoingStreamId(spdy_session_->version(), id(),
+                                    spdy_session_->perspective())) {
+    QUIC_PEER_BUG(WEBTRANSPORT_STREAM received on outgoing request)
+        << ENDPOINT << "Stream " << id()
+        << " tried to convert to WebTransport, but only the "
+           "initiator of the stream can do it.";
+    Reset(QUIC_STREAM_FRAME_UNEXPECTED);
+  }
+
+  QUICHE_DCHECK(web_transport_ == nullptr);
+  web_transport_data_ =
+      std::make_unique<WebTransportDataStream>(this, session_id);
+  spdy_session_->AssociateIncomingWebTransportStreamWithSession(session_id,
+                                                                id());
+}
+
+bool QuicSpdyStream::OnUnknownFrameStart(uint64_t frame_type,
+                                         QuicByteCount header_length,
+                                         QuicByteCount payload_length) {
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnUnknownFrameReceived(id(), frame_type,
+                                                           payload_length);
+  }
+
+  // Ignore unknown frames, but consume frame header.
+  QUIC_DVLOG(1) << ENDPOINT << "Discarding " << header_length
+                << " byte long frame header of frame of unknown type "
+                << frame_type << ".";
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
+  return true;
+}
+
+bool QuicSpdyStream::OnUnknownFramePayload(absl::string_view payload) {
+  // Ignore unknown frames, but consume frame payload.
+  QUIC_DVLOG(1) << ENDPOINT << "Discarding " << payload.size()
+                << " bytes of payload of frame of unknown type.";
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(payload.size()));
+  return true;
+}
+
+bool QuicSpdyStream::OnUnknownFrameEnd() { return true; }
+
+size_t QuicSpdyStream::WriteHeadersImpl(
+    spdy::SpdyHeaderBlock header_block, bool fin,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return spdy_session_->WriteHeadersOnHeadersStream(
+        id(), std::move(header_block), fin, precedence(),
+        std::move(ack_listener));
+  }
+
+  // Encode header list.
+  QuicByteCount encoder_stream_sent_byte_count;
+  std::string encoded_headers =
+      spdy_session_->qpack_encoder()->EncodeHeaderList(
+          id(), header_block, &encoder_stream_sent_byte_count);
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnHeadersFrameSent(id(), header_block);
+  }
+
+  // Write HEADERS frame.
+  std::unique_ptr<char[]> headers_frame_header;
+  const size_t headers_frame_header_length =
+      HttpEncoder::SerializeHeadersFrameHeader(encoded_headers.size(),
+                                               &headers_frame_header);
+  unacked_frame_headers_offsets_.Add(
+      send_buffer().stream_offset(),
+      send_buffer().stream_offset() + headers_frame_header_length);
+
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing HEADERS frame header of length "
+                  << headers_frame_header_length;
+  WriteOrBufferData(absl::string_view(headers_frame_header.get(),
+                                      headers_frame_header_length),
+                    /* fin = */ false, /* ack_listener = */ nullptr);
+
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing HEADERS frame payload of length "
+                  << encoded_headers.length() << " with fin " << fin;
+  WriteOrBufferData(encoded_headers, fin, nullptr);
+
+  QuicSpdySession::LogHeaderCompressionRatioHistogram(
+      /* using_qpack = */ true,
+      /* is_sent = */ true,
+      encoded_headers.size() + encoder_stream_sent_byte_count,
+      header_block.TotalBytesUsed());
+
+  return encoded_headers.size();
+}
+
+bool QuicSpdyStream::CanWriteNewBodyData(QuicByteCount write_size) const {
+  QUICHE_DCHECK_NE(0u, write_size);
+  if (!VersionUsesHttp3(transport_version())) {
+    return CanWriteNewData();
+  }
+
+  return CanWriteNewDataAfterData(
+      HttpEncoder::GetDataFrameHeaderLength(write_size));
+}
+
+void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
+  if (!spdy_session_->SupportsWebTransport()) {
+    return;
+  }
+  if (session()->perspective() != Perspective::IS_SERVER) {
+    return;
+  }
+  QUICHE_DCHECK(IsValidWebTransportSessionId(id(), version()));
+
+  std::string method;
+  std::string protocol;
+  absl::optional<QuicDatagramStreamId> flow_id;
+  bool version_indicated = false;
+  for (const auto& [header_name, header_value] : header_list_) {
+    if (header_name == ":method") {
+      if (!method.empty() || header_value.empty()) {
+        return;
+      }
+      method = header_value;
+    }
+    if (header_name == ":protocol") {
+      if (!protocol.empty() || header_value.empty()) {
+        return;
+      }
+      protocol = header_value;
+    }
+    if (header_name == "datagram-flow-id") {
+      if (spdy_session_->http_datagram_support() !=
+          HttpDatagramSupport::kDraft00) {
+        QUIC_DLOG(ERROR) << ENDPOINT
+                         << "Rejecting WebTransport due to unexpected "
+                            "Datagram-Flow-Id header";
+        return;
+      }
+      if (flow_id.has_value() || header_value.empty()) {
+        return;
+      }
+      QuicDatagramStreamId flow_id_out;
+      if (!absl::SimpleAtoi(header_value, &flow_id_out)) {
+        return;
+      }
+      flow_id = flow_id_out;
+    }
+    if (header_name == "sec-webtransport-http3-draft02") {
+      if (header_value != "1") {
+        QUIC_DLOG(ERROR) << ENDPOINT
+                         << "Rejecting WebTransport due to invalid value of "
+                            "Sec-Webtransport-Http3-Draft02 header";
+        return;
+      }
+      version_indicated = true;
+    }
+  }
+
+  if (method != "CONNECT" || protocol != "webtransport") {
+    return;
+  }
+
+  if (!version_indicated &&
+      spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
+    QUIC_DLOG(ERROR)
+        << ENDPOINT
+        << "WebTransport request rejected due to missing version header.";
+    return;
+  }
+
+  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
+    if (!flow_id.has_value()) {
+      QUIC_DLOG(ERROR)
+          << ENDPOINT
+          << "Rejecting WebTransport due to missing Datagram-Flow-Id header";
+      return;
+    }
+    RegisterHttp3DatagramFlowId(*flow_id);
+  }
+
+  web_transport_ = std::make_unique<WebTransportHttp3>(
+      spdy_session_, this, id(),
+      spdy_session_->ShouldNegotiateDatagramContexts());
+
+  if (spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
+    return;
+  }
+  // If we're in draft-ietf-masque-h3-datagram-00 mode, pretend we also received
+  // a REGISTER_DATAGRAM_NO_CONTEXT capsule.
+  // TODO(b/181256914) remove this when we remove support for
+  // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+  RegisterHttp3DatagramContextId(
+      /*context_id=*/absl::nullopt, DatagramFormatType::WEBTRANSPORT,
+      /*format_additional_data=*/absl::string_view(), web_transport_.get());
+}
+
+void QuicSpdyStream::MaybeProcessSentWebTransportHeaders(
+    spdy::SpdyHeaderBlock& headers) {
+  if (!spdy_session_->SupportsWebTransport()) {
+    return;
+  }
+  if (session()->perspective() != Perspective::IS_CLIENT) {
+    return;
+  }
+  QUICHE_DCHECK(IsValidWebTransportSessionId(id(), version()));
+
+  const auto method_it = headers.find(":method");
+  const auto protocol_it = headers.find(":protocol");
+  if (method_it == headers.end() || protocol_it == headers.end()) {
+    return;
+  }
+  if (method_it->second != "CONNECT" && protocol_it->second != "webtransport") {
+    return;
+  }
+
+  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
+    headers["datagram-flow-id"] = absl::StrCat(id());
+  } else {
+    headers["sec-webtransport-http3-draft02"] = "1";
+  }
+
+  web_transport_ = std::make_unique<WebTransportHttp3>(
+      spdy_session_, this, id(),
+      spdy_session_->ShouldNegotiateDatagramContexts());
+}
+
+void QuicSpdyStream::OnCanWriteNewData() {
+  if (web_transport_data_ != nullptr) {
+    web_transport_data_->adapter.OnCanWriteNewData();
+  }
+}
+
+bool QuicSpdyStream::AssertNotWebTransportDataStream(
+    absl::string_view operation) {
+  if (web_transport_data_ != nullptr) {
+    QUIC_BUG(Invalid operation on WebTransport stream)
+        << "Attempted to " << operation << " on WebTransport data stream "
+        << id() << " associated with session "
+        << web_transport_data_->session_id;
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         absl::StrCat("Attempted to ", operation,
+                                      " on WebTransport data stream"));
+    return false;
+  }
+  return true;
+}
+
+void QuicSpdyStream::ConvertToWebTransportDataStream(
+    WebTransportSessionId session_id) {
+  if (send_buffer().stream_offset() != 0) {
+    QUIC_BUG(Sending WEBTRANSPORT_STREAM when data already sent)
+        << "Attempted to send a WEBTRANSPORT_STREAM frame when other data has "
+           "already been sent on the stream.";
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         "Attempted to send a WEBTRANSPORT_STREAM frame when "
+                         "other data has already been sent on the stream.");
+    return;
+  }
+
+  std::unique_ptr<char[]> header;
+  QuicByteCount header_size =
+      HttpEncoder::SerializeWebTransportStreamFrameHeader(session_id, &header);
+  if (header_size == 0) {
+    QUIC_BUG(Failed to serialize WEBTRANSPORT_STREAM)
+        << "Failed to serialize a WEBTRANSPORT_STREAM frame.";
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         "Failed to serialize a WEBTRANSPORT_STREAM frame.");
+    return;
+  }
+
+  WriteOrBufferData(absl::string_view(header.get(), header_size), /*fin=*/false,
+                    nullptr);
+  web_transport_data_ =
+      std::make_unique<WebTransportDataStream>(this, session_id);
+  QUIC_DVLOG(1) << ENDPOINT << "Successfully opened WebTransport data stream "
+                << id() << " for session " << session_id;
+}
+
+QuicSpdyStream::WebTransportDataStream::WebTransportDataStream(
+    QuicSpdyStream* stream, WebTransportSessionId session_id)
+    : session_id(session_id),
+      adapter(stream->spdy_session_, stream, stream->sequencer()) {}
+
+void QuicSpdyStream::HandleReceivedDatagram(
+    absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  Http3DatagramVisitor* visitor;
+  if (context_id.has_value()) {
+    auto it = datagram_context_visitors_.find(context_id.value());
+    if (it == datagram_context_visitors_.end()) {
+      QUIC_DLOG(ERROR) << ENDPOINT
+                       << "Received datagram without any visitor for context "
+                       << context_id.value();
+      return;
+    }
+    visitor = it->second;
+  } else {
+    if (datagram_no_context_visitor_ == nullptr) {
+      QUIC_DLOG(ERROR)
+          << ENDPOINT << "Received datagram without any visitor for no context";
+      return;
+    }
+    visitor = datagram_no_context_visitor_;
+  }
+  visitor->OnHttp3Datagram(id(), context_id, payload);
+}
+
+bool QuicSpdyStream::OnCapsule(const Capsule& capsule) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " received capsule "
+                  << capsule;
+  if (!headers_decompressed_) {
+    QUIC_PEER_BUG(capsule before headers)
+        << ENDPOINT << "Stream " << id() << " received capsule " << capsule
+        << " before headers";
+    return false;
+  }
+  if (web_transport_ != nullptr && web_transport_->close_received()) {
+    QUIC_PEER_BUG(capsule after close)
+        << ENDPOINT << "Stream " << id() << " received capsule " << capsule
+        << " after CLOSE_WEBTRANSPORT_SESSION.";
+    return false;
+  }
+  switch (capsule.capsule_type()) {
+    case CapsuleType::LEGACY_DATAGRAM: {
+      HandleReceivedDatagram(
+          capsule.legacy_datagram_capsule().context_id,
+          capsule.legacy_datagram_capsule().http_datagram_payload);
+    } break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT: {
+      HandleReceivedDatagram(
+          capsule.datagram_with_context_capsule().context_id,
+          capsule.datagram_with_context_capsule().http_datagram_payload);
+    } break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT: {
+      absl::optional<QuicDatagramContextId> context_id;
+      if (use_datagram_contexts_) {
+        // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
+        // DATAGRAM_WITHOUT_CONTEXT.
+        context_id = 0;
+      }
+      HandleReceivedDatagram(
+          context_id,
+          capsule.datagram_without_context_capsule().http_datagram_payload);
+    } break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT: {
+      if (datagram_registration_visitor_ == nullptr) {
+        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
+                         << " without any registration visitor";
+        return false;
+      }
+      datagram_registration_visitor_->OnContextReceived(
+          id(), capsule.register_datagram_context_capsule().context_id,
+          capsule.register_datagram_context_capsule().format_type,
+          capsule.register_datagram_context_capsule().format_additional_data);
+    } break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT: {
+      if (datagram_registration_visitor_ == nullptr) {
+        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
+                         << " without any registration visitor";
+        return false;
+      }
+      absl::optional<QuicDatagramContextId> context_id;
+      if (use_datagram_contexts_) {
+        // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
+        // REGISTER_DATAGRAM_NO_CONTEXT.
+        context_id = 0;
+      }
+      datagram_registration_visitor_->OnContextReceived(
+          id(), context_id,
+          capsule.register_datagram_no_context_capsule().format_type,
+          capsule.register_datagram_no_context_capsule()
+              .format_additional_data);
+    } break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT: {
+      if (datagram_registration_visitor_ == nullptr) {
+        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
+                         << " without any registration visitor";
+        return false;
+      }
+      datagram_registration_visitor_->OnContextClosed(
+          id(), capsule.close_datagram_context_capsule().context_id,
+          capsule.close_datagram_context_capsule().close_code,
+          capsule.close_datagram_context_capsule().close_details);
+    } break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION: {
+      if (web_transport_ == nullptr) {
+        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
+                         << " for a non-WebTransport stream.";
+        return false;
+      }
+      web_transport_->OnCloseReceived(
+          capsule.close_web_transport_session_capsule().error_code,
+          capsule.close_web_transport_session_capsule().error_message);
+    } break;
+  }
+  return true;
+}
+
+void QuicSpdyStream::OnCapsuleParseFailure(const std::string& error_message) {
+  QUIC_DLOG(ERROR) << ENDPOINT << "Capsule parse failure: " << error_message;
+  Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+}
+
+void QuicSpdyStream::WriteCapsule(const Capsule& capsule, bool fin) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " sending capsule "
+                  << capsule;
+  quiche::QuicheBuffer serialized_capsule = SerializeCapsule(
+      capsule,
+      spdy_session_->connection()->helper()->GetStreamSendBufferAllocator());
+  QUICHE_DCHECK_GT(serialized_capsule.size(), 0u);
+  WriteOrBufferBody(serialized_capsule.AsStringView(), /*fin=*/fin);
+}
+
+void QuicSpdyStream::WriteGreaseCapsule() {
+  // GREASE capsulde IDs have a form of 41 * N + 23.
+  QuicRandom* random = spdy_session_->connection()->random_generator();
+  uint64_t type = random->InsecureRandUint64() >> 4;
+  type = (type / 41) * 41 + 23;
+  QUICHE_DCHECK_EQ((type - 23) % 41, 0u);
+
+  constexpr size_t kMaxLength = 64;
+  size_t length = random->InsecureRandUint64() % kMaxLength;
+  std::string bytes(length, '\0');
+  random->InsecureRandBytes(&bytes[0], bytes.size());
+  Capsule capsule = Capsule::Unknown(type, bytes);
+  WriteCapsule(capsule, /*fin=*/false);
+}
+
+MessageStatus QuicSpdyStream::SendHttp3Datagram(
+    absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  QuicDatagramStreamId stream_id =
+      datagram_flow_id_.has_value() ? datagram_flow_id_.value() : id();
+  return spdy_session_->SendHttp3Datagram(stream_id, context_id, payload);
+}
+
+void QuicSpdyStream::RegisterHttp3DatagramRegistrationVisitor(
+    Http3DatagramRegistrationVisitor* visitor, bool use_datagram_contexts) {
+  if (visitor == nullptr) {
+    QUIC_BUG(null datagram registration visitor)
+        << ENDPOINT << "Null datagram registration visitor for" << id();
+    return;
+  }
+  if (datagram_registration_visitor_ != nullptr) {
+    QUIC_BUG(double datagram registration visitor)
+        << ENDPOINT << "Double datagram registration visitor for" << id();
+    return;
+  }
+  use_datagram_contexts_ = use_datagram_contexts;
+  QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram stream ID " << id()
+                  << " with" << (use_datagram_contexts_ ? "" : "out")
+                  << " contexts";
+  datagram_registration_visitor_ = visitor;
+  QUICHE_DCHECK(!capsule_parser_);
+  capsule_parser_.reset(new CapsuleParser(this));
+}
+
+void QuicSpdyStream::UnregisterHttp3DatagramRegistrationVisitor() {
+  QUIC_BUG_IF(h3 datagram unregister unknown stream ID,
+              datagram_registration_visitor_ == nullptr)
+      << ENDPOINT
+      << "Attempted to unregister unknown HTTP/3 datagram stream ID " << id();
+  QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram stream ID " << id();
+  datagram_registration_visitor_ = nullptr;
+}
+
+void QuicSpdyStream::MoveHttp3DatagramRegistration(
+    Http3DatagramRegistrationVisitor* visitor) {
+  QUIC_BUG_IF(h3 datagram move unknown stream ID,
+              datagram_registration_visitor_ == nullptr)
+      << ENDPOINT << "Attempted to move unknown HTTP/3 datagram stream ID "
+      << id();
+  QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram stream ID " << id();
+  datagram_registration_visitor_ = visitor;
+}
+
+void QuicSpdyStream::RegisterHttp3DatagramContextId(
+    absl::optional<QuicDatagramContextId> context_id,
+    DatagramFormatType format_type, absl::string_view format_additional_data,
+    Http3DatagramVisitor* visitor) {
+  if (visitor == nullptr) {
+    QUIC_BUG(null datagram visitor)
+        << ENDPOINT << "Null datagram visitor for stream ID " << id()
+        << " context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none");
+    return;
+  }
+  if (datagram_registration_visitor_ == nullptr) {
+    QUIC_BUG(context registration without registration visitor)
+        << ENDPOINT << "Cannot register context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " without registration visitor for stream ID " << id();
+    return;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram context ID "
+                  << (context_id.has_value() ? absl::StrCat(context_id.value())
+                                             : "none")
+                  << " with stream ID " << id();
+
+  if (context_id.has_value()) {
+    if (datagram_no_context_visitor_ != nullptr) {
+      QUIC_BUG(h3 datagram context ID mix1)
+          << ENDPOINT
+          << "Attempted to mix registrations without and with context IDs "
+             "for stream ID "
+          << id();
+      return;
+    }
+    auto insertion_result =
+        datagram_context_visitors_.insert({context_id.value(), visitor});
+    if (!insertion_result.second) {
+      QUIC_BUG(h3 datagram double context registration)
+          << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
+          << id() << " context ID " << context_id.value();
+      return;
+    }
+    capsule_parser_->set_datagram_context_id_present(true);
+  } else {
+    // Registration without a context ID.
+    if (!datagram_context_visitors_.empty()) {
+      QUIC_BUG(h3 datagram context ID mix2)
+          << ENDPOINT
+          << "Attempted to mix registrations with and without context IDs "
+             "for stream ID "
+          << id();
+      return;
+    }
+    if (datagram_no_context_visitor_ != nullptr) {
+      QUIC_BUG(h3 datagram double no context registration)
+          << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
+          << id() << " with no context ID";
+      return;
+    }
+    datagram_no_context_visitor_ = visitor;
+    capsule_parser_->set_datagram_context_id_present(false);
+  }
+  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04) {
+    const bool is_client = session()->perspective() == Perspective::IS_CLIENT;
+    if (context_id.has_value()) {
+      const bool is_client_context = context_id.value() % 2 == 0;
+      if (is_client == is_client_context) {
+        QuicConnection::ScopedPacketFlusher flusher(
+            spdy_session_->connection());
+        WriteGreaseCapsule();
+        if (context_id.value() != 0) {
+          WriteCapsule(Capsule::RegisterDatagramContext(
+              context_id.value(), format_type, format_additional_data));
+        } else {
+          // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
+          // REGISTER_DATAGRAM_NO_CONTEXT.
+          WriteCapsule(Capsule::RegisterDatagramNoContext(
+              format_type, format_additional_data));
+        }
+        WriteGreaseCapsule();
+      }
+    } else if (is_client) {
+      QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
+      WriteGreaseCapsule();
+      WriteCapsule(Capsule::RegisterDatagramNoContext(format_type,
+                                                      format_additional_data));
+      WriteGreaseCapsule();
+    }
+  }
+}
+
+void QuicSpdyStream::UnregisterHttp3DatagramContextId(
+    absl::optional<QuicDatagramContextId> context_id) {
+  if (datagram_registration_visitor_ == nullptr) {
+    QUIC_BUG(context unregistration without registration visitor)
+        << ENDPOINT << "Cannot unregister context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " without registration visitor for stream ID " << id();
+    return;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram context ID "
+                  << (context_id.has_value() ? absl::StrCat(context_id.value())
+                                             : "none")
+                  << " with stream ID " << id();
+  if (context_id.has_value()) {
+    size_t num_erased = datagram_context_visitors_.erase(context_id.value());
+    QUIC_BUG_IF(h3 datagram unregister unknown context, num_erased != 1)
+        << "Attempted to unregister unknown HTTP/3 context ID "
+        << context_id.value() << " on stream ID " << id();
+  } else {
+    // Unregistration without a context ID.
+    QUIC_BUG_IF(h3 datagram unknown context unregistration,
+                datagram_no_context_visitor_ == nullptr)
+        << "Attempted to unregister unknown no context on HTTP/3 stream ID "
+        << id();
+    datagram_no_context_visitor_ = nullptr;
+  }
+  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04 &&
+      context_id.has_value()) {
+    WriteCapsule(Capsule::CloseDatagramContext(context_id.value()));
+  }
+}
+
+void QuicSpdyStream::MoveHttp3DatagramContextIdRegistration(
+    absl::optional<QuicDatagramContextId> context_id,
+    Http3DatagramVisitor* visitor) {
+  if (datagram_registration_visitor_ == nullptr) {
+    QUIC_BUG(context move without registration visitor)
+        << ENDPOINT << "Cannot move context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " without registration visitor for stream ID " << id();
+    return;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram context ID "
+                  << (context_id.has_value() ? absl::StrCat(context_id.value())
+                                             : "none")
+                  << " with stream ID " << id();
+  if (context_id.has_value()) {
+    QUIC_BUG_IF(h3 datagram move unknown context,
+                !datagram_context_visitors_.contains(context_id.value()))
+        << ENDPOINT << "Attempted to move unknown context ID "
+        << context_id.value() << " on stream ID " << id();
+    datagram_context_visitors_[context_id.value()] = visitor;
+    return;
+  }
+  // Move without a context ID.
+  QUIC_BUG_IF(h3 datagram unknown context move,
+              datagram_no_context_visitor_ == nullptr)
+      << "Attempted to move unknown no context on HTTP/3 stream ID " << id();
+  datagram_no_context_visitor_ = visitor;
+}
+
+void QuicSpdyStream::SetMaxDatagramTimeInQueue(
+    QuicTime::Delta max_time_in_queue) {
+  spdy_session_->SetMaxDatagramTimeInQueueForStreamId(id(), max_time_in_queue);
+}
+
+QuicDatagramContextId QuicSpdyStream::GetNextDatagramContextId() {
+  QuicDatagramContextId result = datagram_next_available_context_id_;
+  datagram_next_available_context_id_ += kDatagramContextIdIncrement;
+  return result;
+}
+
+void QuicSpdyStream::OnDatagramReceived(QuicDataReader* reader) {
+  if (!headers_decompressed_) {
+    QUIC_DLOG(INFO) << "Dropping datagram received before headers on stream ID "
+                    << id();
+    return;
+  }
+  absl::optional<QuicDatagramContextId> context_id;
+  if (use_datagram_contexts_) {
+    QuicDatagramContextId parsed_context_id;
+    if (!reader->ReadVarInt62(&parsed_context_id)) {
+      QUIC_DLOG(ERROR) << "Failed to parse context ID in received HTTP/3 "
+                          "datagram on stream ID "
+                       << id();
+      return;
+    }
+    context_id = parsed_context_id;
+  }
+  absl::string_view payload = reader->ReadRemainingPayload();
+  HandleReceivedDatagram(context_id, payload);
+}
+
+QuicByteCount QuicSpdyStream::GetMaxDatagramSize(
+    absl::optional<QuicDatagramContextId> context_id) const {
+  QuicByteCount prefix_size = 0;
+  switch (spdy_session_->http_datagram_support()) {
+    case HttpDatagramSupport::kDraft00:
+      if (!datagram_flow_id_.has_value()) {
+        QUIC_BUG(GetMaxDatagramSize with no flow ID)
+            << "GetMaxDatagramSize() called when no flow ID available";
+        break;
+      }
+      prefix_size = QuicDataWriter::GetVarInt62Len(*datagram_flow_id_);
+      break;
+    case HttpDatagramSupport::kDraft04:
+      prefix_size =
+          QuicDataWriter::GetVarInt62Len(id() / kHttpDatagramStreamIdDivisor);
+      break;
+    case HttpDatagramSupport::kNone:
+    case HttpDatagramSupport::kDraft00And04:
+      QUIC_BUG(GetMaxDatagramSize called with no datagram support)
+          << "GetMaxDatagramSize() called when no HTTP/3 datagram support has "
+             "been negotiated.  Support value: "
+          << spdy_session_->http_datagram_support();
+      break;
+  }
+  // If the logic above fails, use the largest possible value as the safe one.
+  if (prefix_size == 0) {
+    prefix_size = 8;
+  }
+
+  if (context_id.has_value()) {
+    QUIC_BUG_IF(
+        context_id with draft00 in GetMaxDatagramSize,
+        spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00)
+        << "GetMaxDatagramSize() called with a context ID specified, but "
+           "draft00 does not support contexts.";
+    prefix_size += QuicDataWriter::GetVarInt62Len(*context_id);
+  }
+
+  QuicByteCount max_datagram_size =
+      session()->GetGuaranteedLargestMessagePayload();
+  if (max_datagram_size < prefix_size) {
+    QUIC_BUG(max_datagram_size smaller than prefix_size)
+        << "GetGuaranteedLargestMessagePayload() returned a datagram size that "
+           "is not sufficient to fit stream and/or context ID into it.";
+    return 0;
+  }
+  return max_datagram_size - prefix_size;
+}
+
+void QuicSpdyStream::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id) {
+  datagram_flow_id_ = flow_id;
+  spdy_session_->RegisterHttp3DatagramFlowId(datagram_flow_id_.value(), id());
+}
+
+void QuicSpdyStream::HandleBodyAvailable() {
+  if (!capsule_parser_) {
+    OnBodyAvailable();
+    return;
+  }
+  while (body_manager_.HasBytesToRead()) {
+    iovec iov;
+    int num_iov = GetReadableRegions(&iov, /*iov_len=*/1);
+    if (num_iov == 0) {
+      break;
+    }
+    if (!capsule_parser_->IngestCapsuleFragment(absl::string_view(
+            reinterpret_cast<const char*>(iov.iov_base), iov.iov_len))) {
+      break;
+    }
+    MarkConsumed(iov.iov_len);
+  }
+  // If we received a FIN, make sure that there isn't a partial capsule buffered
+  // in the capsule parser.
+  if (sequencer()->IsClosed()) {
+    capsule_parser_->ErrorIfThereIsRemainingBufferedData();
+    if (web_transport_ != nullptr) {
+      web_transport_->OnConnectStreamFinReceived();
+    }
+    OnFinRead();
+  }
+}
+
+namespace {
+// Return true if |c| is not allowed in an HTTP/3 wire-encoded header and
+// pseudo-header names according to
+// https://datatracker.ietf.org/doc/html/draft-ietf-quic-http#section-4.1.1 and
+// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-semantics-19#section-5.6.2
+constexpr bool isInvalidHeaderNameCharacter(unsigned char c) {
+  if (c == '!' || c == '|' || c == '~' || c == '*' || c == '+' || c == '-' ||
+      c == '.' ||
+      // #, $, %, &, '
+      (c >= '#' && c <= '\'') ||
+      // [0-9], :
+      (c >= '0' && c <= ':') ||
+      // ^, _, `, [a-z]
+      (c >= '^' && c <= 'z')) {
+    return false;
+  }
+  return true;
+}
+}  // namespace
+
+bool QuicSpdyStream::AreHeadersValid(const QuicHeaderList& header_list) const {
+  QUICHE_DCHECK(GetQuicReloadableFlag(quic_verify_request_headers_2));
+  for (const std::pair<std::string, std::string>& pair : header_list) {
+    const std::string& name = pair.first;
+    if (std::any_of(name.begin(), name.end(), isInvalidHeaderNameCharacter)) {
+      QUIC_DLOG(ERROR) << "Invalid request header " << name;
+      return false;
+    }
+    if (http2::GetInvalidHttp2HeaderSet().contains(name)) {
+      QUIC_DLOG(ERROR) << name << " header is not allowed";
+      return false;
+    }
+  }
+  return true;
+}
+
+void QuicSpdyStream::OnInvalidHeaders() { Reset(QUIC_BAD_APPLICATION_PAYLOAD); }
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_stream.h b/quiche/quic/core/http/quic_spdy_stream.h
new file mode 100644
index 0000000..b7fc714
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream.h
@@ -0,0 +1,540 @@
+// Copyright 2013 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 streams which deliver data to/from an application.
+// In each direction, the data on such a stream first contains compressed
+// headers then body data.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
+
+#include <sys/types.h>
+
+#include <cstddef>
+#include <list>
+#include <memory>
+#include <string>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/http/capsule.h"
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/http/quic_spdy_stream_body_manager.h"
+#include "quiche/quic/core/http/web_transport_stream_adapter.h"
+#include "quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/spdy/core/spdy_framer.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+namespace test {
+class QuicSpdyStreamPeer;
+class QuicStreamPeer;
+}  // namespace test
+
+class QuicSpdySession;
+class WebTransportHttp3;
+
+// A QUIC stream that can send and receive HTTP2 (SPDY) headers.
+class QUIC_EXPORT_PRIVATE QuicSpdyStream
+    : public QuicStream,
+      public CapsuleParser::Visitor,
+      public QpackDecodedHeadersAccumulator::Visitor {
+ public:
+  // Visitor receives callbacks from the stream.
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    Visitor() {}
+    Visitor(const Visitor&) = delete;
+    Visitor& operator=(const Visitor&) = delete;
+
+    // Called when the stream is closed.
+    virtual void OnClose(QuicSpdyStream* stream) = 0;
+
+    // Allows subclasses to override and do work.
+    virtual void OnPromiseHeadersComplete(QuicStreamId /*promised_id*/,
+                                          size_t /*frame_len*/) {}
+
+   protected:
+    virtual ~Visitor() {}
+  };
+
+  QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
+                 StreamType type);
+  QuicSpdyStream(PendingStream* pending, QuicSpdySession* spdy_session);
+  QuicSpdyStream(const QuicSpdyStream&) = delete;
+  QuicSpdyStream& operator=(const QuicSpdyStream&) = delete;
+  ~QuicSpdyStream() override;
+
+  // QuicStream implementation
+  void OnClose() override;
+
+  // Override to maybe close the write side after writing.
+  void OnCanWrite() override;
+
+  // Called by the session when headers with a priority have been received
+  // for this stream.  This method will only be called for server streams.
+  virtual void OnStreamHeadersPriority(
+      const spdy::SpdyStreamPrecedence& precedence);
+
+  // Called by the session when decompressed headers have been completely
+  // delivered to this stream.  If |fin| is true, then this stream
+  // should be closed; no more data will be sent by the peer.
+  virtual void OnStreamHeaderList(bool fin, size_t frame_len,
+                                  const QuicHeaderList& header_list);
+
+  // Called by the session when decompressed push promise headers have
+  // been completely delivered to this stream.
+  virtual void OnPromiseHeaderList(QuicStreamId promised_id, size_t frame_len,
+                                   const QuicHeaderList& header_list);
+
+  // Called by the session when a PRIORITY frame has been been received for this
+  // stream. This method will only be called for server streams.
+  void OnPriorityFrame(const spdy::SpdyStreamPrecedence& precedence);
+
+  // Override the base class to not discard response when receiving
+  // QUIC_STREAM_NO_ERROR.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+  void ResetWithError(QuicResetStreamError error) override;
+  bool OnStopSending(QuicResetStreamError error) override;
+
+  // Called by the sequencer when new data is available. Decodes the data and
+  // calls OnBodyAvailable() to pass to the upper layer.
+  void OnDataAvailable() override;
+
+  // Called in OnDataAvailable() after it finishes the decoding job.
+  virtual void OnBodyAvailable() = 0;
+
+  // Writes the headers contained in |header_block| on the dedicated headers
+  // stream or on this stream, depending on VersionUsesHttp3().  Returns the
+  // number of bytes sent, including data sent on the encoder stream when using
+  // QPACK.
+  virtual size_t WriteHeaders(
+      spdy::SpdyHeaderBlock header_block, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Sends |data| to the peer, or buffers if it can't be sent immediately.
+  void WriteOrBufferBody(absl::string_view data, bool fin);
+
+  // Writes the trailers contained in |trailer_block| on the dedicated headers
+  // stream or on this stream, depending on VersionUsesHttp3().  Trailers will
+  // always have the FIN flag set.  Returns the number of bytes sent, including
+  // data sent on the encoder stream when using QPACK.
+  virtual size_t WriteTrailers(
+      spdy::SpdyHeaderBlock trailer_block,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Override to report newly acked bytes via ack_listener_.
+  bool OnStreamFrameAcked(QuicStreamOffset offset, QuicByteCount data_length,
+                          bool fin_acked, QuicTime::Delta ack_delay_time,
+                          QuicTime receive_timestamp,
+                          QuicByteCount* newly_acked_length) override;
+
+  // Override to report bytes retransmitted via ack_listener_.
+  void OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                  QuicByteCount data_length,
+                                  bool fin_retransmitted) override;
+
+  // Does the same thing as WriteOrBufferBody except this method takes iovec
+  // as the data input. Right now it only calls WritevData.
+  QuicConsumedData WritevBody(const struct iovec* iov, int count, bool fin);
+
+  // Does the same thing as WriteOrBufferBody except this method takes
+  // memslicespan as the data input. Right now it only calls WriteMemSlices.
+  QuicConsumedData WriteBodySlices(absl::Span<quiche::QuicheMemSlice> slices,
+                                   bool fin);
+
+  // Marks the trailers as consumed. This applies to the case where this object
+  // receives headers and trailers as QuicHeaderLists via calls to
+  // OnStreamHeaderList(). Trailer data will be consumed from the sequencer only
+  // once all body data has been consumed.
+  void MarkTrailersConsumed();
+
+  // Clears |header_list_|.
+  void ConsumeHeaderList();
+
+  // This block of functions wraps the sequencer's functions of the same
+  // name.  These methods return uncompressed data until that has
+  // been fully processed.  Then they simply delegate to the sequencer.
+  virtual size_t Readv(const struct iovec* iov, size_t iov_len);
+  virtual int GetReadableRegions(iovec* iov, size_t iov_len) const;
+  void MarkConsumed(size_t num_bytes);
+
+  // Returns true if header contains a valid 3-digit status and parse the status
+  // code to |status_code|.
+  static bool ParseHeaderStatusCode(const spdy::SpdyHeaderBlock& header,
+                                    int* status_code);
+
+  // Returns true when all data from the peer has been read and consumed,
+  // including the fin.
+  bool IsDoneReading() const;
+  bool HasBytesToRead() const;
+
+  void set_visitor(Visitor* visitor) { visitor_ = visitor; }
+
+  bool headers_decompressed() const { return headers_decompressed_; }
+
+  // Returns total amount of body bytes that have been read.
+  uint64_t total_body_bytes_read() const;
+
+  const QuicHeaderList& header_list() const { return header_list_; }
+
+  bool trailers_decompressed() const { return trailers_decompressed_; }
+
+  // Returns whatever trailers have been received for this stream.
+  const spdy::SpdyHeaderBlock& received_trailers() const {
+    return received_trailers_;
+  }
+
+  // Returns true if headers have been fully read and consumed.
+  bool FinishedReadingHeaders() const;
+
+  // Returns true if FIN has been received and either trailers have been fully
+  // read and consumed or there are no trailers.
+  bool FinishedReadingTrailers() const;
+
+  // Returns true if the sequencer has delivered the FIN, and no more body bytes
+  // will be available.
+  bool IsSequencerClosed() { return sequencer()->IsClosed(); }
+
+  // QpackDecodedHeadersAccumulator::Visitor implementation.
+  void OnHeadersDecoded(QuicHeaderList headers,
+                        bool header_list_size_limit_exceeded) override;
+  void OnHeaderDecodingError(QuicErrorCode error_code,
+                             absl::string_view error_message) override;
+
+  QuicSpdySession* spdy_session() const { return spdy_session_; }
+
+  // Send PRIORITY_UPDATE frame and update |last_sent_urgency_| if
+  // |last_sent_urgency_| is different from current priority.
+  void MaybeSendPriorityUpdateFrame() override;
+
+  // Returns the WebTransport session owned by this stream, if one exists.
+  WebTransportHttp3* web_transport() { return web_transport_.get(); }
+
+  // Returns the WebTransport data stream associated with this QUIC stream, or
+  // null if this is not a WebTransport data stream.
+  WebTransportStream* web_transport_stream() {
+    if (web_transport_data_ == nullptr) {
+      return nullptr;
+    }
+    return &web_transport_data_->adapter;
+  }
+
+  // Sends a WEBTRANSPORT_STREAM frame and sets up the appropriate metadata.
+  void ConvertToWebTransportDataStream(WebTransportSessionId session_id);
+
+  void OnCanWriteNewData() override;
+
+  // If this stream is a WebTransport data stream, closes the connection with an
+  // error, and returns false.
+  bool AssertNotWebTransportDataStream(absl::string_view operation);
+
+  // Indicates whether a call to WriteBodySlices will be successful and not
+  // rejected due to buffer being full.  |write_size| must be non-zero.
+  bool CanWriteNewBodyData(QuicByteCount write_size) const;
+
+  // From CapsuleParser::Visitor.
+  bool OnCapsule(const Capsule& capsule) override;
+  void OnCapsuleParseFailure(const std::string& error_message) override;
+
+  // Sends an HTTP/3 datagram. The stream and context IDs are not part of
+  // |payload|.
+  MessageStatus SendHttp3Datagram(
+      absl::optional<QuicDatagramContextId> context_id,
+      absl::string_view payload);
+
+  class QUIC_EXPORT_PRIVATE Http3DatagramVisitor {
+   public:
+    virtual ~Http3DatagramVisitor() {}
+
+    // Called when an HTTP/3 datagram is received. |payload| does not contain
+    // the stream or context IDs. Note that this contains the stream ID even if
+    // flow IDs from draft-ietf-masque-h3-datagram-00 are in use.
+    virtual void OnHttp3Datagram(
+        QuicStreamId stream_id,
+        absl::optional<QuicDatagramContextId> context_id,
+        absl::string_view payload) = 0;
+  };
+
+  class QUIC_EXPORT_PRIVATE Http3DatagramRegistrationVisitor {
+   public:
+    virtual ~Http3DatagramRegistrationVisitor() {}
+
+    // Called when a REGISTER_DATAGRAM_CONTEXT or REGISTER_DATAGRAM_NO_CONTEXT
+    // capsule is received. Note that this contains the stream ID even if flow
+    // IDs from draft-ietf-masque-h3-datagram-00 are in use.
+    virtual void OnContextReceived(
+        QuicStreamId stream_id,
+        absl::optional<QuicDatagramContextId> context_id,
+        DatagramFormatType format_type,
+        absl::string_view format_additional_data) = 0;
+
+    // Called when a CLOSE_DATAGRAM_CONTEXT capsule is received. Note that this
+    // contains the stream ID even if flow IDs from
+    // draft-ietf-masque-h3-datagram-00 are in use.
+    virtual void OnContextClosed(
+        QuicStreamId stream_id,
+        absl::optional<QuicDatagramContextId> context_id,
+        ContextCloseCode close_code, absl::string_view close_details) = 0;
+  };
+
+  // Registers |visitor| to receive HTTP/3 datagram context registrations. This
+  // must not be called without first calling
+  // UnregisterHttp3DatagramRegistrationVisitor. |visitor| must be valid until a
+  // corresponding call to UnregisterHttp3DatagramRegistrationVisitor.
+  void RegisterHttp3DatagramRegistrationVisitor(
+      Http3DatagramRegistrationVisitor* visitor,
+      bool use_datagram_contexts = false);
+
+  // Unregisters for HTTP/3 datagram context registrations. Must not be called
+  // unless previously registered.
+  void UnregisterHttp3DatagramRegistrationVisitor();
+
+  // Moves an HTTP/3 datagram registration to a different visitor. Mainly meant
+  // to be used by the visitors' move operators.
+  void MoveHttp3DatagramRegistration(Http3DatagramRegistrationVisitor* visitor);
+
+  // Registers |visitor| to receive HTTP/3 datagrams for optional context ID
+  // |context_id|. This must not be called on a previously registered context ID
+  // without first calling UnregisterHttp3DatagramContextId. |visitor| must be
+  // valid until a corresponding call to UnregisterHttp3DatagramContextId. If
+  // this method is called multiple times, the context ID MUST either be always
+  // present, or always absent.
+  void RegisterHttp3DatagramContextId(
+      absl::optional<QuicDatagramContextId> context_id,
+      DatagramFormatType format_type, absl::string_view format_additional_data,
+      Http3DatagramVisitor* visitor);
+
+  // Unregisters an HTTP/3 datagram context ID. Must be called on a previously
+  // registered context.
+  void UnregisterHttp3DatagramContextId(
+      absl::optional<QuicDatagramContextId> context_id);
+
+  // Moves an HTTP/3 datagram context ID to a different visitor. Mainly meant
+  // to be used by the visitors' move operators.
+  void MoveHttp3DatagramContextIdRegistration(
+      absl::optional<QuicDatagramContextId> context_id,
+      Http3DatagramVisitor* visitor);
+
+  // Sets max datagram time in queue.
+  void SetMaxDatagramTimeInQueue(QuicTime::Delta max_time_in_queue);
+
+  // Generates a new HTTP/3 datagram context ID for this stream. A datagram
+  // registration visitor must be currently registered on this stream.
+  QuicDatagramContextId GetNextDatagramContextId();
+
+  void OnDatagramReceived(QuicDataReader* reader);
+
+  void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
+
+  QuicByteCount GetMaxDatagramSize(
+      absl::optional<QuicDatagramContextId> context_id) const;
+
+  // Writes |capsule| onto the DATA stream.
+  void WriteCapsule(const Capsule& capsule, bool fin = false);
+
+  void WriteGreaseCapsule();
+
+ protected:
+  // Called when the received headers are too large. By default this will
+  // reset the stream.
+  virtual void OnHeadersTooLarge();
+
+  virtual void OnInitialHeadersComplete(bool fin, size_t frame_len,
+                                        const QuicHeaderList& header_list);
+  virtual void OnTrailingHeadersComplete(bool fin, size_t frame_len,
+                                         const QuicHeaderList& header_list);
+  virtual size_t WriteHeadersImpl(
+      spdy::SpdyHeaderBlock header_block, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  Visitor* visitor() { return visitor_; }
+
+  void set_headers_decompressed(bool val) { headers_decompressed_ = val; }
+
+  void set_ack_listener(
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener) {
+    ack_listener_ = std::move(ack_listener);
+  }
+
+  void OnWriteSideInDataRecvdState() override;
+
+  virtual bool AreHeadersValid(const QuicHeaderList& header_list) const;
+
+  // Reset stream upon invalid request headers.
+  virtual void OnInvalidHeaders();
+
+ private:
+  friend class test::QuicSpdyStreamPeer;
+  friend class test::QuicStreamPeer;
+  friend class QuicStreamUtils;
+  class HttpDecoderVisitor;
+
+  struct QUIC_EXPORT_PRIVATE WebTransportDataStream {
+    WebTransportDataStream(QuicSpdyStream* stream,
+                           WebTransportSessionId session_id);
+
+    WebTransportSessionId session_id;
+    WebTransportStreamAdapter adapter;
+  };
+
+  // Reason codes for `qpack_decoded_headers_accumulator_` being nullptr.
+  enum class QpackDecodedHeadersAccumulatorResetReason {
+    // `qpack_decoded_headers_accumulator_` was default constructed to nullptr.
+    kUnSet = 0,
+    // `qpack_decoded_headers_accumulator_` was reset in the corresponding
+    // method.
+    kResetInOnHeadersDecoded = 1,
+    kResetInOnHeaderDecodingError = 2,
+    kResetInOnStreamReset1 = 3,
+    kResetInOnStreamReset2 = 4,
+    kResetInResetWithError = 5,
+    kResetInOnClose = 6,
+  };
+
+  // Called by HttpDecoderVisitor.
+  bool OnDataFrameStart(QuicByteCount header_length,
+                        QuicByteCount payload_length);
+  bool OnDataFramePayload(absl::string_view payload);
+  bool OnDataFrameEnd();
+  bool OnHeadersFrameStart(QuicByteCount header_length,
+                           QuicByteCount payload_length);
+  bool OnHeadersFramePayload(absl::string_view payload);
+  bool OnHeadersFrameEnd();
+  void OnWebTransportStreamFrameType(QuicByteCount header_length,
+                                     WebTransportSessionId session_id);
+  bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length,
+                           QuicByteCount payload_length);
+  bool OnUnknownFramePayload(absl::string_view payload);
+  bool OnUnknownFrameEnd();
+
+  // Given the interval marked by [|offset|, |offset| + |data_length|), return
+  // the number of frame header bytes contained in it.
+  QuicByteCount GetNumFrameHeadersInInterval(QuicStreamOffset offset,
+                                             QuicByteCount data_length) const;
+
+  void MaybeProcessSentWebTransportHeaders(spdy::SpdyHeaderBlock& headers);
+  void MaybeProcessReceivedWebTransportHeaders();
+
+  // Writes HTTP/3 DATA frame header. If |force_write| is true, use
+  // WriteOrBufferData if send buffer cannot accomodate the header + data.
+  ABSL_MUST_USE_RESULT bool WriteDataFrameHeader(QuicByteCount data_length,
+                                                 bool force_write);
+
+  // Simply calls OnBodyAvailable() unless capsules are in use, in which case
+  // pass the capsule fragments to the capsule manager.
+  void HandleBodyAvailable();
+
+  // Called when a datagram frame or capsule is received.
+  void HandleReceivedDatagram(absl::optional<QuicDatagramContextId> context_id,
+                              absl::string_view payload);
+
+  // Whether datagram contexts should be used on this stream.
+  bool ShouldUseDatagramContexts() const;
+
+  QuicSpdySession* spdy_session_;
+
+  bool on_body_available_called_because_sequencer_is_closed_;
+
+  Visitor* visitor_;
+
+  // True if read side processing is blocked while waiting for callback from
+  // QPACK decoder.
+  bool blocked_on_decoding_headers_;
+  // True if the headers have been completely decompressed.
+  bool headers_decompressed_;
+  // True if uncompressed headers or trailers exceed maximum allowed size
+  // advertised to peer via SETTINGS_MAX_HEADER_LIST_SIZE.
+  bool header_list_size_limit_exceeded_;
+  // Contains a copy of the decompressed header (name, value) pairs until they
+  // are consumed via Readv.
+  QuicHeaderList header_list_;
+  // Length of most recently received HEADERS frame payload.
+  QuicByteCount headers_payload_length_;
+
+  // True if the trailers have been completely decompressed.
+  bool trailers_decompressed_;
+  // True if the trailers have been consumed.
+  bool trailers_consumed_;
+
+  // The parsed trailers received from the peer.
+  spdy::SpdyHeaderBlock received_trailers_;
+
+  // Headers accumulator for decoding HEADERS frame payload.
+  std::unique_ptr<QpackDecodedHeadersAccumulator>
+      qpack_decoded_headers_accumulator_;
+  // Reason for `qpack_decoded_headers_accumulator_` being nullptr.
+  QpackDecodedHeadersAccumulatorResetReason
+      qpack_decoded_headers_accumulator_reset_reason_;
+  // Visitor of the HttpDecoder.
+  std::unique_ptr<HttpDecoderVisitor> http_decoder_visitor_;
+  // HttpDecoder for processing raw incoming stream frames.
+  HttpDecoder decoder_;
+  // Object that manages references to DATA frame payload fragments buffered by
+  // the sequencer and calculates how much data should be marked consumed with
+  // the sequencer each time new stream data is processed.
+  QuicSpdyStreamBodyManager body_manager_;
+
+  std::unique_ptr<CapsuleParser> capsule_parser_;
+
+  // Sequencer offset keeping track of how much data HttpDecoder has processed.
+  // Initial value is zero for fresh streams, or sequencer()->NumBytesConsumed()
+  // at time of construction if a PendingStream is converted to account for the
+  // length of the unidirectional stream type at the beginning of the stream.
+  QuicStreamOffset sequencer_offset_;
+
+  // True when inside an HttpDecoder::ProcessInput() call.
+  // Used for detecting reentrancy.
+  bool is_decoder_processing_input_;
+
+  // Ack listener of this stream, and it is notified when any of written bytes
+  // are acked or retransmitted.
+  quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface> ack_listener_;
+
+  // Offset of unacked frame headers.
+  QuicIntervalSet<QuicStreamOffset> unacked_frame_headers_offsets_;
+
+  // Urgency value sent in the last PRIORITY_UPDATE frame, or default urgency
+  // defined by the spec if no PRIORITY_UPDATE frame has been sent.
+  int last_sent_urgency_;
+
+  // If this stream is a WebTransport extended CONNECT stream, contains the
+  // WebTransport session associated with this stream.
+  std::unique_ptr<WebTransportHttp3> web_transport_;
+
+  // If this stream is a WebTransport data stream, |web_transport_data_|
+  // contains all of the associated metadata.
+  std::unique_ptr<WebTransportDataStream> web_transport_data_;
+
+  // HTTP/3 Datagram support.
+  Http3DatagramRegistrationVisitor* datagram_registration_visitor_ = nullptr;
+  Http3DatagramVisitor* datagram_no_context_visitor_ = nullptr;
+  absl::optional<QuicDatagramStreamId> datagram_flow_id_;
+  QuicDatagramContextId datagram_next_available_context_id_;
+  absl::flat_hash_map<QuicDatagramContextId, Http3DatagramVisitor*>
+      datagram_context_visitors_;
+  bool use_datagram_contexts_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
diff --git a/quiche/quic/core/http/quic_spdy_stream_body_manager.cc b/quiche/quic/core/http/quic_spdy_stream_body_manager.cc
new file mode 100644
index 0000000..d1ba5d2
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream_body_manager.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2018 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 "quiche/quic/core/http/quic_spdy_stream_body_manager.h"
+
+#include <algorithm>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSpdyStreamBodyManager::QuicSpdyStreamBodyManager()
+    : total_body_bytes_received_(0) {}
+
+size_t QuicSpdyStreamBodyManager::OnNonBody(QuicByteCount length) {
+  QUICHE_DCHECK_NE(0u, length);
+
+  if (fragments_.empty()) {
+    // Non-body bytes can be consumed immediately, because all previously
+    // received body bytes have been read.
+    return length;
+  }
+
+  // Non-body bytes will be consumed after last body fragment is read.
+  fragments_.back().trailing_non_body_byte_count += length;
+  return 0;
+}
+
+void QuicSpdyStreamBodyManager::OnBody(absl::string_view body) {
+  QUICHE_DCHECK(!body.empty());
+
+  fragments_.push_back({body, 0});
+  total_body_bytes_received_ += body.length();
+}
+
+size_t QuicSpdyStreamBodyManager::OnBodyConsumed(size_t num_bytes) {
+  QuicByteCount bytes_to_consume = 0;
+  size_t remaining_bytes = num_bytes;
+
+  while (remaining_bytes > 0) {
+    if (fragments_.empty()) {
+      QUIC_BUG(quic_bug_10394_1) << "Not enough available body to consume.";
+      return 0;
+    }
+
+    Fragment& fragment = fragments_.front();
+    const absl::string_view body = fragment.body;
+
+    if (body.length() > remaining_bytes) {
+      // Consume leading |remaining_bytes| bytes of body.
+      bytes_to_consume += remaining_bytes;
+      fragment.body = body.substr(remaining_bytes);
+      return bytes_to_consume;
+    }
+
+    // Consume entire fragment and the following
+    // |trailing_non_body_byte_count| bytes.
+    remaining_bytes -= body.length();
+    bytes_to_consume += body.length() + fragment.trailing_non_body_byte_count;
+    fragments_.pop_front();
+  }
+
+  return bytes_to_consume;
+}
+
+int QuicSpdyStreamBodyManager::PeekBody(iovec* iov, size_t iov_len) const {
+  QUICHE_DCHECK(iov);
+  QUICHE_DCHECK_GT(iov_len, 0u);
+
+  // TODO(bnc): Is this really necessary?
+  if (fragments_.empty()) {
+    iov[0].iov_base = nullptr;
+    iov[0].iov_len = 0;
+    return 0;
+  }
+
+  size_t iov_filled = 0;
+  while (iov_filled < fragments_.size() && iov_filled < iov_len) {
+    absl::string_view body = fragments_[iov_filled].body;
+    iov[iov_filled].iov_base = const_cast<char*>(body.data());
+    iov[iov_filled].iov_len = body.size();
+    iov_filled++;
+  }
+
+  return iov_filled;
+}
+
+size_t QuicSpdyStreamBodyManager::ReadBody(const struct iovec* iov,
+                                           size_t iov_len,
+                                           size_t* total_bytes_read) {
+  *total_bytes_read = 0;
+  QuicByteCount bytes_to_consume = 0;
+
+  // The index of iovec to write to.
+  size_t index = 0;
+  // Address to write to within current iovec.
+  char* dest = reinterpret_cast<char*>(iov[index].iov_base);
+  // Remaining space in current iovec.
+  size_t dest_remaining = iov[index].iov_len;
+
+  while (!fragments_.empty()) {
+    Fragment& fragment = fragments_.front();
+    const absl::string_view body = fragment.body;
+
+    const size_t bytes_to_copy =
+        std::min<size_t>(body.length(), dest_remaining);
+    memcpy(dest, body.data(), bytes_to_copy);
+    bytes_to_consume += bytes_to_copy;
+    *total_bytes_read += bytes_to_copy;
+
+    if (bytes_to_copy == body.length()) {
+      // Entire fragment read.
+      bytes_to_consume += fragment.trailing_non_body_byte_count;
+      fragments_.pop_front();
+    } else {
+      // Consume leading |bytes_to_copy| bytes of body.
+      fragment.body = body.substr(bytes_to_copy);
+    }
+
+    if (bytes_to_copy == dest_remaining) {
+      // Current iovec full.
+      ++index;
+      if (index == iov_len) {
+        break;
+      }
+      dest = reinterpret_cast<char*>(iov[index].iov_base);
+      dest_remaining = iov[index].iov_len;
+    } else {
+      // Advance destination parameters within this iovec.
+      dest += bytes_to_copy;
+      dest_remaining -= bytes_to_copy;
+    }
+  }
+
+  return bytes_to_consume;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_stream_body_manager.h b/quiche/quic/core/http/quic_spdy_stream_body_manager.h
new file mode 100644
index 0000000..fbd4420
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream_body_manager.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2018 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_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_iovec.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+// All data that a request stream receives falls into one of two categories:
+//  * "body", that is, DATA frame payload, which the QuicStreamSequencer must
+//    buffer until it is read;
+//  * everything else, which QuicSpdyStream immediately processes and thus could
+//    be marked as consumed with QuicStreamSequencer, unless there is some piece
+//    of body received prior that still needs to be buffered.
+// QuicSpdyStreamBodyManager does two things: it keeps references to body
+// fragments (owned by QuicStreamSequencer) and offers methods to read them; and
+// it calculates the total number of bytes (including non-body bytes) the caller
+// needs to mark consumed (with QuicStreamSequencer) when non-body bytes are
+// received or when body is consumed.
+class QUIC_EXPORT_PRIVATE QuicSpdyStreamBodyManager {
+ public:
+  QuicSpdyStreamBodyManager();
+  ~QuicSpdyStreamBodyManager() = default;
+
+  // One of the following two methods must be called every time data is received
+  // on the request stream.
+
+  // Called when data that could immediately be marked consumed with the
+  // sequencer (provided that all previous body fragments are consumed) is
+  // received.  |length| must be positive.  Returns number of bytes the caller
+  // must mark consumed, which might be zero.
+  ABSL_MUST_USE_RESULT size_t OnNonBody(QuicByteCount length);
+
+  // Called when body is received.  |body| is added to |fragments_|.  The data
+  // pointed to by |body| must be kept alive until an OnBodyConsumed() or
+  // ReadBody() call consumes it.  |body| must not be empty.
+  void OnBody(absl::string_view body);
+
+  // Internally marks |num_bytes| of body consumed.  |num_bytes| might be zero.
+  // Returns the number of bytes that the caller should mark consumed with the
+  // sequencer, which is the sum of |num_bytes| for body, and the number of any
+  // interleaving or immediately trailing non-body bytes.
+  ABSL_MUST_USE_RESULT size_t OnBodyConsumed(size_t num_bytes);
+
+  // Set up to |iov_len| elements of iov[] to point to available bodies: each
+  // iov[i].iov_base will point to a body fragment, and iov[i].iov_len will be
+  // set to its length.  No data is copied, no data is consumed.  Returns the
+  // number of iov set.
+  int PeekBody(iovec* iov, size_t iov_len) const;
+
+  // Copies data from available bodies into at most |iov_len| elements of iov[].
+  // Internally consumes copied body bytes as well as all interleaving and
+  // immediately trailing non-body bytes.  |iov.iov_base| and |iov.iov_len| are
+  // preassigned and will not be changed.  Returns the total number of bytes the
+  // caller shall mark consumed.  Sets |*total_bytes_read| to the total number
+  // of body bytes read.
+  ABSL_MUST_USE_RESULT size_t ReadBody(const struct iovec* iov,
+                                       size_t iov_len,
+                                       size_t* total_bytes_read);
+
+  bool HasBytesToRead() const { return !fragments_.empty(); }
+
+  uint64_t total_body_bytes_received() const {
+    return total_body_bytes_received_;
+  }
+
+ private:
+  // A Fragment instance represents a body fragment with a count of bytes
+  // received afterwards but before the next body fragment that can be marked
+  // consumed as soon as all of the body fragment is read.
+  struct QUIC_EXPORT_PRIVATE Fragment {
+    // |body| must not be empty.
+    absl::string_view body;
+    // Might be zero.
+    QuicByteCount trailing_non_body_byte_count;
+  };
+  // Queue of body fragments and trailing non-body byte counts.
+  quiche::QuicheCircularDeque<Fragment> fragments_;
+  // Total body bytes received.
+  QuicByteCount total_body_bytes_received_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
diff --git a/quiche/quic/core/http/quic_spdy_stream_body_manager_test.cc b/quiche/quic/core/http/quic_spdy_stream_body_manager_test.cc
new file mode 100644
index 0000000..7eca731
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream_body_manager_test.cc
@@ -0,0 +1,286 @@
+// Copyright (c) 2018 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 "quiche/quic/core/http/quic_spdy_stream_body_manager.h"
+
+#include <algorithm>
+#include <numeric>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+class QuicSpdyStreamBodyManagerTest : public QuicTest {
+ protected:
+  QuicSpdyStreamBodyManager body_manager_;
+};
+
+TEST_F(QuicSpdyStreamBodyManagerTest, HasBytesToRead) {
+  EXPECT_FALSE(body_manager_.HasBytesToRead());
+  EXPECT_EQ(0u, body_manager_.total_body_bytes_received());
+
+  const QuicByteCount header_length = 3;
+  EXPECT_EQ(header_length, body_manager_.OnNonBody(header_length));
+
+  EXPECT_FALSE(body_manager_.HasBytesToRead());
+  EXPECT_EQ(0u, body_manager_.total_body_bytes_received());
+
+  std::string body(1024, 'a');
+  body_manager_.OnBody(body);
+
+  EXPECT_TRUE(body_manager_.HasBytesToRead());
+  EXPECT_EQ(1024u, body_manager_.total_body_bytes_received());
+}
+
+TEST_F(QuicSpdyStreamBodyManagerTest, ConsumeMoreThanAvailable) {
+  std::string body(1024, 'a');
+  body_manager_.OnBody(body);
+  size_t bytes_to_consume = 0;
+  EXPECT_QUIC_BUG(bytes_to_consume = body_manager_.OnBodyConsumed(2048),
+                  "Not enough available body to consume.");
+  EXPECT_EQ(0u, bytes_to_consume);
+}
+
+TEST_F(QuicSpdyStreamBodyManagerTest, OnBodyConsumed) {
+  struct {
+    std::vector<QuicByteCount> frame_header_lengths;
+    std::vector<const char*> frame_payloads;
+    std::vector<QuicByteCount> body_bytes_to_read;
+    std::vector<QuicByteCount> expected_return_values;
+  } const kOnBodyConsumedTestData[] = {
+      // One frame consumed in one call.
+      {{2}, {"foobar"}, {6}, {6}},
+      // Two frames consumed in one call.
+      {{3, 5}, {"foobar", "baz"}, {9}, {14}},
+      // One frame consumed in two calls.
+      {{2}, {"foobar"}, {4, 2}, {4, 2}},
+      // Two frames consumed in two calls matching frame boundaries.
+      {{3, 5}, {"foobar", "baz"}, {6, 3}, {11, 3}},
+      // Two frames consumed in two calls,
+      // the first call only consuming part of the first frame.
+      {{3, 5}, {"foobar", "baz"}, {5, 4}, {5, 9}},
+      // Two frames consumed in two calls,
+      // the first call consuming the entire first frame and part of the second.
+      {{3, 5}, {"foobar", "baz"}, {7, 2}, {12, 2}},
+  };
+
+  for (size_t test_case_index = 0;
+       test_case_index < ABSL_ARRAYSIZE(kOnBodyConsumedTestData);
+       ++test_case_index) {
+    const std::vector<QuicByteCount>& frame_header_lengths =
+        kOnBodyConsumedTestData[test_case_index].frame_header_lengths;
+    const std::vector<const char*>& frame_payloads =
+        kOnBodyConsumedTestData[test_case_index].frame_payloads;
+    const std::vector<QuicByteCount>& body_bytes_to_read =
+        kOnBodyConsumedTestData[test_case_index].body_bytes_to_read;
+    const std::vector<QuicByteCount>& expected_return_values =
+        kOnBodyConsumedTestData[test_case_index].expected_return_values;
+
+    for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
+         ++frame_index) {
+      // Frame header of first frame can immediately be consumed, but not the
+      // other frames.  Each test case start with an empty
+      // QuicSpdyStreamBodyManager.
+      EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
+                body_manager_.OnNonBody(frame_header_lengths[frame_index]));
+      body_manager_.OnBody(frame_payloads[frame_index]);
+    }
+
+    for (size_t call_index = 0; call_index < body_bytes_to_read.size();
+         ++call_index) {
+      EXPECT_EQ(expected_return_values[call_index],
+                body_manager_.OnBodyConsumed(body_bytes_to_read[call_index]));
+    }
+
+    EXPECT_FALSE(body_manager_.HasBytesToRead());
+  }
+}
+
+TEST_F(QuicSpdyStreamBodyManagerTest, PeekBody) {
+  struct {
+    std::vector<QuicByteCount> frame_header_lengths;
+    std::vector<const char*> frame_payloads;
+    size_t iov_len;
+  } const kPeekBodyTestData[] = {
+      // No frames, more iovecs than frames.
+      {{}, {}, 1},
+      // One frame, same number of iovecs.
+      {{3}, {"foobar"}, 1},
+      // One frame, more iovecs than frames.
+      {{3}, {"foobar"}, 2},
+      // Two frames, fewer iovecs than frames.
+      {{3, 5}, {"foobar", "baz"}, 1},
+      // Two frames, same number of iovecs.
+      {{3, 5}, {"foobar", "baz"}, 2},
+      // Two frames, more iovecs than frames.
+      {{3, 5}, {"foobar", "baz"}, 3},
+  };
+
+  for (size_t test_case_index = 0;
+       test_case_index < ABSL_ARRAYSIZE(kPeekBodyTestData); ++test_case_index) {
+    const std::vector<QuicByteCount>& frame_header_lengths =
+        kPeekBodyTestData[test_case_index].frame_header_lengths;
+    const std::vector<const char*>& frame_payloads =
+        kPeekBodyTestData[test_case_index].frame_payloads;
+    size_t iov_len = kPeekBodyTestData[test_case_index].iov_len;
+
+    QuicSpdyStreamBodyManager body_manager;
+
+    for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
+         ++frame_index) {
+      // Frame header of first frame can immediately be consumed, but not the
+      // other frames.  Each test case uses a new QuicSpdyStreamBodyManager
+      // instance.
+      EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
+                body_manager.OnNonBody(frame_header_lengths[frame_index]));
+      body_manager.OnBody(frame_payloads[frame_index]);
+    }
+
+    std::vector<iovec> iovecs;
+    iovecs.resize(iov_len);
+    size_t iovs_filled = std::min(frame_payloads.size(), iov_len);
+    ASSERT_EQ(iovs_filled,
+              static_cast<size_t>(body_manager.PeekBody(&iovecs[0], iov_len)));
+    for (size_t iovec_index = 0; iovec_index < iovs_filled; ++iovec_index) {
+      EXPECT_EQ(frame_payloads[iovec_index],
+                absl::string_view(
+                    static_cast<const char*>(iovecs[iovec_index].iov_base),
+                    iovecs[iovec_index].iov_len));
+    }
+  }
+}
+
+TEST_F(QuicSpdyStreamBodyManagerTest, ReadBody) {
+  struct {
+    std::vector<QuicByteCount> frame_header_lengths;
+    std::vector<const char*> frame_payloads;
+    std::vector<std::vector<QuicByteCount>> iov_lengths;
+    std::vector<QuicByteCount> expected_total_bytes_read;
+    std::vector<QuicByteCount> expected_return_values;
+  } const kReadBodyTestData[] = {
+      // One frame, one read with smaller iovec.
+      {{4}, {"foo"}, {{2}}, {2}, {2}},
+      // One frame, one read with same size iovec.
+      {{4}, {"foo"}, {{3}}, {3}, {3}},
+      // One frame, one read with larger iovec.
+      {{4}, {"foo"}, {{5}}, {3}, {3}},
+      // One frame, one read with two iovecs, smaller total size.
+      {{4}, {"foobar"}, {{2, 3}}, {5}, {5}},
+      // One frame, one read with two iovecs, same total size.
+      {{4}, {"foobar"}, {{2, 4}}, {6}, {6}},
+      // One frame, one read with two iovecs, larger total size in last iovec.
+      {{4}, {"foobar"}, {{2, 6}}, {6}, {6}},
+      // One frame, one read with extra iovecs, body ends at iovec boundary.
+      {{4}, {"foobar"}, {{2, 4, 4, 3}}, {6}, {6}},
+      // One frame, one read with extra iovecs, body ends not at iovec boundary.
+      {{4}, {"foobar"}, {{2, 7, 4, 3}}, {6}, {6}},
+      // One frame, two reads with two iovecs each, smaller total size.
+      {{4}, {"foobarbaz"}, {{2, 1}, {3, 2}}, {3, 5}, {3, 5}},
+      // One frame, two reads with two iovecs each, same total size.
+      {{4}, {"foobarbaz"}, {{2, 1}, {4, 2}}, {3, 6}, {3, 6}},
+      // One frame, two reads with two iovecs each, larger total size.
+      {{4}, {"foobarbaz"}, {{2, 1}, {4, 10}}, {3, 6}, {3, 6}},
+      // Two frames, one read with smaller iovec.
+      {{4, 3}, {"foobar", "baz"}, {{8}}, {8}, {11}},
+      // Two frames, one read with same size iovec.
+      {{4, 3}, {"foobar", "baz"}, {{9}}, {9}, {12}},
+      // Two frames, one read with larger iovec.
+      {{4, 3}, {"foobar", "baz"}, {{10}}, {9}, {12}},
+      // Two frames, one read with two iovecs, smaller total size.
+      {{4, 3}, {"foobar", "baz"}, {{4, 3}}, {7}, {10}},
+      // Two frames, one read with two iovecs, same total size.
+      {{4, 3}, {"foobar", "baz"}, {{4, 5}}, {9}, {12}},
+      // Two frames, one read with two iovecs, larger total size in last iovec.
+      {{4, 3}, {"foobar", "baz"}, {{4, 6}}, {9}, {12}},
+      // Two frames, one read with extra iovecs, body ends at iovec boundary.
+      {{4, 3}, {"foobar", "baz"}, {{4, 6, 4, 3}}, {9}, {12}},
+      // Two frames, one read with extra iovecs, body ends not at iovec
+      // boundary.
+      {{4, 3}, {"foobar", "baz"}, {{4, 7, 4, 3}}, {9}, {12}},
+      // Two frames, two reads with two iovecs each, reads end on frame
+      // boundary.
+      {{4, 3}, {"foobar", "baz"}, {{2, 4}, {2, 1}}, {6, 3}, {9, 3}},
+      // Three frames, three reads, extra iovecs, no iovec ends on frame
+      // boundary.
+      {{4, 3, 6},
+       {"foobar", "bazquux", "qux"},
+       {{4, 3}, {2, 3}, {5, 3}},
+       {7, 5, 4},
+       {10, 5, 10}},
+  };
+
+  for (size_t test_case_index = 0;
+       test_case_index < ABSL_ARRAYSIZE(kReadBodyTestData); ++test_case_index) {
+    const std::vector<QuicByteCount>& frame_header_lengths =
+        kReadBodyTestData[test_case_index].frame_header_lengths;
+    const std::vector<const char*>& frame_payloads =
+        kReadBodyTestData[test_case_index].frame_payloads;
+    const std::vector<std::vector<QuicByteCount>>& iov_lengths =
+        kReadBodyTestData[test_case_index].iov_lengths;
+    const std::vector<QuicByteCount>& expected_total_bytes_read =
+        kReadBodyTestData[test_case_index].expected_total_bytes_read;
+    const std::vector<QuicByteCount>& expected_return_values =
+        kReadBodyTestData[test_case_index].expected_return_values;
+
+    QuicSpdyStreamBodyManager body_manager;
+
+    std::string received_body;
+
+    for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
+         ++frame_index) {
+      // Frame header of first frame can immediately be consumed, but not the
+      // other frames.  Each test case uses a new QuicSpdyStreamBodyManager
+      // instance.
+      EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
+                body_manager.OnNonBody(frame_header_lengths[frame_index]));
+      body_manager.OnBody(frame_payloads[frame_index]);
+      received_body.append(frame_payloads[frame_index]);
+    }
+
+    std::string read_body;
+
+    for (size_t call_index = 0; call_index < iov_lengths.size(); ++call_index) {
+      // Allocate single buffer for iovecs.
+      size_t total_iov_length = std::accumulate(iov_lengths[call_index].begin(),
+                                                iov_lengths[call_index].end(),
+                                                static_cast<size_t>(0));
+      std::string buffer(total_iov_length, 'z');
+
+      // Construct iovecs pointing to contiguous areas in the buffer.
+      std::vector<iovec> iovecs;
+      size_t offset = 0;
+      for (size_t iov_length : iov_lengths[call_index]) {
+        QUICHE_CHECK(offset + iov_length <= buffer.size());
+        iovecs.push_back({&buffer[offset], iov_length});
+        offset += iov_length;
+      }
+
+      // Make sure |total_bytes_read| differs from |expected_total_bytes_read|.
+      size_t total_bytes_read = expected_total_bytes_read[call_index] + 12;
+      EXPECT_EQ(
+          expected_return_values[call_index],
+          body_manager.ReadBody(&iovecs[0], iovecs.size(), &total_bytes_read));
+      read_body.append(buffer.substr(0, total_bytes_read));
+    }
+
+    EXPECT_EQ(received_body.substr(0, read_body.size()), read_body);
+    EXPECT_EQ(read_body.size() < received_body.size(),
+              body_manager.HasBytesToRead());
+  }
+}
+
+}  // anonymous namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_stream_test.cc b/quiche/quic/core/http/quic_spdy_stream_test.cc
new file mode 100644
index 0000000..b0c972d
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream_test.cc
@@ -0,0 +1,3456 @@
+// Copyright 2013 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 "quiche/quic/core/http/quic_spdy_stream.h"
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_stream_sequencer_buffer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_mem_slice_storage.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+using spdy::kV3HighestPriority;
+using spdy::kV3LowestPriority;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyPriority;
+using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::DoAll;
+using testing::ElementsAre;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::MatchesRegex;
+using testing::Pair;
+using testing::Return;
+using testing::SaveArg;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const bool kShouldProcessData = true;
+const char kDataFramePayload[] = "some data";
+
+class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
+ public:
+  explicit TestCryptoStream(QuicSession* session)
+      : QuicCryptoStream(session),
+        QuicCryptoHandshaker(this, session),
+        encryption_established_(false),
+        one_rtt_keys_available_(false),
+        params_(new QuicCryptoNegotiatedParameters) {
+    // Simulate a negotiated cipher_suite with a fake value.
+    params_->cipher_suite = 1;
+  }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
+    encryption_established_ = true;
+    one_rtt_keys_available_ = true;
+    QuicErrorCode error;
+    std::string error_details;
+    session()->config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session()->config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    if (session()->version().UsesTls()) {
+      if (session()->perspective() == Perspective::IS_CLIENT) {
+        session()->config()->SetOriginalConnectionIdToSend(
+            session()->connection()->connection_id());
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->connection_id());
+      } else {
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->client_connection_id());
+      }
+      TransportParameters transport_parameters;
+      EXPECT_TRUE(
+          session()->config()->FillTransportParameters(&transport_parameters));
+      error = session()->config()->ProcessTransportParameters(
+          transport_parameters, /* is_resumption = */ false, &error_details);
+    } else {
+      CryptoHandshakeMessage msg;
+      session()->config()->ToHandshakeMessage(&msg, transport_version());
+      error =
+          session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
+    }
+    EXPECT_THAT(error, IsQuicNoError());
+    session()->OnNewEncryptionKeyAvailable(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+    session()->OnConfigNegotiated();
+    if (session()->version().UsesTls()) {
+      session()->OnTlsHandshakeComplete();
+    } else {
+      session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    if (session()->version().UsesTls()) {
+      // HANDSHAKE_DONE frame.
+      EXPECT_CALL(*this, HasPendingRetransmission());
+    }
+    session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  }
+
+  // QuicCryptoStream implementation
+  ssl_early_data_reason_t EarlyDataReason() const override {
+    return ssl_early_data_unknown;
+  }
+  bool encryption_established() const override {
+    return encryption_established_;
+  }
+  bool one_rtt_keys_available() const override {
+    return one_rtt_keys_available_;
+  }
+  HandshakeState GetHandshakeState() const override {
+    return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+  }
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override {
+    return *params_;
+  }
+  CryptoMessageParser* crypto_message_parser() override {
+    return QuicCryptoHandshaker::crypto_message_parser();
+  }
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_parameters*/)
+      const override {
+    return "";
+  }
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    return true;
+  }
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    return nullptr;
+  }
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+
+  bool HasPendingCryptoRetransmission() const override { return false; }
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    return false;
+  }
+
+  SSL* GetSsl() const override { return nullptr; }
+
+ private:
+  using QuicCryptoStream::session;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+};
+
+class TestStream : public QuicSpdyStream {
+ public:
+  TestStream(QuicStreamId id, QuicSpdySession* session,
+             bool should_process_data)
+      : QuicSpdyStream(id, session, BIDIRECTIONAL),
+        should_process_data_(should_process_data),
+        headers_payload_length_(0) {}
+  ~TestStream() override = default;
+
+  using QuicSpdyStream::set_ack_listener;
+  using QuicStream::CloseWriteSide;
+  using QuicStream::WriteOrBufferData;
+
+  void OnBodyAvailable() override {
+    if (!should_process_data_) {
+      return;
+    }
+    char buffer[2048];
+    struct iovec vec;
+    vec.iov_base = buffer;
+    vec.iov_len = ABSL_ARRAYSIZE(buffer);
+    size_t bytes_read = Readv(&vec, 1);
+    data_ += std::string(buffer, bytes_read);
+  }
+
+  MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
+
+  size_t WriteHeadersImpl(
+      spdy::SpdyHeaderBlock header_block, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+      /*ack_listener*/) override {
+    saved_headers_ = std::move(header_block);
+    WriteHeadersMock(fin);
+    if (VersionUsesHttp3(transport_version())) {
+      // In this case, call QuicSpdyStream::WriteHeadersImpl() that does the
+      // actual work of closing the stream.
+      return QuicSpdyStream::WriteHeadersImpl(saved_headers_.Clone(), fin,
+                                              nullptr);
+    }
+    return 0;
+  }
+
+  const std::string& data() const { return data_; }
+  const spdy::SpdyHeaderBlock& saved_headers() const { return saved_headers_; }
+
+  // Expose protected accessor.
+  const QuicStreamSequencer* sequencer() const {
+    return QuicStream::sequencer();
+  }
+
+  void OnStreamHeaderList(bool fin, size_t frame_len,
+                          const QuicHeaderList& header_list) override {
+    headers_payload_length_ = frame_len;
+    QuicSpdyStream::OnStreamHeaderList(fin, frame_len, header_list);
+  }
+
+  size_t headers_payload_length() const { return headers_payload_length_; }
+
+  bool AreHeadersValid(const QuicHeaderList& header_list) const override {
+    return !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+           QuicSpdyStream::AreHeadersValid(header_list);
+  }
+
+ private:
+  bool should_process_data_;
+  spdy::SpdyHeaderBlock saved_headers_;
+  std::string data_;
+  size_t headers_payload_length_;
+};
+
+class TestSession : public MockQuicSpdySession {
+ public:
+  explicit TestSession(QuicConnection* connection)
+      : MockQuicSpdySession(connection, /*create_mock_crypto_stream=*/false),
+        crypto_stream_(this) {}
+
+  TestCryptoStream* GetMutableCryptoStream() override {
+    return &crypto_stream_;
+  }
+
+  const TestCryptoStream* GetCryptoStream() const override {
+    return &crypto_stream_;
+  }
+
+  bool ShouldNegotiateWebTransport() override { return enable_webtransport_; }
+  void EnableWebTransport() { enable_webtransport_ = true; }
+
+  HttpDatagramSupport LocalHttpDatagramSupport() override {
+    return local_http_datagram_support_;
+  }
+  void set_local_http_datagram_support(HttpDatagramSupport value) {
+    local_http_datagram_support_ = value;
+  }
+
+ private:
+  bool enable_webtransport_ = false;
+  HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
+  StrictMock<TestCryptoStream> crypto_stream_;
+};
+
+class TestMockUpdateStreamSession : public MockQuicSpdySession {
+ public:
+  explicit TestMockUpdateStreamSession(QuicConnection* connection)
+      : MockQuicSpdySession(connection),
+        expected_precedence_(
+            spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority)) {}
+
+  void UpdateStreamPriority(
+      QuicStreamId id, const spdy::SpdyStreamPrecedence& precedence) override {
+    EXPECT_EQ(id, expected_stream_->id());
+    EXPECT_EQ(expected_precedence_, precedence);
+    EXPECT_EQ(expected_precedence_, expected_stream_->precedence());
+  }
+
+  void SetExpectedStream(QuicSpdyStream* stream) { expected_stream_ = stream; }
+  void SetExpectedPriority(const spdy::SpdyStreamPrecedence& precedence) {
+    expected_precedence_ = precedence;
+  }
+
+ private:
+  QuicSpdyStream* expected_stream_;
+  spdy::SpdyStreamPrecedence expected_precedence_;
+};
+
+class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicSpdyStreamTest() {
+    headers_[":host"] = "www.google.com";
+    headers_[":path"] = "/index.hml";
+    headers_[":scheme"] = "https";
+    headers_["cookie"] =
+        "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
+        "__utmc=160408618; "
+        "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
+        "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
+        "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
+        "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
+        "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
+        "1zFMi5vzcns38-8_Sns; "
+        "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
+        "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
+        "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
+        "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
+        "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
+        "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
+        "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
+        "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
+        "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
+        "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
+        "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
+        "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
+        "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
+        "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
+        "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
+  }
+
+  ~QuicSpdyStreamTest() override = default;
+
+  // Return QPACK-encoded header block without using the dynamic table.
+  std::string EncodeQpackHeaders(
+      std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
+    SpdyHeaderBlock header_block;
+    for (const auto& header_field : headers) {
+      header_block.AppendValueOrAddHeader(header_field.first,
+                                          header_field.second);
+    }
+
+    return EncodeQpackHeaders(header_block);
+  }
+
+  // Return QPACK-encoded header block without using the dynamic table.
+  std::string EncodeQpackHeaders(const SpdyHeaderBlock& header) {
+    NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
+    auto qpack_encoder = std::make_unique<QpackEncoder>(session_.get());
+    qpack_encoder->set_qpack_stream_sender_delegate(
+        &encoder_stream_sender_delegate);
+    // QpackEncoder does not use the dynamic table by default,
+    // therefore the value of |stream_id| does not matter.
+    return qpack_encoder->EncodeHeaderList(/* stream_id = */ 0, header,
+                                           nullptr);
+  }
+
+  void Initialize(bool stream_should_process_data) {
+    InitializeWithPerspective(stream_should_process_data,
+                              Perspective::IS_SERVER);
+  }
+
+  void InitializeWithPerspective(bool stream_should_process_data,
+                                 Perspective perspective) {
+    connection_ = new StrictMock<MockQuicConnection>(
+        &helper_, &alarm_factory_, perspective, SupportedVersions(GetParam()));
+    session_ = std::make_unique<StrictMock<TestSession>>(connection_);
+    EXPECT_CALL(*session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_->Initialize();
+    if (connection_->version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(connection_);
+    }
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    ON_CALL(*session_, WritevData(_, _, _, _, _, _))
+        .WillByDefault(
+            Invoke(session_.get(), &MockQuicSpdySession::ConsumeData));
+
+    stream_ =
+        new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(0),
+                                   session_.get(), stream_should_process_data);
+    session_->ActivateStream(absl::WrapUnique(stream_));
+    stream2_ =
+        new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(1),
+                                   session_.get(), stream_should_process_data);
+    session_->ActivateStream(absl::WrapUnique(stream2_));
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 10);
+    session_->OnConfigNegotiated();
+    if (UsesHttp3()) {
+      // The control stream will write the stream type, a greased frame, and
+      // SETTINGS frame.
+      int num_control_stream_writes = 3;
+      auto send_control_stream =
+          QuicSpdySessionPeer::GetSendControlStream(session_.get());
+      EXPECT_CALL(*session_,
+                  WritevData(send_control_stream->id(), _, _, _, _, _))
+          .Times(num_control_stream_writes);
+    }
+    TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission()).Times(AnyNumber());
+
+    if (connection_->version().UsesTls() &&
+        session_->perspective() == Perspective::IS_SERVER) {
+      // HANDSHAKE_DONE frame.
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+    }
+    CryptoHandshakeMessage message;
+    session_->GetMutableCryptoStream()->OnHandshakeMessage(message);
+  }
+
+  QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) {
+    QuicHeaderList h = AsHeaderList(headers);
+    stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h);
+    return h;
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), n);
+  }
+
+  bool UsesHttp3() const {
+    return VersionUsesHttp3(GetParam().transport_version);
+  }
+
+  // Construct HEADERS frame with QPACK-encoded |headers| without using the
+  // dynamic table.
+  std::string HeadersFrame(
+      std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
+    return HeadersFrame(EncodeQpackHeaders(headers));
+  }
+
+  // Construct HEADERS frame with QPACK-encoded |headers| without using the
+  // dynamic table.
+  std::string HeadersFrame(const SpdyHeaderBlock& headers) {
+    return HeadersFrame(EncodeQpackHeaders(headers));
+  }
+
+  // Construct HEADERS frame with given payload.
+  std::string HeadersFrame(absl::string_view payload) {
+    std::unique_ptr<char[]> headers_buffer;
+    QuicByteCount headers_frame_header_length =
+        HttpEncoder::SerializeHeadersFrameHeader(payload.length(),
+                                                 &headers_buffer);
+    absl::string_view headers_frame_header(headers_buffer.get(),
+                                           headers_frame_header_length);
+    return absl::StrCat(headers_frame_header, payload);
+  }
+
+  std::string DataFrame(absl::string_view payload) {
+    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+        payload.length(), quiche::SimpleBufferAllocator::Get());
+    return absl::StrCat(header.AsStringView(), payload);
+  }
+
+  std::string UnknownFrame(uint64_t frame_type, absl::string_view payload) {
+    std::string frame;
+    const size_t length = QuicDataWriter::GetVarInt62Len(frame_type) +
+                          QuicDataWriter::GetVarInt62Len(payload.size()) +
+                          payload.size();
+    frame.resize(length);
+
+    QuicDataWriter writer(length, const_cast<char*>(frame.data()));
+    writer.WriteVarInt62(frame_type);
+    writer.WriteStringPieceVarInt62(payload);
+    // Even though integers can be encoded with different lengths,
+    // QuicDataWriter is expected to produce an encoding in Write*() of length
+    // promised in GetVarInt62Len().
+    QUICHE_DCHECK_EQ(length, writer.length());
+
+    return frame;
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  std::unique_ptr<TestSession> session_;
+
+  // Owned by the |session_|.
+  TestStream* stream_;
+  TestStream* stream2_;
+
+  SpdyHeaderBlock headers_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSpdyStreamTest, ProcessHeaderList) {
+  Initialize(kShouldProcessData);
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  ProcessHeaders(false, headers_);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) {
+  Initialize(kShouldProcessData);
+
+  if (!UsesHttp3()) {
+    QuicHeaderList headers;
+    stream_->OnStreamHeadersPriority(
+        spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+    EXPECT_CALL(
+        *session_,
+        MaybeSendRstStreamFrame(
+            stream_->id(),
+            QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
+    stream_->OnStreamHeaderList(false, 1 << 20, headers);
+
+    EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
+
+    return;
+  }
+
+  // Header list size includes 32 bytes for overhead per header field.
+  session_->set_max_inbound_header_list_size(40);
+  std::string headers =
+      HeadersFrame({std::make_pair("foo", "too long headers")});
+
+  QuicStreamFrame frame(stream_->id(), false, 0, headers);
+
+  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
+                             stream_->id(), QuicResetStreamError::FromInternal(
+                                                QUIC_HEADERS_TOO_LARGE)));
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
+
+  auto qpack_decoder_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  // Stream type and stream cancellation.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), _, _, NO_FIN, _, _))
+      .Times(2);
+
+  stream_->OnStreamFrame(frame);
+  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
+}
+
+TEST_P(QuicSpdyStreamTest, QpackProcessLargeHeaderListDiscountOverhead) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  // Setting this flag to false causes no per-entry overhead to be included
+  // in the header size.
+  SetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead, false);
+  Initialize(kShouldProcessData);
+  session_->set_max_inbound_header_list_size(40);
+  std::string headers =
+      HeadersFrame({std::make_pair("foo", "too long headers")});
+
+  QuicStreamFrame frame(stream_->id(), false, 0, headers);
+  stream_->OnStreamFrame(frame);
+  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_NO_ERROR));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) {
+  Initialize(kShouldProcessData);
+
+  size_t total_bytes = 0;
+  QuicHeaderList headers;
+  for (auto p : headers_) {
+    headers.OnHeader(p.first, p.second);
+    total_bytes += p.first.size() + p.second.size();
+  }
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  stream_->OnStreamHeaderList(true, total_bytes, headers);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+// A valid status code should be 3-digit integer. The first digit should be in
+// the range of [1, 5]. All the others are invalid.
+TEST_P(QuicSpdyStreamTest, ParseHeaderStatusCode) {
+  Initialize(kShouldProcessData);
+  int status_code = 0;
+
+  // Valid status codes.
+  headers_[":status"] = "404";
+  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+  EXPECT_EQ(404, status_code);
+
+  headers_[":status"] = "100";
+  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+  EXPECT_EQ(100, status_code);
+
+  headers_[":status"] = "599";
+  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+  EXPECT_EQ(599, status_code);
+
+  // Invalid status codes.
+  headers_[":status"] = "010";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "600";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "200 ok";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "2000";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "+200";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "+20";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "-10";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "-100";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  // Leading or trailing spaces are also invalid.
+  headers_[":status"] = " 200";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "200 ";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = " 200 ";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "  ";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+}
+
+TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) {
+  Initialize(kShouldProcessData);
+
+  std::string body = "this is the body";
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  EXPECT_EQ(headers, stream_->header_list());
+
+  stream_->ConsumeHeaderList();
+  EXPECT_EQ(QuicHeaderList(), stream_->header_list());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessWrongFramesOnSpdyStream) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  GoAwayFrame goaway;
+  goaway.id = 0x1;
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
+  std::string data = std::string(buffer.get(), header_length);
+
+  EXPECT_EQ("", stream_->data());
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  EXPECT_EQ(headers, stream_->header_list());
+  stream_->ConsumeHeaderList();
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
+      .WillOnce(
+          (Invoke([this](QuicErrorCode error, const std::string& error_details,
+                         ConnectionCloseBehavior connection_close_behavior) {
+            connection_->ReallyCloseConnection(error, error_details,
+                                               connection_close_behavior);
+          })));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(*session_, OnConnectionClosed(_, _))
+      .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
+                              ConnectionCloseSource source) {
+        session_->ReallyOnConnectionClosed(frame, source);
+      }));
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
+
+  stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdyStreamTest, Http3FrameError) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // PUSH_PROMISE frame with empty payload is considered invalid.
+  std::string invalid_http3_frame = absl::HexStringToBytes("0500");
+  QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
+                               /* offset = */ 0, invalid_http3_frame);
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR, _, _));
+  stream_->OnStreamFrame(stream_frame);
+}
+
+TEST_P(QuicSpdyStreamTest, UnexpectedHttp3Frame) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // SETTINGS frame with empty payload.
+  std::string settings = absl::HexStringToBytes("0400");
+  QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
+                               /* offset = */ 0, settings);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _));
+  stream_->OnStreamFrame(stream_frame);
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) {
+  Initialize(kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  EXPECT_EQ("", stream_->data());
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  EXPECT_EQ(headers, stream_->header_list());
+  stream_->ConsumeHeaderList();
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(QuicHeaderList(), stream_->header_list());
+  EXPECT_EQ(body, stream_->data());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) {
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
+    Initialize(kShouldProcessData);
+    QuicHeaderList headers = ProcessHeaders(false, headers_);
+    ASSERT_EQ(headers, stream_->header_list());
+    stream_->ConsumeHeaderList();
+    for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
+      size_t remaining_data = data.size() - offset;
+      absl::string_view fragment(data.data() + offset,
+                                 std::min(fragment_size, remaining_data));
+      QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false,
+                            offset, absl::string_view(fragment));
+      stream_->OnStreamFrame(frame);
+    }
+    ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size;
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
+    Initialize(kShouldProcessData);
+    QuicHeaderList headers = ProcessHeaders(false, headers_);
+    ASSERT_EQ(headers, stream_->header_list());
+    stream_->ConsumeHeaderList();
+
+    absl::string_view fragment1(data.data(), split_point);
+    QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                           absl::string_view(fragment1));
+    stream_->OnStreamFrame(frame1);
+
+    absl::string_view fragment2(data.data() + split_point,
+                                data.size() - split_point);
+    QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                           split_point, absl::string_view(fragment2));
+    stream_->OnStreamFrame(frame2);
+
+    ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point;
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
+  Initialize(!kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  char buffer[2048];
+  ASSERT_LT(data.length(), ABSL_ARRAYSIZE(buffer));
+  struct iovec vec;
+  vec.iov_base = buffer;
+  vec.iov_len = ABSL_ARRAYSIZE(buffer);
+
+  size_t bytes_read = stream_->Readv(&vec, 1);
+  QuicStreamPeer::CloseReadSide(stream_);
+  EXPECT_EQ(body.length(), bytes_read);
+  EXPECT_EQ(body, std::string(buffer, bytes_read));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndLargeBodySmallReadv) {
+  Initialize(kShouldProcessData);
+  std::string body(12 * 1024, 'a');
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+  char buffer[2048];
+  char buffer2[2048];
+  struct iovec vec[2];
+  vec[0].iov_base = buffer;
+  vec[0].iov_len = ABSL_ARRAYSIZE(buffer);
+  vec[1].iov_base = buffer2;
+  vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
+  size_t bytes_read = stream_->Readv(vec, 2);
+  EXPECT_EQ(2048u * 2, bytes_read);
+  EXPECT_EQ(body.substr(0, 2048), std::string(buffer, 2048));
+  EXPECT_EQ(body.substr(2048, 2048), std::string(buffer2, 2048));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) {
+  Initialize(!kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  struct iovec vec;
+
+  EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1));
+  EXPECT_EQ(body.length(), vec.iov_len);
+  EXPECT_EQ(body, std::string(static_cast<char*>(vec.iov_base), vec.iov_len));
+
+  stream_->MarkConsumed(body.length());
+  EXPECT_EQ(data.length(), QuicStreamPeer::bytes_consumed(stream_));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) {
+  Initialize(!kShouldProcessData);
+  std::string body1 = "this is body 1";
+  std::string data1 = UsesHttp3() ? DataFrame(body1) : body1;
+  std::string body2 = "body 2";
+  std::string data2 = UsesHttp3() ? DataFrame(body2) : body2;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         absl::string_view(data1));
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                         data1.length(), absl::string_view(data2));
+  stream_->OnStreamFrame(frame1);
+  stream_->OnStreamFrame(frame2);
+  stream_->ConsumeHeaderList();
+
+  stream_->MarkConsumed(body1.length() + body2.length());
+  EXPECT_EQ(data1.length() + data2.length(),
+            QuicStreamPeer::bytes_consumed(stream_));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
+  Initialize(!kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  char buffer[1];
+  struct iovec vec;
+  vec.iov_base = buffer;
+  vec.iov_len = ABSL_ARRAYSIZE(buffer);
+
+  for (size_t i = 0; i < body.length(); ++i) {
+    size_t bytes_read = stream_->Readv(&vec, 1);
+    ASSERT_EQ(1u, bytes_read);
+    EXPECT_EQ(body.data()[i], buffer[0]);
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
+  Initialize(!kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  char buffer1[1];
+  char buffer2[1];
+  struct iovec vec[2];
+  vec[0].iov_base = buffer1;
+  vec[0].iov_len = ABSL_ARRAYSIZE(buffer1);
+  vec[1].iov_base = buffer2;
+  vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
+
+  for (size_t i = 0; i < body.length(); i += 2) {
+    size_t bytes_read = stream_->Readv(vec, 2);
+    ASSERT_EQ(2u, bytes_read) << i;
+    ASSERT_EQ(body.data()[i], buffer1[0]) << i;
+    ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i;
+  }
+}
+
+// Tests that we send a BLOCKED frame to the peer when we attempt to write, but
+// are flow control blocked.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
+  Initialize(kShouldProcessData);
+  testing::InSequence seq;
+
+  // Set a small flow control limit.
+  const uint64_t kWindow = 36;
+  QuicStreamPeer::SetSendWindowOffset(stream_, kWindow);
+  EXPECT_EQ(kWindow, QuicStreamPeer::SendWindowOffset(stream_));
+
+  // Try to send more data than the flow control limit allows.
+  const uint64_t kOverflow = 15;
+  std::string body(kWindow + kOverflow, 'a');
+
+  const uint64_t kHeaderLength = UsesHttp3() ? 2 : 0;
+  if (UsesHttp3()) {
+    EXPECT_CALL(*session_, WritevData(_, kHeaderLength, _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(kWindow - kHeaderLength, true)));
+  EXPECT_CALL(*session_, SendBlocked(_));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  stream_->WriteOrBufferBody(body, false);
+
+  // Should have sent as much as possible, resulting in no send window left.
+  EXPECT_EQ(0u, QuicStreamPeer::SendWindowSize(stream_));
+
+  // And we should have queued the overflowed data.
+  EXPECT_EQ(kOverflow + kHeaderLength, stream_->BufferedDataBytes());
+}
+
+// The flow control receive window decreases whenever we add new bytes to the
+// sequencer, whether they are consumed immediately or buffered. However we only
+// send WINDOW_UPDATE frames based on increasing number of bytes consumed.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
+  // Don't process data - it will be buffered instead.
+  Initialize(!kShouldProcessData);
+
+  // Expect no WINDOW_UPDATE frames to be sent.
+  EXPECT_CALL(*session_, SendWindowUpdate(_, _)).Times(0);
+
+  // Set a small flow control receive window.
+  const uint64_t kWindow = 36;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
+  QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
+
+  // Stream receives enough data to fill a fraction of the receive window.
+  std::string body(kWindow / 3, 'a');
+  QuicByteCount header_length = 0;
+  std::string data;
+
+  if (UsesHttp3()) {
+    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+        body.length(), quiche::SimpleBufferAllocator::Get());
+    data = absl::StrCat(header.AsStringView(), body);
+    header_length = header.size();
+  } else {
+    data = body;
+  }
+
+  ProcessHeaders(false, headers_);
+
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         absl::string_view(data));
+  stream_->OnStreamFrame(frame1);
+  EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
+            QuicStreamPeer::ReceiveWindowSize(stream_));
+
+  // Now receive another frame which results in the receive window being over
+  // half full. This should all be buffered, decreasing the receive window but
+  // not sending WINDOW_UPDATE.
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                         kWindow / 3 + header_length, absl::string_view(data));
+  stream_->OnStreamFrame(frame2);
+  EXPECT_EQ(kWindow - (2 * kWindow / 3) - 2 * header_length,
+            QuicStreamPeer::ReceiveWindowSize(stream_));
+}
+
+// Tests that on receipt of data, the stream updates its receive window offset
+// appropriately, and sends WINDOW_UPDATE frames when its receive window drops
+// too low.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
+  Initialize(kShouldProcessData);
+
+  // Set a small flow control limit.
+  const uint64_t kWindow = 36;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
+  QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
+
+  // Stream receives enough data to fill a fraction of the receive window.
+  std::string body(kWindow / 3, 'a');
+  QuicByteCount header_length = 0;
+  std::string data;
+
+  if (UsesHttp3()) {
+    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+        body.length(), quiche::SimpleBufferAllocator::Get());
+    data = absl::StrCat(header.AsStringView(), body);
+    header_length = header.size();
+  } else {
+    data = body;
+  }
+
+  ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         absl::string_view(data));
+  stream_->OnStreamFrame(frame1);
+  EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
+            QuicStreamPeer::ReceiveWindowSize(stream_));
+
+  // Now receive another frame which results in the receive window being over
+  // half full.  This will trigger the stream to increase its receive window
+  // offset and send a WINDOW_UPDATE. The result will be again an available
+  // window of kWindow bytes.
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                         kWindow / 3 + header_length, absl::string_view(data));
+  EXPECT_CALL(*session_, SendWindowUpdate(_, _));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  stream_->OnStreamFrame(frame2);
+  EXPECT_EQ(kWindow, QuicStreamPeer::ReceiveWindowSize(stream_));
+}
+
+// Tests that on receipt of data, the connection updates its receive window
+// offset appropriately, and sends WINDOW_UPDATE frames when its receive window
+// drops too low.
+TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
+  Initialize(kShouldProcessData);
+
+  // Set a small flow control limit for streams and connection.
+  const uint64_t kWindow = 36;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
+  QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
+  QuicStreamPeer::SetReceiveWindowOffset(stream2_, kWindow);
+  QuicStreamPeer::SetMaxReceiveWindow(stream2_, kWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
+                                              kWindow);
+
+  // Supply headers to both streams so that they are happy to receive data.
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  stream_->ConsumeHeaderList();
+  stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                               headers);
+  stream2_->ConsumeHeaderList();
+
+  // Each stream gets a quarter window of data. This should not trigger a
+  // WINDOW_UPDATE for either stream, nor for the connection.
+  QuicByteCount header_length = 0;
+  std::string body;
+  std::string data;
+  std::string data2;
+  std::string body2(1, 'a');
+
+  if (UsesHttp3()) {
+    body = std::string(kWindow / 4 - 2, 'a');
+    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+        body.length(), quiche::SimpleBufferAllocator::Get());
+    data = absl::StrCat(header.AsStringView(), body);
+    header_length = header.size();
+    quiche::QuicheBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
+        body.length(), quiche::SimpleBufferAllocator::Get());
+    data2 = absl::StrCat(header2.AsStringView(), body2);
+  } else {
+    body = std::string(kWindow / 4, 'a');
+    data = body;
+    data2 = body2;
+  }
+
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         absl::string_view(data));
+  stream_->OnStreamFrame(frame1);
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
+                         absl::string_view(data));
+  stream2_->OnStreamFrame(frame2);
+
+  // Now receive a further single byte on one stream - again this does not
+  // trigger a stream WINDOW_UPDATE, but now the connection flow control window
+  // is over half full and thus a connection WINDOW_UPDATE is sent.
+  EXPECT_CALL(*session_, SendWindowUpdate(_, _));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false,
+                         body.length() + header_length,
+                         absl::string_view(data2));
+  stream_->OnStreamFrame(frame3);
+}
+
+// Tests that on if the peer sends too much data (i.e. violates the flow control
+// protocol), then we terminate the connection.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) {
+  // Stream should not process data, so that data gets buffered in the
+  // sequencer, triggering flow control limits.
+  Initialize(!kShouldProcessData);
+
+  // Set a small flow control limit.
+  const uint64_t kWindow = 50;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
+
+  ProcessHeaders(false, headers_);
+
+  // Receive data to overflow the window, violating flow control.
+  std::string body(kWindow + 1, 'a');
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) {
+  Initialize(kShouldProcessData);
+  ProcessHeaders(false, headers_);
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
+
+  stream_->OnStreamReset(QuicRstStreamFrame(
+      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_NO_ERROR, 0));
+
+  if (GetQuicReloadableFlag(quic_fix_on_stream_reset) && UsesHttp3()) {
+    // RESET_STREAM should close the read side but not the write side.
+    EXPECT_TRUE(stream_->read_side_closed());
+    EXPECT_FALSE(stream_->write_side_closed());
+  } else {
+    EXPECT_TRUE(stream_->write_side_closed());
+    EXPECT_FALSE(stream_->reading_stopped());
+  }
+}
+
+// Tests that on if the peer sends too much data (i.e. violates the flow control
+// protocol), at the connection level (rather than the stream level) then we
+// terminate the connection.
+TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) {
+  // Stream should not process data, so that data gets buffered in the
+  // sequencer, triggering flow control limits.
+  Initialize(!kShouldProcessData);
+
+  // Set a small flow control window on streams, and connection.
+  const uint64_t kStreamWindow = 50;
+  const uint64_t kConnectionWindow = 10;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kStreamWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
+                                                 kConnectionWindow);
+
+  ProcessHeaders(false, headers_);
+
+  // Send enough data to overflow the connection level flow control window.
+  std::string body(kConnectionWindow + 1, 'a');
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  EXPECT_LT(data.size(), kStreamWindow);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamFrame(frame);
+}
+
+// An attempt to write a FIN with no data should not be flow control blocked,
+// even if the send window is 0.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
+  Initialize(kShouldProcessData);
+
+  // Set a flow control limit of zero.
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, 0);
+
+  // Send a frame with a FIN but no data. This should not be blocked.
+  std::string body = "";
+  bool fin = true;
+
+  EXPECT_CALL(*session_, SendBlocked(GetNthClientInitiatedBidirectionalId(0)))
+      .Times(0);
+  EXPECT_CALL(*session_, WritevData(_, 0, _, FIN, _, _));
+
+  stream_->WriteOrBufferBody(body, fin);
+}
+
+// Test that receiving trailing headers from the peer via OnStreamHeaderList()
+// works, and can be read from the stream and consumed.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) {
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  size_t total_bytes = 0;
+  QuicHeaderList headers;
+  for (const auto& p : headers_) {
+    headers.OnHeader(p.first, p.second);
+    total_bytes += p.first.size() + p.second.size();
+  }
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  stream_->OnStreamHeaderList(/*fin=*/false, total_bytes, headers);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = "value1";
+  trailers_block["key2"] = "value2";
+  trailers_block["key3"] = "value3";
+  SpdyHeaderBlock trailers_block_with_final_offset = trailers_block.Clone();
+  if (!UsesHttp3()) {
+    // :final-offset pseudo-header is only added if trailers are sent
+    // on the headers stream.
+    trailers_block_with_final_offset[kFinalOffsetHeaderKey] = "0";
+  }
+  total_bytes = 0;
+  QuicHeaderList trailers;
+  for (const auto& p : trailers_block_with_final_offset) {
+    trailers.OnHeader(p.first, p.second);
+    total_bytes += p.first.size() + p.second.size();
+  }
+  stream_->OnStreamHeaderList(/*fin=*/true, total_bytes, trailers);
+
+  // The trailers should be decompressed, and readable from the stream.
+  EXPECT_TRUE(stream_->trailers_decompressed());
+  EXPECT_EQ(trailers_block, stream_->received_trailers());
+
+  // IsDoneReading() returns false until trailers marked consumed.
+  EXPECT_FALSE(stream_->IsDoneReading());
+  stream_->MarkTrailersConsumed();
+  EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+// Test that when receiving trailing headers with an offset before response
+// body, stream is closed at the right offset.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) {
+  // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
+  // request/response stream.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  const std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  // Receive trailing headers.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = "value1";
+  trailers_block["key2"] = "value2";
+  trailers_block["key3"] = "value3";
+  trailers_block[kFinalOffsetHeaderKey] = absl::StrCat(data.size());
+
+  QuicHeaderList trailers = ProcessHeaders(true, trailers_block);
+
+  // The trailers should be decompressed, and readable from the stream.
+  EXPECT_TRUE(stream_->trailers_decompressed());
+
+  // The final offset trailer will be consumed by QUIC.
+  trailers_block.erase(kFinalOffsetHeaderKey);
+  EXPECT_EQ(trailers_block, stream_->received_trailers());
+
+  // Consuming the trailers erases them from the stream.
+  stream_->MarkTrailersConsumed();
+  EXPECT_TRUE(stream_->FinishedReadingTrailers());
+
+  EXPECT_FALSE(stream_->IsDoneReading());
+  // Receive and consume body.
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/false,
+                        0, data);
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(body, stream_->data());
+  EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+// Test that receiving trailers without a final offset field is an error.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) {
+  // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
+  // request/response stream.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers, without kFinalOffsetHeaderKey.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = "value1";
+  trailers_block["key2"] = "value2";
+  trailers_block["key3"] = "value3";
+  auto trailers = AsHeaderList(trailers_block);
+
+  // Verify that the trailers block didn't contain a final offset.
+  EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string());
+
+  // Receipt of the malformed trailers will close the connection.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  stream_->OnStreamHeaderList(/*fin=*/true,
+                              trailers.uncompressed_header_bytes(), trailers);
+}
+
+// Test that received Trailers must always have the FIN set.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) {
+  // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
+  // HEADERS frame.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(/*fin=*/false,
+                              headers.uncompressed_header_bytes(), headers);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers with FIN deliberately set to false.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["foo"] = "bar";
+  auto trailers = AsHeaderList(trailers_block);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  stream_->OnStreamHeaderList(/*fin=*/false,
+                              trailers.uncompressed_header_bytes(), trailers);
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterHeadersWithFin) {
+  // If headers are received with a FIN, no trailers should then arrive.
+  Initialize(kShouldProcessData);
+
+  // If HEADERS frames are sent on the request/response stream, then the
+  // sequencer will signal an error if any stream data arrives after a FIN,
+  // so QuicSpdyStream does not need to.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  // Receive initial headers with FIN set.
+  ProcessHeaders(true, headers_);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers after FIN already received.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["foo"] = "bar";
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  ProcessHeaders(true, trailers_block);
+}
+
+// If body data are received with a FIN, no trailers should then arrive.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) {
+  // If HEADERS frames are sent on the request/response stream,
+  // then the sequencer will block them from reaching QuicSpdyStream
+  // after the stream is closed.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers without FIN set.
+  ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  // Receive body data, with FIN.
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
+                        0, "body");
+  stream_->OnStreamFrame(frame);
+
+  // Receive trailing headers after FIN already received.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["foo"] = "bar";
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  ProcessHeaders(true, trailers_block);
+}
+
+TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) {
+  // Verify that a stream receiving headers, body, and no trailers is correctly
+  // marked as done reading on consumption of headers and body.
+  Initialize(kShouldProcessData);
+
+  // Receive and consume initial headers with FIN not set.
+  auto h = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h);
+  stream_->ConsumeHeaderList();
+
+  // Receive and consume body with FIN set, and no trailers.
+  std::string body(1024, 'x');
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
+                        0, data);
+  stream_->OnStreamFrame(frame);
+
+  EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+// Test that writing trailers will send a FIN, as Trailers are the last thing to
+// be sent on a stream.
+TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
+  Initialize(kShouldProcessData);
+
+  if (UsesHttp3()) {
+    // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
+    // Four writes on the request stream: HEADERS frame header and payload both
+    // for headers and trailers.
+    EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(4);
+  }
+
+  // Write the initial headers, without a FIN.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Writing trailers implicitly sends a FIN.
+  SpdyHeaderBlock trailers;
+  trailers["trailer key"] = "trailer value";
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(std::move(trailers), nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+}
+
+TEST_P(QuicSpdyStreamTest, DoNotSendPriorityUpdateWithDefaultUrgency) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // Four writes on the request stream: HEADERS frame header and payload both
+  // for headers and trailers.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(4);
+
+  // No PRIORITY_UPDATE frames on the control stream,
+  // because the stream has default priority.
+  auto send_control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(session_.get());
+  EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _))
+      .Times(0);
+
+  // Write the initial headers, without a FIN.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Writing trailers implicitly sends a FIN.
+  SpdyHeaderBlock trailers;
+  trailers["trailer key"] = "trailer value";
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
+  stream_->WriteTrailers(std::move(trailers), nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+}
+
+TEST_P(QuicSpdyStreamTest, ChangePriority) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // Two writes on the request stream: HEADERS frame header and payload.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // PRIORITY_UPDATE frame on the control stream.
+  auto send_control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(session_.get());
+  EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
+  PriorityUpdateFrame priority_update;
+  priority_update.prioritized_element_id = 0;
+  priority_update.priority_field_value = "u=0";
+  EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameSent(priority_update));
+  stream_->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+}
+
+TEST_P(QuicSpdyStreamTest, ChangePriorityBeforeWritingHeaders) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+
+  // PRIORITY_UPDATE frame sent on the control stream as soon as SetPriority()
+  // is called, before HEADERS frame is sent.
+  auto send_control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(session_.get());
+  EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
+
+  stream_->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  testing::Mock::VerifyAndClearExpectations(session_.get());
+
+  // Two writes on the request stream: HEADERS frame header and payload.
+  // PRIORITY_UPDATE frame is not sent this time, because one is already sent.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
+}
+
+// Test that when writing trailers, the trailers that are actually sent to the
+// peer contain the final offset field indicating last byte of data.
+TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
+  Initialize(kShouldProcessData);
+
+  if (UsesHttp3()) {
+    // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
+    // HEADERS frame header and payload on the request stream.
+    EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
+  }
+
+  // Write the initial headers.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Write non-zero body data to force a non-zero final offset.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  std::string body(1024, 'x');  // 1 kB
+  QuicByteCount header_length = 0;
+  if (UsesHttp3()) {
+    header_length = HttpEncoder::SerializeDataFrameHeader(
+                        body.length(), quiche::SimpleBufferAllocator::Get())
+                        .size();
+  }
+
+  stream_->WriteOrBufferBody(body, false);
+
+  // The final offset field in the trailing headers is populated with the
+  // number of body bytes written (including queued bytes).
+  SpdyHeaderBlock trailers;
+  trailers["trailer key"] = "trailer value";
+
+  SpdyHeaderBlock expected_trailers(trailers.Clone());
+  // :final-offset pseudo-header is only added if trailers are sent
+  // on the headers stream.
+  if (!UsesHttp3()) {
+    expected_trailers[kFinalOffsetHeaderKey] =
+        absl::StrCat(body.length() + header_length);
+  }
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(std::move(trailers), nullptr);
+  EXPECT_EQ(expected_trailers, stream_->saved_headers());
+}
+
+// Test that if trailers are written after all other data has been written
+// (headers and body), that this closes the stream for writing.
+TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
+  Initialize(kShouldProcessData);
+
+  // Expect data being written on the stream.  In addition to that, headers are
+  // also written on the stream in case of IETF QUIC.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AtLeast(1));
+
+  // Write the initial headers.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Write non-zero body data.
+  const int kBodySize = 1 * 1024;  // 1 kB
+  stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
+  EXPECT_EQ(0u, stream_->BufferedDataBytes());
+
+  // Headers and body have been fully written, there is no queued data. Writing
+  // trailers marks the end of this stream, and thus the write side is closed.
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+// Test that the stream is not closed for writing when trailers are sent while
+// there are still body bytes queued.
+TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
+  // This test exercises sending trailers on the headers stream while data is
+  // still queued on the response/request stream.  In IETF QUIC, data and
+  // trailers are sent on the same stream, so this test does not apply.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  testing::InSequence seq;
+  Initialize(kShouldProcessData);
+
+  // Write the initial headers.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Write non-zero body data, but only consume partially, ensuring queueing.
+  const int kBodySize = 1 * 1024;  // 1 kB
+  if (UsesHttp3()) {
+    EXPECT_CALL(*session_, WritevData(_, 3, _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(*session_, WritevData(_, kBodySize, _, NO_FIN, _, _))
+      .WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
+  stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
+  EXPECT_EQ(1u, stream_->BufferedDataBytes());
+
+  // Writing trailers will send a FIN, but not close the write side of the
+  // stream as there are queued bytes.
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+  EXPECT_FALSE(stream_->write_side_closed());
+
+  // Writing the queued bytes will close the write side of the stream.
+  EXPECT_CALL(*session_, WritevData(_, 1, _, NO_FIN, _, _));
+  stream_->OnCanWrite();
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+// Test that it is not possible to write Trailers after a FIN has been sent.
+TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
+  // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
+  // HEADERS frame.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Write the initial headers, with a FIN.
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+
+  // Writing Trailers should fail, as the FIN has already been sent.
+  // populated with the number of body bytes written.
+  EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr),
+                  "Trailers cannot be sent after a FIN");
+}
+
+TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
+  // There is no headers stream if QPACK is used.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  const char kHeader1[] = "Header1";
+  const char kHeader2[] = "Header2";
+  const char kBody1[] = "Test1";
+  const char kBody2[] = "Test2";
+
+  Initialize(kShouldProcessData);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  testing::InSequence s;
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  stream_->set_ack_listener(ack_listener1);
+  stream2_->set_ack_listener(ack_listener2);
+
+  session_->headers_stream()->WriteOrBufferData(kHeader1, false, ack_listener1);
+  stream_->WriteOrBufferBody(kBody1, true);
+
+  session_->headers_stream()->WriteOrBufferData(kHeader2, false, ack_listener2);
+  stream2_->WriteOrBufferBody(kBody2, false);
+
+  QuicStreamFrame frame1(
+      QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 0,
+      kHeader1);
+
+  std::string data1 = UsesHttp3() ? DataFrame(kBody1) : kBody1;
+  QuicStreamFrame frame2(stream_->id(), true, 0, data1);
+  QuicStreamFrame frame3(
+      QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 7,
+      kHeader2);
+  std::string data2 = UsesHttp3() ? DataFrame(kBody2) : kBody2;
+  QuicStreamFrame frame4(stream2_->id(), false, 0, data2);
+
+  EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(7));
+  session_->OnStreamFrameRetransmitted(frame1);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame1), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame4), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+}
+
+TEST_P(QuicSpdyStreamTest, OnPriorityFrame) {
+  Initialize(kShouldProcessData);
+  stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
+            stream_->precedence());
+}
+
+TEST_P(QuicSpdyStreamTest, OnPriorityFrameAfterSendingData) {
+  Initialize(kShouldProcessData);
+  testing::InSequence seq;
+
+  if (UsesHttp3()) {
+    EXPECT_CALL(*session_, WritevData(_, 2, _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(*session_, WritevData(_, 4, _, FIN, _, _));
+  stream_->WriteOrBufferBody("data", true);
+  stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
+            stream_->precedence());
+}
+
+TEST_P(QuicSpdyStreamTest, SetPriorityBeforeUpdateStreamPriority) {
+  MockQuicConnection* connection = new StrictMock<MockQuicConnection>(
+      &helper_, &alarm_factory_, Perspective::IS_SERVER,
+      SupportedVersions(GetParam()));
+  std::unique_ptr<TestMockUpdateStreamSession> session(
+      new StrictMock<TestMockUpdateStreamSession>(connection));
+  auto stream =
+      new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalStreamId(
+                                     session->transport_version(), 0),
+                                 session.get(),
+                                 /*should_process_data=*/true);
+  session->ActivateStream(absl::WrapUnique(stream));
+
+  // QuicSpdyStream::SetPriority() should eventually call UpdateStreamPriority()
+  // on the session. Make sure stream->priority() returns the updated priority
+  // if called within UpdateStreamPriority(). This expectation is enforced in
+  // TestMockUpdateStreamSession::UpdateStreamPriority().
+  session->SetExpectedStream(stream);
+  session->SetExpectedPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  stream->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+  session->SetExpectedPriority(spdy::SpdyStreamPrecedence(kV3LowestPriority));
+  stream->SetPriority(spdy::SpdyStreamPrecedence(kV3LowestPriority));
+}
+
+TEST_P(QuicSpdyStreamTest, StreamWaitsForAcks) {
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  // Stream is not waiting for acks initially.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // Send kData1.
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  // Stream is not waiting for acks as all sent data is acked.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // Send kData2.
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Send FIN.
+  stream_->WriteOrBufferData("", true, nullptr);
+  // Fin only frame is not stored in send buffer.
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // kData2 is retransmitted.
+  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(9));
+  stream_->OnStreamFrameRetransmitted(9, 9, false);
+
+  // kData2 is acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  // Stream is waiting for acks as FIN is not acked.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // FIN is acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+}
+
+TEST_P(QuicSpdyStreamTest, StreamDataGetAckedMultipleTimes) {
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  // Send [0, 27) and fin.
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  stream_->WriteOrBufferData("FooAndBar", true, nullptr);
+
+  // Ack [0, 9), [5, 22) and [18, 26)
+  // Verify [0, 9) 9 bytes are acked.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [9, 22) 13 bytes are acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(13, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [22, 26) 4 bytes are acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(4, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+
+  // Ack [0, 27).
+  // Verify [26, 27) 1 byte is acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(1, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+
+  // Ack Fin. Verify OnPacketAcked is called.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+
+  // Ack [10, 27) and fin.
+  // No new data is acked, verify OnPacketAcked is not called.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(_, _)).Times(0);
+  EXPECT_FALSE(
+      stream_->OnStreamFrameAcked(10, 17, true, QuicTime::Delta::Zero(),
+                                  QuicTime::Zero(), &newly_acked_length));
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+}
+
+// HTTP/3 only.
+TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteOrBufferBody) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  std::string body = "Test1";
+  std::string body2(100, 'x');
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  stream_->WriteOrBufferBody(body, false);
+  stream_->WriteOrBufferBody(body2, true);
+
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body.length(), quiche::SimpleBufferAllocator::Get());
+  quiche::QuicheBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
+      body2.length(), quiche::SimpleBufferAllocator::Get());
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body.length(), _));
+  QuicStreamFrame frame(stream_->id(), false, 0,
+                        absl::StrCat(header.AsStringView(), body));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
+  QuicStreamFrame frame2(stream_->id(), false, header.size() + body.length(),
+                         header2.AsStringView());
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body2.length(), _));
+  QuicStreamFrame frame3(stream_->id(), true,
+                         header.size() + body.length() + header2.size(), body2);
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+
+  EXPECT_TRUE(
+      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
+}
+
+// HTTP/3 only.
+TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteBodySlices) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  std::string body1 = "Test1";
+  std::string body2(100, 'x');
+  struct iovec body1_iov = {const_cast<char*>(body1.data()), body1.length()};
+  struct iovec body2_iov = {const_cast<char*>(body2.data()), body2.length()};
+  quiche::QuicheMemSliceStorage storage(
+      &body1_iov, 1, helper_.GetStreamSendBufferAllocator(), 1024);
+  quiche::QuicheMemSliceStorage storage2(
+      &body2_iov, 1, helper_.GetStreamSendBufferAllocator(), 1024);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  stream_->WriteBodySlices(storage.ToSpan(), false);
+  stream_->WriteBodySlices(storage2.ToSpan(), true);
+
+  std::string data1 = DataFrame(body1);
+  std::string data2 = DataFrame(body2);
+
+  EXPECT_CALL(*mock_ack_listener,
+              OnPacketAcked(body1.length() + body2.length(), _));
+  QuicStreamFrame frame(stream_->id(), true, 0, data1 + data2);
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+
+  EXPECT_TRUE(
+      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
+}
+
+// HTTP/3 only.
+TEST_P(QuicSpdyStreamTest, HeaderBytesNotReportedOnRetransmission) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  std::string body1 = "Test1";
+  std::string body2(100, 'x');
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  stream_->WriteOrBufferBody(body1, false);
+  stream_->WriteOrBufferBody(body2, true);
+
+  std::string data1 = DataFrame(body1);
+  std::string data2 = DataFrame(body2);
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body1.length()));
+  QuicStreamFrame frame(stream_->id(), false, 0, data1);
+  session_->OnStreamFrameRetransmitted(frame);
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body2.length()));
+  QuicStreamFrame frame2(stream_->id(), true, data1.length(), data2);
+  session_->OnStreamFrameRetransmitted(frame2);
+
+  EXPECT_FALSE(
+      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
+}
+
+TEST_P(QuicSpdyStreamTest, HeadersFrameOnRequestStream) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  std::string data = DataFrame(kDataFramePayload);
+  std::string trailers =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+
+  std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
+  QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
+  stream_->OnStreamFrame(frame);
+
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+
+  // QuicSpdyStream only calls OnBodyAvailable()
+  // after the header list has been consumed.
+  EXPECT_EQ("", stream_->data());
+  stream_->ConsumeHeaderList();
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessBodyAfterTrailers) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(!kShouldProcessData);
+
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  std::string data = DataFrame(kDataFramePayload);
+
+  // A header block that will take more than one block of sequencer buffer.
+  // This ensures that when the trailers are consumed, some buffer buckets will
+  // be freed.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = std::string(10000, 'x');
+  std::string trailers = HeadersFrame(trailers_block);
+
+  // Feed all three HTTP/3 frames in a single stream frame.
+  std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
+  QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
+  stream_->OnStreamFrame(frame);
+
+  stream_->ConsumeHeaderList();
+  stream_->MarkTrailersConsumed();
+
+  EXPECT_TRUE(stream_->trailers_decompressed());
+  EXPECT_EQ(trailers_block, stream_->received_trailers());
+
+  EXPECT_TRUE(stream_->HasBytesToRead());
+
+  // Consume data.
+  char buffer[2048];
+  struct iovec vec;
+  vec.iov_base = buffer;
+  vec.iov_len = ABSL_ARRAYSIZE(buffer);
+  size_t bytes_read = stream_->Readv(&vec, 1);
+  EXPECT_EQ(kDataFramePayload, absl::string_view(buffer, bytes_read));
+
+  EXPECT_FALSE(stream_->HasBytesToRead());
+}
+
+// The test stream will receive a stream frame containing malformed headers and
+// normal body. Make sure the http decoder stops processing body after the
+// connection shuts down.
+TEST_P(QuicSpdyStreamTest, MalformedHeadersStopHttpDecoder) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+  // Random bad headers.
+  std::string headers =
+      HeadersFrame(absl::HexStringToBytes("00002a94e7036261"));
+  std::string data = DataFrame(kDataFramePayload);
+
+  std::string stream_frame_payload = absl::StrCat(headers, data);
+  QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                      MatchesRegex("Error decoding headers on stream \\d+: "
+                                   "Incomplete header block."),
+                      _))
+      .WillOnce(
+          (Invoke([this](QuicErrorCode error, const std::string& error_details,
+                         ConnectionCloseBehavior connection_close_behavior) {
+            connection_->ReallyCloseConnection(error, error_details,
+                                               connection_close_behavior);
+          })));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(*session_, OnConnectionClosed(_, _))
+      .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
+                              ConnectionCloseSource source) {
+        session_->ReallyOnConnectionClosed(frame, source);
+      }));
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
+  stream_->OnStreamFrame(frame);
+}
+
+// Regression test for https://crbug.com/1027895: a HEADERS frame triggers an
+// error in QuicSpdyStream::OnHeadersFramePayload().  This closes the
+// connection, freeing the buffer of QuicStreamSequencer.  Therefore
+// QuicStreamSequencer::MarkConsumed() must not be called from
+// QuicSpdyStream::OnHeadersFramePayload().
+TEST_P(QuicSpdyStreamTest, DoNotMarkConsumedAfterQpackDecodingError) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+  {
+    testing::InSequence s;
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                        MatchesRegex("Error decoding headers on stream \\d+: "
+                                     "Invalid relative index."),
+                        _))
+        .WillOnce((
+            Invoke([this](QuicErrorCode error, const std::string& error_details,
+                          ConnectionCloseBehavior connection_close_behavior) {
+              connection_->ReallyCloseConnection(error, error_details,
+                                                 connection_close_behavior);
+            })));
+    EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+    EXPECT_CALL(*session_, OnConnectionClosed(_, _))
+        .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
+                                ConnectionCloseSource source) {
+          session_->ReallyOnConnectionClosed(frame, source);
+        }));
+  }
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream_->id(), _, _));
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream2_->id(), _, _));
+
+  // Invalid headers: Required Insert Count is zero, but the header block
+  // contains a dynamic table reference.
+  std::string headers = HeadersFrame(absl::HexStringToBytes("000080"));
+  QuicStreamFrame frame(stream_->id(), false, 0, headers);
+  stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdyStreamTest, ImmediateHeaderDecodingWithDynamicTableEntries) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string encoded_headers = absl::HexStringToBytes("020080");
+  std::string headers = HeadersFrame(encoded_headers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
+  // Decoder stream type.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Header acknowledgement.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Headers can be decoded immediately.
+  EXPECT_TRUE(stream_->headers_decompressed());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // DATA frame.
+  std::string data = DataFrame(kDataFramePayload);
+  EXPECT_CALL(debug_visitor,
+              OnDataFrameReceived(stream_->id(), strlen(kDataFramePayload)));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
+                                         headers.length(), data));
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Deliver second dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
+
+  // Trailing HEADERS frame referencing second dynamic table entry.
+  std::string encoded_trailers = absl::HexStringToBytes("030080");
+  std::string trailers = HeadersFrame(encoded_trailers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
+  // Header acknowledgement.
+  EXPECT_CALL(*session_, WritevData(decoder_send_stream->id(), _, _, _, _, _));
+  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
+                                         headers.length() + data.length(),
+                                         trailers));
+
+  // Trailers can be decoded immediately.
+  EXPECT_TRUE(stream_->trailers_decompressed());
+
+  // Verify trailers.
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("trailing", "foobar")));
+  stream_->MarkTrailersConsumed();
+}
+
+TEST_P(QuicSpdyStreamTest, BlockedHeaderDecoding) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string encoded_headers = absl::HexStringToBytes("020080");
+  std::string headers = HeadersFrame(encoded_headers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+
+  // Decoder stream type.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Header acknowledgement.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+  EXPECT_TRUE(stream_->headers_decompressed());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // DATA frame.
+  std::string data = DataFrame(kDataFramePayload);
+  EXPECT_CALL(debug_visitor,
+              OnDataFrameReceived(stream_->id(), strlen(kDataFramePayload)));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
+                                         headers.length(), data));
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Trailing HEADERS frame referencing second dynamic table entry.
+  std::string encoded_trailers = absl::HexStringToBytes("030080");
+  std::string trailers = HeadersFrame(encoded_trailers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
+                                         headers.length() + data.length(),
+                                         trailers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->trailers_decompressed());
+
+  // Header acknowledgement.
+  EXPECT_CALL(*session_, WritevData(decoder_send_stream->id(), _, _, _, _, _));
+  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  // Deliver second dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
+  EXPECT_TRUE(stream_->trailers_decompressed());
+
+  // Verify trailers.
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("trailing", "foobar")));
+  stream_->MarkTrailersConsumed();
+}
+
+TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingHeaders) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  // HEADERS frame only referencing entry with absolute index 0 but with
+  // Required Insert Count = 2, which is incorrect.
+  std::string headers = HeadersFrame(absl::HexStringToBytes("030081"));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Even though entire header block is received and every referenced entry is
+  // available, decoding is blocked until insert count reaches the Required
+  // Insert Count value advertised in the header block prefix.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                      MatchesRegex("Error decoding headers on stream \\d+: "
+                                   "Required Insert Count too large."),
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  // Deliver two dynamic table entries to decoder
+  // to trigger decoding of header block.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+}
+
+// Regression test for https://crbug.com/1024263 and for
+// https://crbug.com/1025209#c11.
+TEST_P(QuicSpdyStreamTest, BlockedHeaderDecodingUnblockedWithBufferedError) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  // Relative index 2 is invalid because it is larger than or equal to the Base.
+  std::string headers = HeadersFrame(absl::HexStringToBytes("020082"));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                      MatchesRegex("Error decoding headers on stream \\d+: "
+                                   "Invalid relative index."),
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  // Deliver one dynamic table entry to decoder
+  // to trigger decoding of header block.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+}
+
+TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingTrailers) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string headers = HeadersFrame(absl::HexStringToBytes("020080"));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+
+  // Decoder stream type.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Header acknowledgement.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+  EXPECT_TRUE(stream_->headers_decompressed());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // DATA frame.
+  std::string data = DataFrame(kDataFramePayload);
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
+                                         headers.length(), data));
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Trailing HEADERS frame only referencing entry with absolute index 0 but
+  // with Required Insert Count = 2, which is incorrect.
+  std::string trailers = HeadersFrame(absl::HexStringToBytes("030081"));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
+                                         headers.length() + data.length(),
+                                         trailers));
+
+  // Even though entire header block is received and every referenced entry is
+  // available, decoding is blocked until insert count reaches the Required
+  // Insert Count value advertised in the header block prefix.
+  EXPECT_FALSE(stream_->trailers_decompressed());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                      MatchesRegex("Error decoding trailers on stream \\d+: "
+                                   "Required Insert Count too large."),
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  // Deliver second dynamic table entry to decoder
+  // to trigger decoding of trailing header block.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
+}
+
+// Regression test for b/132603592: QPACK decoding unblocked after stream is
+// closed.
+TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterStreamClosed) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string encoded_headers = absl::HexStringToBytes("020080");
+  std::string headers = HeadersFrame(encoded_headers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  // Decoder stream type and stream cancellation instruction.
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+
+  // Reset stream by this endpoint, for example, due to stream cancellation.
+  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
+                             stream_->id(), QuicResetStreamError::FromInternal(
+                                                QUIC_STREAM_CANCELLED)));
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
+  stream_->Reset(QUIC_STREAM_CANCELLED);
+
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+
+  EXPECT_FALSE(stream_->headers_decompressed());
+}
+
+TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterResetReceived) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string encoded_headers = absl::HexStringToBytes("020080");
+  std::string headers = HeadersFrame(encoded_headers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  // Decoder stream type and stream cancellation instruction.
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+
+  // OnStreamReset() is called when RESET_STREAM frame is received from peer.
+  stream_->OnStreamReset(QuicRstStreamFrame(
+      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
+
+  if (!GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
+    // Header acknowledgement.
+    EXPECT_CALL(*session_,
+                WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                           /* offset = */ 2, _, _, _));
+    EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  }
+
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+
+  if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
+    EXPECT_FALSE(stream_->headers_decompressed());
+  } else {
+    // Verify headers.
+    EXPECT_TRUE(stream_->headers_decompressed());
+    EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  }
+}
+
+class QuicSpdyStreamIncrementalConsumptionTest : public QuicSpdyStreamTest {
+ protected:
+  QuicSpdyStreamIncrementalConsumptionTest() : offset_(0), consumed_bytes_(0) {}
+  ~QuicSpdyStreamIncrementalConsumptionTest() override = default;
+
+  // Create QuicStreamFrame with |payload|
+  // and pass it to stream_->OnStreamFrame().
+  void OnStreamFrame(absl::string_view payload) {
+    QuicStreamFrame frame(stream_->id(), /* fin = */ false, offset_, payload);
+    stream_->OnStreamFrame(frame);
+    offset_ += payload.size();
+  }
+
+  // Return number of bytes marked consumed with sequencer
+  // since last NewlyConsumedBytes() call.
+  QuicStreamOffset NewlyConsumedBytes() {
+    QuicStreamOffset previously_consumed_bytes = consumed_bytes_;
+    consumed_bytes_ = stream_->sequencer()->NumBytesConsumed();
+    return consumed_bytes_ - previously_consumed_bytes;
+  }
+
+  // Read |size| bytes from the stream.
+  std::string ReadFromStream(QuicByteCount size) {
+    std::string buffer;
+    buffer.resize(size);
+
+    struct iovec vec;
+    vec.iov_base = const_cast<char*>(buffer.data());
+    vec.iov_len = size;
+
+    size_t bytes_read = stream_->Readv(&vec, 1);
+    EXPECT_EQ(bytes_read, size);
+
+    return buffer;
+  }
+
+ private:
+  QuicStreamOffset offset_;
+  QuicStreamOffset consumed_bytes_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamIncrementalConsumptionTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+// Test that stream bytes are consumed (by calling
+// sequencer()->MarkConsumed()) incrementally, as soon as possible.
+TEST_P(QuicSpdyStreamIncrementalConsumptionTest, OnlyKnownFrames) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(!kShouldProcessData);
+
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+
+  // All HEADERS frame bytes are consumed even if the frame is not received
+  // completely.
+  OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
+  EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
+
+  // The rest of the HEADERS frame is also consumed immediately.
+  OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
+  EXPECT_EQ(1u, NewlyConsumedBytes());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // DATA frame.
+  absl::string_view data_payload(kDataFramePayload);
+  std::string data_frame = DataFrame(data_payload);
+  QuicByteCount data_frame_header_length =
+      data_frame.size() - data_payload.size();
+
+  // DATA frame header is consumed.
+  // DATA frame payload is not consumed because payload has to be buffered.
+  OnStreamFrame(data_frame);
+  EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
+
+  // Consume all but last byte of data.
+  EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
+            ReadFromStream(data_payload.size() - 1));
+  EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
+
+  std::string trailers =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+
+  // No bytes are consumed, because last byte of DATA payload is still buffered.
+  OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
+  EXPECT_EQ(0u, NewlyConsumedBytes());
+
+  // Reading last byte of DATA payload triggers consumption of all data received
+  // so far, even though last HEADERS frame has not been received completely.
+  EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
+  EXPECT_EQ(1 + trailers.size() - 1, NewlyConsumedBytes());
+
+  // Last byte of trailers is immediately consumed.
+  OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
+  EXPECT_EQ(1u, NewlyConsumedBytes());
+
+  // Verify trailers.
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+}
+
+TEST_P(QuicSpdyStreamIncrementalConsumptionTest, ReceiveUnknownFrame) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  EXPECT_CALL(debug_visitor,
+              OnUnknownFrameReceived(stream_->id(), /* frame_type = */ 0x21,
+                                     /* payload_length = */ 3));
+  std::string unknown_frame = UnknownFrame(0x21, "foo");
+  OnStreamFrame(unknown_frame);
+}
+
+TEST_P(QuicSpdyStreamIncrementalConsumptionTest, UnknownFramesInterleaved) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(!kShouldProcessData);
+
+  // Unknown frame of reserved type before HEADERS is consumed immediately.
+  std::string unknown_frame1 = UnknownFrame(0x21, "foo");
+  OnStreamFrame(unknown_frame1);
+  EXPECT_EQ(unknown_frame1.size(), NewlyConsumedBytes());
+
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+
+  // All HEADERS frame bytes are consumed even if the frame is not received
+  // completely.
+  OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
+  EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
+
+  // The rest of the HEADERS frame is also consumed immediately.
+  OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
+  EXPECT_EQ(1u, NewlyConsumedBytes());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // Frame of unknown, not reserved type between HEADERS and DATA is consumed
+  // immediately.
+  std::string unknown_frame2 = UnknownFrame(0x3a, "");
+  OnStreamFrame(unknown_frame2);
+  EXPECT_EQ(unknown_frame2.size(), NewlyConsumedBytes());
+
+  // DATA frame.
+  absl::string_view data_payload(kDataFramePayload);
+  std::string data_frame = DataFrame(data_payload);
+  QuicByteCount data_frame_header_length =
+      data_frame.size() - data_payload.size();
+
+  // DATA frame header is consumed.
+  // DATA frame payload is not consumed because payload has to be buffered.
+  OnStreamFrame(data_frame);
+  EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
+
+  // Frame of unknown, not reserved type is not consumed because DATA payload is
+  // still buffered.
+  std::string unknown_frame3 = UnknownFrame(0x39, "bar");
+  OnStreamFrame(unknown_frame3);
+  EXPECT_EQ(0u, NewlyConsumedBytes());
+
+  // Consume all but last byte of data.
+  EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
+            ReadFromStream(data_payload.size() - 1));
+  EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
+
+  std::string trailers =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+
+  // No bytes are consumed, because last byte of DATA payload is still buffered.
+  OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
+  EXPECT_EQ(0u, NewlyConsumedBytes());
+
+  // Reading last byte of DATA payload triggers consumption of all data received
+  // so far, even though last HEADERS frame has not been received completely.
+  EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
+  EXPECT_EQ(1 + unknown_frame3.size() + trailers.size() - 1,
+            NewlyConsumedBytes());
+
+  // Last byte of trailers is immediately consumed.
+  OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
+  EXPECT_EQ(1u, NewlyConsumedBytes());
+
+  // Verify trailers.
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+
+  // Unknown frame of reserved type after trailers is consumed immediately.
+  std::string unknown_frame4 = UnknownFrame(0x40, "");
+  OnStreamFrame(unknown_frame4);
+  EXPECT_EQ(unknown_frame4.size(), NewlyConsumedBytes());
+}
+
+// Close connection if a DATA frame is received before a HEADERS frame.
+TEST_P(QuicSpdyStreamTest, DataBeforeHeaders) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Closing the connection is mocked out in tests.  Instead, simply stop
+  // reading data at the stream level to prevent QuicSpdyStream from blowing up.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+                      "Unexpected DATA frame received.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+      .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
+
+  std::string data = DataFrame(kDataFramePayload);
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, data));
+}
+
+// Close connection if a HEADERS frame is received after the trailing HEADERS.
+TEST_P(QuicSpdyStreamTest, TrailersAfterTrailers) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive and consume headers.
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  QuicStreamOffset offset = 0;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, headers));
+  offset += headers.size();
+
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // Receive data.  It is consumed by TestStream.
+  std::string data = DataFrame(kDataFramePayload);
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data));
+  offset += data.size();
+
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Receive and consume trailers.
+  std::string trailers1 =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, trailers1));
+  offset += trailers1.size();
+
+  EXPECT_TRUE(stream_->trailers_decompressed());
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+
+  // Closing the connection is mocked out in tests.  Instead, simply stop
+  // reading data at the stream level to prevent QuicSpdyStream from blowing up.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+                      "HEADERS frame received after trailing HEADERS.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+      .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
+
+  // Receive another HEADERS frame, with no header fields.
+  std::string trailers2 = HeadersFrame(SpdyHeaderBlock());
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, trailers2));
+}
+
+// Regression test for https://crbug.com/978733.
+// Close connection if a DATA frame is received after the trailing HEADERS.
+TEST_P(QuicSpdyStreamTest, DataAfterTrailers) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive and consume headers.
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  QuicStreamOffset offset = 0;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, headers));
+  offset += headers.size();
+
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // Receive data.  It is consumed by TestStream.
+  std::string data1 = DataFrame(kDataFramePayload);
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data1));
+  offset += data1.size();
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Receive trailers, with single header field "custom-key: custom-value".
+  std::string trailers =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, trailers));
+  offset += trailers.size();
+
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+
+  // Closing the connection is mocked out in tests.  Instead, simply stop
+  // reading data at the stream level to prevent QuicSpdyStream from blowing up.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+                      "Unexpected DATA frame received.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+      .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
+
+  // Receive more data.
+  std::string data2 = DataFrame("This payload should not be proccessed.");
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data2));
+}
+
+// SETTINGS frames are invalid on bidirectional streams.  If one is received,
+// the connection is closed.  No more data should be processed.
+TEST_P(QuicSpdyStreamTest, StopProcessingIfConnectionClosed) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // SETTINGS frame with empty payload.
+  std::string settings = absl::HexStringToBytes("0400");
+
+  // HEADERS frame.
+  // Since it arrives after a SETTINGS frame, it should never be read.
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+
+  // Combine the two frames to make sure they are processed in a single
+  // QuicSpdyStream::OnDataAvailable() call.
+  std::string frames = absl::StrCat(settings, headers);
+
+  EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(*session_, OnConnectionClosed(_, _));
+
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), /* fin = */ false,
+                                         /* offset = */ 0, frames));
+
+  EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
+}
+
+// Stream Cancellation instruction is sent on QPACK decoder stream
+// when stream is reset.
+TEST_P(QuicSpdyStreamTest, StreamCancellationWhenStreamReset) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  auto qpack_decoder_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  // Stream type.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Stream cancellation.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
+                             stream_->id(), QuicResetStreamError::FromInternal(
+                                                QUIC_STREAM_CANCELLED)));
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
+
+  stream_->Reset(QUIC_STREAM_CANCELLED);
+}
+
+// Stream Cancellation instruction is sent on QPACK decoder stream
+// when RESET_STREAM frame is received.
+TEST_P(QuicSpdyStreamTest, StreamCancellationOnResetReceived) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  auto qpack_decoder_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  // Stream type.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Stream cancellation.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+
+  stream_->OnStreamReset(QuicRstStreamFrame(
+      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
+}
+
+TEST_P(QuicSpdyStreamTest, WriteHeadersReturnValue) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+
+  // Enable QPACK dynamic table.
+  session_->OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024);
+  session_->OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 1);
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+
+  QpackSendStream* encoder_stream =
+      QuicSpdySessionPeer::GetQpackEncoderSendStream(session_.get());
+  EXPECT_CALL(*session_, WritevData(encoder_stream->id(), _, _, _, _, _))
+      .Times(AnyNumber());
+
+  // HEADERS frame header.
+  EXPECT_CALL(*session_,
+              WritevData(stream_->id(), _, /* offset = */ 0, _, _, _));
+  // HEADERS frame payload.
+  size_t headers_frame_payload_length = 0;
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .WillOnce(
+          DoAll(SaveArg<1>(&headers_frame_payload_length),
+                Invoke(session_.get(), &MockQuicSpdySession::ConsumeData)));
+
+  SpdyHeaderBlock request_headers;
+  request_headers["foo"] = "bar";
+  size_t write_headers_return_value =
+      stream_->WriteHeaders(std::move(request_headers), /*fin=*/true, nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+
+  EXPECT_EQ(headers_frame_payload_length, write_headers_return_value);
+}
+
+// Regression test for https://crbug.com/1177662.
+// RESET_STREAM with QUIC_STREAM_NO_ERROR should not be treated in a special
+// way: it should close the read side but not the write side.
+TEST_P(QuicSpdyStreamTest, TwoResetStreamFrames) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
+
+  QuicRstStreamFrame rst_frame1(kInvalidControlFrameId, stream_->id(),
+                                QUIC_STREAM_CANCELLED, /* bytes_written = */ 0);
+  stream_->OnStreamReset(rst_frame1);
+  EXPECT_TRUE(stream_->read_side_closed());
+  EXPECT_FALSE(stream_->write_side_closed());
+
+  QuicRstStreamFrame rst_frame2(kInvalidControlFrameId, stream_->id(),
+                                QUIC_STREAM_NO_ERROR, /* bytes_written = */ 0);
+  if (GetQuicReloadableFlag(quic_fix_on_stream_reset)) {
+    stream_->OnStreamReset(rst_frame2);
+    EXPECT_TRUE(stream_->read_side_closed());
+    EXPECT_FALSE(stream_->write_side_closed());
+  } else {
+    EXPECT_CALL(
+        *session_,
+        MaybeSendRstStreamFrame(
+            stream_->id(),
+            QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), _));
+    EXPECT_QUIC_BUG(
+        stream_->OnStreamReset(rst_frame2),
+        "The stream should've already sent RST in response to STOP_SENDING");
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft00) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft00);
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AnyNumber());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":method"] = "CONNECT";
+  headers[":protocol"] = "webtransport";
+  headers["datagram-flow-id"] = absl::StrCat(stream_->id());
+  stream_->WriteHeaders(std::move(headers), /*fin=*/false, nullptr);
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft04) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AnyNumber());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":method"] = "CONNECT";
+  headers[":protocol"] = "webtransport";
+  stream_->WriteHeaders(std::move(headers), /*fin=*/false, nullptr);
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft04) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["sec-webtransport-http3-draft02"] = "1";
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  ProcessHeaders(false, headers_);
+  stream_->OnCapsule(
+      Capsule::RegisterDatagramNoContext(DatagramFormatType::WEBTRANSPORT));
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft00) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft00);
+
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  ProcessHeaders(false, headers_);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest,
+       ProcessIncomingWebTransportHeadersWithMismatchedFlowId) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  // TODO(b/181256914) Remove this test when we deprecate
+  // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft00);
+
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["datagram-flow-id"] = "2";
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  ProcessHeaders(false, headers_);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdClient) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
+  stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 0u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 2u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 4u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 6u);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+}
+
+TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdServer) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_SERVER);
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
+  stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 1u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 3u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 5u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 7u);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+}
+
+TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithoutContextDraft00) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft00);
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
+  ProcessHeaders(false, headers_);
+  session_->RegisterHttp3DatagramFlowId(stream_->id(), stream_->id());
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor;
+  SavingHttp3DatagramVisitor h3_datagram_visitor;
+  absl::optional<QuicDatagramContextId> context_id;
+  absl::string_view format_additional_data;
+  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
+  std::array<char, 256> datagram;
+  datagram[0] = stream_->id();
+  for (size_t i = 1; i < datagram.size(); i++) {
+    datagram[i] = i;
+  }
+  stream_->RegisterHttp3DatagramRegistrationVisitor(
+      &h3_datagram_registration_visitor);
+  stream_->RegisterHttp3DatagramContextId(
+      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
+      &h3_datagram_visitor);
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[1], datagram.size() - 1)}));
+  // Test move.
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor2;
+  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
+  SavingHttp3DatagramVisitor h3_datagram_visitor2;
+  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
+                                                  &h3_datagram_visitor2);
+  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[1], datagram.size() - 1)}));
+  // Cleanup.
+  stream_->UnregisterHttp3DatagramContextId(context_id);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+  session_->UnregisterHttp3DatagramFlowId(stream_->id());
+}
+
+TEST_P(QuicSpdyStreamTest, H3DatagramRegistrationWithoutContextDraft04) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  ProcessHeaders(false, headers_);
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor;
+  SavingHttp3DatagramVisitor h3_datagram_visitor;
+  absl::optional<QuicDatagramContextId> context_id;
+  absl::string_view format_additional_data;
+  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
+  std::array<char, 256> datagram;
+  datagram[0] = stream_->id();
+  for (size_t i = 1; i < datagram.size(); i++) {
+    datagram[i] = i;
+  }
+  stream_->RegisterHttp3DatagramRegistrationVisitor(
+      &h3_datagram_registration_visitor);
+
+  // Expect us to send a REGISTER_DATAGRAM_NO_CONTEXT capsule.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AtLeast(1));
+
+  stream_->RegisterHttp3DatagramContextId(
+      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
+      &h3_datagram_visitor);
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[1], datagram.size() - 1)}));
+  // Test move.
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor2;
+  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
+  SavingHttp3DatagramVisitor h3_datagram_visitor2;
+  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
+                                                  &h3_datagram_visitor2);
+  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[1], datagram.size() - 1)}));
+  // Cleanup.
+  stream_->UnregisterHttp3DatagramContextId(context_id);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+}
+
+TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithContext) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor;
+  SavingHttp3DatagramVisitor h3_datagram_visitor;
+  absl::optional<QuicDatagramContextId> context_id = 42;
+  absl::string_view format_additional_data;
+  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
+  std::array<char, 256> datagram;
+  datagram[0] = stream_->id();
+  datagram[1] = context_id.value();
+  for (size_t i = 2; i < datagram.size(); i++) {
+    datagram[i] = i;
+  }
+  stream_->RegisterHttp3DatagramRegistrationVisitor(
+      &h3_datagram_registration_visitor, /*use_datagram_contexts=*/true);
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["sec-use-datagram-contexts"] = "?1";
+  ProcessHeaders(false, headers_);
+
+  // Expect us to send a REGISTER_DATAGRAM_CONTEXT capsule.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AtLeast(1));
+
+  stream_->RegisterHttp3DatagramContextId(
+      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
+      &h3_datagram_visitor);
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[2], datagram.size() - 2)}));
+  // Test move.
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor2;
+  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
+  SavingHttp3DatagramVisitor h3_datagram_visitor2;
+  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
+                                                  &h3_datagram_visitor2);
+  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[2], datagram.size() - 2)}));
+  // Cleanup.
+
+  // Expect us to send a CLOSE_DATAGRAM_CONTEXT capsule.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AtLeast(1));
+  stream_->UnregisterHttp3DatagramContextId(context_id);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+  session_->UnregisterHttp3DatagramFlowId(stream_->id());
+}
+
+TEST_P(QuicSpdyStreamTest, SendHttp3Datagram) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+  absl::optional<QuicDatagramContextId> context_id;
+  std::string h3_datagram_payload = {1, 2, 3, 4, 5, 6};
+  EXPECT_CALL(*connection_, SendMessage(1, _, false))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  EXPECT_EQ(stream_->SendHttp3Datagram(context_id, h3_datagram_payload),
+            MESSAGE_STATUS_SUCCESS);
+}
+
+TEST_P(QuicSpdyStreamTest, GetMaxDatagramSize) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+
+  QuicByteCount size = stream_->GetMaxDatagramSize(absl::nullopt);
+  QuicByteCount size_with_context =
+      stream_->GetMaxDatagramSize(/*context_id=*/1);
+  EXPECT_GT(size, 512u);
+  EXPECT_EQ(size - 1, size_with_context);
+}
+
+TEST_P(QuicSpdyStreamTest,
+       QUIC_TEST_DISABLED_IN_CHROME(HeadersAccumulatorNullptr)) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Creates QpackDecodedHeadersAccumulator in
+  // `qpack_decoded_headers_accumulator_`.
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Resets `qpack_decoded_headers_accumulator_`.
+  stream_->OnHeadersDecoded({}, false);
+
+  // This private method should never be called when
+  // `qpack_decoded_headers_accumulator_` is nullptr.  The number 1 identifies
+  // the site where `qpack_decoded_headers_accumulator_` was last reset.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _));
+  bool result = true;
+  EXPECT_QUIC_BUG(result = QuicSpdyStreamPeer::OnHeadersFrameEnd(stream_),
+                  "b215142466_OnHeadersFrameEnd.: 1$");
+  EXPECT_FALSE(result);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/spdy_server_push_utils.cc b/quiche/quic/core/http/spdy_server_push_utils.cc
new file mode 100644
index 0000000..103f6dd
--- /dev/null
+++ b/quiche/quic/core/http/spdy_server_push_utils.cc
@@ -0,0 +1,215 @@
+// Copyright (c) 2013 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 "quiche/quic/core/http/spdy_server_push_utils.h"
+
+#include "absl/strings/string_view.h"
+#include "url/gurl.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+// static
+std::string SpdyServerPushUtils::GetPromisedUrlFromHeaders(
+    const SpdyHeaderBlock& headers) {
+  // RFC 7540, Section 8.1.2.3: All HTTP/2 requests MUST include exactly
+  // one valid value for the ":method", ":scheme", and ":path" pseudo-header
+  // fields, unless it is a CONNECT request.
+
+  // RFC 7540, Section  8.2.1:  The header fields in PUSH_PROMISE and any
+  // subsequent CONTINUATION frames MUST be a valid and complete set of request
+  // header fields (Section 8.1.2.3).  The server MUST include a method in the
+  // ":method" pseudo-header field that is safe and cacheable.
+  //
+  // RFC 7231, Section  4.2.1: Of the request methods defined by this
+  // specification, the GET, HEAD, OPTIONS, and TRACE methods are defined to be
+  // safe.
+  //
+  // RFC 7231, Section  4.2.1: ... this specification defines GET, HEAD, and
+  // POST as cacheable, ...
+  //
+  // So the only methods allowed in a PUSH_PROMISE are GET and HEAD.
+  SpdyHeaderBlock::const_iterator it = headers.find(":method");
+  if (it == headers.end() || (it->second != "GET" && it->second != "HEAD")) {
+    return std::string();
+  }
+
+  it = headers.find(":scheme");
+  if (it == headers.end() || it->second.empty()) {
+    return std::string();
+  }
+  absl::string_view scheme = it->second;
+
+  // RFC 7540, Section 8.2: The server MUST include a value in the
+  // ":authority" pseudo-header field for which the server is authoritative
+  // (see Section 10.1).
+  it = headers.find(":authority");
+  if (it == headers.end() || it->second.empty()) {
+    return std::string();
+  }
+  absl::string_view authority = it->second;
+
+  // RFC 7540, Section 8.1.2.3 requires that the ":path" pseudo-header MUST
+  // NOT be empty for "http" or "https" URIs;
+  //
+  // However, to ensure the scheme is consistently canonicalized, that check
+  // is deferred to implementations in QuicUrlUtils::GetPushPromiseUrl().
+  it = headers.find(":path");
+  if (it == headers.end()) {
+    return std::string();
+  }
+  absl::string_view path = it->second;
+
+  return GetPushPromiseUrl(scheme, authority, path);
+}
+
+// static
+std::string SpdyServerPushUtils::GetPromisedHostNameFromHeaders(
+    const SpdyHeaderBlock& headers) {
+  // TODO(fayang): Consider just checking out the value of the ":authority" key
+  // in headers.
+  return GURL(GetPromisedUrlFromHeaders(headers)).host();
+}
+
+// static
+bool SpdyServerPushUtils::PromisedUrlIsValid(const SpdyHeaderBlock& headers) {
+  std::string url(GetPromisedUrlFromHeaders(headers));
+  return !url.empty() && GURL(url).is_valid();
+}
+
+// static
+std::string SpdyServerPushUtils::GetPushPromiseUrl(absl::string_view scheme,
+                                                   absl::string_view authority,
+                                                   absl::string_view path) {
+  // RFC 7540, Section 8.1.2.3: The ":path" pseudo-header field includes the
+  // path and query parts of the target URI (the "path-absolute" production
+  // and optionally a '?' character followed by the "query" production (see
+  // Sections 3.3 and 3.4 of RFC3986). A request in asterisk form includes the
+  // value '*' for the ":path" pseudo-header field.
+  //
+  // This pseudo-header field MUST NOT be empty for "http" or "https" URIs;
+  // "http" or "https" URIs that do not contain a path MUST include a value of
+  // '/'. The exception to this rule is an OPTIONS request for an "http" or
+  // "https" URI that does not include a path component; these MUST include a
+  // ":path" pseudo-header with a value of '*' (see RFC7230, Section 5.3.4).
+  //
+  // In addition to the above restriction from RFC 7540, note that RFC3986
+  // defines the "path-absolute" construction as starting with "/" but not "//".
+  //
+  // RFC 7540, Section  8.2.1:  The header fields in PUSH_PROMISE and any
+  // subsequent CONTINUATION frames MUST be a valid and complete set of request
+  // header fields (Section 8.1.2.3).  The server MUST include a method in the
+  // ":method" pseudo-header field that is safe and cacheable.
+  //
+  // RFC 7231, Section  4.2.1:
+  // ... this specification defines GET, HEAD, and POST as cacheable, ...
+  //
+  // Since the OPTIONS method is not cacheable, it cannot be the method of a
+  // PUSH_PROMISE. Therefore, the exception mentioned in RFC 7540, Section
+  // 8.1.2.3 about OPTIONS requests does not apply here (i.e. ":path" cannot be
+  // "*").
+  if (path.empty() || path[0] != '/' || (path.size() >= 2 && path[1] == '/')) {
+    return std::string();
+  }
+
+  // Validate the scheme; this is to ensure a scheme of "foo://bar" is not
+  // parsed as a URL of "foo://bar://baz" when combined with a host of "baz".
+  std::string canonical_scheme;
+  url::StdStringCanonOutput canon_scheme_output(&canonical_scheme);
+  url::Component canon_component;
+  url::Component scheme_component(0, scheme.size());
+
+  if (!url::CanonicalizeScheme(scheme.data(), scheme_component,
+                               &canon_scheme_output, &canon_component) ||
+      !canon_component.is_nonempty() || canon_component.begin != 0) {
+    return std::string();
+  }
+  canonical_scheme.resize(canon_component.len + 1);
+
+  // Validate the authority; this is to ensure an authority such as
+  // "host/path" is not accepted, as when combined with a scheme like
+  // "http://", could result in a URL of "http://host/path".
+  url::Component auth_component(0, authority.size());
+  url::Component username_component;
+  url::Component password_component;
+  url::Component host_component;
+  url::Component port_component;
+
+  url::ParseAuthority(authority.data(), auth_component, &username_component,
+                      &password_component, &host_component, &port_component);
+
+  // RFC 7540, Section 8.1.2.3: The authority MUST NOT include the deprecated
+  // "userinfo" subcomponent for "http" or "https" schemed URIs.
+  //
+  // Note: Although |canonical_scheme| has not yet been checked for that, as
+  // it is performed later in processing, only "http" and "https" schemed
+  // URIs are supported for PUSH.
+  if (username_component.is_valid() || password_component.is_valid()) {
+    return std::string();
+  }
+
+  // Failed parsing or no host present. ParseAuthority() will ensure that
+  // host_component + port_component cover the entire string, if
+  // username_component and password_component are not present.
+  if (!host_component.is_nonempty()) {
+    return std::string();
+  }
+
+  // Validate the port (if present; it's optional).
+  int parsed_port_number = url::PORT_INVALID;
+  if (port_component.is_nonempty()) {
+    parsed_port_number = url::ParsePort(authority.data(), port_component);
+    if (parsed_port_number < 0 && parsed_port_number != url::PORT_UNSPECIFIED) {
+      return std::string();
+    }
+  }
+
+  // Validate the host by attempting to canonicalize it. Invalid characters
+  // will result in a canonicalization failure (e.g. '/')
+  std::string canon_host;
+  url::StdStringCanonOutput canon_host_output(&canon_host);
+  canon_component.reset();
+  if (!url::CanonicalizeHost(authority.data(), host_component,
+                             &canon_host_output, &canon_component) ||
+      !canon_component.is_nonempty() || canon_component.begin != 0) {
+    return std::string();
+  }
+
+  // At this point, "authority" has been validated to either be of the form
+  // 'host:port' or 'host', with 'host' being a valid domain or IP address,
+  // and 'port' (if present), being a valid port. Attempt to construct a
+  // URL of just the (scheme, host, port), which should be safe and will not
+  // result in ambiguous parsing.
+  //
+  // This also enforces that all PUSHed URLs are either HTTP or HTTPS-schemed
+  // URIs, consistent with the other restrictions enforced above.
+  //
+  // Note: url::CanonicalizeScheme() will have added the ':' to
+  // |canonical_scheme|.
+  GURL origin_url(canonical_scheme + "//" + std::string(authority));
+  if (!origin_url.is_valid() || !origin_url.SchemeIsHTTPOrHTTPS() ||
+      // The following checks are merely defense in depth.
+      origin_url.has_username() || origin_url.has_password() ||
+      (origin_url.has_path() && origin_url.path_piece() != "/") ||
+      origin_url.has_query() || origin_url.has_ref()) {
+    return std::string();
+  }
+
+  // Attempt to parse the path.
+  std::string spec = origin_url.GetWithEmptyPath().spec();
+  spec.pop_back();  // Remove the '/', as ":path" must contain it.
+  spec.append(std::string(path));
+
+  // Attempt to parse the full URL, with the path as well. Ensure there is no
+  // fragment to the query.
+  GURL full_url(spec);
+  if (!full_url.is_valid() || full_url.has_ref()) {
+    return std::string();
+  }
+
+  return full_url.spec();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/spdy_server_push_utils.h b/quiche/quic/core/http/spdy_server_push_utils.h
new file mode 100644
index 0000000..c79f52c
--- /dev/null
+++ b/quiche/quic/core/http/spdy_server_push_utils.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2013 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_HTTP_SPDY_SERVER_PUSH_UTILS_H_
+#define QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE SpdyServerPushUtils {
+ public:
+  SpdyServerPushUtils() = delete;
+
+  // Returns a canonicalized URL composed from the :scheme, :authority, and
+  // :path headers of a PUSH_PROMISE. Returns empty string if the headers do not
+  // conform to HTTP/2 spec or if the ":method" header contains a forbidden
+  // method for PUSH_PROMISE.
+  static std::string GetPromisedUrlFromHeaders(
+      const spdy::SpdyHeaderBlock& headers);
+
+  // Returns hostname, or empty string if missing.
+  static std::string GetPromisedHostNameFromHeaders(
+      const spdy::SpdyHeaderBlock& headers);
+
+  // Returns true if result of |GetPromisedUrlFromHeaders()| is non-empty
+  // and is a well-formed URL.
+  static bool PromisedUrlIsValid(const spdy::SpdyHeaderBlock& headers);
+
+  // Returns a canonical, valid URL for a PUSH_PROMISE with the specified
+  // ":scheme", ":authority", and ":path" header fields, or an empty
+  // string if the resulting URL is not valid or supported.
+  static std::string GetPushPromiseUrl(absl::string_view scheme,
+                                       absl::string_view authority,
+                                       absl::string_view path);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
diff --git a/quiche/quic/core/http/spdy_server_push_utils_test.cc b/quiche/quic/core/http/spdy_server_push_utils_test.cc
new file mode 100644
index 0000000..d9aff41
--- /dev/null
+++ b/quiche/quic/core/http/spdy_server_push_utils_test.cc
@@ -0,0 +1,217 @@
+// Copyright 2016 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 "quiche/quic/core/http/spdy_server_push_utils.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+namespace test {
+
+using GetPromisedUrlFromHeaders = QuicTest;
+
+TEST_F(GetPromisedUrlFromHeaders, Basic) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":scheme"] = "https";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":authority"] = "www.google.com";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":path"] = "/index.html";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers),
+            "https://www.google.com/index.html");
+  headers["key1"] = "value1";
+  headers["key2"] = "value2";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers),
+            "https://www.google.com/index.html");
+}
+
+TEST_F(GetPromisedUrlFromHeaders, Connect) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "CONNECT";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":authority"] = "www.google.com";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":scheme"] = "https";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":path"] = "https";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+}
+
+TEST_F(GetPromisedUrlFromHeaders, InvalidUserinfo) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  headers[":authority"] = "user@www.google.com";
+  headers[":scheme"] = "https";
+  headers[":path"] = "/";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+}
+
+TEST_F(GetPromisedUrlFromHeaders, InvalidPath) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  headers[":authority"] = "www.google.com";
+  headers[":scheme"] = "https";
+  headers[":path"] = "";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+}
+
+using GetPromisedHostNameFromHeaders = QuicTest;
+
+TEST_F(GetPromisedHostNameFromHeaders, NormalUsage) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
+  headers[":scheme"] = "https";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
+  headers[":authority"] = "www.google.com";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
+  headers[":path"] = "/index.html";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "www.google.com");
+  headers["key1"] = "value1";
+  headers["key2"] = "value2";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "www.google.com");
+  headers[":authority"] = "www.google.com:6666";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "www.google.com");
+  headers[":authority"] = "192.168.1.1";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "192.168.1.1");
+  headers[":authority"] = "192.168.1.1:6666";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "192.168.1.1");
+}
+
+using PushPromiseUrlTest = QuicTest;
+
+TEST_F(PushPromiseUrlTest, GetPushPromiseUrl) {
+  // Test rejection of various inputs.
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("file", "localhost",
+                                                       "/etc/password"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl(
+                    "file", "", "/C:/Windows/System32/Config/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl(
+                    "", "https://www.google.com", "/"));
+
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https://www.google.com",
+                                                       "www.google.com", "/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https://",
+                                                       "www.google.com", "/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "", "/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "",
+                                                       "www.google.com/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https",
+                                                       "www.google.com/", "/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https",
+                                                       "www.google.com", ""));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "www.google",
+                                                       ".com/"));
+
+  // Test acception/rejection of various input combinations.
+  // |input_headers| is an array of pairs. The first value of each pair is a
+  // string that will be used as one of the inputs of GetPushPromiseUrl(). The
+  // second value of each pair is a bitfield where the lowest 3 bits indicate
+  // for which headers that string is valid (in a PUSH_PROMISE). For example,
+  // the string "http" would be valid for both the ":scheme" and ":authority"
+  // headers, so the bitfield paired with it is set to SCHEME | AUTH.
+  const unsigned char SCHEME = (1u << 0);
+  const unsigned char AUTH = (1u << 1);
+  const unsigned char PATH = (1u << 2);
+  const std::pair<const char*, unsigned char> input_headers[] = {
+      {"http", SCHEME | AUTH},
+      {"https", SCHEME | AUTH},
+      {"hTtP", SCHEME | AUTH},
+      {"HTTPS", SCHEME | AUTH},
+      {"www.google.com", AUTH},
+      {"90af90e0", AUTH},
+      {"12foo%20-bar:00001233", AUTH},
+      {"GOO\u200b\u2060\ufeffgoo", AUTH},
+      {"192.168.0.5", AUTH},
+      {"[::ffff:192.168.0.1.]", AUTH},
+      {"http:", AUTH},
+      {"bife l", AUTH},
+      {"/", PATH},
+      {"/foo/bar/baz", PATH},
+      {"/%20-2DVdkj.cie/foe_.iif/", PATH},
+      {"http://", 0},
+      {":443", 0},
+      {":80/eddd", 0},
+      {"google.com:-0", 0},
+      {"google.com:65536", 0},
+      {"http://google.com", 0},
+      {"http://google.com:39", 0},
+      {"//google.com/foo", 0},
+      {".com/", 0},
+      {"http://www.google.com/", 0},
+      {"http://foo:439", 0},
+      {"[::ffff:192.168", 0},
+      {"]/", 0},
+      {"//", 0}};
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(input_headers); ++i) {
+    bool should_accept = (input_headers[i].second & SCHEME);
+    for (size_t j = 0; j < ABSL_ARRAYSIZE(input_headers); ++j) {
+      bool should_accept_2 = should_accept && (input_headers[j].second & AUTH);
+      for (size_t k = 0; k < ABSL_ARRAYSIZE(input_headers); ++k) {
+        // |should_accept_3| indicates whether or not GetPushPromiseUrl() is
+        // expected to accept this input combination.
+        bool should_accept_3 =
+            should_accept_2 && (input_headers[k].second & PATH);
+
+        std::string url = SpdyServerPushUtils::GetPushPromiseUrl(
+            input_headers[i].first, input_headers[j].first,
+            input_headers[k].first);
+
+        ::testing::AssertionResult result = ::testing::AssertionSuccess();
+        if (url.empty() == should_accept_3) {
+          result = ::testing::AssertionFailure()
+                   << "GetPushPromiseUrl() accepted/rejected the inputs when "
+                      "it shouldn't have."
+                   << std::endl
+                   << "     scheme: " << input_headers[i].first << std::endl
+                   << "  authority: " << input_headers[j].first << std::endl
+                   << "       path: " << input_headers[k].first << std::endl
+                   << "Output: " << url << std::endl;
+        }
+        ASSERT_TRUE(result);
+      }
+    }
+  }
+
+  // Test canonicalization of various valid inputs.
+  EXPECT_EQ("http://www.google.com/", SpdyServerPushUtils::GetPushPromiseUrl(
+                                          "http", "www.google.com", "/"));
+  EXPECT_EQ("https://www.goo-gle.com/fOOo/baRR",
+            SpdyServerPushUtils::GetPushPromiseUrl("hTtPs", "wWw.gOo-gLE.cOm",
+                                                   "/fOOo/baRR"));
+  EXPECT_EQ("https://www.goo-gle.com:3278/pAth/To/reSOurce",
+            SpdyServerPushUtils::GetPushPromiseUrl(
+                "hTtPs", "Www.gOo-Gle.Com:000003278", "/pAth/To/reSOurce"));
+  EXPECT_EQ("https://foo%20bar/foo/bar/baz",
+            SpdyServerPushUtils::GetPushPromiseUrl("https", "foo bar",
+                                                   "/foo/bar/baz"));
+  EXPECT_EQ("http://foo.com:70/e/", SpdyServerPushUtils::GetPushPromiseUrl(
+                                        "http", "foo.com:0000070", "/e/"));
+  EXPECT_EQ("http://192.168.0.1:70/e/",
+            SpdyServerPushUtils::GetPushPromiseUrl(
+                "http", "0300.0250.00.01:0070", "/e/"));
+  EXPECT_EQ("http://192.168.0.1/e/", SpdyServerPushUtils::GetPushPromiseUrl(
+                                         "http", "0xC0a80001", "/e/"));
+  EXPECT_EQ("http://[::c0a8:1]/", SpdyServerPushUtils::GetPushPromiseUrl(
+                                      "http", "[::192.168.0.1]", "/"));
+  EXPECT_EQ("https://[::ffff:c0a8:1]/",
+            SpdyServerPushUtils::GetPushPromiseUrl(
+                "https", "[::ffff:0xC0.0Xa8.0x0.0x1]", "/"));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/spdy_utils.cc b/quiche/quic/core/http/spdy_utils.cc
new file mode 100644
index 0000000..d0eac9f
--- /dev/null
+++ b/quiche/quic/core/http/spdy_utils.cc
@@ -0,0 +1,217 @@
+// Copyright (c) 2013 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 "quiche/quic/core/http/spdy_utils.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+// static
+bool SpdyUtils::ExtractContentLengthFromHeaders(int64_t* content_length,
+                                                SpdyHeaderBlock* headers) {
+  auto it = headers->find("content-length");
+  if (it == headers->end()) {
+    return false;
+  } else {
+    // Check whether multiple values are consistent.
+    absl::string_view content_length_header = it->second;
+    std::vector<absl::string_view> values =
+        absl::StrSplit(content_length_header, '\0');
+    for (const absl::string_view& value : values) {
+      uint64_t new_value;
+      if (!absl::SimpleAtoi(value, &new_value) ||
+          !quiche::QuicheTextUtils::IsAllDigits(value)) {
+        QUIC_DLOG(ERROR)
+            << "Content length was either unparseable or negative.";
+        return false;
+      }
+      if (*content_length < 0) {
+        *content_length = new_value;
+        continue;
+      }
+      if (new_value != static_cast<uint64_t>(*content_length)) {
+        QUIC_DLOG(ERROR)
+            << "Parsed content length " << new_value << " is "
+            << "inconsistent with previously detected content length "
+            << *content_length;
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+bool SpdyUtils::CopyAndValidateHeaders(const QuicHeaderList& header_list,
+                                       int64_t* content_length,
+                                       SpdyHeaderBlock* headers) {
+  for (const auto& p : header_list) {
+    const std::string& name = p.first;
+    if (name.empty()) {
+      QUIC_DLOG(ERROR) << "Header name must not be empty.";
+      return false;
+    }
+
+    if (quiche::QuicheTextUtils::ContainsUpperCase(name)) {
+      QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
+                       << " contains upper-case characters.";
+      return false;
+    }
+
+    headers->AppendValueOrAddHeader(name, p.second);
+  }
+
+  if (headers->contains("content-length") &&
+      !ExtractContentLengthFromHeaders(content_length, headers)) {
+    return false;
+  }
+
+  QUIC_DVLOG(1) << "Successfully parsed headers: " << headers->DebugString();
+  return true;
+}
+
+bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list,
+                                        bool expect_final_byte_offset,
+                                        size_t* final_byte_offset,
+                                        SpdyHeaderBlock* trailers) {
+  bool found_final_byte_offset = false;
+  for (const auto& p : header_list) {
+    const std::string& name = p.first;
+
+    // Pull out the final offset pseudo header which indicates the number of
+    // response body bytes expected.
+    if (expect_final_byte_offset && !found_final_byte_offset &&
+        name == kFinalOffsetHeaderKey &&
+        absl::SimpleAtoi(p.second, final_byte_offset)) {
+      found_final_byte_offset = true;
+      continue;
+    }
+
+    if (name.empty() || name[0] == ':') {
+      QUIC_DLOG(ERROR)
+          << "Trailers must not be empty, and must not contain pseudo-"
+          << "headers. Found: '" << name << "'";
+      return false;
+    }
+
+    if (quiche::QuicheTextUtils::ContainsUpperCase(name)) {
+      QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
+                       << " contains upper-case characters.";
+      return false;
+    }
+
+    trailers->AppendValueOrAddHeader(name, p.second);
+  }
+
+  if (expect_final_byte_offset && !found_final_byte_offset) {
+    QUIC_DLOG(ERROR) << "Required key '" << kFinalOffsetHeaderKey
+                     << "' not present";
+    return false;
+  }
+
+  // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
+
+  QUIC_DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString();
+  return true;
+}
+
+// static
+// TODO(danzh): Move it to quic/tools/ and switch to use GURL.
+bool SpdyUtils::PopulateHeaderBlockFromUrl(const std::string url,
+                                           SpdyHeaderBlock* headers) {
+  (*headers)[":method"] = "GET";
+  size_t pos = url.find("://");
+  if (pos == std::string::npos) {
+    return false;
+  }
+  (*headers)[":scheme"] = url.substr(0, pos);
+  size_t start = pos + 3;
+  pos = url.find('/', start);
+  if (pos == std::string::npos) {
+    (*headers)[":authority"] = url.substr(start);
+    (*headers)[":path"] = "/";
+    return true;
+  }
+  (*headers)[":authority"] = url.substr(start, pos - start);
+  (*headers)[":path"] = url.substr(pos);
+  return true;
+}
+
+// static
+absl::optional<QuicDatagramStreamId> SpdyUtils::ParseDatagramFlowIdHeader(
+    const spdy::SpdyHeaderBlock& headers) {
+  auto flow_id_pair = headers.find("datagram-flow-id");
+  if (flow_id_pair == headers.end()) {
+    return absl::nullopt;
+  }
+  std::vector<absl::string_view> flow_id_strings =
+      absl::StrSplit(flow_id_pair->second, ',');
+  absl::optional<QuicDatagramStreamId> first_named_flow_id;
+  for (absl::string_view flow_id_string : flow_id_strings) {
+    std::vector<absl::string_view> flow_id_components =
+        absl::StrSplit(flow_id_string, ';');
+    if (flow_id_components.empty()) {
+      continue;
+    }
+    absl::string_view flow_id_value_string = flow_id_components[0];
+    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
+        &flow_id_value_string);
+    QuicDatagramStreamId flow_id;
+    if (!absl::SimpleAtoi(flow_id_value_string, &flow_id)) {
+      continue;
+    }
+    if (flow_id_components.size() == 1) {
+      // This flow ID is unnamed, return this one.
+      return flow_id;
+    }
+    // Otherwise this is a named flow ID.
+    if (!first_named_flow_id.has_value()) {
+      first_named_flow_id = flow_id;
+    }
+  }
+  return first_named_flow_id;
+}
+
+// static
+void SpdyUtils::AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
+                                        QuicDatagramStreamId flow_id) {
+  (*headers)["datagram-flow-id"] = absl::StrCat(flow_id);
+}
+
+// static
+ParsedQuicVersion SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+    const spdy::SpdyAltSvcWireFormat::AlternativeService&
+        alternative_service_entry,
+    const ParsedQuicVersionVector& supported_versions) {
+  for (const ParsedQuicVersion& version : supported_versions) {
+    if (version.AlpnDeferToRFCv1()) {
+      // Versions with share an ALPN with v1 are currently unable to be
+      // advertised with Alt-Svc.
+      continue;
+    }
+    if (AlpnForVersion(version) == alternative_service_entry.protocol_id) {
+      return version;
+    }
+  }
+
+  return ParsedQuicVersion::Unsupported();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/spdy_utils.h b/quiche/quic/core/http/spdy_utils.h
new file mode 100644
index 0000000..5654b2f
--- /dev/null
+++ b/quiche/quic/core/http/spdy_utils.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2013 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_HTTP_SPDY_UTILS_H_
+#define QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE SpdyUtils {
+ public:
+  SpdyUtils() = delete;
+
+  // Populate |content length| with the value of the content-length header.
+  // Returns true on success, false if parsing fails or content-length header is
+  // missing.
+  static bool ExtractContentLengthFromHeaders(int64_t* content_length,
+                                              spdy::SpdyHeaderBlock* headers);
+
+  // Copies a list of headers to a SpdyHeaderBlock.
+  static bool CopyAndValidateHeaders(const QuicHeaderList& header_list,
+                                     int64_t* content_length,
+                                     spdy::SpdyHeaderBlock* headers);
+
+  // Copies a list of headers to a SpdyHeaderBlock.
+  // If |expect_final_byte_offset| is true, requires exactly one header field
+  // with key kFinalOffsetHeaderKey and an integer value.
+  // If |expect_final_byte_offset| is false, no kFinalOffsetHeaderKey may be
+  // present.
+  // Returns true if parsing is successful.  Returns false if the presence of
+  // kFinalOffsetHeaderKey does not match the value of
+  // |expect_final_byte_offset|, the kFinalOffsetHeaderKey value cannot be
+  // parsed, any other pseudo-header is present, an empty header key is present,
+  // or a header key contains an uppercase character.
+  static bool CopyAndValidateTrailers(const QuicHeaderList& header_list,
+                                      bool expect_final_byte_offset,
+                                      size_t* final_byte_offset,
+                                      spdy::SpdyHeaderBlock* trailers);
+
+  // Populates the fields of |headers| to make a GET request of |url|,
+  // which must be fully-qualified.
+  static bool PopulateHeaderBlockFromUrl(const std::string url,
+                                         spdy::SpdyHeaderBlock* headers);
+
+  // Parses the "datagram-flow-id" header, returns the flow ID on success, or
+  // returns absl::nullopt if the header was not present or failed to parse.
+  static absl::optional<QuicDatagramStreamId> ParseDatagramFlowIdHeader(
+      const spdy::SpdyHeaderBlock& headers);
+
+  // Adds the "datagram-flow-id" header.
+  static void AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
+                                      QuicDatagramStreamId flow_id);
+
+  // Returns the advertised QUIC version from the specified alternative service
+  // advertisement, or ParsedQuicVersion::Unsupported() if no supported version
+  // is advertised.
+  static ParsedQuicVersion ExtractQuicVersionFromAltSvcEntry(
+      const spdy::SpdyAltSvcWireFormat::AlternativeService&
+          alternative_service_entry,
+      const ParsedQuicVersionVector& supported_versions);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
diff --git a/quiche/quic/core/http/spdy_utils_test.cc b/quiche/quic/core/http/spdy_utils_test.cc
new file mode 100644
index 0000000..d22a0e8
--- /dev/null
+++ b/quiche/quic/core/http/spdy_utils_test.cc
@@ -0,0 +1,442 @@
+// Copyright 2016 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 "quiche/quic/core/http/spdy_utils.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::Pair;
+using testing::UnorderedElementsAre;
+
+namespace quic {
+namespace test {
+namespace {
+
+const bool kExpectFinalByteOffset = true;
+const bool kDoNotExpectFinalByteOffset = false;
+
+static std::unique_ptr<QuicHeaderList> FromList(
+    const QuicHeaderList::ListType& src) {
+  std::unique_ptr<QuicHeaderList> headers(new QuicHeaderList);
+  headers->OnHeaderBlockStart();
+  for (const auto& p : src) {
+    headers->OnHeader(p.first, p.second);
+  }
+  headers->OnHeaderBlockEnd(0, 0);
+  return headers;
+}
+
+static void ValidateDatagramFlowId(
+    const std::string& header_value,
+    absl::optional<QuicDatagramStreamId> expected_flow_id) {
+  SpdyHeaderBlock headers;
+  headers["datagram-flow-id"] = header_value;
+  ASSERT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), expected_flow_id);
+}
+
+}  // anonymous namespace
+
+using CopyAndValidateHeaders = QuicTest;
+
+TEST_F(CopyAndValidateHeaders, NormalUsage) {
+  auto headers = FromList({// All cookie crumbs are joined.
+                           {"cookie", " part 1"},
+                           {"cookie", "part 2 "},
+                           {"cookie", "part3"},
+
+                           // Already-delimited headers are passed through.
+                           {"passed-through", std::string("foo\0baz", 7)},
+
+                           // Other headers are joined on \0.
+                           {"joined", "value 1"},
+                           {"joined", "value 2"},
+
+                           // Empty headers remain empty.
+                           {"empty", ""},
+
+                           // Joined empty headers work as expected.
+                           {"empty-joined", ""},
+                           {"empty-joined", "foo"},
+                           {"empty-joined", ""},
+                           {"empty-joined", ""},
+
+                           // Non-continguous cookie crumb.
+                           {"cookie", " fin!"}});
+
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block,
+              UnorderedElementsAre(
+                  Pair("cookie", " part 1; part 2 ; part3;  fin!"),
+                  Pair("passed-through", absl::string_view("foo\0baz", 7)),
+                  Pair("joined", absl::string_view("value 1\0value 2", 15)),
+                  Pair("empty", ""),
+                  Pair("empty-joined", absl::string_view("\0foo\0\0", 6))));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, EmptyName) {
+  auto headers = FromList({{"foo", "foovalue"}, {"", "barvalue"}, {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, UpperCaseName) {
+  auto headers =
+      FromList({{"foo", "foovalue"}, {"bar", "barvalue"}, {"bAz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, MultipleContentLengths) {
+  auto headers = FromList({{"content-length", "9"},
+                           {"foo", "foovalue"},
+                           {"content-length", "9"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("content-length", absl::string_view("9\09", 3)),
+                         Pair("baz", "")));
+  EXPECT_EQ(9, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, InconsistentContentLengths) {
+  auto headers = FromList({{"content-length", "9"},
+                           {"foo", "foovalue"},
+                           {"content-length", "8"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, LargeContentLength) {
+  auto headers = FromList({{"content-length", "9000000000"},
+                           {"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block,
+              UnorderedElementsAre(
+                  Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                  Pair("content-length", absl::string_view("9000000000")),
+                  Pair("baz", "")));
+  EXPECT_EQ(9000000000, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, NonDigitContentLength) {
+  // Section 3.3.2 of RFC 7230 defines content-length as being only digits.
+  // Number parsers might accept symbols like a leading plus; test that this
+  // fails to parse.
+  auto headers = FromList({{"content-length", "+123"},
+                           {"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, MultipleValues) {
+  auto headers = FromList({{"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"baz", ""},
+                           {"foo", "boo"},
+                           {"baz", "buzz"}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", absl::string_view("foovalue\0boo", 12)),
+                         Pair("bar", "barvalue"),
+                         Pair("baz", absl::string_view("\0buzz", 5))));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, MoreThanTwoValues) {
+  auto headers = FromList({{"set-cookie", "value1"},
+                           {"set-cookie", "value2"},
+                           {"set-cookie", "value3"}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(Pair(
+                         "set-cookie",
+                         absl::string_view("value1\0value2\0value3", 20))));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, Cookie) {
+  auto headers = FromList({{"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"cookie", "value1"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("cookie", "value1"), Pair("baz", "")));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, MultipleCookies) {
+  auto headers = FromList({{"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"cookie", "value1"},
+                           {"baz", ""},
+                           {"cookie", "value2"}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("cookie", "value1; value2"), Pair("baz", "")));
+  EXPECT_EQ(-1, content_length);
+}
+
+using CopyAndValidateTrailers = QuicTest;
+
+TEST_F(CopyAndValidateTrailers, SimplestValidList) {
+  // Verify that the simplest trailers are valid: just a final byte offset that
+  // gets parsed successfully.
+  auto trailers = FromList({{kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_EQ(1234u, final_byte_offset);
+}
+
+TEST_F(CopyAndValidateTrailers, EmptyTrailerListWithFinalByteOffsetExpected) {
+  // An empty trailer list will fail as expected key kFinalOffsetHeaderKey is
+  // not present.
+  QuicHeaderList trailers;
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers,
+       EmptyTrailerListWithFinalByteOffsetNotExpected) {
+  // An empty trailer list will pass successfully if kFinalOffsetHeaderKey is
+  // not expected.
+  QuicHeaderList trailers;
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_TRUE(block.empty());
+}
+
+TEST_F(CopyAndValidateTrailers, FinalByteOffsetExpectedButNotPresent) {
+  // Validation fails if expected kFinalOffsetHeaderKey is not present, even if
+  // the rest of the header block is valid.
+  auto trailers = FromList({{"key", "value"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers, FinalByteOffsetNotExpectedButPresent) {
+  // Validation fails if kFinalOffsetHeaderKey is present but should not be,
+  // even if the rest of the header block is valid.
+  auto trailers = FromList({{"key", "value"}, {kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers, FinalByteOffsetNotExpectedAndNotPresent) {
+  // Validation succeeds if kFinalOffsetHeaderKey is not expected and not
+  // present.
+  auto trailers = FromList({{"key", "value"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(Pair("key", "value")));
+}
+
+TEST_F(CopyAndValidateTrailers, EmptyName) {
+  // Trailer validation will fail with an empty header key, in an otherwise
+  // valid block of trailers.
+  auto trailers = FromList({{"", "value"}, {kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers, PseudoHeaderInTrailers) {
+  // Pseudo headers are illegal in trailers.
+  auto trailers =
+      FromList({{":pseudo_key", "value"}, {kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers, DuplicateTrailers) {
+  // Duplicate trailers are allowed, and their values are concatenated into a
+  // single string delimted with '\0'. Some of the duplicate headers
+  // deliberately have an empty value.
+  auto trailers = FromList({{"key", "value0"},
+                            {"key", "value1"},
+                            {"key", ""},
+                            {"key", ""},
+                            {"key", "value2"},
+                            {"key", ""},
+                            {kFinalOffsetHeaderKey, "1234"},
+                            {"other_key", "value"},
+                            {"key", "non_contiguous_duplicate"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_THAT(
+      block,
+      UnorderedElementsAre(
+          Pair("key",
+               absl::string_view(
+                   "value0\0value1\0\0\0value2\0\0non_contiguous_duplicate",
+                   48)),
+          Pair("other_key", "value")));
+}
+
+TEST_F(CopyAndValidateTrailers, DuplicateCookies) {
+  // Duplicate cookie headers in trailers should be concatenated into a single
+  //  "; " delimted string.
+  auto headers = FromList({{"cookie", " part 1"},
+                           {"cookie", "part 2 "},
+                           {"cookie", "part3"},
+                           {"key", "value"},
+                           {kFinalOffsetHeaderKey, "1234"},
+                           {"cookie", " non_contiguous_cookie!"}});
+
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      *headers, kExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_THAT(
+      block,
+      UnorderedElementsAre(
+          Pair("cookie", " part 1; part 2 ; part3;  non_contiguous_cookie!"),
+          Pair("key", "value")));
+}
+
+using PopulateHeaderBlockFromUrl = QuicTest;
+
+TEST_F(PopulateHeaderBlockFromUrl, NormalUsage) {
+  std::string url = "https://www.google.com/index.html";
+  SpdyHeaderBlock headers;
+  EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
+  EXPECT_EQ("https", headers[":scheme"].as_string());
+  EXPECT_EQ("www.google.com", headers[":authority"].as_string());
+  EXPECT_EQ("/index.html", headers[":path"].as_string());
+}
+
+TEST_F(PopulateHeaderBlockFromUrl, UrlWithNoPath) {
+  std::string url = "https://www.google.com";
+  SpdyHeaderBlock headers;
+  EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
+  EXPECT_EQ("https", headers[":scheme"].as_string());
+  EXPECT_EQ("www.google.com", headers[":authority"].as_string());
+  EXPECT_EQ("/", headers[":path"].as_string());
+}
+
+TEST_F(PopulateHeaderBlockFromUrl, Failure) {
+  SpdyHeaderBlock headers;
+  EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/", &headers));
+  EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/index.html", &headers));
+  EXPECT_FALSE(
+      SpdyUtils::PopulateHeaderBlockFromUrl("www.google.com/", &headers));
+}
+
+using DatagramFlowIdTest = QuicTest;
+
+TEST_F(DatagramFlowIdTest, DatagramFlowId) {
+  // Test missing header.
+  SpdyHeaderBlock headers;
+  EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), absl::nullopt);
+  // Add header and verify it parses.
+  QuicDatagramStreamId flow_id = 123;
+  SpdyUtils::AddDatagramFlowIdHeader(&headers, flow_id);
+  EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), flow_id);
+  // Test empty header.
+  ValidateDatagramFlowId("", absl::nullopt);
+  // Test invalid header.
+  ValidateDatagramFlowId("M4SQU3", absl::nullopt);
+  // Test simple header.
+  ValidateDatagramFlowId("42", 42);
+  // Test with parameter.
+  ValidateDatagramFlowId("42; abc=def", 42);
+  // Test list.
+  ValidateDatagramFlowId("42, 44; ecn-ect0, 46; ecn-ect1, 48; ecn-ce", 42);
+  // Test reordered list.
+  ValidateDatagramFlowId("44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1", 42);
+}
+
+using ExtractQuicVersionFromAltSvcEntry = QuicTest;
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, SupportedVersion) {
+  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+  for (const ParsedQuicVersion& version : supported_versions) {
+    entry.protocol_id = AlpnForVersion(version);
+    ParsedQuicVersion expected_version = version;
+    // Versions with share an ALPN with v1 are currently unable to be
+    // advertised with Alt-Svc.
+    if (entry.protocol_id == AlpnForVersion(ParsedQuicVersion::RFCv1()) &&
+        version != ParsedQuicVersion::RFCv1()) {
+      expected_version = ParsedQuicVersion::RFCv1();
+    }
+    EXPECT_EQ(expected_version, SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+                                    entry, supported_versions))
+        << "version: " << version;
+  }
+}
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, UnsupportedVersion) {
+  spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+  entry.protocol_id = "quic";
+  EXPECT_EQ(ParsedQuicVersion::Unsupported(),
+            SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+                entry, AllSupportedVersions()));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/web_transport_http3.cc b/quiche/quic/core/http/web_transport_http3.cc
new file mode 100644
index 0000000..f0e3849
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_http3.cc
@@ -0,0 +1,546 @@
+// Copyright 2021 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 "quiche/quic/core/http/web_transport_http3.h"
+
+#include <limits>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/http/capsule.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+#define ENDPOINT \
+  (session_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+namespace quic {
+
+namespace {
+class QUIC_NO_EXPORT NoopWebTransportVisitor : public WebTransportVisitor {
+  void OnSessionReady(const spdy::SpdyHeaderBlock&) override {}
+  void OnSessionClosed(WebTransportSessionError /*error_code*/,
+                       const std::string& /*error_message*/) override {}
+  void OnIncomingBidirectionalStreamAvailable() override {}
+  void OnIncomingUnidirectionalStreamAvailable() override {}
+  void OnDatagramReceived(absl::string_view /*datagram*/) override {}
+  void OnCanCreateNewOutgoingBidirectionalStream() override {}
+  void OnCanCreateNewOutgoingUnidirectionalStream() override {}
+};
+}  // namespace
+
+WebTransportHttp3::WebTransportHttp3(QuicSpdySession* session,
+                                     QuicSpdyStream* connect_stream,
+                                     WebTransportSessionId id,
+                                     bool attempt_to_use_datagram_contexts)
+    : session_(session),
+      connect_stream_(connect_stream),
+      id_(id),
+      visitor_(std::make_unique<NoopWebTransportVisitor>()) {
+  QUICHE_DCHECK(session_->SupportsWebTransport());
+  QUICHE_DCHECK(IsValidWebTransportSessionId(id, session_->version()));
+  QUICHE_DCHECK_EQ(connect_stream_->id(), id);
+  connect_stream_->RegisterHttp3DatagramRegistrationVisitor(
+      this, attempt_to_use_datagram_contexts);
+  if (session_->perspective() == Perspective::IS_CLIENT) {
+    context_is_known_ = true;
+    context_currently_registered_ = true;
+    if (attempt_to_use_datagram_contexts) {
+      context_id_ = connect_stream_->GetNextDatagramContextId();
+    }
+  }
+}
+
+void WebTransportHttp3::AssociateStream(QuicStreamId stream_id) {
+  streams_.insert(stream_id);
+
+  ParsedQuicVersion version = session_->version();
+  if (QuicUtils::IsOutgoingStreamId(version, stream_id,
+                                    session_->perspective())) {
+    return;
+  }
+  if (QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
+    incoming_bidirectional_streams_.push_back(stream_id);
+    visitor_->OnIncomingBidirectionalStreamAvailable();
+  } else {
+    incoming_unidirectional_streams_.push_back(stream_id);
+    visitor_->OnIncomingUnidirectionalStreamAvailable();
+  }
+}
+
+void WebTransportHttp3::OnConnectStreamClosing() {
+  // Copy the stream list before iterating over it, as calls to ResetStream()
+  // can potentially mutate the |session_| list.
+  std::vector<QuicStreamId> streams(streams_.begin(), streams_.end());
+  streams_.clear();
+  for (QuicStreamId id : streams) {
+    session_->ResetStream(id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
+  }
+  if (context_currently_registered_) {
+    context_currently_registered_ = false;
+    connect_stream_->UnregisterHttp3DatagramContextId(context_id_);
+  }
+  connect_stream_->UnregisterHttp3DatagramRegistrationVisitor();
+
+  MaybeNotifyClose();
+}
+
+void WebTransportHttp3::CloseSession(WebTransportSessionError error_code,
+                                     absl::string_view error_message) {
+  if (close_sent_) {
+    QUIC_BUG(WebTransportHttp3 close sent twice)
+        << "Calling WebTransportHttp3::CloseSession() more than once is not "
+           "allowed.";
+    return;
+  }
+  close_sent_ = true;
+
+  // There can be a race between us trying to send our close and peer sending
+  // one.  If we received a close, however, we cannot send ours since we already
+  // closed the stream in response.
+  if (close_received_) {
+    QUIC_DLOG(INFO) << "Not sending CLOSE_WEBTRANSPORT_SESSION as we've "
+                       "already sent one from peer.";
+    return;
+  }
+
+  error_code_ = error_code;
+  error_message_ = std::string(error_message);
+  QuicConnection::ScopedPacketFlusher flusher(
+      connect_stream_->spdy_session()->connection());
+  connect_stream_->WriteCapsule(
+      Capsule::CloseWebTransportSession(error_code, error_message),
+      /*fin=*/true);
+}
+
+void WebTransportHttp3::OnCloseReceived(WebTransportSessionError error_code,
+                                        absl::string_view error_message) {
+  if (close_received_) {
+    QUIC_BUG(WebTransportHttp3 notified of close received twice)
+        << "WebTransportHttp3::OnCloseReceived() may be only called once.";
+  }
+  close_received_ = true;
+
+  // If the peer has sent a close after we sent our own, keep the local error.
+  if (close_sent_) {
+    QUIC_DLOG(INFO) << "Ignoring received CLOSE_WEBTRANSPORT_SESSION as we've "
+                       "already sent our own.";
+    return;
+  }
+
+  error_code_ = error_code;
+  error_message_ = std::string(error_message);
+  connect_stream_->WriteOrBufferBody("", /*fin=*/true);
+  MaybeNotifyClose();
+}
+
+void WebTransportHttp3::OnConnectStreamFinReceived() {
+  // If we already received a CLOSE_WEBTRANSPORT_SESSION capsule, we don't need
+  // to do anything about receiving a FIN, since we already sent one in
+  // response.
+  if (close_received_) {
+    return;
+  }
+  close_received_ = true;
+  if (close_sent_) {
+    QUIC_DLOG(INFO) << "Ignoring received FIN as we've already sent our close.";
+    return;
+  }
+
+  connect_stream_->WriteOrBufferBody("", /*fin=*/true);
+  MaybeNotifyClose();
+}
+
+void WebTransportHttp3::CloseSessionWithFinOnlyForTests() {
+  QUICHE_DCHECK(!close_sent_);
+  close_sent_ = true;
+  if (close_received_) {
+    return;
+  }
+
+  connect_stream_->WriteOrBufferBody("", /*fin=*/true);
+}
+
+void WebTransportHttp3::HeadersReceived(const spdy::SpdyHeaderBlock& headers) {
+  if (session_->perspective() == Perspective::IS_CLIENT) {
+    int status_code;
+    if (!QuicSpdyStream::ParseHeaderStatusCode(headers, &status_code)) {
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Received WebTransport headers from server without "
+                       "a valid status code, rejecting.";
+      rejection_reason_ = WebTransportHttp3RejectionReason::kNoStatusCode;
+      return;
+    }
+    bool valid_status = status_code >= 200 && status_code <= 299;
+    if (!valid_status) {
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Received WebTransport headers from server with "
+                       "status code "
+                    << status_code << ", rejecting.";
+      rejection_reason_ = WebTransportHttp3RejectionReason::kWrongStatusCode;
+      return;
+    }
+    bool should_validate_version =
+        session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
+        session_->ShouldValidateWebTransportVersion();
+    if (should_validate_version) {
+      auto draft_version_it = headers.find("sec-webtransport-http3-draft");
+      if (draft_version_it == headers.end()) {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "Received WebTransport headers from server without "
+                         "a draft version, rejecting.";
+        rejection_reason_ =
+            WebTransportHttp3RejectionReason::kMissingDraftVersion;
+        return;
+      }
+      if (draft_version_it->second != "draft02") {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "Received WebTransport headers from server with "
+                         "an unknown draft version ("
+                      << draft_version_it->second << "), rejecting.";
+        rejection_reason_ =
+            WebTransportHttp3RejectionReason::kUnsupportedDraftVersion;
+        return;
+      }
+    }
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "WebTransport session " << id_ << " ready.";
+  ready_ = true;
+  visitor_->OnSessionReady(headers);
+  session_->ProcessBufferedWebTransportStreamsForSession(this);
+}
+
+WebTransportStream* WebTransportHttp3::AcceptIncomingBidirectionalStream() {
+  while (!incoming_bidirectional_streams_.empty()) {
+    QuicStreamId id = incoming_bidirectional_streams_.front();
+    incoming_bidirectional_streams_.pop_front();
+    QuicSpdyStream* stream = session_->GetOrCreateSpdyDataStream(id);
+    if (stream == nullptr) {
+      // Skip the streams that were reset in between the time they were
+      // receieved and the time the client has polled for them.
+      continue;
+    }
+    return stream->web_transport_stream();
+  }
+  return nullptr;
+}
+
+WebTransportStream* WebTransportHttp3::AcceptIncomingUnidirectionalStream() {
+  while (!incoming_unidirectional_streams_.empty()) {
+    QuicStreamId id = incoming_unidirectional_streams_.front();
+    incoming_unidirectional_streams_.pop_front();
+    QuicStream* stream = session_->GetOrCreateStream(id);
+    if (stream == nullptr) {
+      // Skip the streams that were reset in between the time they were
+      // receieved and the time the client has polled for them.
+      continue;
+    }
+    return static_cast<WebTransportHttp3UnidirectionalStream*>(stream)
+        ->interface();
+  }
+  return nullptr;
+}
+
+bool WebTransportHttp3::CanOpenNextOutgoingBidirectionalStream() {
+  return session_->CanOpenOutgoingBidirectionalWebTransportStream(id_);
+}
+bool WebTransportHttp3::CanOpenNextOutgoingUnidirectionalStream() {
+  return session_->CanOpenOutgoingUnidirectionalWebTransportStream(id_);
+}
+WebTransportStream* WebTransportHttp3::OpenOutgoingBidirectionalStream() {
+  QuicSpdyStream* stream =
+      session_->CreateOutgoingBidirectionalWebTransportStream(this);
+  if (stream == nullptr) {
+    // If stream cannot be created due to flow control or other errors, return
+    // nullptr.
+    return nullptr;
+  }
+  return stream->web_transport_stream();
+}
+
+WebTransportStream* WebTransportHttp3::OpenOutgoingUnidirectionalStream() {
+  WebTransportHttp3UnidirectionalStream* stream =
+      session_->CreateOutgoingUnidirectionalWebTransportStream(this);
+  if (stream == nullptr) {
+    // If stream cannot be created due to flow control, return nullptr.
+    return nullptr;
+  }
+  return stream->interface();
+}
+
+MessageStatus WebTransportHttp3::SendOrQueueDatagram(
+    quiche::QuicheMemSlice datagram) {
+  return connect_stream_->SendHttp3Datagram(
+      context_id_, absl::string_view(datagram.data(), datagram.length()));
+}
+
+QuicByteCount WebTransportHttp3::GetMaxDatagramSize() const {
+  return connect_stream_->GetMaxDatagramSize(context_id_);
+}
+
+void WebTransportHttp3::SetDatagramMaxTimeInQueue(
+    QuicTime::Delta max_time_in_queue) {
+  connect_stream_->SetMaxDatagramTimeInQueue(max_time_in_queue);
+}
+
+void WebTransportHttp3::OnHttp3Datagram(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  QUICHE_DCHECK_EQ(stream_id, connect_stream_->id());
+  QUICHE_DCHECK(context_id == context_id_);
+  visitor_->OnDatagramReceived(payload);
+}
+
+void WebTransportHttp3::OnContextReceived(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    DatagramFormatType format_type, absl::string_view format_additional_data) {
+  if (stream_id != connect_stream_->id()) {
+    QUIC_BUG(WT3 bad datagram context registration)
+        << ENDPOINT << "Registered stream ID " << stream_id << ", expected "
+        << connect_stream_->id();
+    return;
+  }
+  if (format_type != DatagramFormatType::WEBTRANSPORT) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected datagram format type "
+                    << DatagramFormatTypeToString(format_type);
+    return;
+  }
+  if (!format_additional_data.empty()) {
+    QUIC_DLOG(ERROR)
+        << ENDPOINT
+        << "Received non-empty format additional data for context ID "
+        << (context_id_.has_value() ? context_id_.value() : 0)
+        << " on stream ID " << connect_stream_->id();
+    session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+  if (!context_is_known_) {
+    context_is_known_ = true;
+    context_id_ = context_id;
+  }
+  if (context_id != context_id_) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected context ID "
+                    << (context_id.has_value() ? context_id.value() : 0)
+                    << " instead of "
+                    << (context_id_.has_value() ? context_id_.value() : 0)
+                    << " on stream ID " << connect_stream_->id();
+    return;
+  }
+  if (session_->perspective() == Perspective::IS_SERVER) {
+    if (context_currently_registered_) {
+      QUIC_DLOG(ERROR) << ENDPOINT << "Received duplicate context ID "
+                       << (context_id_.has_value() ? context_id_.value() : 0)
+                       << " on stream ID " << connect_stream_->id();
+      session_->ResetStream(connect_stream_->id(), QUIC_STREAM_CANCELLED);
+      return;
+    }
+    context_currently_registered_ = true;
+    connect_stream_->RegisterHttp3DatagramContextId(
+        context_id_, format_type, format_additional_data, this);
+  }
+}
+
+void WebTransportHttp3::OnContextClosed(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    ContextCloseCode close_code, absl::string_view close_details) {
+  if (stream_id != connect_stream_->id()) {
+    QUIC_BUG(WT3 bad datagram context registration)
+        << ENDPOINT << "Closed context on stream ID " << stream_id
+        << ", expected " << connect_stream_->id();
+    return;
+  }
+  if (context_id != context_id_) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected close of context ID "
+                    << (context_id.has_value() ? context_id.value() : 0)
+                    << " instead of "
+                    << (context_id_.has_value() ? context_id_.value() : 0)
+                    << " on stream ID " << connect_stream_->id();
+    return;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "Received datagram context close with close code "
+                  << close_code << " close details \"" << close_details
+                  << "\" on stream ID " << connect_stream_->id()
+                  << ", resetting stream";
+  session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
+}
+
+void WebTransportHttp3::MaybeNotifyClose() {
+  if (close_notified_) {
+    return;
+  }
+  close_notified_ = true;
+  visitor_->OnSessionClosed(error_code_, error_message_);
+}
+
+WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(
+    PendingStream* pending, QuicSpdySession* session)
+    : QuicStream(pending, session, /*is_static=*/false),
+      session_(session),
+      adapter_(session, this, sequencer()),
+      needs_to_send_preamble_(false) {}
+
+WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(
+    QuicStreamId id, QuicSpdySession* session, WebTransportSessionId session_id)
+    : QuicStream(id, session, /*is_static=*/false, WRITE_UNIDIRECTIONAL),
+      session_(session),
+      adapter_(session, this, sequencer()),
+      session_id_(session_id),
+      needs_to_send_preamble_(true) {}
+
+void WebTransportHttp3UnidirectionalStream::WritePreamble() {
+  if (!needs_to_send_preamble_ || !session_id_.has_value()) {
+    QUIC_BUG(WebTransportHttp3UnidirectionalStream duplicate preamble)
+        << ENDPOINT << "Sending preamble on stream ID " << id()
+        << " at the wrong time.";
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         "Attempting to send a WebTransport unidirectional "
+                         "stream preamble at the wrong time.");
+    return;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(session_->connection());
+  char buffer[sizeof(uint64_t) * 2];  // varint62, varint62
+  QuicDataWriter writer(sizeof(buffer), buffer);
+  bool success = true;
+  success = success && writer.WriteVarInt62(kWebTransportUnidirectionalStream);
+  success = success && writer.WriteVarInt62(*session_id_);
+  QUICHE_DCHECK(success);
+  WriteOrBufferData(absl::string_view(buffer, writer.length()), /*fin=*/false,
+                    /*ack_listener=*/nullptr);
+  QUIC_DVLOG(1) << ENDPOINT << "Sent stream type and session ID ("
+                << *session_id_ << ") on WebTransport stream " << id();
+  needs_to_send_preamble_ = false;
+}
+
+bool WebTransportHttp3UnidirectionalStream::ReadSessionId() {
+  iovec iov;
+  if (!sequencer()->GetReadableRegion(&iov)) {
+    return false;
+  }
+  QuicDataReader reader(static_cast<const char*>(iov.iov_base), iov.iov_len);
+  WebTransportSessionId session_id;
+  uint8_t session_id_length = reader.PeekVarInt62Length();
+  if (!reader.ReadVarInt62(&session_id)) {
+    // If all of the data has been received, and we still cannot associate the
+    // stream with a session, consume all of the data so that the stream can
+    // be closed.
+    if (sequencer()->NumBytesConsumed() + sequencer()->NumBytesBuffered() >=
+        sequencer()->close_offset()) {
+      QUIC_DLOG(WARNING)
+          << ENDPOINT << "Failed to associate WebTransport stream " << id()
+          << " with a session because the stream ended prematurely.";
+      sequencer()->MarkConsumed(sequencer()->NumBytesBuffered());
+    }
+    return false;
+  }
+  sequencer()->MarkConsumed(session_id_length);
+  session_id_ = session_id;
+  session_->AssociateIncomingWebTransportStreamWithSession(session_id, id());
+  return true;
+}
+
+void WebTransportHttp3UnidirectionalStream::OnDataAvailable() {
+  if (!session_id_.has_value()) {
+    if (!ReadSessionId()) {
+      return;
+    }
+  }
+
+  adapter_.OnDataAvailable();
+}
+
+void WebTransportHttp3UnidirectionalStream::OnCanWriteNewData() {
+  adapter_.OnCanWriteNewData();
+}
+
+void WebTransportHttp3UnidirectionalStream::OnClose() {
+  QuicStream::OnClose();
+
+  if (!session_id_.has_value()) {
+    return;
+  }
+  WebTransportHttp3* session = session_->GetWebTransportSession(*session_id_);
+  if (session == nullptr) {
+    QUIC_DLOG(WARNING) << ENDPOINT << "WebTransport stream " << id()
+                       << " attempted to notify parent session " << *session_id_
+                       << ", but the session could not be found.";
+    return;
+  }
+  session->OnStreamClosed(id());
+}
+
+void WebTransportHttp3UnidirectionalStream::OnStreamReset(
+    const QuicRstStreamFrame& frame) {
+  if (adapter_.visitor() != nullptr) {
+    adapter_.visitor()->OnResetStreamReceived(
+        Http3ErrorToWebTransportOrDefault(frame.ietf_error_code));
+  }
+  QuicStream::OnStreamReset(frame);
+}
+bool WebTransportHttp3UnidirectionalStream::OnStopSending(
+    QuicResetStreamError error) {
+  if (adapter_.visitor() != nullptr) {
+    adapter_.visitor()->OnStopSendingReceived(
+        Http3ErrorToWebTransportOrDefault(error.ietf_application_code()));
+  }
+  return QuicStream::OnStopSending(error);
+}
+void WebTransportHttp3UnidirectionalStream::OnWriteSideInDataRecvdState() {
+  if (adapter_.visitor() != nullptr) {
+    adapter_.visitor()->OnWriteSideInDataRecvdState();
+  }
+
+  QuicStream::OnWriteSideInDataRecvdState();
+}
+
+namespace {
+constexpr uint64_t kWebTransportMappedErrorCodeFirst = 0x52e4a40fa8db;
+constexpr uint64_t kWebTransportMappedErrorCodeLast = 0x52e4a40fa9e2;
+constexpr WebTransportStreamError kDefaultWebTransportError = 0;
+}  // namespace
+
+absl::optional<WebTransportStreamError> Http3ErrorToWebTransport(
+    uint64_t http3_error_code) {
+  // Ensure the code is within the valid range.
+  if (http3_error_code < kWebTransportMappedErrorCodeFirst ||
+      http3_error_code > kWebTransportMappedErrorCodeLast) {
+    return absl::nullopt;
+  }
+  // Exclude GREASE codepoints.
+  if ((http3_error_code - 0x21) % 0x1f == 0) {
+    return absl::nullopt;
+  }
+
+  uint64_t shifted = http3_error_code - kWebTransportMappedErrorCodeFirst;
+  uint64_t result = shifted - shifted / 0x1f;
+  QUICHE_DCHECK_LE(result, std::numeric_limits<uint8_t>::max());
+  return result;
+}
+
+WebTransportStreamError Http3ErrorToWebTransportOrDefault(
+    uint64_t http3_error_code) {
+  absl::optional<WebTransportStreamError> result =
+      Http3ErrorToWebTransport(http3_error_code);
+  return result.has_value() ? *result : kDefaultWebTransportError;
+}
+
+uint64_t WebTransportErrorToHttp3(
+    WebTransportStreamError webtransport_error_code) {
+  return kWebTransportMappedErrorCodeFirst + webtransport_error_code +
+         webtransport_error_code / 0x1e;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/web_transport_http3.h b/quiche/quic/core/http/web_transport_http3.h
new file mode 100644
index 0000000..03ed764
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_http3.h
@@ -0,0 +1,198 @@
+// Copyright 2021 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_HTTP_WEB_TRANSPORT_HTTP3_H_
+#define QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
+
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/http/web_transport_stream_adapter.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+class QuicSpdySession;
+class QuicSpdyStream;
+
+enum class WebTransportHttp3RejectionReason {
+  kNone,
+  kNoStatusCode,
+  kWrongStatusCode,
+  kMissingDraftVersion,
+  kUnsupportedDraftVersion,
+};
+
+// A session of WebTransport over HTTP/3.  The session is owned by
+// QuicSpdyStream object for the CONNECT stream that established it.
+//
+// WebTransport over HTTP/3 specification:
+// <https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3>
+class QUIC_EXPORT_PRIVATE WebTransportHttp3
+    : public WebTransportSession,
+      public QuicSpdyStream::Http3DatagramRegistrationVisitor,
+      public QuicSpdyStream::Http3DatagramVisitor {
+ public:
+  WebTransportHttp3(QuicSpdySession* session, QuicSpdyStream* connect_stream,
+                    WebTransportSessionId id,
+                    bool attempt_to_use_datagram_contexts);
+
+  void HeadersReceived(const spdy::SpdyHeaderBlock& headers);
+  void SetVisitor(std::unique_ptr<WebTransportVisitor> visitor) {
+    visitor_ = std::move(visitor);
+  }
+
+  WebTransportSessionId id() { return id_; }
+  bool ready() { return ready_; }
+  absl::optional<QuicDatagramContextId> context_id() const {
+    return context_id_;
+  }
+
+  void AssociateStream(QuicStreamId stream_id);
+  void OnStreamClosed(QuicStreamId stream_id) { streams_.erase(stream_id); }
+  void OnConnectStreamClosing();
+
+  size_t NumberOfAssociatedStreams() { return streams_.size(); }
+
+  void CloseSession(WebTransportSessionError error_code,
+                    absl::string_view error_message) override;
+  void OnCloseReceived(WebTransportSessionError error_code,
+                       absl::string_view error_message);
+  void OnConnectStreamFinReceived();
+
+  // It is legal for WebTransport to be closed without a
+  // CLOSE_WEBTRANSPORT_SESSION capsule.  We always send a capsule, but we still
+  // need to ensure we handle this case correctly.
+  void CloseSessionWithFinOnlyForTests();
+
+  // Return the earliest incoming stream that has been received by the session
+  // but has not been accepted.  Returns nullptr if there are no incoming
+  // streams.
+  WebTransportStream* AcceptIncomingBidirectionalStream() override;
+  WebTransportStream* AcceptIncomingUnidirectionalStream() override;
+
+  bool CanOpenNextOutgoingBidirectionalStream() override;
+  bool CanOpenNextOutgoingUnidirectionalStream() override;
+  WebTransportStream* OpenOutgoingBidirectionalStream() override;
+  WebTransportStream* OpenOutgoingUnidirectionalStream() override;
+
+  MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram) override;
+  QuicByteCount GetMaxDatagramSize() const override;
+  void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override;
+
+  // From QuicSpdyStream::Http3DatagramVisitor.
+  void OnHttp3Datagram(QuicStreamId stream_id,
+                       absl::optional<QuicDatagramContextId> context_id,
+                       absl::string_view payload) override;
+
+  // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
+  void OnContextReceived(QuicStreamId stream_id,
+                         absl::optional<QuicDatagramContextId> context_id,
+                         DatagramFormatType format_type,
+                         absl::string_view format_additional_data) override;
+  void OnContextClosed(QuicStreamId stream_id,
+                       absl::optional<QuicDatagramContextId> context_id,
+                       ContextCloseCode close_code,
+                       absl::string_view close_details) override;
+
+  bool close_received() const { return close_received_; }
+  WebTransportHttp3RejectionReason rejection_reason() const {
+    return rejection_reason_;
+  }
+
+ private:
+  // Notifies the visitor that the connection has been closed.  Ensures that the
+  // visitor is only ever called once.
+  void MaybeNotifyClose();
+
+  QuicSpdySession* const session_;        // Unowned.
+  QuicSpdyStream* const connect_stream_;  // Unowned.
+  const WebTransportSessionId id_;
+  absl::optional<QuicDatagramContextId> context_id_;
+  // |ready_| is set to true when the peer has seen both sets of headers.
+  bool ready_ = false;
+  // Whether we know which |context_id_| to use. On the client this is always
+  // true, and on the server it becomes true when we receive a context
+  // registration capsule.
+  bool context_is_known_ = false;
+  // Whether |context_id_| is currently registered with |connect_stream_|.
+  bool context_currently_registered_ = false;
+  std::unique_ptr<WebTransportVisitor> visitor_;
+  absl::flat_hash_set<QuicStreamId> streams_;
+  quiche::QuicheCircularDeque<QuicStreamId> incoming_bidirectional_streams_;
+  quiche::QuicheCircularDeque<QuicStreamId> incoming_unidirectional_streams_;
+
+  bool close_sent_ = false;
+  bool close_received_ = false;
+  bool close_notified_ = false;
+
+  WebTransportHttp3RejectionReason rejection_reason_ =
+      WebTransportHttp3RejectionReason::kNone;
+  // Those are set to default values, which are used if the session is not
+  // closed cleanly using an appropriate capsule.
+  WebTransportSessionError error_code_ = 0;
+  std::string error_message_ = "";
+};
+
+class QUIC_EXPORT_PRIVATE WebTransportHttp3UnidirectionalStream
+    : public QuicStream {
+ public:
+  // Incoming stream.
+  WebTransportHttp3UnidirectionalStream(PendingStream* pending,
+                                        QuicSpdySession* session);
+  // Outgoing stream.
+  WebTransportHttp3UnidirectionalStream(QuicStreamId id,
+                                        QuicSpdySession* session,
+                                        WebTransportSessionId session_id);
+
+  // Sends the stream type and the session ID on the stream.
+  void WritePreamble();
+
+  // Implementation of QuicStream.
+  void OnDataAvailable() override;
+  void OnCanWriteNewData() override;
+  void OnClose() override;
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+  bool OnStopSending(QuicResetStreamError error) override;
+  void OnWriteSideInDataRecvdState() override;
+
+  WebTransportStream* interface() { return &adapter_; }
+  void SetUnblocked() { sequencer()->SetUnblocked(); }
+
+ private:
+  QuicSpdySession* session_;
+  WebTransportStreamAdapter adapter_;
+  absl::optional<WebTransportSessionId> session_id_;
+  bool needs_to_send_preamble_;
+
+  bool ReadSessionId();
+  // Closes the stream if all of the data has been received.
+  void MaybeCloseIncompleteStream();
+};
+
+// Remaps HTTP/3 error code into a WebTransport error code.  Returns nullopt if
+// the provided code is outside of valid range.
+QUIC_EXPORT_PRIVATE absl::optional<WebTransportStreamError>
+Http3ErrorToWebTransport(uint64_t http3_error_code);
+
+// Same as above, but returns default error value (zero) when none could be
+// mapped.
+QUIC_EXPORT_PRIVATE WebTransportStreamError
+Http3ErrorToWebTransportOrDefault(uint64_t http3_error_code);
+
+// Remaps WebTransport error code into an HTTP/3 error code.
+QUIC_EXPORT_PRIVATE uint64_t
+WebTransportErrorToHttp3(WebTransportStreamError webtransport_error_code);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
diff --git a/quiche/quic/core/http/web_transport_http3_test.cc b/quiche/quic/core/http/web_transport_http3_test.cc
new file mode 100644
index 0000000..87cd0d3
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_http3_test.cc
@@ -0,0 +1,52 @@
+// Copyright 2021 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 "quiche/quic/core/http/web_transport_http3.h"
+
+#include <cstdint>
+#include <limits>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+using ::testing::Optional;
+
+TEST(WebTransportHttp3Test, ErrorCodesToHttp3) {
+  EXPECT_EQ(0x52e4a40fa8dbu, WebTransportErrorToHttp3(0x00));
+  EXPECT_EQ(0x52e4a40fa9e2u, WebTransportErrorToHttp3(0xff));
+
+  EXPECT_EQ(0x52e4a40fa8f7u, WebTransportErrorToHttp3(0x1c));
+  EXPECT_EQ(0x52e4a40fa8f8u, WebTransportErrorToHttp3(0x1d));
+  //        0x52e4a40fa8f9 is a GREASE codepoint
+  EXPECT_EQ(0x52e4a40fa8fau, WebTransportErrorToHttp3(0x1e));
+}
+
+TEST(WebTransportHttp3Test, ErrorCodesToWebTransport) {
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8db), Optional(0x00));
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa9e2), Optional(0xff));
+
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f7), Optional(0x1cu));
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f8), Optional(0x1du));
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f9), absl::nullopt);
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8fa), Optional(0x1eu));
+
+  EXPECT_EQ(Http3ErrorToWebTransport(0), absl::nullopt);
+  EXPECT_EQ(Http3ErrorToWebTransport(std::numeric_limits<uint64_t>::max()),
+            absl::nullopt);
+}
+
+TEST(WebTransportHttp3Test, ErrorCodeRoundTrip) {
+  for (int error = 0; error < 256; error++) {
+    uint64_t http_error = WebTransportErrorToHttp3(error);
+    absl::optional<WebTransportStreamError> mapped_back =
+        quic::Http3ErrorToWebTransport(http_error);
+    EXPECT_THAT(mapped_back, Optional(error));
+  }
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/http/web_transport_stream_adapter.cc b/quiche/quic/core/http/web_transport_stream_adapter.cc
new file mode 100644
index 0000000..ff19214
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_stream_adapter.cc
@@ -0,0 +1,128 @@
+// Copyright 2021 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 "quiche/quic/core/http/web_transport_stream_adapter.h"
+
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+WebTransportStreamAdapter::WebTransportStreamAdapter(
+    QuicSession* session,
+    QuicStream* stream,
+    QuicStreamSequencer* sequencer)
+    : session_(session), stream_(stream), sequencer_(sequencer) {}
+
+WebTransportStream::ReadResult WebTransportStreamAdapter::Read(
+    char* buffer,
+    size_t buffer_size) {
+  iovec iov;
+  iov.iov_base = buffer;
+  iov.iov_len = buffer_size;
+  const size_t result = sequencer_->Readv(&iov, 1);
+  if (!fin_read_ && sequencer_->IsClosed()) {
+    fin_read_ = true;
+    stream_->OnFinRead();
+  }
+  return ReadResult{result, sequencer_->IsClosed()};
+}
+
+WebTransportStream::ReadResult WebTransportStreamAdapter::Read(
+    std::string* output) {
+  const size_t old_size = output->size();
+  const size_t bytes_to_read = ReadableBytes();
+  output->resize(old_size + bytes_to_read);
+  ReadResult result = Read(&(*output)[old_size], bytes_to_read);
+  QUICHE_DCHECK_EQ(bytes_to_read, result.bytes_read);
+  output->resize(old_size + result.bytes_read);
+  return result;
+}
+
+bool WebTransportStreamAdapter::Write(absl::string_view data) {
+  if (!CanWrite()) {
+    return false;
+  }
+
+  quiche::QuicheMemSlice memslice(quiche::QuicheBuffer::Copy(
+      session_->connection()->helper()->GetStreamSendBufferAllocator(), data));
+  QuicConsumedData consumed =
+      stream_->WriteMemSlices(absl::MakeSpan(&memslice, 1), /*fin=*/false);
+
+  if (consumed.bytes_consumed == data.size()) {
+    return true;
+  }
+  if (consumed.bytes_consumed == 0) {
+    return false;
+  }
+  // WebTransportStream::Write() is an all-or-nothing write API.  To achieve
+  // that property, it relies on WriteMemSlices() being an all-or-nothing API.
+  // If WriteMemSlices() fails to provide that guarantee, we have no way to
+  // communicate a partial write to the caller, and thus it's safer to just
+  // close the connection.
+  QUIC_BUG(WebTransportStreamAdapter partial write)
+      << "WriteMemSlices() unexpectedly partially consumed the input "
+         "data, provided: "
+      << data.size() << ", written: " << consumed.bytes_consumed;
+  stream_->OnUnrecoverableError(
+      QUIC_INTERNAL_ERROR,
+      "WriteMemSlices() unexpectedly partially consumed the input data");
+  return false;
+}
+
+bool WebTransportStreamAdapter::SendFin() {
+  if (!CanWrite()) {
+    return false;
+  }
+
+  quiche::QuicheMemSlice empty;
+  QuicConsumedData consumed =
+      stream_->WriteMemSlices(absl::MakeSpan(&empty, 1), /*fin=*/true);
+  QUICHE_DCHECK_EQ(consumed.bytes_consumed, 0u);
+  return consumed.fin_consumed;
+}
+
+bool WebTransportStreamAdapter::CanWrite() const {
+  return stream_->CanWriteNewData() && !stream_->write_side_closed();
+}
+
+size_t WebTransportStreamAdapter::ReadableBytes() const {
+  return sequencer_->ReadableBytes();
+}
+
+void WebTransportStreamAdapter::OnDataAvailable() {
+  if (visitor_ == nullptr) {
+    return;
+  }
+  const bool fin_readable = sequencer_->IsClosed() && !fin_read_;
+  if (ReadableBytes() == 0 && !fin_readable) {
+    return;
+  }
+  visitor_->OnCanRead();
+}
+
+void WebTransportStreamAdapter::OnCanWriteNewData() {
+  // Ensure the origin check has been completed, as the stream can be notified
+  // about being writable before that.
+  if (!CanWrite()) {
+    return;
+  }
+  if (visitor_ != nullptr) {
+    visitor_->OnCanWrite();
+  }
+}
+
+void WebTransportStreamAdapter::ResetWithUserCode(
+    WebTransportStreamError error) {
+  stream_->ResetWriteSide(QuicResetStreamError(
+      QUIC_STREAM_CANCELLED, WebTransportErrorToHttp3(error)));
+}
+
+void WebTransportStreamAdapter::SendStopSending(WebTransportStreamError error) {
+  stream_->SendStopSending(QuicResetStreamError(
+      QUIC_STREAM_CANCELLED, WebTransportErrorToHttp3(error)));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/web_transport_stream_adapter.h b/quiche/quic/core/http/web_transport_stream_adapter.h
new file mode 100644
index 0000000..5549cba
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_stream_adapter.h
@@ -0,0 +1,66 @@
+// Copyright 2021 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_WEB_TRANSPORT_STREAM_ADAPTER_H_
+#define QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
+
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/web_transport_interface.h"
+
+namespace quic {
+
+// Converts WebTransportStream API calls into QuicStream API calls.  The users
+// of this class can either subclass it, or wrap around it.
+class QUIC_EXPORT_PRIVATE WebTransportStreamAdapter
+    : public WebTransportStream {
+ public:
+  WebTransportStreamAdapter(QuicSession* session,
+                            QuicStream* stream,
+                            QuicStreamSequencer* sequencer);
+
+  // WebTransportStream implementation.
+  ABSL_MUST_USE_RESULT ReadResult Read(char* buffer,
+                                       size_t buffer_size) override;
+  ABSL_MUST_USE_RESULT ReadResult Read(std::string* output) override;
+  ABSL_MUST_USE_RESULT bool Write(absl::string_view data) override;
+  ABSL_MUST_USE_RESULT bool SendFin() override;
+  bool CanWrite() const override;
+  size_t ReadableBytes() const override;
+  void SetVisitor(std::unique_ptr<WebTransportStreamVisitor> visitor) override {
+    visitor_ = std::move(visitor);
+  }
+  QuicStreamId GetStreamId() const override { return stream_->id(); }
+
+  void ResetWithUserCode(WebTransportStreamError error) override;
+  void ResetDueToInternalError() override {
+    stream_->Reset(QUIC_STREAM_INTERNAL_ERROR);
+  }
+  void SendStopSending(WebTransportStreamError error) override;
+  void MaybeResetDueToStreamObjectGone() override {
+    if (stream_->write_side_closed() && stream_->read_side_closed()) {
+      return;
+    }
+    stream_->Reset(QUIC_STREAM_CANCELLED);
+  }
+
+  WebTransportStreamVisitor* visitor() override { return visitor_.get(); }
+
+  // Calls that need to be passed from the corresponding QuicStream methods.
+  void OnDataAvailable();
+  void OnCanWriteNewData();
+
+ private:
+  QuicSession* session_;            // Unowned.
+  QuicStream* stream_;              // Unowned.
+  QuicStreamSequencer* sequencer_;  // Unowned.
+  std::unique_ptr<WebTransportStreamVisitor> visitor_;
+  bool fin_read_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
diff --git a/quiche/quic/core/legacy_quic_stream_id_manager.cc b/quiche/quic/core/legacy_quic_stream_id_manager.cc
new file mode 100644
index 0000000..1afefaa
--- /dev/null
+++ b/quiche/quic/core/legacy_quic_stream_id_manager.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2018 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 "quiche/quic/core/legacy_quic_stream_id_manager.h"
+
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+
+namespace quic {
+
+LegacyQuicStreamIdManager::LegacyQuicStreamIdManager(
+    Perspective perspective,
+    QuicTransportVersion transport_version,
+    size_t max_open_outgoing_streams,
+    size_t max_open_incoming_streams)
+    : perspective_(perspective),
+      transport_version_(transport_version),
+      max_open_outgoing_streams_(max_open_outgoing_streams),
+      max_open_incoming_streams_(max_open_incoming_streams),
+      next_outgoing_stream_id_(
+          QuicUtils::GetFirstBidirectionalStreamId(transport_version_,
+                                                   perspective_)),
+      largest_peer_created_stream_id_(
+          perspective_ == Perspective::IS_SERVER
+              ? (QuicVersionUsesCryptoFrames(transport_version_)
+                     ? QuicUtils::GetInvalidStreamId(transport_version_)
+                     : QuicUtils::GetCryptoStreamId(transport_version_))
+              : QuicUtils::GetInvalidStreamId(transport_version_)),
+      num_open_incoming_streams_(0),
+      num_open_outgoing_streams_(0) {}
+
+LegacyQuicStreamIdManager::~LegacyQuicStreamIdManager() {}
+
+bool LegacyQuicStreamIdManager::CanOpenNextOutgoingStream() const {
+  QUICHE_DCHECK_LE(num_open_outgoing_streams_, max_open_outgoing_streams_);
+  QUIC_DLOG_IF(INFO, num_open_outgoing_streams_ == max_open_outgoing_streams_)
+      << "Failed to create a new outgoing stream. "
+      << "Already " << num_open_outgoing_streams_ << " open.";
+  return num_open_outgoing_streams_ < max_open_outgoing_streams_;
+}
+
+bool LegacyQuicStreamIdManager::CanOpenIncomingStream() const {
+  return num_open_incoming_streams_ < max_open_incoming_streams_;
+}
+
+bool LegacyQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
+    const QuicStreamId stream_id) {
+  available_streams_.erase(stream_id);
+
+  if (largest_peer_created_stream_id_ !=
+          QuicUtils::GetInvalidStreamId(transport_version_) &&
+      stream_id <= largest_peer_created_stream_id_) {
+    return true;
+  }
+
+  // Check if the new number of available streams would cause the number of
+  // available streams to exceed the limit.  Note that the peer can create
+  // only alternately-numbered streams.
+  size_t additional_available_streams =
+      (stream_id - largest_peer_created_stream_id_) / 2 - 1;
+  if (largest_peer_created_stream_id_ ==
+      QuicUtils::GetInvalidStreamId(transport_version_)) {
+    additional_available_streams = (stream_id + 1) / 2 - 1;
+  }
+  size_t new_num_available_streams =
+      GetNumAvailableStreams() + additional_available_streams;
+  if (new_num_available_streams > MaxAvailableStreams()) {
+    QUIC_DLOG(INFO) << perspective_
+                    << "Failed to create a new incoming stream with id:"
+                    << stream_id << ".  There are already "
+                    << GetNumAvailableStreams()
+                    << " streams available, which would become "
+                    << new_num_available_streams << ", which exceeds the limit "
+                    << MaxAvailableStreams() << ".";
+    return false;
+  }
+  QuicStreamId first_available_stream = largest_peer_created_stream_id_ + 2;
+  if (largest_peer_created_stream_id_ ==
+      QuicUtils::GetInvalidStreamId(transport_version_)) {
+    first_available_stream = QuicUtils::GetFirstBidirectionalStreamId(
+        transport_version_, QuicUtils::InvertPerspective(perspective_));
+  }
+  for (QuicStreamId id = first_available_stream; id < stream_id; id += 2) {
+    available_streams_.insert(id);
+  }
+  largest_peer_created_stream_id_ = stream_id;
+
+  return true;
+}
+
+QuicStreamId LegacyQuicStreamIdManager::GetNextOutgoingStreamId() {
+  QuicStreamId id = next_outgoing_stream_id_;
+  next_outgoing_stream_id_ += 2;
+  return id;
+}
+
+void LegacyQuicStreamIdManager::ActivateStream(bool is_incoming) {
+  if (is_incoming) {
+    ++num_open_incoming_streams_;
+    return;
+  }
+  ++num_open_outgoing_streams_;
+}
+
+void LegacyQuicStreamIdManager::OnStreamClosed(bool is_incoming) {
+  if (is_incoming) {
+    QUIC_BUG_IF(quic_bug_12720_1, num_open_incoming_streams_ == 0);
+    --num_open_incoming_streams_;
+    return;
+  }
+  QUIC_BUG_IF(quic_bug_12720_2, num_open_outgoing_streams_ == 0);
+  --num_open_outgoing_streams_;
+}
+
+bool LegacyQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
+  if (!IsIncomingStream(id)) {
+    // Stream IDs under next_ougoing_stream_id_ are either open or previously
+    // open but now closed.
+    return id >= next_outgoing_stream_id_;
+  }
+  // For peer created streams, we also need to consider available streams.
+  return largest_peer_created_stream_id_ ==
+             QuicUtils::GetInvalidStreamId(transport_version_) ||
+         id > largest_peer_created_stream_id_ ||
+         available_streams_.contains(id);
+}
+
+bool LegacyQuicStreamIdManager::IsIncomingStream(QuicStreamId id) const {
+  return id % 2 != next_outgoing_stream_id_ % 2;
+}
+
+size_t LegacyQuicStreamIdManager::GetNumAvailableStreams() const {
+  return available_streams_.size();
+}
+
+size_t LegacyQuicStreamIdManager::MaxAvailableStreams() const {
+  return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/legacy_quic_stream_id_manager.h b/quiche/quic/core/legacy_quic_stream_id_manager.h
new file mode 100644
index 0000000..3c67028
--- /dev/null
+++ b/quiche/quic/core/legacy_quic_stream_id_manager.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2018 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_LEGACY_QUIC_STREAM_ID_MANAGER_H_
+#define QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
+
+#include "absl/container/flat_hash_set.h"
+#include "quiche/quic/core/quic_stream_id_manager.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+
+namespace quic {
+
+namespace test {
+class QuicSessionPeer;
+}  // namespace test
+
+class QuicSession;
+
+// Manages Google QUIC stream IDs. This manager is responsible for two
+// questions: 1) can next outgoing stream ID be allocated (if yes, what is the
+// next outgoing stream ID) and 2) can a new incoming stream be opened.
+class QUIC_EXPORT_PRIVATE LegacyQuicStreamIdManager {
+ public:
+  LegacyQuicStreamIdManager(Perspective perspective,
+                            QuicTransportVersion transport_version,
+                            size_t max_open_outgoing_streams,
+                            size_t max_open_incoming_streams);
+
+  ~LegacyQuicStreamIdManager();
+
+  // Returns true if the next outgoing stream ID can be allocated.
+  bool CanOpenNextOutgoingStream() const;
+
+  // Returns true if a new incoming stream can be opened.
+  bool CanOpenIncomingStream() const;
+
+  // Returns false when increasing the largest created stream id to |id| would
+  // violate the limit, so the connection should be closed.
+  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId id);
+
+  // Returns true if |id| is still available.
+  bool IsAvailableStream(QuicStreamId id) const;
+
+  // Returns the stream ID for a new outgoing stream, and increments the
+  // underlying counter.
+  QuicStreamId GetNextOutgoingStreamId();
+
+  // Called when a new stream is open.
+  void ActivateStream(bool is_incoming);
+
+  // Called when a stream ID is closed.
+  void OnStreamClosed(bool is_incoming);
+
+  // Return true if |id| is peer initiated.
+  bool IsIncomingStream(QuicStreamId id) const;
+
+  size_t MaxAvailableStreams() const;
+
+  void set_max_open_incoming_streams(size_t max_open_incoming_streams) {
+    max_open_incoming_streams_ = max_open_incoming_streams;
+  }
+
+  void set_max_open_outgoing_streams(size_t max_open_outgoing_streams) {
+    max_open_outgoing_streams_ = max_open_outgoing_streams;
+  }
+
+  void set_largest_peer_created_stream_id(
+      QuicStreamId largest_peer_created_stream_id) {
+    largest_peer_created_stream_id_ = largest_peer_created_stream_id;
+  }
+
+  size_t max_open_incoming_streams() const {
+    return max_open_incoming_streams_;
+  }
+
+  size_t max_open_outgoing_streams() const {
+    return max_open_outgoing_streams_;
+  }
+
+  QuicStreamId next_outgoing_stream_id() const {
+    return next_outgoing_stream_id_;
+  }
+
+  QuicStreamId largest_peer_created_stream_id() const {
+    return largest_peer_created_stream_id_;
+  }
+
+  size_t GetNumAvailableStreams() const;
+
+  size_t num_open_incoming_streams() const {
+    return num_open_incoming_streams_;
+  }
+  size_t num_open_outgoing_streams() const {
+    return num_open_outgoing_streams_;
+  }
+
+ private:
+  friend class test::QuicSessionPeer;
+
+  const Perspective perspective_;
+  const QuicTransportVersion transport_version_;
+
+  // The maximum number of outgoing streams this connection can open.
+  size_t max_open_outgoing_streams_;
+
+  // The maximum number of incoming streams this connection will allow.
+  size_t max_open_incoming_streams_;
+
+  // The ID to use for the next outgoing stream.
+  QuicStreamId next_outgoing_stream_id_;
+
+  // Set of stream ids that are less than the largest stream id that has been
+  // received, but are nonetheless available to be created.
+  absl::flat_hash_set<QuicStreamId> available_streams_;
+
+  QuicStreamId largest_peer_created_stream_id_;
+
+  // A counter for peer initiated open streams.
+  size_t num_open_incoming_streams_;
+
+  // A counter for self initiated open streams.
+  size_t num_open_outgoing_streams_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
diff --git a/quiche/quic/core/legacy_quic_stream_id_manager_test.cc b/quiche/quic/core/legacy_quic_stream_id_manager_test.cc
new file mode 100644
index 0000000..5ab742c
--- /dev/null
+++ b/quiche/quic/core/legacy_quic_stream_id_manager_test.cc
@@ -0,0 +1,180 @@
+// Copyright (c) 2018 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 "quiche/quic/core/legacy_quic_stream_id_manager.h"
+
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using testing::_;
+using testing::StrictMock;
+
+struct TestParams {
+  TestParams(ParsedQuicVersion version, Perspective perspective)
+      : version(version), perspective(perspective) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version),
+      (p.perspective == Perspective::IS_CLIENT ? "Client" : "Server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (ParsedQuicVersion version : AllSupportedVersions()) {
+    for (auto perspective : {Perspective::IS_CLIENT, Perspective::IS_SERVER}) {
+      // LegacyQuicStreamIdManager is only used when IETF QUIC frames are not
+      // presented.
+      if (!VersionHasIetfQuicFrames(version.transport_version)) {
+        params.push_back(TestParams(version, perspective));
+      }
+    }
+  }
+  return params;
+}
+
+class LegacyQuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
+ public:
+  LegacyQuicStreamIdManagerTest()
+      : manager_(GetParam().perspective,
+                 GetParam().version.transport_version,
+                 kDefaultMaxStreamsPerConnection,
+                 kDefaultMaxStreamsPerConnection) {}
+
+ protected:
+  QuicStreamId GetNthPeerInitiatedId(int n) {
+    if (GetParam().perspective == Perspective::IS_SERVER) {
+      return QuicUtils::GetFirstBidirectionalStreamId(
+                 GetParam().version.transport_version, Perspective::IS_CLIENT) +
+             2 * n;
+    } else {
+      return 2 + 2 * n;
+    }
+  }
+
+  LegacyQuicStreamIdManager manager_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         LegacyQuicStreamIdManagerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(LegacyQuicStreamIdManagerTest, CanOpenNextOutgoingStream) {
+  for (size_t i = 0; i < manager_.max_open_outgoing_streams() - 1; ++i) {
+    manager_.ActivateStream(/*is_incoming=*/false);
+  }
+  EXPECT_TRUE(manager_.CanOpenNextOutgoingStream());
+  manager_.ActivateStream(/*is_incoming=*/false);
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingStream());
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, CanOpenIncomingStream) {
+  for (size_t i = 0; i < manager_.max_open_incoming_streams() - 1; ++i) {
+    manager_.ActivateStream(/*is_incoming=*/true);
+  }
+  EXPECT_TRUE(manager_.CanOpenIncomingStream());
+  manager_.ActivateStream(/*is_incoming=*/true);
+  EXPECT_FALSE(manager_.CanOpenIncomingStream());
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, AvailableStreams) {
+  ASSERT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(3)));
+  EXPECT_TRUE(manager_.IsAvailableStream(GetNthPeerInitiatedId(1)));
+  EXPECT_TRUE(manager_.IsAvailableStream(GetNthPeerInitiatedId(2)));
+  ASSERT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(2)));
+  ASSERT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(1)));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, MaxAvailableStreams) {
+  // Test that the server closes the connection if a client makes too many data
+  // streams available.  The server accepts slightly more than the negotiated
+  // stream limit to deal with rare cases where a client FIN/RST is lost.
+  const size_t kMaxStreamsForTest = 10;
+  const size_t kAvailableStreamLimit = manager_.MaxAvailableStreams();
+  EXPECT_EQ(
+      manager_.max_open_incoming_streams() * kMaxAvailableStreamsMultiplier,
+      manager_.MaxAvailableStreams());
+  // The protocol specification requires that there can be at least 10 times
+  // as many available streams as the connection's maximum open streams.
+  EXPECT_LE(10 * kMaxStreamsForTest, kAvailableStreamLimit);
+
+  EXPECT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(0)));
+
+  // Establish available streams up to the server's limit.
+  const int kLimitingStreamId =
+      GetNthPeerInitiatedId(kAvailableStreamLimit + 1);
+  // This exceeds the stream limit. In versions other than 99
+  // this is allowed. Version 99 hews to the IETF spec and does
+  // not allow it.
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(kLimitingStreamId));
+
+  // This forces stream kLimitingStreamId + 2 to become available, which
+  // violates the quota.
+  EXPECT_FALSE(
+      manager_.MaybeIncreaseLargestPeerStreamId(kLimitingStreamId + 2 * 2));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, MaximumAvailableOpenedStreams) {
+  QuicStreamId stream_id = GetNthPeerInitiatedId(0);
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
+
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      stream_id + 2 * (manager_.max_open_incoming_streams() - 1)));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, TooManyAvailableStreams) {
+  QuicStreamId stream_id = GetNthPeerInitiatedId(0);
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
+
+  // A stream ID which is too large to create.
+  QuicStreamId stream_id2 =
+      GetNthPeerInitiatedId(2 * manager_.MaxAvailableStreams() + 4);
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id2));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, ManyAvailableStreams) {
+  // When max_open_streams_ is 200, should be able to create 200 streams
+  // out-of-order, that is, creating the one with the largest stream ID first.
+  manager_.set_max_open_incoming_streams(200);
+  QuicStreamId stream_id = GetNthPeerInitiatedId(0);
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
+
+  // Create the largest stream ID of a threatened total of 200 streams.
+  // GetNth... starts at 0, so for 200 streams, get the 199th.
+  EXPECT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(199)));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest,
+       TestMaxIncomingAndOutgoingStreamsAllowed) {
+  EXPECT_EQ(manager_.max_open_incoming_streams(),
+            kDefaultMaxStreamsPerConnection);
+  EXPECT_EQ(manager_.max_open_outgoing_streams(),
+            kDefaultMaxStreamsPerConnection);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/packet_number_indexed_queue.h b/quiche/quic/core/packet_number_indexed_queue.h
new file mode 100644
index 0000000..ef48bd1
--- /dev/null
+++ b/quiche/quic/core/packet_number_indexed_queue.h
@@ -0,0 +1,252 @@
+// Copyright (c) 2017 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_PACKET_NUMBER_INDEXED_QUEUE_H_
+#define QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+// PacketNumberIndexedQueue is a queue of mostly continuous numbered entries
+// which supports the following operations:
+// - adding elements to the end of the queue, or at some point past the end
+// - removing elements in any order
+// - retrieving elements
+// If all elements are inserted in order, all of the operations above are
+// amortized O(1) time.
+//
+// Internally, the data structure is a deque where each element is marked as
+// present or not.  The deque starts at the lowest present index.  Whenever an
+// element is removed, it's marked as not present, and the front of the deque is
+// cleared of elements that are not present.
+//
+// The tail of the queue is not cleared due to the assumption of entries being
+// inserted in order, though removing all elements of the queue will return it
+// to its initial state.
+//
+// Note that this data structure is inherently hazardous, since an addition of
+// just two entries will cause it to consume all of the memory available.
+// Because of that, it is not a general-purpose container and should not be used
+// as one.
+// TODO(wub): Update the comments when deprecating
+// --quic_bw_sampler_remove_packets_once_per_congestion_event.
+template <typename T>
+class QUIC_NO_EXPORT PacketNumberIndexedQueue {
+ public:
+  PacketNumberIndexedQueue() : number_of_present_entries_(0) {}
+
+  // Retrieve the entry associated with the packet number.  Returns the pointer
+  // to the entry in case of success, or nullptr if the entry does not exist.
+  T* GetEntry(QuicPacketNumber packet_number);
+  const T* GetEntry(QuicPacketNumber packet_number) const;
+
+  // Inserts data associated |packet_number| into (or past) the end of the
+  // queue, filling up the missing intermediate entries as necessary.  Returns
+  // true if the element has been inserted successfully, false if it was already
+  // in the queue or inserted out of order.
+  template <typename... Args>
+  bool Emplace(QuicPacketNumber packet_number, Args&&... args);
+
+  // Removes data associated with |packet_number| and frees the slots in the
+  // queue as necessary.
+  bool Remove(QuicPacketNumber packet_number);
+
+  // Same as above, but if an entry is present in the queue, also call f(entry)
+  // before removing it.
+  template <typename Function>
+  bool Remove(QuicPacketNumber packet_number, Function f);
+
+  // Remove up to, but not including |packet_number|.
+  // Unused slots in the front are also removed, which means when the function
+  // returns, |first_packet()| can be larger than |packet_number|.
+  void RemoveUpTo(QuicPacketNumber packet_number);
+
+  bool IsEmpty() const { return number_of_present_entries_ == 0; }
+
+  // Returns the number of entries in the queue.
+  size_t number_of_present_entries() const {
+    return number_of_present_entries_;
+  }
+
+  // Returns the number of entries allocated in the underlying deque.  This is
+  // proportional to the memory usage of the queue.
+  size_t entry_slots_used() const { return entries_.size(); }
+
+  // Packet number of the first entry in the queue.
+  QuicPacketNumber first_packet() const { return first_packet_; }
+
+  // Packet number of the last entry ever inserted in the queue.  Note that the
+  // entry in question may have already been removed.  Zero if the queue is
+  // empty.
+  QuicPacketNumber last_packet() const {
+    if (IsEmpty()) {
+      return QuicPacketNumber();
+    }
+    return first_packet_ + entries_.size() - 1;
+  }
+
+ private:
+  // Wrapper around T used to mark whether the entry is actually in the map.
+  struct QUIC_NO_EXPORT EntryWrapper : T {
+    // NOTE(wub): When quic_bw_sampler_remove_packets_once_per_congestion_event
+    // is enabled, |present| is false if and only if this is a placeholder entry
+    // for holes in the parent's |entries|.
+    bool present;
+
+    EntryWrapper() : present(false) {}
+
+    template <typename... Args>
+    explicit EntryWrapper(Args&&... args)
+        : T(std::forward<Args>(args)...), present(true) {}
+  };
+
+  // Cleans up unused slots in the front after removing an element.
+  void Cleanup();
+
+  const EntryWrapper* GetEntryWrapper(QuicPacketNumber offset) const;
+  EntryWrapper* GetEntryWrapper(QuicPacketNumber offset) {
+    const auto* const_this = this;
+    return const_cast<EntryWrapper*>(const_this->GetEntryWrapper(offset));
+  }
+
+  quiche::QuicheCircularDeque<EntryWrapper> entries_;
+  // NOTE(wub): When --quic_bw_sampler_remove_packets_once_per_congestion_event
+  // is enabled, |number_of_present_entries_| only represents number of holes,
+  // which does not include number of acked or lost packets.
+  size_t number_of_present_entries_;
+  QuicPacketNumber first_packet_;
+};
+
+template <typename T>
+T* PacketNumberIndexedQueue<T>::GetEntry(QuicPacketNumber packet_number) {
+  EntryWrapper* entry = GetEntryWrapper(packet_number);
+  if (entry == nullptr) {
+    return nullptr;
+  }
+  return entry;
+}
+
+template <typename T>
+const T* PacketNumberIndexedQueue<T>::GetEntry(
+    QuicPacketNumber packet_number) const {
+  const EntryWrapper* entry = GetEntryWrapper(packet_number);
+  if (entry == nullptr) {
+    return nullptr;
+  }
+  return entry;
+}
+
+template <typename T>
+template <typename... Args>
+bool PacketNumberIndexedQueue<T>::Emplace(QuicPacketNumber packet_number,
+                                          Args&&... args) {
+  if (!packet_number.IsInitialized()) {
+    QUIC_BUG(quic_bug_10359_1)
+        << "Try to insert an uninitialized packet number";
+    return false;
+  }
+
+  if (IsEmpty()) {
+    QUICHE_DCHECK(entries_.empty());
+    QUICHE_DCHECK(!first_packet_.IsInitialized());
+
+    entries_.emplace_back(std::forward<Args>(args)...);
+    number_of_present_entries_ = 1;
+    first_packet_ = packet_number;
+    return true;
+  }
+
+  // Do not allow insertion out-of-order.
+  if (packet_number <= last_packet()) {
+    return false;
+  }
+
+  // Handle potentially missing elements.
+  size_t offset = packet_number - first_packet_;
+  if (offset > entries_.size()) {
+    entries_.resize(offset);
+  }
+
+  number_of_present_entries_++;
+  entries_.emplace_back(std::forward<Args>(args)...);
+  QUICHE_DCHECK_EQ(packet_number, last_packet());
+  return true;
+}
+
+template <typename T>
+bool PacketNumberIndexedQueue<T>::Remove(QuicPacketNumber packet_number) {
+  return Remove(packet_number, [](const T&) {});
+}
+
+template <typename T>
+template <typename Function>
+bool PacketNumberIndexedQueue<T>::Remove(QuicPacketNumber packet_number,
+                                         Function f) {
+  EntryWrapper* entry = GetEntryWrapper(packet_number);
+  if (entry == nullptr) {
+    return false;
+  }
+  f(*static_cast<const T*>(entry));
+  entry->present = false;
+  number_of_present_entries_--;
+
+  if (packet_number == first_packet()) {
+    Cleanup();
+  }
+  return true;
+}
+
+template <typename T>
+void PacketNumberIndexedQueue<T>::RemoveUpTo(QuicPacketNumber packet_number) {
+  while (!entries_.empty() && first_packet_.IsInitialized() &&
+         first_packet_ < packet_number) {
+    if (entries_.front().present) {
+      number_of_present_entries_--;
+    }
+    entries_.pop_front();
+    first_packet_++;
+  }
+  Cleanup();
+}
+
+template <typename T>
+void PacketNumberIndexedQueue<T>::Cleanup() {
+  while (!entries_.empty() && !entries_.front().present) {
+    entries_.pop_front();
+    first_packet_++;
+  }
+  if (entries_.empty()) {
+    first_packet_.Clear();
+  }
+}
+
+template <typename T>
+auto PacketNumberIndexedQueue<T>::GetEntryWrapper(
+    QuicPacketNumber packet_number) const -> const EntryWrapper* {
+  if (!packet_number.IsInitialized() || IsEmpty() ||
+      packet_number < first_packet_) {
+    return nullptr;
+  }
+
+  uint64_t offset = packet_number - first_packet_;
+  if (offset >= entries_.size()) {
+    return nullptr;
+  }
+
+  const EntryWrapper* entry = &entries_[offset];
+  if (!entry->present) {
+    return nullptr;
+  }
+
+  return entry;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
diff --git a/quiche/quic/core/packet_number_indexed_queue_test.cc b/quiche/quic/core/packet_number_indexed_queue_test.cc
new file mode 100644
index 0000000..b8a5b2a
--- /dev/null
+++ b/quiche/quic/core/packet_number_indexed_queue_test.cc
@@ -0,0 +1,205 @@
+// Copyright (c) 2017 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 "quiche/quic/core/packet_number_indexed_queue.h"
+
+#include <limits>
+#include <map>
+#include <string>
+
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+class PacketNumberIndexedQueueTest : public QuicTest {
+ public:
+  PacketNumberIndexedQueueTest() {}
+
+ protected:
+  PacketNumberIndexedQueue<std::string> queue_;
+};
+
+TEST_F(PacketNumberIndexedQueueTest, InitialState) {
+  EXPECT_TRUE(queue_.IsEmpty());
+  EXPECT_FALSE(queue_.first_packet().IsInitialized());
+  EXPECT_FALSE(queue_.last_packet().IsInitialized());
+  EXPECT_EQ(0u, queue_.number_of_present_entries());
+  EXPECT_EQ(0u, queue_.entry_slots_used());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, InsertingContinuousElements) {
+  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1001), "one"));
+  EXPECT_EQ("one", *queue_.GetEntry(QuicPacketNumber(1001)));
+
+  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1002), "two"));
+  EXPECT_EQ("two", *queue_.GetEntry(QuicPacketNumber(1002)));
+
+  EXPECT_FALSE(queue_.IsEmpty());
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1002u), queue_.last_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+  EXPECT_EQ(2u, queue_.entry_slots_used());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, InsertingOutOfOrder) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+
+  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1003), "three"));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
+  EXPECT_EQ("three", *queue_.GetEntry(QuicPacketNumber(1003)));
+
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+  EXPECT_EQ(3u, queue_.entry_slots_used());
+
+  ASSERT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, InsertingIntoPast) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1000), "zero"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, InsertingDuplicate) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1001), "one"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveInTheMiddle) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(1002), "two");
+  queue_.Emplace(QuicPacketNumber(1003), "three");
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
+
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+  EXPECT_EQ(3u, queue_.entry_slots_used());
+
+  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveAtImmediateEdges) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(1002), "two");
+  queue_.Emplace(QuicPacketNumber(1003), "three");
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1001)));
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1003)));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1003)));
+
+  EXPECT_EQ(QuicPacketNumber(1002u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
+  EXPECT_EQ(1u, queue_.number_of_present_entries());
+  EXPECT_EQ(2u, queue_.entry_slots_used());
+
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantFront) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(1002), "one (kinda)");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
+
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+  EXPECT_EQ(3u, queue_.number_of_present_entries());
+  EXPECT_EQ(1001u, queue_.entry_slots_used());
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+  EXPECT_EQ(1001u, queue_.entry_slots_used());
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+  EXPECT_EQ(1u, queue_.number_of_present_entries());
+  EXPECT_EQ(1u, queue_.entry_slots_used());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantBack) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
+
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, ClearAndRepopulate) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
+  EXPECT_TRUE(queue_.IsEmpty());
+  EXPECT_FALSE(queue_.first_packet().IsInitialized());
+  EXPECT_FALSE(queue_.last_packet().IsInitialized());
+
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(101), "one"));
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(201), "two"));
+  EXPECT_EQ(QuicPacketNumber(101u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(201u), queue_.last_packet());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsThatNeverExisted) {
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1002)));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsTwice) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveUpTo) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+
+  queue_.RemoveUpTo(QuicPacketNumber(1001));
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+
+  // Remove up to 1100, since [1100, 2001) are !present, they should be cleaned
+  // up from the front.
+  queue_.RemoveUpTo(QuicPacketNumber(1100));
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
+  EXPECT_EQ(1u, queue_.number_of_present_entries());
+
+  queue_.RemoveUpTo(QuicPacketNumber(2001));
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
+  EXPECT_EQ(1u, queue_.number_of_present_entries());
+
+  queue_.RemoveUpTo(QuicPacketNumber(2002));
+  EXPECT_FALSE(queue_.first_packet().IsInitialized());
+  EXPECT_EQ(0u, queue_.number_of_present_entries());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, ConstGetter) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  const auto& const_queue = queue_;
+
+  EXPECT_EQ("one", *const_queue.GetEntry(QuicPacketNumber(1001)));
+  EXPECT_EQ(nullptr, const_queue.GetEntry(QuicPacketNumber(1002)));
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/proto/cached_network_parameters.proto b/quiche/quic/core/proto/cached_network_parameters.proto
new file mode 100644
index 0000000..d609be9
--- /dev/null
+++ b/quiche/quic/core/proto/cached_network_parameters.proto
@@ -0,0 +1,43 @@
+// Copyright 2015 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package quic;
+
+// CachedNetworkParameters contains data that can be used to choose appropriate
+// connection parameters (initial RTT, initial CWND, etc.) in new connections.
+// Next id: 8
+message CachedNetworkParameters {
+  // Describes the state of the connection during which the supplied network
+  // parameters were calculated.
+  enum PreviousConnectionState {
+    SLOW_START = 0;
+    CONGESTION_AVOIDANCE = 1;
+  }
+
+  // serving_region is used to decide whether or not the bandwidth estimate and
+  // min RTT are reasonable and if they should be used.
+  // For example a group of geographically close servers may share the same
+  // serving_region string if they are expected to have similar network
+  // performance.
+  optional string serving_region = 1;
+  // The server can supply a bandwidth estimate (in bytes/s) which it may re-use
+  // on receipt of a source-address token with this field set.
+  optional int32 bandwidth_estimate_bytes_per_second = 2;
+  // The maximum bandwidth seen to the client, not necessarily the latest.
+  optional int32 max_bandwidth_estimate_bytes_per_second = 5;
+  // Timestamp (seconds since UNIX epoch) that indicates when the max bandwidth
+  // was seen by the server.
+  optional int64 max_bandwidth_timestamp_seconds = 6;
+  // The min RTT seen on a previous connection can be used by the server to
+  // inform initial connection parameters for new connections.
+  optional int32 min_rtt_ms = 3;
+  // Encodes the PreviousConnectionState enum.
+  optional int32 previous_connection_state = 4;
+  // UNIX timestamp when this bandwidth estimate was created.
+  optional int64 timestamp = 7;
+};
diff --git a/quiche/quic/core/proto/cached_network_parameters_proto.h b/quiche/quic/core/proto/cached_network_parameters_proto.h
new file mode 100644
index 0000000..90c9156
--- /dev/null
+++ b/quiche/quic/core/proto/cached_network_parameters_proto.h
@@ -0,0 +1,15 @@
+// Copyright 2019 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_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
+#define QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+
+#include "quiche/quic/core/proto/cached_network_parameters.pb.h"
+
+#pragma clang diagnostic pop
+
+#endif  // QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
diff --git a/quiche/quic/core/proto/crypto_server_config.proto b/quiche/quic/core/proto/crypto_server_config.proto
new file mode 100644
index 0000000..bb447dc
--- /dev/null
+++ b/quiche/quic/core/proto/crypto_server_config.proto
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package quic;
+
+// QuicServerConfigProtobuf contains QUIC server config block and the private
+// keys needed to prove ownership.
+message QuicServerConfigProtobuf {
+  // config is a serialised config in QUIC wire format.
+  required bytes config = 1;
+
+  // PrivateKey contains a QUIC tag of a key exchange algorithm and a
+  // serialised private key for that algorithm. The format of the serialised
+  // private key is specific to the algorithm in question.
+  message PrivateKey {
+    required uint32 tag = 1;
+    required bytes private_key = 2;
+  }
+  repeated PrivateKey key = 2;
+
+  // primary_time contains a UNIX epoch seconds value that indicates when this
+  // config should become primary.
+  optional int64 primary_time = 3;
+
+  // Relative priority of this config vs other configs with the same
+  // primary time.  For use as a secondary sort key when selecting the
+  // primary config.
+  optional uint64 priority = 4;
+};
diff --git a/quiche/quic/core/proto/crypto_server_config_proto.h b/quiche/quic/core/proto/crypto_server_config_proto.h
new file mode 100644
index 0000000..5d50ff8
--- /dev/null
+++ b/quiche/quic/core/proto/crypto_server_config_proto.h
@@ -0,0 +1,15 @@
+// Copyright 2019 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_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
+#define QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+
+#include "quiche/quic/core/proto/crypto_server_config.pb.h"
+
+#pragma clang diagnostic pop
+
+#endif  // QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
diff --git a/quiche/quic/core/proto/source_address_token.proto b/quiche/quic/core/proto/source_address_token.proto
new file mode 100644
index 0000000..d261d46
--- /dev/null
+++ b/quiche/quic/core/proto/source_address_token.proto
@@ -0,0 +1,32 @@
+// Copyright 2015 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+import "quiche/quic/core/proto/cached_network_parameters.proto";
+
+package quic;
+
+// A SourceAddressToken is serialised, encrypted and sent to clients so that
+// they can prove ownership of an IP address.
+message SourceAddressToken {
+  // ip contains either 4 (IPv4) or 16 (IPv6) bytes of IP address in network
+  // byte order.
+  required bytes ip = 1;
+  // timestamp contains a UNIX timestamp value of the time when the token was
+  // created.
+  required int64 timestamp = 2;
+  // The server can provide estimated network parameters to be used for
+  // initial parameter selection in future connections.
+  optional CachedNetworkParameters cached_network_parameters = 3;
+};
+
+// SourceAddressTokens are simply lists of SourceAddressToken messages.
+message SourceAddressTokens {
+  // This field has id 4 to avoid ambiguity between the serialized form of
+  // SourceAddressToken vs SourceAddressTokens.
+  repeated SourceAddressToken tokens = 4;
+};
diff --git a/quiche/quic/core/proto/source_address_token_proto.h b/quiche/quic/core/proto/source_address_token_proto.h
new file mode 100644
index 0000000..3144ca1
--- /dev/null
+++ b/quiche/quic/core/proto/source_address_token_proto.h
@@ -0,0 +1,15 @@
+// Copyright 2019 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_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
+#define QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+
+#include "quiche/quic/core/proto/source_address_token.pb.h"
+
+#pragma clang diagnostic pop
+
+#endif  // QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc
new file mode 100644
index 0000000..93ce0a9
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc
@@ -0,0 +1,191 @@
+// Copyright 2016 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 <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+namespace quic {
+namespace test {
+
+struct DecoderAndHandler {
+  std::unique_ptr<QpackProgressiveDecoder> decoder;
+  std::unique_ptr<QpackProgressiveDecoder::HeadersHandlerInterface> handler;
+};
+
+using DecoderAndHandlerMap = std::map<QuicStreamId, DecoderAndHandler>;
+
+// Class that sets externally owned |error_detected| to true
+// on encoder stream error.
+class ErrorDelegate : public QpackDecoder::EncoderStreamErrorDelegate {
+ public:
+  ErrorDelegate(bool* error_detected) : error_detected_(error_detected) {}
+  ~ErrorDelegate() override = default;
+
+  void OnEncoderStreamError(QuicErrorCode /*error_code*/,
+                            absl::string_view /*error_message*/) override {
+    *error_detected_ = true;
+  }
+
+ private:
+  bool* const error_detected_;
+};
+
+// Class that destroys DecoderAndHandler when decoding completes, and sets
+// externally owned |error_detected| to true on encoder stream error.
+class HeadersHandler : public QpackProgressiveDecoder::HeadersHandlerInterface {
+ public:
+  HeadersHandler(QuicStreamId stream_id,
+                 DecoderAndHandlerMap* processing_decoders,
+                 bool* error_detected)
+      : stream_id_(stream_id),
+        processing_decoders_(processing_decoders),
+        error_detected_(error_detected) {}
+  ~HeadersHandler() override = default;
+
+  void OnHeaderDecoded(absl::string_view /*name*/,
+                       absl::string_view /*value*/) override {}
+
+  // Remove DecoderAndHandler from |*processing_decoders|.
+  void OnDecodingCompleted() override {
+    // Will delete |this|.
+    size_t result = processing_decoders_->erase(stream_id_);
+    QUICHE_CHECK_EQ(1u, result);
+  }
+
+  void OnDecodingErrorDetected(QuicErrorCode /*error_code*/,
+                               absl::string_view /*error_message*/) override {
+    *error_detected_ = true;
+  }
+
+ private:
+  const QuicStreamId stream_id_;
+  DecoderAndHandlerMap* const processing_decoders_;
+  bool* const error_detected_;
+};
+
+// This fuzzer exercises QpackDecoder.  It should be able to cover all possible
+// code paths.  There is no point in encoding QpackDecoder's output to turn this
+// into a roundtrip test, because the same header list can be encoded in many
+// different ways, so the output could not be expected to match the original
+// input.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider provider(data, size);
+
+  // Maximum 256 byte dynamic table.  Such a small size helps test draining
+  // entries and eviction.
+  const uint64_t maximum_dynamic_table_capacity =
+      provider.ConsumeIntegral<uint8_t>();
+  // Maximum 256 blocked streams.
+  const uint64_t maximum_blocked_streams = provider.ConsumeIntegral<uint8_t>();
+
+  // |error_detected| will be set to true if an error is encountered either in a
+  // header block or on the encoder stream.
+  bool error_detected = false;
+
+  ErrorDelegate encoder_stream_error_delegate(&error_detected);
+  QpackDecoder decoder(maximum_dynamic_table_capacity, maximum_blocked_streams,
+                       &encoder_stream_error_delegate);
+
+  NoopQpackStreamSenderDelegate decoder_stream_sender_delegate;
+  decoder.set_qpack_stream_sender_delegate(&decoder_stream_sender_delegate);
+
+  // Decoders still reading the header block, with corresponding handlers.
+  DecoderAndHandlerMap reading_decoders;
+
+  // Decoders still processing the completely read header block,
+  // with corresponding handlers.
+  DecoderAndHandlerMap processing_decoders;
+
+  // Maximum 256 data fragments to limit runtime and memory usage.
+  auto fragment_count = provider.ConsumeIntegral<uint8_t>();
+  while (fragment_count > 0 && !error_detected &&
+         provider.remaining_bytes() > 0) {
+    --fragment_count;
+    switch (provider.ConsumeIntegralInRange<uint8_t>(0, 3)) {
+      // Feed encoder stream data to QpackDecoder.
+      case 0: {
+        size_t fragment_size = provider.ConsumeIntegral<uint8_t>();
+        std::string data = provider.ConsumeRandomLengthString(fragment_size);
+        decoder.encoder_stream_receiver()->Decode(data);
+
+        continue;
+      }
+
+      // Create new progressive decoder.
+      case 1: {
+        QuicStreamId stream_id = provider.ConsumeIntegral<uint8_t>();
+        if (reading_decoders.find(stream_id) != reading_decoders.end() ||
+            processing_decoders.find(stream_id) != processing_decoders.end()) {
+          continue;
+        }
+
+        DecoderAndHandler decoder_and_handler;
+        decoder_and_handler.handler = std::make_unique<HeadersHandler>(
+            stream_id, &processing_decoders, &error_detected);
+        decoder_and_handler.decoder = decoder.CreateProgressiveDecoder(
+            stream_id, decoder_and_handler.handler.get());
+        reading_decoders.insert({stream_id, std::move(decoder_and_handler)});
+
+        continue;
+      }
+
+      // Feed header block data to existing decoder.
+      case 2: {
+        if (reading_decoders.empty()) {
+          continue;
+        }
+
+        auto it = reading_decoders.begin();
+        auto distance = provider.ConsumeIntegralInRange<uint8_t>(
+            0, reading_decoders.size() - 1);
+        std::advance(it, distance);
+
+        size_t fragment_size = provider.ConsumeIntegral<uint8_t>();
+        std::string data = provider.ConsumeRandomLengthString(fragment_size);
+        it->second.decoder->Decode(data);
+
+        continue;
+      }
+
+      // End header block.
+      case 3: {
+        if (reading_decoders.empty()) {
+          continue;
+        }
+
+        auto it = reading_decoders.begin();
+        auto distance = provider.ConsumeIntegralInRange<uint8_t>(
+            0, reading_decoders.size() - 1);
+        std::advance(it, distance);
+
+        QpackProgressiveDecoder* decoder = it->second.decoder.get();
+
+        // Move DecoderAndHandler to |reading_decoders| first, because
+        // EndHeaderBlock() might synchronously call OnDecodingCompleted().
+        QuicStreamId stream_id = it->first;
+        processing_decoders.insert({stream_id, std::move(it->second)});
+        reading_decoders.erase(it);
+
+        decoder->EndHeaderBlock();
+
+        continue;
+      }
+    }
+  }
+
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_receiver_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_receiver_fuzzer.cc
new file mode 100644
index 0000000..7d8542e
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_receiver_fuzzer.cc
@@ -0,0 +1,62 @@
+// Copyright 2018 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 <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder_stream_receiver.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_stream.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// A QpackDecoderStreamReceiver::Delegate implementation that ignores all
+// decoded instructions but keeps track of whether an error has been detected.
+class NoOpDelegate : public QpackDecoderStreamReceiver::Delegate {
+ public:
+  NoOpDelegate() : error_detected_(false) {}
+  ~NoOpDelegate() override = default;
+
+  void OnInsertCountIncrement(uint64_t /*increment*/) override {}
+  void OnHeaderAcknowledgement(QuicStreamId /*stream_id*/) override {}
+  void OnStreamCancellation(QuicStreamId /*stream_id*/) override {}
+  void OnErrorDetected(QuicErrorCode /*error_code*/,
+                       absl::string_view /*error_message*/) override {
+    error_detected_ = true;
+  }
+
+  bool error_detected() const { return error_detected_; }
+
+ private:
+  bool error_detected_;
+};
+
+}  // namespace
+
+// This fuzzer exercises QpackDecoderStreamReceiver.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  NoOpDelegate delegate;
+  QpackDecoderStreamReceiver receiver(&delegate);
+
+  FuzzedDataProvider provider(data, size);
+
+  while (!delegate.error_detected() && provider.remaining_bytes() != 0) {
+    // Process up to 64 kB fragments at a time.  Too small upper bound might not
+    // provide enough coverage, too large might make fuzzing too inefficient.
+    size_t fragment_size = provider.ConsumeIntegralInRange<uint16_t>(
+        0, std::numeric_limits<uint16_t>::max());
+    receiver.Decode(provider.ConsumeRandomLengthString(fragment_size));
+  }
+
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_sender_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_sender_fuzzer.cc
new file mode 100644
index 0000000..57fe718
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_sender_fuzzer.cc
@@ -0,0 +1,54 @@
+// Copyright 2018 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 <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+
+#include "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+namespace quic {
+namespace test {
+
+// This fuzzer exercises QpackDecoderStreamSender.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  NoopQpackStreamSenderDelegate delegate;
+  QpackDecoderStreamSender sender;
+  sender.set_qpack_stream_sender_delegate(&delegate);
+
+  FuzzedDataProvider provider(data, size);
+
+  while (provider.remaining_bytes() != 0) {
+    switch (provider.ConsumeIntegral<uint8_t>() % 4) {
+      case 0: {
+        uint64_t increment = provider.ConsumeIntegral<uint64_t>();
+        sender.SendInsertCountIncrement(increment);
+        break;
+      }
+      case 1: {
+        QuicStreamId stream_id = provider.ConsumeIntegral<QuicStreamId>();
+        sender.SendHeaderAcknowledgement(stream_id);
+        break;
+      }
+      case 2: {
+        QuicStreamId stream_id = provider.ConsumeIntegral<QuicStreamId>();
+        sender.SendStreamCancellation(stream_id);
+        break;
+      }
+      case 3: {
+        sender.Flush();
+        break;
+      }
+    }
+  }
+
+  sender.Flush();
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_receiver_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_receiver_fuzzer.cc
new file mode 100644
index 0000000..8030bb9
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_receiver_fuzzer.cc
@@ -0,0 +1,68 @@
+// Copyright 2018 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 <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// A QpackEncoderStreamReceiver::Delegate implementation that ignores all
+// decoded instructions but keeps track of whether an error has been detected.
+class NoOpDelegate : public QpackEncoderStreamReceiver::Delegate {
+ public:
+  NoOpDelegate() : error_detected_(false) {}
+  ~NoOpDelegate() override = default;
+
+  void OnInsertWithNameReference(bool /*is_static*/,
+                                 uint64_t /*name_index*/,
+                                 absl::string_view /*value*/) override {}
+  void OnInsertWithoutNameReference(absl::string_view /*name*/,
+                                    absl::string_view /*value*/) override {}
+  void OnDuplicate(uint64_t /*index*/) override {}
+  void OnSetDynamicTableCapacity(uint64_t /*capacity*/) override {}
+  void OnErrorDetected(QuicErrorCode /*error_code*/,
+                       absl::string_view /*error_message*/) override {
+    error_detected_ = true;
+  }
+
+  bool error_detected() const { return error_detected_; }
+
+ private:
+  bool error_detected_;
+};
+
+}  // namespace
+
+// This fuzzer exercises QpackEncoderStreamReceiver.
+// Note that since string literals may be encoded with or without Huffman
+// encoding, one could not expect identical encoded data if the decoded
+// instructions were fed into QpackEncoderStreamSender.  Therefore there is no
+// point in extending this fuzzer into a round-trip test.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  NoOpDelegate delegate;
+  QpackEncoderStreamReceiver receiver(&delegate);
+
+  FuzzedDataProvider provider(data, size);
+
+  while (!delegate.error_detected() && provider.remaining_bytes() != 0) {
+    // Process up to 64 kB fragments at a time.  Too small upper bound might not
+    // provide enough coverage, too large might make fuzzing too inefficient.
+    size_t fragment_size = provider.ConsumeIntegralInRange<uint16_t>(
+        0, std::numeric_limits<uint16_t>::max());
+    receiver.Decode(provider.ConsumeRandomLengthString(fragment_size));
+  }
+
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc
new file mode 100644
index 0000000..bc68536
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc
@@ -0,0 +1,73 @@
+// Copyright 2018 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 <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <string>
+
+#include "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+namespace quic {
+namespace test {
+
+// This fuzzer exercises QpackEncoderStreamSender.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  NoopQpackStreamSenderDelegate delegate;
+  QpackEncoderStreamSender sender;
+  sender.set_qpack_stream_sender_delegate(&delegate);
+
+  FuzzedDataProvider provider(data, size);
+  // Limit string literal length to 2 kB for efficiency.
+  const uint16_t kMaxStringLength = 2048;
+
+  while (provider.remaining_bytes() != 0) {
+    switch (provider.ConsumeIntegral<uint8_t>() % 5) {
+      case 0: {
+        bool is_static = provider.ConsumeBool();
+        uint64_t name_index = provider.ConsumeIntegral<uint64_t>();
+        uint16_t value_length =
+            provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
+        std::string value = provider.ConsumeRandomLengthString(value_length);
+
+        sender.SendInsertWithNameReference(is_static, name_index, value);
+        break;
+      }
+      case 1: {
+        uint16_t name_length =
+            provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
+        std::string name = provider.ConsumeRandomLengthString(name_length);
+        uint16_t value_length =
+            provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
+        std::string value = provider.ConsumeRandomLengthString(value_length);
+        sender.SendInsertWithoutNameReference(name, value);
+        break;
+      }
+      case 2: {
+        uint64_t index = provider.ConsumeIntegral<uint64_t>();
+        sender.SendDuplicate(index);
+        break;
+      }
+      case 3: {
+        uint64_t capacity = provider.ConsumeIntegral<uint64_t>();
+        sender.SendSetDynamicTableCapacity(capacity);
+        break;
+      }
+      case 4: {
+        sender.Flush();
+        break;
+      }
+    }
+  }
+
+  sender.Flush();
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
new file mode 100644
index 0000000..2d7cd88
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
@@ -0,0 +1,665 @@
+// Copyright 2016 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 <fuzzer/FuzzedDataProvider.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "quiche/quic/core/qpack/value_splitting_header_list.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Find the first occurrence of invalid characters NUL, LF, CR in |*value| and
+// remove that and the remaining of the string.
+void TruncateValueOnInvalidChars(std::string* value) {
+  for (auto it = value->begin(); it != value->end(); ++it) {
+    if (*it == '\0' || *it == '\n' || *it == '\r') {
+      value->erase(it, value->end());
+      return;
+    }
+  }
+}
+
+}  // anonymous namespace
+
+// Class to hold QpackEncoder and its DecoderStreamErrorDelegate.
+class EncodingEndpoint {
+ public:
+  EncodingEndpoint(uint64_t maximum_dynamic_table_capacity,
+                   uint64_t maximum_blocked_streams)
+      : encoder_(&decoder_stream_error_delegate) {
+    encoder_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
+    encoder_.SetMaximumBlockedStreams(maximum_blocked_streams);
+  }
+
+  ~EncodingEndpoint() {
+    // Every reference should be acknowledged.
+    QUICHE_CHECK_EQ(std::numeric_limits<uint64_t>::max(),
+                    QpackEncoderPeer::smallest_blocking_index(&encoder_));
+  }
+
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    encoder_.set_qpack_stream_sender_delegate(delegate);
+  }
+
+  void SetDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity) {
+    encoder_.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
+  }
+
+  QpackStreamReceiver* decoder_stream_receiver() {
+    return encoder_.decoder_stream_receiver();
+  }
+
+  std::string EncodeHeaderList(QuicStreamId stream_id,
+                               const spdy::Http2HeaderBlock& header_list) {
+    return encoder_.EncodeHeaderList(stream_id, header_list, nullptr);
+  }
+
+ private:
+  // DecoderStreamErrorDelegate implementation that crashes on error.
+  class CrashingDecoderStreamErrorDelegate
+      : public QpackEncoder::DecoderStreamErrorDelegate {
+   public:
+    ~CrashingDecoderStreamErrorDelegate() override = default;
+
+    void OnDecoderStreamError(QuicErrorCode error_code,
+                              absl::string_view error_message) override {
+      QUICHE_CHECK(false) << QuicErrorCodeToString(error_code) << " "
+                          << error_message;
+    }
+  };
+
+  CrashingDecoderStreamErrorDelegate decoder_stream_error_delegate;
+  QpackEncoder encoder_;
+};
+
+// Class that receives all header blocks from the encoding endpoint and passes
+// them to the decoding endpoint, with delay determined by fuzzer data,
+// preserving order within each stream but not among streams.
+class DelayedHeaderBlockTransmitter {
+ public:
+  class Visitor {
+   public:
+    virtual ~Visitor() = default;
+
+    // If decoding of the previous header block is still in progress, then
+    // DelayedHeaderBlockTransmitter will not start transmitting the next header
+    // block.
+    virtual bool IsDecodingInProgressOnStream(QuicStreamId stream_id) = 0;
+
+    // Called when a header block starts.
+    virtual void OnHeaderBlockStart(QuicStreamId stream_id) = 0;
+    // Called when part or all of a header block is transmitted.
+    virtual void OnHeaderBlockFragment(QuicStreamId stream_id,
+                                       absl::string_view data) = 0;
+    // Called when transmission of a header block is complete.
+    virtual void OnHeaderBlockEnd(QuicStreamId stream_id) = 0;
+  };
+
+  DelayedHeaderBlockTransmitter(Visitor* visitor, FuzzedDataProvider* provider)
+      : visitor_(visitor), provider_(provider) {}
+
+  ~DelayedHeaderBlockTransmitter() { QUICHE_CHECK(header_blocks_.empty()); }
+
+  // Enqueues |encoded_header_block| for delayed transmission.
+  void SendEncodedHeaderBlock(QuicStreamId stream_id,
+                              std::string encoded_header_block) {
+    auto it = header_blocks_.lower_bound(stream_id);
+    if (it == header_blocks_.end() || it->first != stream_id) {
+      it = header_blocks_.insert(it, {stream_id, {}});
+    }
+    QUICHE_CHECK_EQ(stream_id, it->first);
+    it->second.push(HeaderBlock(std::move(encoded_header_block)));
+  }
+
+  // Release some (possibly none) header block data.
+  void MaybeTransmitSomeData() {
+    if (header_blocks_.empty()) {
+      return;
+    }
+
+    auto index =
+        provider_->ConsumeIntegralInRange<size_t>(0, header_blocks_.size() - 1);
+    auto it = header_blocks_.begin();
+    std::advance(it, index);
+    const QuicStreamId stream_id = it->first;
+
+    // Do not start new header block if processing of previous header block is
+    // blocked.
+    if (visitor_->IsDecodingInProgressOnStream(stream_id)) {
+      return;
+    }
+
+    auto& header_block_queue = it->second;
+    HeaderBlock& header_block = header_block_queue.front();
+
+    if (header_block.ConsumedLength() == 0) {
+      visitor_->OnHeaderBlockStart(stream_id);
+    }
+
+    QUICHE_DCHECK_NE(0u, header_block.RemainingLength());
+
+    size_t length = provider_->ConsumeIntegralInRange<size_t>(
+        1, header_block.RemainingLength());
+    visitor_->OnHeaderBlockFragment(stream_id, header_block.Consume(length));
+
+    QUICHE_DCHECK_NE(0u, header_block.ConsumedLength());
+
+    if (header_block.RemainingLength() == 0) {
+      visitor_->OnHeaderBlockEnd(stream_id);
+
+      header_block_queue.pop();
+      if (header_block_queue.empty()) {
+        header_blocks_.erase(it);
+      }
+    }
+  }
+
+  // Release all header block data.  Must be called before destruction.  All
+  // encoder stream data must have been released before calling Flush() so that
+  // all header blocks can be decoded synchronously.
+  void Flush() {
+    while (!header_blocks_.empty()) {
+      auto it = header_blocks_.begin();
+      const QuicStreamId stream_id = it->first;
+
+      auto& header_block_queue = it->second;
+      HeaderBlock& header_block = header_block_queue.front();
+
+      if (header_block.ConsumedLength() == 0) {
+        QUICHE_CHECK(!visitor_->IsDecodingInProgressOnStream(stream_id));
+        visitor_->OnHeaderBlockStart(stream_id);
+      }
+
+      QUICHE_DCHECK_NE(0u, header_block.RemainingLength());
+
+      visitor_->OnHeaderBlockFragment(stream_id,
+                                      header_block.ConsumeRemaining());
+
+      QUICHE_DCHECK_NE(0u, header_block.ConsumedLength());
+      QUICHE_DCHECK_EQ(0u, header_block.RemainingLength());
+
+      visitor_->OnHeaderBlockEnd(stream_id);
+      QUICHE_CHECK(!visitor_->IsDecodingInProgressOnStream(stream_id));
+
+      header_block_queue.pop();
+      if (header_block_queue.empty()) {
+        header_blocks_.erase(it);
+      }
+    }
+  }
+
+ private:
+  // Helper class that allows the header block to be consumed in parts.
+  class HeaderBlock {
+   public:
+    explicit HeaderBlock(std::string data)
+        : data_(std::move(data)), offset_(0) {
+      // Valid QPACK header block cannot be empty.
+      QUICHE_DCHECK(!data_.empty());
+    }
+
+    size_t ConsumedLength() const { return offset_; }
+
+    size_t RemainingLength() const { return data_.length() - offset_; }
+
+    absl::string_view Consume(size_t length) {
+      QUICHE_DCHECK_NE(0u, length);
+      QUICHE_DCHECK_LE(length, RemainingLength());
+
+      absl::string_view consumed = absl::string_view(&data_[offset_], length);
+      offset_ += length;
+      return consumed;
+    }
+
+    absl::string_view ConsumeRemaining() { return Consume(RemainingLength()); }
+
+   private:
+    // Complete header block.
+    const std::string data_;
+
+    // Offset of the part not consumed yet.  Same as number of consumed bytes.
+    size_t offset_;
+  };
+
+  Visitor* const visitor_;
+  FuzzedDataProvider* const provider_;
+
+  std::map<QuicStreamId, std::queue<HeaderBlock>> header_blocks_;
+};
+
+// Class to decode and verify a header block, and in case of blocked decoding,
+// keep necessary decoding context while waiting for decoding to complete.
+class VerifyingDecoder : public QpackDecodedHeadersAccumulator::Visitor {
+ public:
+  class Visitor {
+   public:
+    virtual ~Visitor() = default;
+
+    // Called when header block is decoded, either synchronously or
+    // asynchronously.  Might destroy VerifyingDecoder.
+    virtual void OnHeaderBlockDecoded(QuicStreamId stream_id) = 0;
+  };
+
+  VerifyingDecoder(QuicStreamId stream_id,
+                   Visitor* visitor,
+                   QpackDecoder* qpack_decoder,
+                   QuicHeaderList expected_header_list)
+      : stream_id_(stream_id),
+        visitor_(visitor),
+        accumulator_(
+            stream_id,
+            qpack_decoder,
+            this,
+            /* max_header_list_size = */ std::numeric_limits<size_t>::max()),
+        expected_header_list_(std::move(expected_header_list)) {}
+
+  VerifyingDecoder(const VerifyingDecoder&) = delete;
+  VerifyingDecoder& operator=(const VerifyingDecoder&) = delete;
+  // VerifyingDecoder must not be moved because it passes |this| to
+  // |accumulator_| upon construction.
+  VerifyingDecoder(VerifyingDecoder&&) = delete;
+  VerifyingDecoder& operator=(VerifyingDecoder&&) = delete;
+
+  virtual ~VerifyingDecoder() = default;
+
+  // QpackDecodedHeadersAccumulator::Visitor implementation.
+  void OnHeadersDecoded(QuicHeaderList headers,
+                        bool header_list_size_limit_exceeded) override {
+    // Verify headers.
+    QUICHE_CHECK(!header_list_size_limit_exceeded);
+    QUICHE_CHECK(expected_header_list_ == headers);
+
+    // Might destroy |this|.
+    visitor_->OnHeaderBlockDecoded(stream_id_);
+  }
+
+  void OnHeaderDecodingError(QuicErrorCode error_code,
+                             absl::string_view error_message) override {
+    QUICHE_CHECK(false) << QuicErrorCodeToString(error_code) << " "
+                        << error_message;
+  }
+
+  void Decode(absl::string_view data) { accumulator_.Decode(data); }
+
+  void EndHeaderBlock() { accumulator_.EndHeaderBlock(); }
+
+ private:
+  QuicStreamId stream_id_;
+  Visitor* const visitor_;
+  QpackDecodedHeadersAccumulator accumulator_;
+  QuicHeaderList expected_header_list_;
+};
+
+// Class that holds QpackDecoder and its EncoderStreamErrorDelegate, and creates
+// and keeps VerifyingDecoders for each received header block until decoding is
+// complete.
+class DecodingEndpoint : public DelayedHeaderBlockTransmitter::Visitor,
+                         public VerifyingDecoder::Visitor {
+ public:
+  DecodingEndpoint(uint64_t maximum_dynamic_table_capacity,
+                   uint64_t maximum_blocked_streams)
+      : decoder_(maximum_dynamic_table_capacity,
+                 maximum_blocked_streams,
+                 &encoder_stream_error_delegate_) {}
+
+  ~DecodingEndpoint() override {
+    // All decoding must have been completed.
+    QUICHE_CHECK(expected_header_lists_.empty());
+    QUICHE_CHECK(verifying_decoders_.empty());
+  }
+
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    decoder_.set_qpack_stream_sender_delegate(delegate);
+  }
+
+  QpackStreamReceiver* encoder_stream_receiver() {
+    return decoder_.encoder_stream_receiver();
+  }
+
+  void AddExpectedHeaderList(QuicStreamId stream_id,
+                             QuicHeaderList expected_header_list) {
+    auto it = expected_header_lists_.lower_bound(stream_id);
+    if (it == expected_header_lists_.end() || it->first != stream_id) {
+      it = expected_header_lists_.insert(it, {stream_id, {}});
+    }
+    QUICHE_CHECK_EQ(stream_id, it->first);
+    it->second.push(std::move(expected_header_list));
+  }
+
+  // VerifyingDecoder::Visitor implementation.
+  void OnHeaderBlockDecoded(QuicStreamId stream_id) override {
+    auto result = verifying_decoders_.erase(stream_id);
+    QUICHE_CHECK_EQ(1u, result);
+  }
+
+  // DelayedHeaderBlockTransmitter::Visitor implementation.
+  bool IsDecodingInProgressOnStream(QuicStreamId stream_id) override {
+    return verifying_decoders_.find(stream_id) != verifying_decoders_.end();
+  }
+
+  void OnHeaderBlockStart(QuicStreamId stream_id) override {
+    QUICHE_CHECK(!IsDecodingInProgressOnStream(stream_id));
+    auto it = expected_header_lists_.find(stream_id);
+    QUICHE_CHECK(it != expected_header_lists_.end());
+
+    auto& header_list_queue = it->second;
+    QuicHeaderList expected_header_list = std::move(header_list_queue.front());
+
+    header_list_queue.pop();
+    if (header_list_queue.empty()) {
+      expected_header_lists_.erase(it);
+    }
+
+    auto verifying_decoder = std::make_unique<VerifyingDecoder>(
+        stream_id, this, &decoder_, std::move(expected_header_list));
+    auto result =
+        verifying_decoders_.insert({stream_id, std::move(verifying_decoder)});
+    QUICHE_CHECK(result.second);
+  }
+
+  void OnHeaderBlockFragment(QuicStreamId stream_id,
+                             absl::string_view data) override {
+    auto it = verifying_decoders_.find(stream_id);
+    QUICHE_CHECK(it != verifying_decoders_.end());
+    it->second->Decode(data);
+  }
+
+  void OnHeaderBlockEnd(QuicStreamId stream_id) override {
+    auto it = verifying_decoders_.find(stream_id);
+    QUICHE_CHECK(it != verifying_decoders_.end());
+    it->second->EndHeaderBlock();
+  }
+
+ private:
+  // EncoderStreamErrorDelegate implementation that crashes on error.
+  class CrashingEncoderStreamErrorDelegate
+      : public QpackDecoder::EncoderStreamErrorDelegate {
+   public:
+    ~CrashingEncoderStreamErrorDelegate() override = default;
+
+    void OnEncoderStreamError(QuicErrorCode error_code,
+                              absl::string_view error_message) override {
+      QUICHE_CHECK(false) << QuicErrorCodeToString(error_code) << " "
+                          << error_message;
+    }
+  };
+
+  CrashingEncoderStreamErrorDelegate encoder_stream_error_delegate_;
+  QpackDecoder decoder_;
+
+  // Expected header lists in order for each stream.
+  std::map<QuicStreamId, std::queue<QuicHeaderList>> expected_header_lists_;
+
+  // A VerifyingDecoder object keeps context necessary for asynchronously
+  // decoding blocked header blocks.  It is destroyed as soon as it signals that
+  // decoding is completed, which might happen synchronously within an
+  // EndHeaderBlock() call.
+  std::map<QuicStreamId, std::unique_ptr<VerifyingDecoder>> verifying_decoders_;
+};
+
+// Class that receives encoder stream data from the encoder and passes it to the
+// decoder, or receives decoder stream data from the decoder and passes it to
+// the encoder, with delay determined by fuzzer data.
+class DelayedStreamDataTransmitter : public QpackStreamSenderDelegate {
+ public:
+  DelayedStreamDataTransmitter(QpackStreamReceiver* receiver,
+                               FuzzedDataProvider* provider)
+      : receiver_(receiver), provider_(provider) {}
+
+  ~DelayedStreamDataTransmitter() { QUICHE_CHECK(stream_data.empty()); }
+
+  // QpackStreamSenderDelegate implementation.
+  void WriteStreamData(absl::string_view data) override {
+    stream_data.push_back(std::string(data.data(), data.size()));
+  }
+  uint64_t NumBytesBuffered() const override { return 0; }
+
+  // Release some (possibly none) delayed stream data.
+  void MaybeTransmitSomeData() {
+    auto count = provider_->ConsumeIntegral<uint8_t>();
+    while (!stream_data.empty() && count > 0) {
+      receiver_->Decode(stream_data.front());
+      stream_data.pop_front();
+      --count;
+    }
+  }
+
+  // Release all delayed stream data.  Must be called before destruction.
+  void Flush() {
+    while (!stream_data.empty()) {
+      receiver_->Decode(stream_data.front());
+      stream_data.pop_front();
+    }
+  }
+
+ private:
+  QpackStreamReceiver* const receiver_;
+  FuzzedDataProvider* const provider_;
+  quiche::QuicheCircularDeque<std::string> stream_data;
+};
+
+// Generate header list using fuzzer data.
+spdy::Http2HeaderBlock GenerateHeaderList(FuzzedDataProvider* provider) {
+  spdy::Http2HeaderBlock header_list;
+  uint8_t header_count = provider->ConsumeIntegral<uint8_t>();
+  for (uint8_t header_index = 0; header_index < header_count; ++header_index) {
+    if (provider->remaining_bytes() == 0) {
+      // Do not add more headers if there is no more fuzzer data.
+      break;
+    }
+
+    std::string name;
+    std::string value;
+    switch (provider->ConsumeIntegral<uint8_t>()) {
+      case 0:
+        // Static table entry with no header value.
+        name = ":authority";
+        break;
+      case 1:
+        // Static table entry with no header value, using non-empty header
+        // value.
+        name = ":authority";
+        value = "www.example.org";
+        break;
+      case 2:
+        // Static table entry with header value, using that header value.
+        name = ":accept-encoding";
+        value = "gzip, deflate";
+        break;
+      case 3:
+        // Static table entry with header value, using empty header value.
+        name = ":accept-encoding";
+        break;
+      case 4:
+        // Static table entry with header value, using different, non-empty
+        // header value.
+        name = ":accept-encoding";
+        value = "brotli";
+        break;
+      case 5:
+        // Header name that has multiple entries in the static table,
+        // using header value from one of them.
+        name = ":method";
+        value = "GET";
+        break;
+      case 6:
+        // Header name that has multiple entries in the static table,
+        // using empty header value.
+        name = ":method";
+        break;
+      case 7:
+        // Header name that has multiple entries in the static table,
+        // using different, non-empty header value.
+        name = ":method";
+        value = "CONNECT";
+        break;
+      case 8:
+        // Header name not in the static table, empty header value.
+        name = "foo";
+        value = "";
+        break;
+      case 9:
+        // Header name not in the static table, non-empty fixed header value.
+        name = "foo";
+        value = "bar";
+        break;
+      case 10:
+        // Header name not in the static table, fuzzed header value.
+        name = "foo";
+        value = provider->ConsumeRandomLengthString(128);
+        TruncateValueOnInvalidChars(&value);
+        break;
+      case 11:
+        // Another header name not in the static table, empty header value.
+        name = "bar";
+        value = "";
+        break;
+      case 12:
+        // Another header name not in the static table, non-empty fixed header
+        // value.
+        name = "bar";
+        value = "baz";
+        break;
+      case 13:
+        // Another header name not in the static table, fuzzed header value.
+        name = "bar";
+        value = provider->ConsumeRandomLengthString(128);
+        TruncateValueOnInvalidChars(&value);
+        break;
+      default:
+        // Fuzzed header name and header value.
+        name = provider->ConsumeRandomLengthString(128);
+        value = provider->ConsumeRandomLengthString(128);
+        TruncateValueOnInvalidChars(&value);
+    }
+
+    header_list.AppendValueOrAddHeader(name, value);
+  }
+
+  return header_list;
+}
+
+// Splits |*header_list| header values along '\0' or ';' separators.
+QuicHeaderList SplitHeaderList(const spdy::Http2HeaderBlock& header_list) {
+  QuicHeaderList split_header_list;
+  split_header_list.OnHeaderBlockStart();
+
+  size_t total_size = 0;
+  ValueSplittingHeaderList splitting_header_list(&header_list);
+  for (const auto& header : splitting_header_list) {
+    split_header_list.OnHeader(header.first, header.second);
+    total_size += header.first.size() + header.second.size();
+  }
+
+  split_header_list.OnHeaderBlockEnd(total_size, total_size);
+
+  return split_header_list;
+}
+
+// This fuzzer exercises QpackEncoder and QpackDecoder.  It should be able to
+// cover all possible code paths of QpackEncoder.  However, since the resulting
+// header block is always valid and is encoded in a particular way, this fuzzer
+// is not expected to cover all code paths of QpackDecoder.  On the other hand,
+// encoding then decoding is expected to result in the original header list, and
+// this fuzzer checks for that.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider provider(data, size);
+
+  // Maximum 256 byte dynamic table.  Such a small size helps test draining
+  // entries and eviction.
+  const uint64_t maximum_dynamic_table_capacity =
+      provider.ConsumeIntegral<uint8_t>();
+  // Maximum 256 blocked streams.
+  const uint64_t maximum_blocked_streams = provider.ConsumeIntegral<uint8_t>();
+
+  // Set up encoder.
+  EncodingEndpoint encoder(maximum_dynamic_table_capacity,
+                           maximum_blocked_streams);
+
+  // Set up decoder.
+  DecodingEndpoint decoder(maximum_dynamic_table_capacity,
+                           maximum_blocked_streams);
+
+  // Transmit encoder stream data from encoder to decoder.
+  DelayedStreamDataTransmitter encoder_stream_transmitter(
+      decoder.encoder_stream_receiver(), &provider);
+  encoder.set_qpack_stream_sender_delegate(&encoder_stream_transmitter);
+
+  // Use a dynamic table as large as the peer allows.  This sends data on the
+  // encoder stream, so it can only be done after delegate is set.
+  encoder.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
+
+  // Transmit decoder stream data from encoder to decoder.
+  DelayedStreamDataTransmitter decoder_stream_transmitter(
+      encoder.decoder_stream_receiver(), &provider);
+  decoder.set_qpack_stream_sender_delegate(&decoder_stream_transmitter);
+
+  // Transmit header blocks from encoder to decoder.
+  DelayedHeaderBlockTransmitter header_block_transmitter(&decoder, &provider);
+
+  // Maximum 256 header lists to limit runtime and memory usage.
+  auto header_list_count = provider.ConsumeIntegral<uint8_t>();
+  while (header_list_count > 0 && provider.remaining_bytes() > 0) {
+    const QuicStreamId stream_id = provider.ConsumeIntegral<uint8_t>();
+
+    // Generate header list.
+    spdy::Http2HeaderBlock header_list = GenerateHeaderList(&provider);
+
+    // Encode header list.
+    std::string encoded_header_block =
+        encoder.EncodeHeaderList(stream_id, header_list);
+
+    // TODO(bnc): Randomly cancel the stream.
+
+    // Encoder splits |header_list| header values along '\0' or ';' separators.
+    // Do the same here so that we get matching results.
+    QuicHeaderList expected_header_list = SplitHeaderList(header_list);
+    decoder.AddExpectedHeaderList(stream_id, std::move(expected_header_list));
+
+    header_block_transmitter.SendEncodedHeaderBlock(
+        stream_id, std::move(encoded_header_block));
+
+    // Transmit some encoder stream data, decoder stream data, or header blocks
+    // on the request stream, repeating a few times.
+    for (auto transmit_data_count = provider.ConsumeIntegralInRange(1, 5);
+         transmit_data_count > 0; --transmit_data_count) {
+      encoder_stream_transmitter.MaybeTransmitSomeData();
+      decoder_stream_transmitter.MaybeTransmitSomeData();
+      header_block_transmitter.MaybeTransmitSomeData();
+    }
+
+    --header_list_count;
+  }
+
+  // Release all delayed encoder stream data so that remaining header blocks can
+  // be decoded synchronously.
+  encoder_stream_transmitter.Flush();
+  // Release all delayed header blocks.
+  header_block_transmitter.Flush();
+  // Release all delayed decoder stream data.
+  decoder_stream_transmitter.Flush();
+
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_blocking_manager.cc b/quiche/quic/core/qpack/qpack_blocking_manager.cc
new file mode 100644
index 0000000..6ab7307
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_blocking_manager.cc
@@ -0,0 +1,159 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/qpack_blocking_manager.h"
+
+#include <limits>
+#include <utility>
+
+namespace quic {
+
+QpackBlockingManager::QpackBlockingManager() : known_received_count_(0) {}
+
+bool QpackBlockingManager::OnHeaderAcknowledgement(QuicStreamId stream_id) {
+  auto it = header_blocks_.find(stream_id);
+  if (it == header_blocks_.end()) {
+    return false;
+  }
+
+  QUICHE_DCHECK(!it->second.empty());
+
+  const IndexSet& indices = it->second.front();
+  QUICHE_DCHECK(!indices.empty());
+
+  const uint64_t required_index_count = RequiredInsertCount(indices);
+  if (known_received_count_ < required_index_count) {
+    known_received_count_ = required_index_count;
+  }
+
+  DecreaseReferenceCounts(indices);
+
+  it->second.pop_front();
+  if (it->second.empty()) {
+    header_blocks_.erase(it);
+  }
+
+  return true;
+}
+
+void QpackBlockingManager::OnStreamCancellation(QuicStreamId stream_id) {
+  auto it = header_blocks_.find(stream_id);
+  if (it == header_blocks_.end()) {
+    return;
+  }
+
+  for (const IndexSet& indices : it->second) {
+    DecreaseReferenceCounts(indices);
+  }
+
+  header_blocks_.erase(it);
+}
+
+bool QpackBlockingManager::OnInsertCountIncrement(uint64_t increment) {
+  if (increment >
+      std::numeric_limits<uint64_t>::max() - known_received_count_) {
+    return false;
+  }
+
+  known_received_count_ += increment;
+  return true;
+}
+
+void QpackBlockingManager::OnHeaderBlockSent(QuicStreamId stream_id,
+                                             IndexSet indices) {
+  QUICHE_DCHECK(!indices.empty());
+
+  IncreaseReferenceCounts(indices);
+  header_blocks_[stream_id].push_back(std::move(indices));
+}
+
+bool QpackBlockingManager::blocking_allowed_on_stream(
+    QuicStreamId stream_id,
+    uint64_t maximum_blocked_streams) const {
+  // This should be the most common case: the limit is larger than the number of
+  // streams that have unacknowledged header blocks (regardless of whether they
+  // are blocked or not) plus one for stream |stream_id|.
+  if (header_blocks_.size() + 1 <= maximum_blocked_streams) {
+    return true;
+  }
+
+  // This should be another common case: no blocked stream allowed.
+  if (maximum_blocked_streams == 0) {
+    return false;
+  }
+
+  uint64_t blocked_stream_count = 0;
+  for (const auto& header_blocks_for_stream : header_blocks_) {
+    for (const IndexSet& indices : header_blocks_for_stream.second) {
+      if (RequiredInsertCount(indices) > known_received_count_) {
+        if (header_blocks_for_stream.first == stream_id) {
+          // Sending blocking references is allowed if stream |stream_id| is
+          // already blocked.
+          return true;
+        }
+        ++blocked_stream_count;
+        // If stream |stream_id| is already blocked, then it is not counted yet,
+        // therefore the number of blocked streams is at least
+        // |blocked_stream_count + 1|, which cannot be more than
+        // |maximum_blocked_streams| by API contract.
+        // If stream |stream_id| is not blocked, then blocking will increase the
+        // blocked stream count to at least |blocked_stream_count + 1|.  If that
+        // is larger than |maximum_blocked_streams|, then blocking is not
+        // allowed on stream |stream_id|.
+        if (blocked_stream_count + 1 > maximum_blocked_streams) {
+          return false;
+        }
+        break;
+      }
+    }
+  }
+
+  // Stream |stream_id| is not blocked.
+  // If there are no blocked streams, then
+  // |blocked_stream_count + 1 <= maximum_blocked_streams| because
+  // |maximum_blocked_streams| is larger than zero.
+  // If there are are blocked streams, then
+  // |blocked_stream_count + 1 <= maximum_blocked_streams| otherwise the method
+  // would have returned false when |blocked_stream_count| was incremented.
+  // Therefore blocking on |stream_id| is allowed.
+  return true;
+}
+
+uint64_t QpackBlockingManager::smallest_blocking_index() const {
+  return entry_reference_counts_.empty()
+             ? std::numeric_limits<uint64_t>::max()
+             : entry_reference_counts_.begin()->first;
+}
+
+// static
+uint64_t QpackBlockingManager::RequiredInsertCount(const IndexSet& indices) {
+  return *indices.rbegin() + 1;
+}
+
+void QpackBlockingManager::IncreaseReferenceCounts(const IndexSet& indices) {
+  for (const uint64_t index : indices) {
+    auto it = entry_reference_counts_.lower_bound(index);
+    if (it != entry_reference_counts_.end() && it->first == index) {
+      ++it->second;
+    } else {
+      entry_reference_counts_.insert(it, {index, 1});
+    }
+  }
+}
+
+void QpackBlockingManager::DecreaseReferenceCounts(const IndexSet& indices) {
+  for (const uint64_t index : indices) {
+    auto it = entry_reference_counts_.find(index);
+    QUICHE_DCHECK(it != entry_reference_counts_.end());
+    QUICHE_DCHECK_NE(0u, it->second);
+
+    if (it->second == 1) {
+      entry_reference_counts_.erase(it);
+    } else {
+      --it->second;
+    }
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_blocking_manager.h b/quiche/quic/core/qpack/qpack_blocking_manager.h
new file mode 100644
index 0000000..4fc1029
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_blocking_manager.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2019 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_QPACK_QPACK_BLOCKING_MANAGER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
+
+#include <cstdint>
+#include <map>
+#include <set>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+
+class QpackBlockingManagerPeer;
+
+}  // namespace test
+
+// Class to keep track of blocked streams and blocking dynamic table entries:
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-decoding
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-insertion
+class QUIC_EXPORT_PRIVATE QpackBlockingManager {
+ public:
+  using IndexSet = std::multiset<uint64_t>;
+
+  QpackBlockingManager();
+
+  // Called when a Header Acknowledgement instruction is received on the decoder
+  // stream.  Returns false if there are no outstanding header blocks to be
+  // acknowledged on |stream_id|.
+  bool OnHeaderAcknowledgement(QuicStreamId stream_id);
+
+  // Called when a Stream Cancellation instruction is received on the decoder
+  // stream.
+  void OnStreamCancellation(QuicStreamId stream_id);
+
+  // Called when an Insert Count Increment instruction is received on the
+  // decoder stream.  Returns true if Known Received Count is successfully
+  // updated.  Returns false on overflow.
+  bool OnInsertCountIncrement(uint64_t increment);
+
+  // Called when sending a header block containing references to dynamic table
+  // entries with |indices|.  |indices| must not be empty.
+  void OnHeaderBlockSent(QuicStreamId stream_id, IndexSet indices);
+
+  // Returns true if sending blocking references on stream |stream_id| would not
+  // increase the total number of blocked streams above
+  // |maximum_blocked_streams|.  Note that if |stream_id| is already blocked
+  // then it is always allowed to send more blocking references on it.
+  // Behavior is undefined if |maximum_blocked_streams| is smaller than number
+  // of currently blocked streams.
+  bool blocking_allowed_on_stream(QuicStreamId stream_id,
+                                  uint64_t maximum_blocked_streams) const;
+
+  // Returns the index of the blocking entry with the smallest index,
+  // or std::numeric_limits<uint64_t>::max() if there are no blocking entries.
+  uint64_t smallest_blocking_index() const;
+
+  // Returns the Known Received Count as defined at
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count.
+  uint64_t known_received_count() const { return known_received_count_; }
+
+  // Required Insert Count for set of indices.
+  static uint64_t RequiredInsertCount(const IndexSet& indices);
+
+ private:
+  friend test::QpackBlockingManagerPeer;
+
+  // A stream typically has only one header block, except for the rare cases of
+  // 1xx responses, trailers, or push promises.  Even if there are multiple
+  // header blocks sent on a single stream, they might not be blocked at the
+  // same time.  Use std::list instead of quiche::QuicheCircularDeque because it
+  // has lower memory footprint when holding few elements.
+  using HeaderBlocksForStream = std::list<IndexSet>;
+  using HeaderBlocks = absl::flat_hash_map<QuicStreamId, HeaderBlocksForStream>;
+
+  // Increase or decrease the reference count for each index in |indices|.
+  void IncreaseReferenceCounts(const IndexSet& indices);
+  void DecreaseReferenceCounts(const IndexSet& indices);
+
+  // Multiset of indices in each header block for each stream.
+  // Must not contain a stream id with an empty queue.
+  HeaderBlocks header_blocks_;
+
+  // Number of references in |header_blocks_| for each entry index.
+  std::map<uint64_t, uint64_t> entry_reference_counts_;
+
+  uint64_t known_received_count_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
diff --git a/quiche/quic/core/qpack/qpack_blocking_manager_test.cc b/quiche/quic/core/qpack/qpack_blocking_manager_test.cc
new file mode 100644
index 0000000..670264e
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_blocking_manager_test.cc
@@ -0,0 +1,319 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/qpack_blocking_manager.h"
+
+#include <limits>
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QpackBlockingManagerPeer {
+ public:
+  static bool stream_is_blocked(const QpackBlockingManager* manager,
+                                QuicStreamId stream_id) {
+    for (const auto& header_blocks_for_stream : manager->header_blocks_) {
+      if (header_blocks_for_stream.first != stream_id) {
+        continue;
+      }
+      for (const auto& indices : header_blocks_for_stream.second) {
+        if (QpackBlockingManager::RequiredInsertCount(indices) >
+            manager->known_received_count_) {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+};
+
+namespace {
+
+class QpackBlockingManagerTest : public QuicTest {
+ protected:
+  QpackBlockingManagerTest() = default;
+  ~QpackBlockingManagerTest() override = default;
+
+  bool stream_is_blocked(QuicStreamId stream_id) const {
+    return QpackBlockingManagerPeer::stream_is_blocked(&manager_, stream_id);
+  }
+
+  QpackBlockingManager manager_;
+};
+
+TEST_F(QpackBlockingManagerTest, Empty) {
+  EXPECT_EQ(0u, manager_.known_received_count());
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+
+  EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_FALSE(manager_.OnHeaderAcknowledgement(1));
+}
+
+TEST_F(QpackBlockingManagerTest, NotBlockedByInsertCountIncrement) {
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
+
+  // Stream 0 is not blocked, because it only references entries that are
+  // already acknowledged by an Insert Count Increment instruction.
+  manager_.OnHeaderBlockSent(0, {1, 0});
+  EXPECT_FALSE(stream_is_blocked(0));
+}
+
+TEST_F(QpackBlockingManagerTest, UnblockedByInsertCountIncrement) {
+  manager_.OnHeaderBlockSent(0, {1, 0});
+  EXPECT_TRUE(stream_is_blocked(0));
+
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
+  EXPECT_FALSE(stream_is_blocked(0));
+}
+
+TEST_F(QpackBlockingManagerTest, NotBlockedByHeaderAcknowledgement) {
+  manager_.OnHeaderBlockSent(0, {2, 1, 1});
+  EXPECT_TRUE(stream_is_blocked(0));
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_FALSE(stream_is_blocked(0));
+
+  // Stream 1 is not blocked, because it only references entries that are
+  // already acknowledged by a Header Acknowledgement instruction.
+  manager_.OnHeaderBlockSent(1, {2, 2});
+  EXPECT_FALSE(stream_is_blocked(1));
+}
+
+TEST_F(QpackBlockingManagerTest, UnblockedByHeaderAcknowledgement) {
+  manager_.OnHeaderBlockSent(0, {2, 1, 1});
+  manager_.OnHeaderBlockSent(1, {2, 2});
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_TRUE(stream_is_blocked(1));
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_FALSE(stream_is_blocked(1));
+}
+
+TEST_F(QpackBlockingManagerTest, KnownReceivedCount) {
+  EXPECT_EQ(0u, manager_.known_received_count());
+
+  // Sending a header block does not change Known Received Count.
+  manager_.OnHeaderBlockSent(0, {0});
+  EXPECT_EQ(0u, manager_.known_received_count());
+
+  manager_.OnHeaderBlockSent(1, {1});
+  EXPECT_EQ(0u, manager_.known_received_count());
+
+  // Header Acknowledgement might increase Known Received Count.
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(1u, manager_.known_received_count());
+
+  manager_.OnHeaderBlockSent(2, {5});
+  EXPECT_EQ(1u, manager_.known_received_count());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
+  EXPECT_EQ(2u, manager_.known_received_count());
+
+  // Insert Count Increment increases Known Received Count.
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
+  EXPECT_EQ(4u, manager_.known_received_count());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(2));
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  // Stream Cancellation does not change Known Received Count.
+  manager_.OnStreamCancellation(0);
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  // Header Acknowledgement of a block with smaller Required Insert Count does
+  // not increase Known Received Count.
+  manager_.OnHeaderBlockSent(0, {3});
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  // Header Acknowledgement of a block with equal Required Insert Count does not
+  // increase Known Received Count.
+  manager_.OnHeaderBlockSent(1, {5});
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
+  EXPECT_EQ(6u, manager_.known_received_count());
+}
+
+TEST_F(QpackBlockingManagerTest, SmallestBlockingIndex) {
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {0});
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(1, {2});
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(2u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(1, {1});
+  EXPECT_EQ(1u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
+  EXPECT_EQ(1u, manager_.smallest_blocking_index());
+
+  // Insert Count Increment does not change smallest blocking index.
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
+  EXPECT_EQ(1u, manager_.smallest_blocking_index());
+
+  manager_.OnStreamCancellation(1);
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+}
+
+TEST_F(QpackBlockingManagerTest, HeaderAcknowledgementsOnSingleStream) {
+  EXPECT_EQ(0u, manager_.known_received_count());
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {2, 1, 1});
+  EXPECT_EQ(0u, manager_.known_received_count());
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(1u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {1, 0});
+  EXPECT_EQ(0u, manager_.known_received_count());
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(3u, manager_.known_received_count());
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {3});
+  EXPECT_EQ(3u, manager_.known_received_count());
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(3u, manager_.known_received_count());
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(3u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(4u, manager_.known_received_count());
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+
+  EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
+}
+
+TEST_F(QpackBlockingManagerTest, CancelStream) {
+  manager_.OnHeaderBlockSent(0, {3});
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(3u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {2});
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(2u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(1, {4});
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_TRUE(stream_is_blocked(1));
+  EXPECT_EQ(2u, manager_.smallest_blocking_index());
+
+  manager_.OnStreamCancellation(0);
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_TRUE(stream_is_blocked(1));
+  EXPECT_EQ(4u, manager_.smallest_blocking_index());
+
+  manager_.OnStreamCancellation(1);
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_FALSE(stream_is_blocked(1));
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+}
+
+TEST_F(QpackBlockingManagerTest, BlockingAllowedOnStream) {
+  const QuicStreamId kStreamId1 = 1;
+  const QuicStreamId kStreamId2 = 2;
+  const QuicStreamId kStreamId3 = 3;
+
+  // No stream can block if limit is 0.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
+
+  // Either stream can block if limit is larger.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
+
+  // Doubly block first stream.
+  manager_.OnHeaderBlockSent(kStreamId1, {0});
+  manager_.OnHeaderBlockSent(kStreamId1, {1});
+
+  // First stream is already blocked so it can carry more blocking references.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
+  // Second stream is not allowed to block if limit is already reached.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
+
+  // Either stream can block if limit is larger than number of blocked streams.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
+
+  // Block second stream.
+  manager_.OnHeaderBlockSent(kStreamId2, {2});
+
+  // Streams are already blocked so either can carry more blocking references.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
+
+  // Third, unblocked stream is not allowed to block unless limit is strictly
+  // larger than number of blocked streams.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId3, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId3, 3));
+
+  // Acknowledge decoding of first header block on first stream.
+  // Stream is still blocked on its second header block.
+  manager_.OnHeaderAcknowledgement(kStreamId1);
+
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
+
+  // Acknowledge decoding of second header block on first stream.
+  // This unblocks the stream.
+  manager_.OnHeaderAcknowledgement(kStreamId1);
+
+  // First stream is not allowed to block if limit is already reached.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
+  // Second stream is already blocked so it can carry more blocking references.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
+
+  // Either stream can block if limit is larger than number of blocked streams.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
+
+  // Unblock second stream.
+  manager_.OnHeaderAcknowledgement(kStreamId2);
+
+  // No stream can block if limit is 0.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
+
+  // Either stream can block if limit is larger.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
+}
+
+TEST_F(QpackBlockingManagerTest, InsertCountIncrementOverflow) {
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(10));
+  EXPECT_EQ(10u, manager_.known_received_count());
+
+  EXPECT_FALSE(manager_.OnInsertCountIncrement(
+      std::numeric_limits<uint64_t>::max() - 5));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc
new file mode 100644
index 0000000..9e87f20
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QpackDecodedHeadersAccumulator::QpackDecodedHeadersAccumulator(
+    QuicStreamId id,
+    QpackDecoder* qpack_decoder,
+    Visitor* visitor,
+    size_t max_header_list_size)
+    : decoder_(qpack_decoder->CreateProgressiveDecoder(id, this)),
+      visitor_(visitor),
+      max_header_list_size_(max_header_list_size),
+      uncompressed_header_bytes_including_overhead_(0),
+      uncompressed_header_bytes_without_overhead_(0),
+      compressed_header_bytes_(0),
+      header_list_size_limit_exceeded_(false),
+      headers_decoded_(false),
+      error_detected_(false) {
+  quic_header_list_.OnHeaderBlockStart();
+}
+
+void QpackDecodedHeadersAccumulator::OnHeaderDecoded(absl::string_view name,
+                                                     absl::string_view value) {
+  QUICHE_DCHECK(!error_detected_);
+
+  uncompressed_header_bytes_without_overhead_ += name.size() + value.size();
+
+  if (header_list_size_limit_exceeded_) {
+    return;
+  }
+
+  uncompressed_header_bytes_including_overhead_ +=
+      name.size() + value.size() + kQpackEntrySizeOverhead;
+
+  const size_t uncompressed_header_bytes =
+      GetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead)
+          ? uncompressed_header_bytes_including_overhead_
+          : uncompressed_header_bytes_without_overhead_;
+  if (uncompressed_header_bytes > max_header_list_size_) {
+    header_list_size_limit_exceeded_ = true;
+    quic_header_list_.Clear();
+  } else {
+    quic_header_list_.OnHeader(name, value);
+  }
+}
+
+void QpackDecodedHeadersAccumulator::OnDecodingCompleted() {
+  QUICHE_DCHECK(!headers_decoded_);
+  QUICHE_DCHECK(!error_detected_);
+
+  headers_decoded_ = true;
+
+  quic_header_list_.OnHeaderBlockEnd(
+      uncompressed_header_bytes_without_overhead_, compressed_header_bytes_);
+
+  // Might destroy |this|.
+  visitor_->OnHeadersDecoded(std::move(quic_header_list_),
+                             header_list_size_limit_exceeded_);
+}
+
+void QpackDecodedHeadersAccumulator::OnDecodingErrorDetected(
+    QuicErrorCode error_code, absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+  QUICHE_DCHECK(!headers_decoded_);
+
+  error_detected_ = true;
+  // Might destroy |this|.
+  visitor_->OnHeaderDecodingError(error_code, error_message);
+}
+
+void QpackDecodedHeadersAccumulator::Decode(absl::string_view data) {
+  QUICHE_DCHECK(!error_detected_);
+
+  compressed_header_bytes_ += data.size();
+  // Might destroy |this|.
+  decoder_->Decode(data);
+}
+
+void QpackDecodedHeadersAccumulator::EndHeaderBlock() {
+  QUICHE_DCHECK(!error_detected_);
+  QUICHE_DCHECK(!headers_decoded_);
+
+  if (!decoder_) {
+    QUIC_BUG(b215142466_EndHeaderBlock);
+    return;
+  }
+
+  // Might destroy |this|.
+  decoder_->EndHeaderBlock();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h
new file mode 100644
index 0000000..27c94bd
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h
@@ -0,0 +1,106 @@
+// Copyright (c) 2019 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_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
+
+#include <cstddef>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/qpack/qpack_progressive_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QpackDecoder;
+
+// A class that creates and owns a QpackProgressiveDecoder instance, accumulates
+// decoded headers in a QuicHeaderList, and keeps track of uncompressed and
+// compressed size so that it can be passed to
+// QuicHeaderList::OnHeaderBlockEnd().
+class QUIC_EXPORT_PRIVATE QpackDecodedHeadersAccumulator
+    : public QpackProgressiveDecoder::HeadersHandlerInterface {
+ public:
+  // Visitor interface to signal success or error.
+  // Exactly one method will be called.
+  // Methods may be called synchronously from Decode() and EndHeaderBlock(),
+  // or asynchronously.
+  // Method implementations are allowed to destroy |this|.
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() = default;
+
+    // Called when headers are successfully decoded.  If the uncompressed header
+    // list size including an overhead for each header field exceeds the limit
+    // specified via |max_header_list_size| in QpackDecodedHeadersAccumulator
+    // constructor, then |header_list_size_limit_exceeded| will be true, and
+    // |headers| will be empty but will still have the correct compressed and
+    // uncompressed size
+    // information.
+    virtual void OnHeadersDecoded(QuicHeaderList headers,
+                                  bool header_list_size_limit_exceeded) = 0;
+
+    // Called when an error has occurred.
+    virtual void OnHeaderDecodingError(QuicErrorCode error_code,
+                                       absl::string_view error_message) = 0;
+  };
+
+  QpackDecodedHeadersAccumulator(QuicStreamId id,
+                                 QpackDecoder* qpack_decoder,
+                                 Visitor* visitor,
+                                 size_t max_header_list_size);
+  virtual ~QpackDecodedHeadersAccumulator() = default;
+
+  // QpackProgressiveDecoder::HeadersHandlerInterface implementation.
+  // These methods should only be called by |decoder_|.
+  void OnHeaderDecoded(absl::string_view name,
+                       absl::string_view value) override;
+  void OnDecodingCompleted() override;
+  void OnDecodingErrorDetected(QuicErrorCode error_code,
+                               absl::string_view error_message) override;
+
+  // Decode payload data.
+  // Must not be called if an error has been detected.
+  // Must not be called after EndHeaderBlock().
+  void Decode(absl::string_view data);
+
+  // Signal end of HEADERS frame.
+  // Must not be called if an error has been detected.
+  // Must not be called more that once.
+  void EndHeaderBlock();
+
+ private:
+  std::unique_ptr<QpackProgressiveDecoder> decoder_;
+  Visitor* visitor_;
+  // Maximum header list size including overhead.
+  size_t max_header_list_size_;
+  // Uncompressed header list size including overhead, for enforcing the limit.
+  size_t uncompressed_header_bytes_including_overhead_;
+  QuicHeaderList quic_header_list_;
+  // Uncompressed header list size with overhead,
+  // for passing in to QuicHeaderList::OnHeaderBlockEnd().
+  size_t uncompressed_header_bytes_without_overhead_;
+  // Compressed header list size
+  // for passing in to QuicHeaderList::OnHeaderBlockEnd().
+  size_t compressed_header_bytes_;
+
+  // True if the header size limit has been exceeded.
+  // Input data is still fed to QpackProgressiveDecoder.
+  bool header_list_size_limit_exceeded_;
+
+  // The following two members are only used for QUICHE_DCHECKs.
+
+  // True if headers have been completedly and successfully decoded.
+  bool headers_decoded_;
+  // True if an error has been detected during decoding.
+  bool error_detected_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
diff --git a/quiche/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
new file mode 100644
index 0000000..92d7511
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
@@ -0,0 +1,253 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h"
+
+#include <cstring>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::Eq;
+using ::testing::Pair;
+using ::testing::SaveArg;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+// Arbitrary stream ID used for testing.
+QuicStreamId kTestStreamId = 1;
+
+// Limit on header list size.
+const size_t kMaxHeaderListSize = 100;
+
+// Maximum dynamic table capacity.
+const size_t kMaxDynamicTableCapacity = 100;
+
+// Maximum number of blocked streams.
+const uint64_t kMaximumBlockedStreams = 1;
+
+// Header Acknowledgement decoder stream instruction with stream_id = 1.
+const char* const kHeaderAcknowledgement = "\x81";
+
+class MockVisitor : public QpackDecodedHeadersAccumulator::Visitor {
+ public:
+  ~MockVisitor() override = default;
+  MOCK_METHOD(void,
+              OnHeadersDecoded,
+              (QuicHeaderList headers, bool header_list_size_limit_exceeded),
+              (override));
+  MOCK_METHOD(void, OnHeaderDecodingError,
+              (QuicErrorCode error_code, absl::string_view error_message),
+              (override));
+};
+
+}  // anonymous namespace
+
+class QpackDecodedHeadersAccumulatorTest : public QuicTest {
+ protected:
+  QpackDecodedHeadersAccumulatorTest()
+      : qpack_decoder_(kMaxDynamicTableCapacity,
+                       kMaximumBlockedStreams,
+                       &encoder_stream_error_delegate_),
+        accumulator_(kTestStreamId,
+                     &qpack_decoder_,
+                     &visitor_,
+                     kMaxHeaderListSize) {
+    qpack_decoder_.set_qpack_stream_sender_delegate(
+        &decoder_stream_sender_delegate_);
+  }
+
+  NoopEncoderStreamErrorDelegate encoder_stream_error_delegate_;
+  StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
+  QpackDecoder qpack_decoder_;
+  StrictMock<MockVisitor> visitor_;
+  QpackDecodedHeadersAccumulator accumulator_;
+};
+
+// HEADERS frame payload must have a complete Header Block Prefix.
+TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyPayload) {
+  EXPECT_CALL(visitor_,
+              OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                    Eq("Incomplete header data prefix.")));
+  accumulator_.EndHeaderBlock();
+}
+
+// HEADERS frame payload must have a complete Header Block Prefix.
+TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedHeaderBlockPrefix) {
+  accumulator_.Decode(absl::HexStringToBytes("00"));
+
+  EXPECT_CALL(visitor_,
+              OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                    Eq("Incomplete header data prefix.")));
+  accumulator_.EndHeaderBlock();
+}
+
+TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyHeaderList) {
+  std::string encoded_data(absl::HexStringToBytes("0000"));
+  accumulator_.Decode(encoded_data);
+
+  QuicHeaderList header_list;
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+      .WillOnce(SaveArg<0>(&header_list));
+  accumulator_.EndHeaderBlock();
+
+  EXPECT_EQ(0u, header_list.uncompressed_header_bytes());
+  EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
+  EXPECT_TRUE(header_list.empty());
+}
+
+// This payload is the prefix of a valid payload, but EndHeaderBlock() is called
+// before it can be completely decoded.
+TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedPayload) {
+  accumulator_.Decode(absl::HexStringToBytes("00002366"));
+
+  EXPECT_CALL(visitor_, OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                              Eq("Incomplete header block.")));
+  accumulator_.EndHeaderBlock();
+}
+
+// This payload is invalid because it refers to a non-existing static entry.
+TEST_F(QpackDecodedHeadersAccumulatorTest, InvalidPayload) {
+  EXPECT_CALL(visitor_,
+              OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                    Eq("Static table entry not found.")));
+  accumulator_.Decode(absl::HexStringToBytes("0000ff23ff24"));
+}
+
+TEST_F(QpackDecodedHeadersAccumulatorTest, Success) {
+  std::string encoded_data(absl::HexStringToBytes("000023666f6f03626172"));
+  accumulator_.Decode(encoded_data);
+
+  QuicHeaderList header_list;
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+      .WillOnce(SaveArg<0>(&header_list));
+  accumulator_.EndHeaderBlock();
+
+  EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
+  EXPECT_EQ(strlen("foo") + strlen("bar"),
+            header_list.uncompressed_header_bytes());
+  EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
+}
+
+// Test that Decode() calls are not ignored after header list limit is exceeded,
+// otherwise decoding could fail with "incomplete header block" error.
+TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitThenSplitInstruction) {
+  // Total length of header list exceeds kMaxHeaderListSize.
+  accumulator_.Decode(absl::HexStringToBytes(
+      "0000"                                      // header block prefix
+      "26666f6f626172"                            // header key: "foobar"
+      "7d61616161616161616161616161616161616161"  // header value: 'a' 125 times
+      "616161616161616161616161616161616161616161616161616161616161616161616161"
+      "616161616161616161616161616161616161616161616161616161616161616161616161"
+      "61616161616161616161616161616161616161616161616161616161616161616161"
+      "ff"));  // first byte of a two-byte long Indexed Header Field instruction
+  accumulator_.Decode(absl::HexStringToBytes(
+      "0f"  // second byte of a two-byte long Indexed Header Field instruction
+      ));
+
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
+  accumulator_.EndHeaderBlock();
+}
+
+// Test that header list limit enforcement works with blocked encoding.
+TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitBlocked) {
+  // Total length of header list exceeds kMaxHeaderListSize.
+  accumulator_.Decode(absl::HexStringToBytes(
+      "0200"            // header block prefix
+      "80"              // reference to dynamic table entry not yet received
+      "26666f6f626172"  // header key: "foobar"
+      "7d61616161616161616161616161616161616161"  // header value: 'a' 125 times
+      "616161616161616161616161616161616161616161616161616161616161616161616161"
+      "616161616161616161616161616161616161616161616161616161616161616161616161"
+      "61616161616161616161616161616161616161616161616161616161616161616161"));
+  accumulator_.EndHeaderBlock();
+
+  // Set dynamic table capacity.
+  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
+  // Adding dynamic table entry unblocks decoding.
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
+  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
+}
+
+TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecoding) {
+  // Reference to dynamic table entry not yet received.
+  std::string encoded_data(absl::HexStringToBytes("020080"));
+  accumulator_.Decode(encoded_data);
+  accumulator_.EndHeaderBlock();
+
+  // Set dynamic table capacity.
+  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
+  // Adding dynamic table entry unblocks decoding.
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  QuicHeaderList header_list;
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+      .WillOnce(SaveArg<0>(&header_list));
+  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
+
+  EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
+  EXPECT_EQ(strlen("foo") + strlen("bar"),
+            header_list.uncompressed_header_bytes());
+  EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
+}
+
+TEST_F(QpackDecodedHeadersAccumulatorTest,
+       BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
+  // Reference to dynamic table entry not yet received.
+  accumulator_.Decode(absl::HexStringToBytes("020080"));
+
+  // Set dynamic table capacity.
+  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
+  // Adding dynamic table entry unblocks decoding.
+  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
+
+  // Rest of header block: same entry again.
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+  accumulator_.Decode(absl::HexStringToBytes("80"));
+
+  QuicHeaderList header_list;
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+      .WillOnce(SaveArg<0>(&header_list));
+  accumulator_.EndHeaderBlock();
+
+  EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar"), Pair("foo", "bar")));
+}
+
+// Regression test for https://crbug.com/1024263.
+TEST_F(QpackDecodedHeadersAccumulatorTest,
+       BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
+  // Required Insert Count higher than number of entries causes decoding to be
+  // blocked.
+  accumulator_.Decode(absl::HexStringToBytes("0200"));
+  // Indexed Header Field instruction addressing dynamic table entry with
+  // relative index 0, absolute index 0.
+  accumulator_.Decode(absl::HexStringToBytes("80"));
+  // Relative index larger than or equal to Base is invalid.
+  accumulator_.Decode(absl::HexStringToBytes("81"));
+
+  // Set dynamic table capacity.
+  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
+
+  // Adding dynamic table entry unblocks decoding.  Error is detected.
+  EXPECT_CALL(visitor_, OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                              Eq("Invalid relative index.")));
+  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder.cc b/quiche/quic/core/qpack/qpack_decoder.cc
new file mode 100644
index 0000000..e93db67
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_decoder.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_index_conversions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackDecoder::QpackDecoder(
+    uint64_t maximum_dynamic_table_capacity,
+    uint64_t maximum_blocked_streams,
+    EncoderStreamErrorDelegate* encoder_stream_error_delegate)
+    : encoder_stream_error_delegate_(encoder_stream_error_delegate),
+      encoder_stream_receiver_(this),
+      maximum_blocked_streams_(maximum_blocked_streams),
+      known_received_count_(0) {
+  QUICHE_DCHECK(encoder_stream_error_delegate_);
+
+  header_table_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
+}
+
+QpackDecoder::~QpackDecoder() {}
+
+void QpackDecoder::OnStreamReset(QuicStreamId stream_id) {
+  if (header_table_.maximum_dynamic_table_capacity() > 0) {
+    decoder_stream_sender_.SendStreamCancellation(stream_id);
+    decoder_stream_sender_.Flush();
+  }
+}
+
+bool QpackDecoder::OnStreamBlocked(QuicStreamId stream_id) {
+  auto result = blocked_streams_.insert(stream_id);
+  QUICHE_DCHECK(result.second);
+  return blocked_streams_.size() <= maximum_blocked_streams_;
+}
+
+void QpackDecoder::OnStreamUnblocked(QuicStreamId stream_id) {
+  size_t result = blocked_streams_.erase(stream_id);
+  QUICHE_DCHECK_EQ(1u, result);
+}
+
+void QpackDecoder::OnDecodingCompleted(QuicStreamId stream_id,
+                                       uint64_t required_insert_count) {
+  if (required_insert_count > 0) {
+    decoder_stream_sender_.SendHeaderAcknowledgement(stream_id);
+
+    if (known_received_count_ < required_insert_count) {
+      known_received_count_ = required_insert_count;
+    }
+  }
+
+  // Send an Insert Count Increment instruction if not all dynamic table entries
+  // have been acknowledged yet.  This is necessary for efficient compression in
+  // case the encoder chooses not to reference unacknowledged dynamic table
+  // entries, otherwise inserted entries would never be acknowledged.
+  if (known_received_count_ < header_table_.inserted_entry_count()) {
+    decoder_stream_sender_.SendInsertCountIncrement(
+        header_table_.inserted_entry_count() - known_received_count_);
+    known_received_count_ = header_table_.inserted_entry_count();
+  }
+
+  decoder_stream_sender_.Flush();
+}
+
+void QpackDecoder::OnInsertWithNameReference(bool is_static,
+                                             uint64_t name_index,
+                                             absl::string_view value) {
+  if (is_static) {
+    auto entry = header_table_.LookupEntry(/* is_static = */ true, name_index);
+    if (!entry) {
+      OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY,
+                      "Invalid static table entry.");
+      return;
+    }
+
+    if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(), value)) {
+      OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC,
+                      "Error inserting entry with name reference.");
+      return;
+    }
+    header_table_.InsertEntry(entry->name(), value);
+    return;
+  }
+
+  uint64_t absolute_index;
+  if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+          name_index, header_table_.inserted_entry_count(), &absolute_index)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX,
+                    "Invalid relative index.");
+    return;
+  }
+
+  const QpackEntry* entry =
+      header_table_.LookupEntry(/* is_static = */ false, absolute_index);
+  if (!entry) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND,
+                    "Dynamic table entry not found.");
+    return;
+  }
+  if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(), value)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC,
+                    "Error inserting entry with name reference.");
+    return;
+  }
+  header_table_.InsertEntry(entry->name(), value);
+}
+
+void QpackDecoder::OnInsertWithoutNameReference(absl::string_view name,
+                                                absl::string_view value) {
+  if (!header_table_.EntryFitsDynamicTableCapacity(name, value)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL,
+                    "Error inserting literal entry.");
+    return;
+  }
+  header_table_.InsertEntry(name, value);
+}
+
+void QpackDecoder::OnDuplicate(uint64_t index) {
+  uint64_t absolute_index;
+  if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+          index, header_table_.inserted_entry_count(), &absolute_index)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
+                    "Invalid relative index.");
+    return;
+  }
+
+  const QpackEntry* entry =
+      header_table_.LookupEntry(/* is_static = */ false, absolute_index);
+  if (!entry) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND,
+                    "Dynamic table entry not found.");
+    return;
+  }
+  if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(),
+                                                   entry->value())) {
+    // This is impossible since entry was retrieved from the dynamic table.
+    OnErrorDetected(QUIC_INTERNAL_ERROR, "Error inserting duplicate entry.");
+    return;
+  }
+  header_table_.InsertEntry(entry->name(), entry->value());
+}
+
+void QpackDecoder::OnSetDynamicTableCapacity(uint64_t capacity) {
+  if (!header_table_.SetDynamicTableCapacity(capacity)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY,
+                    "Error updating dynamic table capacity.");
+  }
+}
+
+void QpackDecoder::OnErrorDetected(QuicErrorCode error_code,
+                                   absl::string_view error_message) {
+  encoder_stream_error_delegate_->OnEncoderStreamError(error_code,
+                                                       error_message);
+}
+
+std::unique_ptr<QpackProgressiveDecoder> QpackDecoder::CreateProgressiveDecoder(
+    QuicStreamId stream_id,
+    QpackProgressiveDecoder::HeadersHandlerInterface* handler) {
+  return std::make_unique<QpackProgressiveDecoder>(stream_id, this, this,
+                                                   &header_table_, handler);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder.h b/quiche/quic/core/qpack/qpack_decoder.h
new file mode 100644
index 0000000..940535d
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2018 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_QPACK_QPACK_DECODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
+
+#include <cstdint>
+#include <memory>
+#include <set>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/qpack/qpack_progressive_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QPACK decoder class.  Exactly one instance should exist per QUIC connection.
+// This class vends a new QpackProgressiveDecoder instance for each new header
+// list to be encoded.
+// QpackProgressiveDecoder detects and signals errors with header blocks, which
+// are stream errors.
+// The only input of QpackDecoder is the encoder stream.  Any error QpackDecoder
+// signals is an encoder stream error, which is fatal to the connection.
+class QUIC_EXPORT_PRIVATE QpackDecoder
+    : public QpackEncoderStreamReceiver::Delegate,
+      public QpackProgressiveDecoder::BlockedStreamLimitEnforcer,
+      public QpackProgressiveDecoder::DecodingCompletedVisitor {
+ public:
+  // Interface for receiving notification that an error has occurred on the
+  // encoder stream.  This MUST be treated as a connection error of type
+  // HTTP_QPACK_ENCODER_STREAM_ERROR.
+  class QUIC_EXPORT_PRIVATE EncoderStreamErrorDelegate {
+   public:
+    virtual ~EncoderStreamErrorDelegate() {}
+
+    virtual void OnEncoderStreamError(QuicErrorCode error_code,
+                                      absl::string_view error_message) = 0;
+  };
+
+  QpackDecoder(uint64_t maximum_dynamic_table_capacity,
+               uint64_t maximum_blocked_streams,
+               EncoderStreamErrorDelegate* encoder_stream_error_delegate);
+  ~QpackDecoder() override;
+
+  // Signal to the peer's encoder that a stream is reset.  This lets the peer's
+  // encoder know that no more header blocks will be processed on this stream,
+  // therefore references to dynamic table entries shall not prevent their
+  // eviction.
+  // This method should be called regardless of whether a header block is being
+  // decoded on that stream, because a header block might be in flight from the
+  // peer.
+  // This method should be called every time a request or push stream is reset
+  // for any reason: for example, client cancels request, or a decoding error
+  // occurs and HeadersHandlerInterface::OnDecodingErrorDetected() is called.
+  // This method should also be called if the stream is reset by the peer,
+  // because the peer's encoder can only evict entries referenced by header
+  // blocks once it receives acknowledgement from this endpoint that the stream
+  // is reset.
+  // However, this method should not be called if the stream is closed normally
+  // using the FIN bit.
+  void OnStreamReset(QuicStreamId stream_id);
+
+  // QpackProgressiveDecoder::BlockedStreamLimitEnforcer implementation.
+  bool OnStreamBlocked(QuicStreamId stream_id) override;
+  void OnStreamUnblocked(QuicStreamId stream_id) override;
+
+  // QpackProgressiveDecoder::DecodingCompletedVisitor implementation.
+  void OnDecodingCompleted(QuicStreamId stream_id,
+                           uint64_t required_insert_count) override;
+
+  // Factory method to create a QpackProgressiveDecoder for decoding a header
+  // block.  |handler| must remain valid until the returned
+  // QpackProgressiveDecoder instance is destroyed or the decoder calls
+  // |handler->OnHeaderBlockEnd()|.
+  std::unique_ptr<QpackProgressiveDecoder> CreateProgressiveDecoder(
+      QuicStreamId stream_id,
+      QpackProgressiveDecoder::HeadersHandlerInterface* handler);
+
+  // QpackEncoderStreamReceiver::Delegate implementation
+  void OnInsertWithNameReference(bool is_static,
+                                 uint64_t name_index,
+                                 absl::string_view value) override;
+  void OnInsertWithoutNameReference(absl::string_view name,
+                                    absl::string_view value) override;
+  void OnDuplicate(uint64_t index) override;
+  void OnSetDynamicTableCapacity(uint64_t capacity) override;
+  void OnErrorDetected(QuicErrorCode error_code,
+                       absl::string_view error_message) override;
+
+  // delegate must be set if dynamic table capacity is not zero.
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    decoder_stream_sender_.set_qpack_stream_sender_delegate(delegate);
+  }
+
+  QpackStreamReceiver* encoder_stream_receiver() {
+    return &encoder_stream_receiver_;
+  }
+
+  // True if any dynamic table entries have been referenced from a header block.
+  bool dynamic_table_entry_referenced() const {
+    return header_table_.dynamic_table_entry_referenced();
+  }
+
+ private:
+  EncoderStreamErrorDelegate* const encoder_stream_error_delegate_;
+  QpackEncoderStreamReceiver encoder_stream_receiver_;
+  QpackDecoderStreamSender decoder_stream_sender_;
+  QpackDecoderHeaderTable header_table_;
+  std::set<QuicStreamId> blocked_streams_;
+  const uint64_t maximum_blocked_streams_;
+
+  // Known Received Count is the number of insertions the encoder has received
+  // acknowledgement for (through Header Acknowledgement and Insert Count
+  // Increment instructions).  The encoder must keep track of it in order to be
+  // able to send Insert Count Increment instructions.  See
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count.
+  uint64_t known_received_count_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_receiver.cc b/quiche/quic/core/qpack/qpack_decoder_stream_receiver.cc
new file mode 100644
index 0000000..699eb4f
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_receiver.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_decoder_stream_receiver.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+
+namespace quic {
+
+QpackDecoderStreamReceiver::QpackDecoderStreamReceiver(Delegate* delegate)
+    : instruction_decoder_(QpackDecoderStreamLanguage(), this),
+      delegate_(delegate),
+      error_detected_(false) {
+  QUICHE_DCHECK(delegate_);
+}
+
+void QpackDecoderStreamReceiver::Decode(absl::string_view data) {
+  if (data.empty() || error_detected_) {
+    return;
+  }
+
+  instruction_decoder_.Decode(data);
+}
+
+bool QpackDecoderStreamReceiver::OnInstructionDecoded(
+    const QpackInstruction* instruction) {
+  if (instruction == InsertCountIncrementInstruction()) {
+    delegate_->OnInsertCountIncrement(instruction_decoder_.varint());
+    return true;
+  }
+
+  if (instruction == HeaderAcknowledgementInstruction()) {
+    delegate_->OnHeaderAcknowledgement(instruction_decoder_.varint());
+    return true;
+  }
+
+  QUICHE_DCHECK_EQ(instruction, StreamCancellationInstruction());
+  delegate_->OnStreamCancellation(instruction_decoder_.varint());
+  return true;
+}
+
+void QpackDecoderStreamReceiver::OnInstructionDecodingError(
+    QpackInstructionDecoder::ErrorCode error_code,
+    absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+
+  error_detected_ = true;
+
+  // There is no string literals on the decoder stream,
+  // the only possible error is INTEGER_TOO_LARGE.
+  QuicErrorCode quic_error_code =
+      (error_code == QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE)
+          ? QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE
+          : QUIC_INTERNAL_ERROR;
+  delegate_->OnErrorDetected(quic_error_code, error_message);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_receiver.h b/quiche/quic/core/qpack/qpack_decoder_stream_receiver.h
new file mode 100644
index 0000000..f78fca9
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_receiver.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2018 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_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_receiver.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This class decodes data received on the decoder stream,
+// and passes it along to its Delegate.
+class QUIC_EXPORT_PRIVATE QpackDecoderStreamReceiver
+    : public QpackInstructionDecoder::Delegate,
+      public QpackStreamReceiver {
+ public:
+  // An interface for handling instructions decoded from the decoder stream, see
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.3
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // 5.3.1 Insert Count Increment
+    virtual void OnInsertCountIncrement(uint64_t increment) = 0;
+    // 5.3.2 Header Acknowledgement
+    virtual void OnHeaderAcknowledgement(QuicStreamId stream_id) = 0;
+    // 5.3.3 Stream Cancellation
+    virtual void OnStreamCancellation(QuicStreamId stream_id) = 0;
+    // Decoding error
+    virtual void OnErrorDetected(QuicErrorCode error_code,
+                                 absl::string_view error_message) = 0;
+  };
+
+  explicit QpackDecoderStreamReceiver(Delegate* delegate);
+  QpackDecoderStreamReceiver() = delete;
+  QpackDecoderStreamReceiver(const QpackDecoderStreamReceiver&) = delete;
+  QpackDecoderStreamReceiver& operator=(const QpackDecoderStreamReceiver&) =
+      delete;
+
+  // Implements QpackStreamReceiver::Decode().
+  // Decode data and call appropriate Delegate method after each decoded
+  // instruction.  Once an error occurs, Delegate::OnErrorDetected() is called,
+  // and all further data is ignored.
+  void Decode(absl::string_view data) override;
+
+  // QpackInstructionDecoder::Delegate implementation.
+  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
+  void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
+                                  absl::string_view error_message) override;
+
+ private:
+  QpackInstructionDecoder instruction_decoder_;
+  Delegate* const delegate_;
+
+  // True if a decoding error has been detected.
+  bool error_detected_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_receiver_test.cc b/quiche/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
new file mode 100644
index 0000000..c78cbe7
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
@@ -0,0 +1,102 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_decoder_stream_receiver.h"
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using testing::Eq;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockDelegate : public QpackDecoderStreamReceiver::Delegate {
+ public:
+  ~MockDelegate() override = default;
+
+  MOCK_METHOD(void, OnInsertCountIncrement, (uint64_t increment), (override));
+  MOCK_METHOD(void,
+              OnHeaderAcknowledgement,
+              (QuicStreamId stream_id),
+              (override));
+  MOCK_METHOD(void, OnStreamCancellation, (QuicStreamId stream_id), (override));
+  MOCK_METHOD(void,
+              OnErrorDetected,
+              (QuicErrorCode error_code, absl::string_view error_message),
+              (override));
+};
+
+class QpackDecoderStreamReceiverTest : public QuicTest {
+ protected:
+  QpackDecoderStreamReceiverTest() : stream_(&delegate_) {}
+  ~QpackDecoderStreamReceiverTest() override = default;
+
+  QpackDecoderStreamReceiver stream_;
+  StrictMock<MockDelegate> delegate_;
+};
+
+TEST_F(QpackDecoderStreamReceiverTest, InsertCountIncrement) {
+  EXPECT_CALL(delegate_, OnInsertCountIncrement(0));
+  stream_.Decode(absl::HexStringToBytes("00"));
+
+  EXPECT_CALL(delegate_, OnInsertCountIncrement(10));
+  stream_.Decode(absl::HexStringToBytes("0a"));
+
+  EXPECT_CALL(delegate_, OnInsertCountIncrement(63));
+  stream_.Decode(absl::HexStringToBytes("3f00"));
+
+  EXPECT_CALL(delegate_, OnInsertCountIncrement(200));
+  stream_.Decode(absl::HexStringToBytes("3f8901"));
+
+  EXPECT_CALL(delegate_,
+              OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+  stream_.Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
+}
+
+TEST_F(QpackDecoderStreamReceiverTest, HeaderAcknowledgement) {
+  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(0));
+  stream_.Decode(absl::HexStringToBytes("80"));
+
+  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(37));
+  stream_.Decode(absl::HexStringToBytes("a5"));
+
+  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(127));
+  stream_.Decode(absl::HexStringToBytes("ff00"));
+
+  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(503));
+  stream_.Decode(absl::HexStringToBytes("fff802"));
+
+  EXPECT_CALL(delegate_,
+              OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+  stream_.Decode(absl::HexStringToBytes("ffffffffffffffffffffff"));
+}
+
+TEST_F(QpackDecoderStreamReceiverTest, StreamCancellation) {
+  EXPECT_CALL(delegate_, OnStreamCancellation(0));
+  stream_.Decode(absl::HexStringToBytes("40"));
+
+  EXPECT_CALL(delegate_, OnStreamCancellation(19));
+  stream_.Decode(absl::HexStringToBytes("53"));
+
+  EXPECT_CALL(delegate_, OnStreamCancellation(63));
+  stream_.Decode(absl::HexStringToBytes("7f00"));
+
+  EXPECT_CALL(delegate_, OnStreamCancellation(110));
+  stream_.Decode(absl::HexStringToBytes("7f2f"));
+
+  EXPECT_CALL(delegate_,
+              OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+  stream_.Decode(absl::HexStringToBytes("7fffffffffffffffffffff"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_sender.cc b/quiche/quic/core/qpack/qpack_decoder_stream_sender.cc
new file mode 100644
index 0000000..cc48587
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_sender.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+
+#include <cstddef>
+#include <limits>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackDecoderStreamSender::QpackDecoderStreamSender() : delegate_(nullptr) {}
+
+void QpackDecoderStreamSender::SendInsertCountIncrement(uint64_t increment) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::InsertCountIncrement(increment), &buffer_);
+}
+
+void QpackDecoderStreamSender::SendHeaderAcknowledgement(
+    QuicStreamId stream_id) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::HeaderAcknowledgement(stream_id), &buffer_);
+}
+
+void QpackDecoderStreamSender::SendStreamCancellation(QuicStreamId stream_id) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::StreamCancellation(stream_id), &buffer_);
+}
+
+void QpackDecoderStreamSender::Flush() {
+  if (buffer_.empty()) {
+    return;
+  }
+
+  delegate_->WriteStreamData(buffer_);
+  buffer_.clear();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_sender.h b/quiche/quic/core/qpack/qpack_decoder_stream_sender.h
new file mode 100644
index 0000000..443e850
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_sender.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2018 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_QPACK_QPACK_DECODER_STREAM_SENDER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This class serializes instructions for transmission on the decoder stream.
+// Serialized instructions are buffered until Flush() is called.
+class QUIC_EXPORT_PRIVATE QpackDecoderStreamSender {
+ public:
+  QpackDecoderStreamSender();
+  QpackDecoderStreamSender(const QpackDecoderStreamSender&) = delete;
+  QpackDecoderStreamSender& operator=(const QpackDecoderStreamSender&) = delete;
+
+  // Methods for serializing and buffering instructions, see
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.3
+
+  // 5.3.1 Insert Count Increment
+  void SendInsertCountIncrement(uint64_t increment);
+  // 5.3.2 Header Acknowledgement
+  void SendHeaderAcknowledgement(QuicStreamId stream_id);
+  // 5.3.3 Stream Cancellation
+  void SendStreamCancellation(QuicStreamId stream_id);
+
+  // Writes all buffered instructions on the decoder stream.
+  void Flush();
+
+  // delegate must be set if dynamic table capacity is not zero.
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    delegate_ = delegate;
+  }
+
+ private:
+  QpackStreamSenderDelegate* delegate_;
+  QpackInstructionEncoder instruction_encoder_;
+  std::string buffer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_sender_test.cc b/quiche/quic/core/qpack/qpack_decoder_stream_sender_test.cc
new file mode 100644
index 0000000..8c43af5
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_sender_test.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::Eq;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QpackDecoderStreamSenderTest : public QuicTest {
+ protected:
+  QpackDecoderStreamSenderTest() {
+    stream_.set_qpack_stream_sender_delegate(&delegate_);
+  }
+  ~QpackDecoderStreamSenderTest() override = default;
+
+  StrictMock<MockQpackStreamSenderDelegate> delegate_;
+  QpackDecoderStreamSender stream_;
+};
+
+TEST_F(QpackDecoderStreamSenderTest, InsertCountIncrement) {
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("00"))));
+  stream_.SendInsertCountIncrement(0);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0a"))));
+  stream_.SendInsertCountIncrement(10);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f00"))));
+  stream_.SendInsertCountIncrement(63);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f8901"))));
+  stream_.SendInsertCountIncrement(200);
+  stream_.Flush();
+}
+
+TEST_F(QpackDecoderStreamSenderTest, HeaderAcknowledgement) {
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("80"))));
+  stream_.SendHeaderAcknowledgement(0);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("a5"))));
+  stream_.SendHeaderAcknowledgement(37);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("ff00"))));
+  stream_.SendHeaderAcknowledgement(127);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("fff802"))));
+  stream_.SendHeaderAcknowledgement(503);
+  stream_.Flush();
+}
+
+TEST_F(QpackDecoderStreamSenderTest, StreamCancellation) {
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("40"))));
+  stream_.SendStreamCancellation(0);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("53"))));
+  stream_.SendStreamCancellation(19);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f00"))));
+  stream_.SendStreamCancellation(63);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f2f"))));
+  stream_.SendStreamCancellation(110);
+  stream_.Flush();
+}
+
+TEST_F(QpackDecoderStreamSenderTest, Coalesce) {
+  stream_.SendInsertCountIncrement(10);
+  stream_.SendHeaderAcknowledgement(37);
+  stream_.SendStreamCancellation(0);
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0aa540"))));
+  stream_.Flush();
+
+  stream_.SendInsertCountIncrement(63);
+  stream_.SendStreamCancellation(110);
+
+  EXPECT_CALL(delegate_,
+              WriteStreamData(Eq(absl::HexStringToBytes("3f007f2f"))));
+  stream_.Flush();
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder_test.cc b/quiche/quic/core/qpack/qpack_decoder_test.cc
new file mode 100644
index 0000000..f15b3e8
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_test.cc
@@ -0,0 +1,984 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_decoder.h"
+
+#include <algorithm>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Invoke;
+using ::testing::Mock;
+using ::testing::Sequence;
+using ::testing::StrictMock;
+using ::testing::Values;
+
+namespace quic {
+namespace test {
+namespace {
+
+// Header Acknowledgement decoder stream instruction with stream_id = 1.
+const char* const kHeaderAcknowledgement = "\x81";
+
+const uint64_t kMaximumDynamicTableCapacity = 1024;
+const uint64_t kMaximumBlockedStreams = 1;
+
+class QpackDecoderTest : public QuicTestWithParam<FragmentMode> {
+ protected:
+  QpackDecoderTest()
+      : qpack_decoder_(kMaximumDynamicTableCapacity,
+                       kMaximumBlockedStreams,
+                       &encoder_stream_error_delegate_),
+        fragment_mode_(GetParam()) {
+    qpack_decoder_.set_qpack_stream_sender_delegate(
+        &decoder_stream_sender_delegate_);
+  }
+
+  ~QpackDecoderTest() override = default;
+
+  void SetUp() override {
+    // Destroy QpackProgressiveDecoder on error to test that it does not crash.
+    // See https://crbug.com/1025209.
+    ON_CALL(handler_, OnDecodingErrorDetected(_, _))
+        .WillByDefault(Invoke([this](QuicErrorCode /* error_code */,
+                                     absl::string_view /* error_message */) {
+          progressive_decoder_.reset();
+        }));
+  }
+
+  void DecodeEncoderStreamData(absl::string_view data) {
+    qpack_decoder_.encoder_stream_receiver()->Decode(data);
+  }
+
+  std::unique_ptr<QpackProgressiveDecoder> CreateProgressiveDecoder(
+      QuicStreamId stream_id) {
+    return qpack_decoder_.CreateProgressiveDecoder(stream_id, &handler_);
+  }
+
+  // Set up |progressive_decoder_|.
+  void StartDecoding() {
+    progressive_decoder_ = CreateProgressiveDecoder(/* stream_id = */ 1);
+  }
+
+  // Pass header block data to QpackProgressiveDecoder::Decode()
+  // in fragments dictated by |fragment_mode_|.
+  void DecodeData(absl::string_view data) {
+    auto fragment_size_generator =
+        FragmentModeToFragmentSizeGenerator(fragment_mode_);
+    while (progressive_decoder_ && !data.empty()) {
+      size_t fragment_size = std::min(fragment_size_generator(), data.size());
+      progressive_decoder_->Decode(data.substr(0, fragment_size));
+      data = data.substr(fragment_size);
+    }
+  }
+
+  // Signal end of header block to QpackProgressiveDecoder.
+  void EndDecoding() {
+    if (progressive_decoder_) {
+      progressive_decoder_->EndHeaderBlock();
+    }
+    // If no error was detected, |*progressive_decoder_| is kept alive so that
+    // it can handle callbacks later in case of blocked decoding.
+  }
+
+  // Decode an entire header block.
+  void DecodeHeaderBlock(absl::string_view data) {
+    StartDecoding();
+    DecodeData(data);
+    EndDecoding();
+  }
+
+  StrictMock<MockEncoderStreamErrorDelegate> encoder_stream_error_delegate_;
+  StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
+  StrictMock<MockHeadersHandler> handler_;
+
+ private:
+  QpackDecoder qpack_decoder_;
+  const FragmentMode fragment_mode_;
+  std::unique_ptr<QpackProgressiveDecoder> progressive_decoder_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         QpackDecoderTest,
+                         Values(FragmentMode::kSingleChunk,
+                                FragmentMode::kOctetByOctet));
+
+TEST_P(QpackDecoderTest, NoPrefix) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Incomplete header data prefix.")));
+
+  // Header Data Prefix is at least two bytes long.
+  DecodeHeaderBlock(absl::HexStringToBytes("00"));
+}
+
+// Regression test for https://1025209: QpackProgressiveDecoder must not crash
+// in Decode() if it is destroyed by handler_.OnDecodingErrorDetected().
+TEST_P(QpackDecoderTest, InvalidPrefix) {
+  StartDecoding();
+
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Encoded integer too large.")));
+
+  // Encoded Required Insert Count in Header Data Prefix is too large.
+  DecodeData(absl::HexStringToBytes("ffffffffffffffffffffffffffff"));
+}
+
+TEST_P(QpackDecoderTest, EmptyHeaderBlock) {
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("0000"));
+}
+
+TEST_P(QpackDecoderTest, LiteralEntryEmptyName) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("foo")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("00002003666f6f"));
+}
+
+TEST_P(QpackDecoderTest, LiteralEntryEmptyValue) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f00"));
+}
+
+TEST_P(QpackDecoderTest, LiteralEntryEmptyNameAndValue) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("00002000"));
+}
+
+TEST_P(QpackDecoderTest, SimpleLiteralEntry) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f03626172"));
+}
+
+TEST_P(QpackDecoderTest, MultipleLiteralEntries) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  std::string str(127, 'a');
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foobaar"), absl::string_view(str)));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0000"                // prefix
+      "23666f6f03626172"    // foo: bar
+      "2700666f6f62616172"  // 7 octet long header name, the smallest number
+                            // that does not fit on a 3-bit prefix.
+      "7f0061616161616161"  // 127 octet long header value, the smallest number
+      "616161616161616161"  // that does not fit on a 7-bit prefix.
+      "6161616161616161616161616161616161616161616161616161616161616161616161"
+      "6161616161616161616161616161616161616161616161616161616161616161616161"
+      "6161616161616161616161616161616161616161616161616161616161616161616161"
+      "616161616161"));
+}
+
+// Name Length value is too large for varint decoder to decode.
+TEST_P(QpackDecoderTest, NameLenTooLargeForVarintDecoder) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Encoded integer too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000027ffffffffffffffffffff"));
+}
+
+// Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
+TEST_P(QpackDecoderTest, NameLenExceedsLimit) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("String literal too long.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000027ffff7f"));
+}
+
+// Value Length value is too large for varint decoder to decode.
+TEST_P(QpackDecoderTest, ValueLenTooLargeForVarintDecoder) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Encoded integer too large.")));
+
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("000023666f6f7fffffffffffffffffffff"));
+}
+
+// Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
+TEST_P(QpackDecoderTest, ValueLenExceedsLimit) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("String literal too long.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f7fffff7f"));
+}
+
+TEST_P(QpackDecoderTest, LineFeedInValue) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE,
+                                      "Invalid character in field value."));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f0462610a72"));
+}
+
+TEST_P(QpackDecoderTest, IncompleteHeaderBlock) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Incomplete header block.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("00002366"));
+}
+
+TEST_P(QpackDecoderTest, HuffmanSimple) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf"));
+}
+
+TEST_P(QpackDecoderTest, AlternatingHuffmanNonHuffman) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")))
+      .Times(4);
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0000"                        // Prefix.
+      "2f0125a849e95ba97d7f"        // Huffman-encoded name.
+      "8925a849e95bb8e8b4bf"        // Huffman-encoded value.
+      "2703637573746f6d2d6b6579"    // Non-Huffman encoded name.
+      "0c637573746f6d2d76616c7565"  // Non-Huffman encoded value.
+      "2f0125a849e95ba97d7f"        // Huffman-encoded name.
+      "0c637573746f6d2d76616c7565"  // Non-Huffman encoded value.
+      "2703637573746f6d2d6b6579"    // Non-Huffman encoded name.
+      "8925a849e95bb8e8b4bf"));     // Huffman-encoded value.
+}
+
+TEST_P(QpackDecoderTest, HuffmanNameDoesNotHaveEOSPrefix) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Error in Huffman-encoded string.")));
+
+  // 'y' ends in 0b0 on the most significant bit of the last byte.
+  // The remaining 7 bits must be a prefix of EOS, which is all 1s.
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7e8925a849e95bb8e8b4bf"));
+}
+
+TEST_P(QpackDecoderTest, HuffmanValueDoesNotHaveEOSPrefix) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Error in Huffman-encoded string.")));
+
+  // 'e' ends in 0b101, taking up the 3 most significant bits of the last byte.
+  // The remaining 5 bits must be a prefix of EOS, which is all 1s.
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4be"));
+}
+
+TEST_P(QpackDecoderTest, HuffmanNameEOSPrefixTooLong) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Error in Huffman-encoded string.")));
+
+  // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
+  // with value 0xff is invalid, even though 0b111111111111111 (15 bits) is a
+  // prefix of EOS.
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0225a849e95ba97d7fff8925a849e95bb8e8b4bf"));
+}
+
+TEST_P(QpackDecoderTest, HuffmanValueEOSPrefixTooLong) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Error in Huffman-encoded string.")));
+
+  // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
+  // with value 0xff is invalid, even though 0b1111111111111 (13 bits) is a
+  // prefix of EOS.
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7f8a25a849e95bb8e8b4bfff"));
+}
+
+TEST_P(QpackDecoderTest, StaticTable) {
+  // A header name that has multiple entries with different values.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("POST")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("TRACE")));
+
+  // A header name that has a single entry with non-empty value.
+  EXPECT_CALL(handler_,
+              OnHeaderDecoded(Eq("accept-encoding"), Eq("gzip, deflate, br")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("compress")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("")));
+
+  // A header name that has a single entry with empty value.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("foo")));
+
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0000d1dfccd45f108621e9aec2a11f5c8294e75f000554524143455f1000"));
+}
+
+TEST_P(QpackDecoderTest, TooHighStaticTableIndex) {
+  // This is the last entry in the static table with index 98.
+  EXPECT_CALL(handler_,
+              OnHeaderDecoded(Eq("x-frame-options"), Eq("sameorigin")));
+
+  // Addressing entry 99 should trigger an error.
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Static table entry not found.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("0000ff23ff24"));
+}
+
+TEST_P(QpackDecoderTest, DynamicTable) {
+  DecodeEncoderStreamData(absl::HexStringToBytes(
+      "3fe107"          // Set dynamic table capacity to 1024.
+      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
+      "80035a5a5a"      // Add entry with name of dynamic table entry index 0
+                        // (relative index) and value "ZZZ".
+      "cf8294e7"        // Add entry with name of static table entry index 15
+                        // and value "foo".
+      "01"));           // Duplicate entry with relative index 1.
+
+  // Now there are four entries in the dynamic table.
+  // Entry 0: "foo", "bar"
+  // Entry 1: "foo", "ZZZ"
+  // Entry 2: ":method", "foo"
+  // Entry 3: "foo", "ZZZ"
+
+  // Use a Sequence to test that mock methods are called in order.
+  Sequence s;
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0500"  // Required Insert Count 4 and Delta Base 0.
+              // Base is 4 + 0 = 4.
+      "83"    // Dynamic table entry with relative index 3, absolute index 0.
+      "82"    // Dynamic table entry with relative index 2, absolute index 1.
+      "81"    // Dynamic table entry with relative index 1, absolute index 2.
+      "80"    // Dynamic table entry with relative index 0, absolute index 3.
+      "41025a5a"));  // Name of entry 1 (relative index) from dynamic table,
+                     // with value "ZZ".
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0502"  // Required Insert Count 4 and Delta Base 2.
+              // Base is 4 + 2 = 6.
+      "85"    // Dynamic table entry with relative index 5, absolute index 0.
+      "84"    // Dynamic table entry with relative index 4, absolute index 1.
+      "83"    // Dynamic table entry with relative index 3, absolute index 2.
+      "82"    // Dynamic table entry with relative index 2, absolute index 3.
+      "43025a5a"));  // Name of entry 3 (relative index) from dynamic table,
+                     // with value "ZZ".
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0582"  // Required Insert Count 4 and Delta Base 2 with sign bit set.
+              // Base is 4 - 2 - 1 = 1.
+      "80"    // Dynamic table entry with relative index 0, absolute index 0.
+      "10"    // Dynamic table entry with post-base index 0, absolute index 1.
+      "11"    // Dynamic table entry with post-base index 1, absolute index 2.
+      "12"    // Dynamic table entry with post-base index 2, absolute index 3.
+      "01025a5a"));  // Name of entry 1 (post-base index) from dynamic table,
+                     // with value "ZZ".
+}
+
+TEST_P(QpackDecoderTest, DecreasingDynamicTableCapacityEvictsEntries) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"));  // Dynamic table entry with relative index 0, absolute index 0.
+
+  // Change dynamic table capacity to 32 bytes, smaller than the entry.
+  // This must cause the entry to be evicted.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f01"));
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"));  // Dynamic table entry with relative index 0, absolute index 0.
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorEntryTooLarge) {
+  EXPECT_CALL(
+      encoder_stream_error_delegate_,
+      OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL,
+                           Eq("Error inserting literal entry.")));
+
+  // Set dynamic table capacity to 34.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f03"));
+  // Add literal entry with name "foo" and value "bar", size is 32 + 3 + 3 = 38.
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidStaticTableEntry) {
+  EXPECT_CALL(
+      encoder_stream_error_delegate_,
+      OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY,
+                           Eq("Invalid static table entry.")));
+
+  // Address invalid static table entry index 99.
+  DecodeEncoderStreamData(absl::HexStringToBytes("ff2400"));
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidDynamicTableEntry) {
+  EXPECT_CALL(encoder_stream_error_delegate_,
+              OnEncoderStreamError(
+                  QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX,
+                  Eq("Invalid relative index.")));
+
+  DecodeEncoderStreamData(absl::HexStringToBytes(
+      "3fe107"          // Set dynamic table capacity to 1024.
+      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
+      "8100"));  // Address dynamic table entry with relative index 1.  Such
+                 // entry does not exist.  The most recently added and only
+                 // dynamic table entry has relative index 0.
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorDuplicateInvalidEntry) {
+  EXPECT_CALL(encoder_stream_error_delegate_,
+              OnEncoderStreamError(
+                  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
+                  Eq("Invalid relative index.")));
+
+  DecodeEncoderStreamData(absl::HexStringToBytes(
+      "3fe107"          // Set dynamic table capacity to 1024.
+      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
+      "01"));  // Duplicate dynamic table entry with relative index 1.  Such
+               // entry does not exist.  The most recently added and only
+               // dynamic table entry has relative index 0.
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorTooLargeInteger) {
+  EXPECT_CALL(encoder_stream_error_delegate_,
+              OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                                   Eq("Encoded integer too large.")));
+
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fffffffffffffffffffff"));
+}
+
+TEST_P(QpackDecoderTest, InvalidDynamicEntryWhenBaseIsZero) {
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Invalid relative index.")));
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0280"   // Required Insert Count is 1.  Base 1 - 1 - 0 = 0 is explicitly
+               // permitted by the spec.
+      "80"));  // However, addressing entry with relative index 0 would point to
+               // absolute index -1, which is invalid.
+}
+
+TEST_P(QpackDecoderTest, InvalidNegativeBase) {
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Error calculating Base.")));
+
+  // Required Insert Count 1, Delta Base 1 with sign bit set, Base would
+  // be 1 - 1 - 1 = -1, but it is not allowed to be negative.
+  DecodeHeaderBlock(absl::HexStringToBytes("0281"));
+}
+
+TEST_P(QpackDecoderTest, InvalidDynamicEntryByRelativeIndex) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Invalid relative index.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "81"));  // Indexed Header Field instruction addressing relative index 1.
+               // This is absolute index -1, which is invalid.
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Invalid relative index.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"     // Required Insert Count 1 and Delta Base 0.
+                 // Base is 1 + 0 = 1.
+      "4100"));  // Literal Header Field with Name Reference instruction
+                 // addressing relative index 1.  This is absolute index -1,
+                 // which is invalid.
+}
+
+TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) {
+  // Update dynamic table capacity to 128.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
+
+  // Add literal entry with name "foo" and value "bar", size 32 + 3 + 3 = 38.
+  // This fits in the table three times.
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+  // Duplicate entry four times.  This evicts the first two instances.
+  DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0500"   // Required Insert Count 4 and Delta Base 0.
+               // Base is 4 + 0 = 4.
+      "82"));  // Indexed Header Field instruction addressing relative index 2.
+               // This is absolute index 1. Such entry does not exist.
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0500"     // Required Insert Count 4 and Delta Base 0.
+                 // Base is 4 + 0 = 4.
+      "4200"));  // Literal Header Field with Name Reference instruction
+                 // addressing relative index 2.  This is absolute index 1. Such
+                 // entry does not exist.
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0380"   // Required Insert Count 2 and Delta Base 0 with sign bit set.
+               // Base is 2 - 0 - 1 = 1
+      "10"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with post-base index 0, absolute index 1.  Such entry
+               // does not exist.
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0380"     // Required Insert Count 2 and Delta Base 0 with sign bit set.
+                 // Base is 2 - 0 - 1 = 1
+      "0000"));  // Literal Header Field With Name Reference instruction
+                 // addressing dynamic table entry with post-base index 0,
+                 // absolute index 1.  Such entry does not exist.
+}
+
+TEST_P(QpackDecoderTest, TableCapacityMustNotExceedMaximum) {
+  EXPECT_CALL(
+      encoder_stream_error_delegate_,
+      OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY,
+                           Eq("Error updating dynamic table capacity.")));
+
+  // Try to update dynamic table capacity to 2048, which exceeds the maximum.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe10f"));
+}
+
+TEST_P(QpackDecoderTest, SetDynamicTableCapacity) {
+  // Update dynamic table capacity to 128, which does not exceed the maximum.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
+}
+
+TEST_P(QpackDecoderTest, InvalidEncodedRequiredInsertCount) {
+  // Maximum dynamic table capacity is 1024.
+  // MaxEntries is 1024 / 32 = 32.
+  // Required Insert Count is decoded modulo 2 * MaxEntries, that is, modulo 64.
+  // A value of 1 cannot be encoded as 65 even though it has the same remainder.
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Error decoding Required Insert Count.")));
+  DecodeHeaderBlock(absl::HexStringToBytes("4100"));
+}
+
+// Regression test for https://crbug.com/970218:  Decoder must stop processing
+// after a Header Block Prefix with an invalid Encoded Required Insert Count.
+TEST_P(QpackDecoderTest, DataAfterInvalidEncodedRequiredInsertCount) {
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Error decoding Required Insert Count.")));
+  // Header Block Prefix followed by some extra data.
+  DecodeHeaderBlock(absl::HexStringToBytes("410000"));
+}
+
+TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) {
+  // Maximum dynamic table capacity is 1024.
+  // MaxEntries is 1024 / 32 = 32.
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and a 600 byte long value.  This will fit
+  // in the dynamic table once but not twice.
+  DecodeEncoderStreamData(
+      absl::HexStringToBytes("6294e7"     // Name "foo".
+                             "7fd903"));  // Value length 600.
+  std::string header_value(600, 'Z');
+  DecodeEncoderStreamData(header_value);
+
+  // Duplicate most recent entry 200 times.
+  DecodeEncoderStreamData(std::string(200, '\x00'));
+
+  // Now there is only one entry in the dynamic table, with absolute index 200.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq(header_value)));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  // Send header block with Required Insert Count = 201.
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0a00"   // Encoded Required Insert Count 10, Required Insert Count 201,
+               // Delta Base 0, Base 201.
+      "80"));  // Emit dynamic table entry with relative index 0.
+}
+
+TEST_P(QpackDecoderTest, NonZeroRequiredInsertCountButNoDynamicEntries) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count is 1.
+      "d1"));  // But the only instruction references the static table.
+}
+
+TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  EXPECT_CALL(
+      handler_,
+      OnDecodingErrorDetected(
+          QUIC_QPACK_DECOMPRESSION_FAILED,
+          Eq("Absolute Index must be smaller than Required Insert Count.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0201"   // Required Insert Count 1 and Delta Base 1.
+               // Base is 1 + 1 = 2.
+      "80"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 1.  This is not
+               // allowed by Required Insert Count.
+
+  EXPECT_CALL(
+      handler_,
+      OnDecodingErrorDetected(
+          QUIC_QPACK_DECOMPRESSION_FAILED,
+          Eq("Absolute Index must be smaller than Required Insert Count.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0201"     // Required Insert Count 1 and Delta Base 1.
+                 // Base is 1 + 1 = 2.
+      "4000"));  // Literal Header Field with Name Reference instruction
+                 // addressing dynamic table entry with relative index 0,
+                 // absolute index 1.  This is not allowed by Required Index
+                 // Count.
+
+  EXPECT_CALL(
+      handler_,
+      OnDecodingErrorDetected(
+          QUIC_QPACK_DECOMPRESSION_FAILED,
+          Eq("Absolute Index must be smaller than Required Insert Count.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "10"));  // Indexed Header Field with Post-Base Index instruction
+               // addressing dynamic table entry with post-base index 0,
+               // absolute index 1.  This is not allowed by Required Insert
+               // Count.
+
+  EXPECT_CALL(
+      handler_,
+      OnDecodingErrorDetected(
+          QUIC_QPACK_DECOMPRESSION_FAILED,
+          Eq("Absolute Index must be smaller than Required Insert Count.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"     // Required Insert Count 1 and Delta Base 0.
+                 // Base is 1 + 0 = 1.
+      "0000"));  // Literal Header Field with Post-Base Name Reference
+                 // instruction addressing dynamic table entry with post-base
+                 // index 0, absolute index 1.  This is not allowed by Required
+                 // Index Count.
+}
+
+TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+  // Duplicate entry twice so that decoding of header blocks with Required
+  // Insert Count not exceeding 3 is not blocked.
+  DecodeEncoderStreamData(absl::HexStringToBytes("00"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("00"));
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0300"   // Required Insert Count 2 and Delta Base 0.
+               // Base is 2 + 0 = 2.
+      "81"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 1, absolute index 0.  Header block
+               // requires insert count of 1, even though Required Insert Count
+               // is 2.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0300"     // Required Insert Count 2 and Delta Base 0.
+                 // Base is 2 + 0 = 2.
+      "4100"));  // Literal Header Field with Name Reference instruction
+                 // addressing dynamic table entry with relative index 1,
+                 // absolute index 0.  Header block requires insert count of 1,
+                 // even though Required Insert Count is 2.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0481"   // Required Insert Count 3 and Delta Base 1 with sign bit set.
+               // Base is 3 - 1 - 1 = 1.
+      "10"));  // Indexed Header Field with Post-Base Index instruction
+               // addressing dynamic table entry with post-base index 0,
+               // absolute index 1.  Header block requires insert count of 2,
+               // even though Required Insert Count is 3.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0481"     // Required Insert Count 3 and Delta Base 1 with sign bit set.
+                 // Base is 3 - 1 - 1 = 1.
+      "0000"));  // Literal Header Field with Post-Base Name Reference
+                 // instruction addressing dynamic table entry with post-base
+                 // index 0, absolute index 1.  Header block requires insert
+                 // count of 2, even though Required Insert Count is 3.
+}
+
+TEST_P(QpackDecoderTest, BlockedDecoding) {
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 0.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+}
+
+TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
+  StartDecoding();
+  DecodeData(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"     // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 0.
+      "d1"));  // Static table entry with index 17.
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+
+  // Add literal entry with name "foo" and value "bar".  Decoding is now
+  // unblocked because dynamic table Insert Count reached the Required Insert
+  // Count of the header block.  |handler_| methods are called immediately for
+  // the already consumed part of the header block.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+  Mock::VerifyAndClearExpectations(&handler_);
+
+  // Rest of header block is processed by QpackProgressiveDecoder
+  // in the unblocked state.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":scheme"), Eq("https")));
+  DecodeData(absl::HexStringToBytes(
+      "80"     // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 0.
+      "d7"));  // Static table entry with index 23.
+  Mock::VerifyAndClearExpectations(&handler_);
+
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+  EndDecoding();
+}
+
+// Regression test for https://crbug.com/1024263.
+TEST_P(QpackDecoderTest,
+       BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
+  StartDecoding();
+  DecodeData(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"     // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 0.
+      "81"));  // Relative index 1 is equal to Base, therefore invalid.
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+
+  // Add literal entry with name "foo" and value "bar".  Decoding is now
+  // unblocked because dynamic table Insert Count reached the Required Insert
+  // Count of the header block.  |handler_| methods are called immediately for
+  // the already consumed part of the header block.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Invalid relative index.")));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+}
+
+// Make sure that Required Insert Count is compared to Insert Count,
+// not size of dynamic table.
+TEST_P(QpackDecoderTest, BlockedDecodingAndEvictedEntries) {
+  // Update dynamic table capacity to 128.
+  // At most three non-empty entries fit in the dynamic table.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0700"   // Required Insert Count 6 and Delta Base 0.
+               // Base is 6 + 0 = 6.
+      "80"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 5.
+
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  // Duplicate entry four times.  This evicts the first two instances.
+  DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("baz")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  // Add literal entry with name "foo" and value "bar".
+  // Insert Count is now 6, reaching Required Insert Count of the header block.
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e70362617a"));
+}
+
+TEST_P(QpackDecoderTest, TooManyBlockedStreams) {
+  // Required Insert Count 1 and Delta Base 0.
+  // Without any dynamic table entries received, decoding is blocked.
+  std::string data = absl::HexStringToBytes("0200");
+
+  auto progressive_decoder1 = CreateProgressiveDecoder(/* stream_id = */ 1);
+  progressive_decoder1->Decode(data);
+
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(
+                  QUIC_QPACK_DECOMPRESSION_FAILED,
+                  Eq("Limit on number of blocked streams exceeded.")));
+
+  auto progressive_decoder2 = CreateProgressiveDecoder(/* stream_id = */ 2);
+  progressive_decoder2->Decode(data);
+}
+
+TEST_P(QpackDecoderTest, InsertCountIncrement) {
+  DecodeEncoderStreamData(absl::HexStringToBytes(
+      "3fe107"          // Set dynamic table capacity to 1024.
+      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
+      "00"));           // Duplicate entry.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  // Decoder received two insertions, but Header Acknowledgement only increases
+  // Known Insert Count to one.  Decoder should send an Insert Count Increment
+  // instruction with increment of one to update Known Insert Count to two.
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(absl::HexStringToBytes(
+                  "81"       // Header Acknowledgement on stream 1
+                  "01"))));  // Insert Count Increment with increment of one
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"));  // Dynamic table entry with relative index 0, absolute index 0.
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder.cc b/quiche/quic/core/qpack/qpack_encoder.cc
new file mode 100644
index 0000000..db3f803
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder.cc
@@ -0,0 +1,461 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_encoder.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_index_conversions.h"
+#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+#include "quiche/quic/core/qpack/qpack_required_insert_count.h"
+#include "quiche/quic/core/qpack/value_splitting_header_list.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Fraction to calculate draining index.  The oldest |kDrainingFraction| entries
+// will not be referenced in header blocks.  A new entry (duplicate or literal
+// with name reference) will be added to the dynamic table instead.  This allows
+// the number of references to the draining entry to go to zero faster, so that
+// it can be evicted.  See
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#avoiding-blocked-insertions.
+// TODO(bnc): Fine tune.
+const float kDrainingFraction = 0.25;
+
+}  // anonymous namespace
+
+QpackEncoder::QpackEncoder(
+    DecoderStreamErrorDelegate* decoder_stream_error_delegate)
+    : decoder_stream_error_delegate_(decoder_stream_error_delegate),
+      decoder_stream_receiver_(this),
+      maximum_blocked_streams_(0),
+      header_list_count_(0) {
+  QUICHE_DCHECK(decoder_stream_error_delegate_);
+}
+
+QpackEncoder::~QpackEncoder() {}
+
+// static
+QpackEncoder::Representation QpackEncoder::EncodeIndexedHeaderField(
+    bool is_static,
+    uint64_t index,
+    QpackBlockingManager::IndexSet* referred_indices) {
+  // Add |index| to |*referred_indices| only if entry is in the dynamic table.
+  if (!is_static) {
+    referred_indices->insert(index);
+  }
+  return Representation::IndexedHeaderField(is_static, index);
+}
+
+// static
+QpackEncoder::Representation
+QpackEncoder::EncodeLiteralHeaderFieldWithNameReference(
+    bool is_static,
+    uint64_t index,
+    absl::string_view value,
+    QpackBlockingManager::IndexSet* referred_indices) {
+  // Add |index| to |*referred_indices| only if entry is in the dynamic table.
+  if (!is_static) {
+    referred_indices->insert(index);
+  }
+  return Representation::LiteralHeaderFieldNameReference(is_static, index,
+                                                         value);
+}
+
+// static
+QpackEncoder::Representation QpackEncoder::EncodeLiteralHeaderField(
+    absl::string_view name,
+    absl::string_view value) {
+  return Representation::LiteralHeaderField(name, value);
+}
+
+QpackEncoder::Representations QpackEncoder::FirstPassEncode(
+    QuicStreamId stream_id,
+    const spdy::Http2HeaderBlock& header_list,
+    QpackBlockingManager::IndexSet* referred_indices,
+    QuicByteCount* encoder_stream_sent_byte_count) {
+  // If previous instructions are buffered in |encoder_stream_sender_|,
+  // do not count them towards the current header block.
+  const QuicByteCount initial_encoder_stream_buffered_byte_count =
+      encoder_stream_sender_.BufferedByteCount();
+
+  const bool can_write_to_encoder_stream = encoder_stream_sender_.CanWrite();
+
+  Representations representations;
+  representations.reserve(header_list.size());
+
+  // The index of the oldest entry that must not be evicted.
+  uint64_t smallest_blocking_index =
+      blocking_manager_.smallest_blocking_index();
+  // Entries with index larger than or equal to |known_received_count| are
+  // blocking.
+  const uint64_t known_received_count =
+      blocking_manager_.known_received_count();
+  // Only entries with index greater than or equal to |draining_index| are
+  // allowed to be referenced.
+  const uint64_t draining_index =
+      header_table_.draining_index(kDrainingFraction);
+  // Blocking references are allowed if the number of blocked streams is less
+  // than the limit.
+  const bool blocking_allowed = blocking_manager_.blocking_allowed_on_stream(
+      stream_id, maximum_blocked_streams_);
+
+  // Track events for histograms.
+  bool dynamic_table_insertion_blocked = false;
+  bool blocked_stream_limit_exhausted = false;
+
+  for (const auto& header : ValueSplittingHeaderList(&header_list)) {
+    // These strings are owned by |header_list|.
+    absl::string_view name = header.first;
+    absl::string_view value = header.second;
+
+    bool is_static;
+    uint64_t index;
+
+    auto match_type =
+        header_table_.FindHeaderField(name, value, &is_static, &index);
+
+    switch (match_type) {
+      case QpackEncoderHeaderTable::MatchType::kNameAndValue:
+        if (is_static) {
+          // Refer to entry directly.
+          representations.push_back(
+              EncodeIndexedHeaderField(is_static, index, referred_indices));
+
+          break;
+        }
+
+        if (index >= draining_index) {
+          // If allowed, refer to entry directly.
+          if (!blocking_allowed && index >= known_received_count) {
+            blocked_stream_limit_exhausted = true;
+          } else {
+            representations.push_back(
+                EncodeIndexedHeaderField(is_static, index, referred_indices));
+            smallest_blocking_index = std::min(smallest_blocking_index, index);
+            header_table_.set_dynamic_table_entry_referenced();
+
+            break;
+          }
+        } else {
+          // Entry is draining, needs to be duplicated.
+          if (!blocking_allowed) {
+            blocked_stream_limit_exhausted = true;
+          } else if (QpackEntry::Size(name, value) >
+                     header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
+                         std::min(smallest_blocking_index, index))) {
+            dynamic_table_insertion_blocked = true;
+          } else {
+            if (can_write_to_encoder_stream) {
+              // If allowed, duplicate entry and refer to it.
+              encoder_stream_sender_.SendDuplicate(
+                  QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+                      index, header_table_.inserted_entry_count()));
+              uint64_t new_index = header_table_.InsertEntry(name, value);
+              representations.push_back(EncodeIndexedHeaderField(
+                  is_static, new_index, referred_indices));
+              smallest_blocking_index =
+                  std::min(smallest_blocking_index, index);
+              header_table_.set_dynamic_table_entry_referenced();
+
+              break;
+            }
+          }
+        }
+
+        // Encode entry as string literals.
+        // TODO(b/112770235): Use already acknowledged entry with lower index if
+        // exists.
+        // TODO(b/112770235): Use static entry name with literal value if
+        // dynamic entry exists but cannot be used.
+        representations.push_back(EncodeLiteralHeaderField(name, value));
+
+        break;
+
+      case QpackEncoderHeaderTable::MatchType::kName:
+        if (is_static) {
+          if (blocking_allowed &&
+              QpackEntry::Size(name, value) <=
+                  header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
+                      smallest_blocking_index)) {
+            // If allowed, insert entry into dynamic table and refer to it.
+            if (can_write_to_encoder_stream) {
+              encoder_stream_sender_.SendInsertWithNameReference(is_static,
+                                                                 index, value);
+              uint64_t new_index = header_table_.InsertEntry(name, value);
+              representations.push_back(EncodeIndexedHeaderField(
+                  /* is_static = */ false, new_index, referred_indices));
+              smallest_blocking_index =
+                  std::min<uint64_t>(smallest_blocking_index, new_index);
+
+              break;
+            }
+          }
+
+          // Emit literal field with name reference.
+          representations.push_back(EncodeLiteralHeaderFieldWithNameReference(
+              is_static, index, value, referred_indices));
+
+          break;
+        }
+
+        if (!blocking_allowed) {
+          blocked_stream_limit_exhausted = true;
+        } else if (QpackEntry::Size(name, value) >
+                   header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
+                       std::min(smallest_blocking_index, index))) {
+          dynamic_table_insertion_blocked = true;
+        } else {
+          // If allowed, insert entry with name reference and refer to it.
+          if (can_write_to_encoder_stream) {
+            encoder_stream_sender_.SendInsertWithNameReference(
+                is_static,
+                QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+                    index, header_table_.inserted_entry_count()),
+                value);
+            uint64_t new_index = header_table_.InsertEntry(name, value);
+            representations.push_back(EncodeIndexedHeaderField(
+                is_static, new_index, referred_indices));
+            smallest_blocking_index = std::min(smallest_blocking_index, index);
+            header_table_.set_dynamic_table_entry_referenced();
+
+            break;
+          }
+        }
+
+        if ((blocking_allowed || index < known_received_count) &&
+            index >= draining_index) {
+          // If allowed, refer to entry name directly, with literal value.
+          representations.push_back(EncodeLiteralHeaderFieldWithNameReference(
+              is_static, index, value, referred_indices));
+          smallest_blocking_index = std::min(smallest_blocking_index, index);
+          header_table_.set_dynamic_table_entry_referenced();
+
+          break;
+        }
+
+        // Encode entry as string literals.
+        // TODO(b/112770235): Use already acknowledged entry with lower index if
+        // exists.
+        // TODO(b/112770235): Use static entry name with literal value if
+        // dynamic entry exists but cannot be used.
+        representations.push_back(EncodeLiteralHeaderField(name, value));
+
+        break;
+
+      case QpackEncoderHeaderTable::MatchType::kNoMatch:
+        // If allowed, insert entry and refer to it.
+        if (!blocking_allowed) {
+          blocked_stream_limit_exhausted = true;
+        } else if (QpackEntry::Size(name, value) >
+                   header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
+                       smallest_blocking_index)) {
+          dynamic_table_insertion_blocked = true;
+        } else {
+          if (can_write_to_encoder_stream) {
+            encoder_stream_sender_.SendInsertWithoutNameReference(name, value);
+            uint64_t new_index = header_table_.InsertEntry(name, value);
+            representations.push_back(EncodeIndexedHeaderField(
+                /* is_static = */ false, new_index, referred_indices));
+            smallest_blocking_index =
+                std::min<uint64_t>(smallest_blocking_index, new_index);
+
+            break;
+          }
+        }
+
+        // Encode entry as string literals.
+        // TODO(b/112770235): Consider also adding to dynamic table to improve
+        // compression ratio for subsequent header blocks with peers that do not
+        // allow any blocked streams.
+        representations.push_back(EncodeLiteralHeaderField(name, value));
+
+        break;
+    }
+  }
+
+  const QuicByteCount encoder_stream_buffered_byte_count =
+      encoder_stream_sender_.BufferedByteCount();
+  QUICHE_DCHECK_GE(encoder_stream_buffered_byte_count,
+                   initial_encoder_stream_buffered_byte_count);
+
+  if (encoder_stream_sent_byte_count) {
+    *encoder_stream_sent_byte_count =
+        encoder_stream_buffered_byte_count -
+        initial_encoder_stream_buffered_byte_count;
+  }
+  if (can_write_to_encoder_stream) {
+    encoder_stream_sender_.Flush();
+  } else {
+    QUICHE_DCHECK_EQ(encoder_stream_buffered_byte_count,
+                     initial_encoder_stream_buffered_byte_count);
+  }
+
+  ++header_list_count_;
+
+  if (dynamic_table_insertion_blocked) {
+    QUIC_HISTOGRAM_COUNTS(
+        "QuicSession.Qpack.HeaderListCountWhenInsertionBlocked",
+        header_list_count_, /* min = */ 1, /* max = */ 1000,
+        /* bucket_count = */ 50,
+        "The ordinality of a header list within a connection during the "
+        "encoding of which at least one dynamic table insertion was "
+        "blocked.");
+  } else {
+    QUIC_HISTOGRAM_COUNTS(
+        "QuicSession.Qpack.HeaderListCountWhenInsertionNotBlocked",
+        header_list_count_, /* min = */ 1, /* max = */ 1000,
+        /* bucket_count = */ 50,
+        "The ordinality of a header list within a connection during the "
+        "encoding of which no dynamic table insertion was blocked.");
+  }
+
+  if (blocked_stream_limit_exhausted) {
+    QUIC_HISTOGRAM_COUNTS(
+        "QuicSession.Qpack.HeaderListCountWhenBlockedStreamLimited",
+        header_list_count_, /* min = */ 1, /* max = */ 1000,
+        /* bucket_count = */ 50,
+        "The ordinality of a header list within a connection during the "
+        "encoding of which unacknowledged dynamic table entries could not be "
+        "referenced due to the limit on the number of blocked streams.");
+  } else {
+    QUIC_HISTOGRAM_COUNTS(
+        "QuicSession.Qpack.HeaderListCountWhenNotBlockedStreamLimited",
+        header_list_count_, /* min = */ 1, /* max = */ 1000,
+        /* bucket_count = */ 50,
+        "The ordinality of a header list within a connection during the "
+        "encoding of which the limit on the number of blocked streams did "
+        "not "
+        "prevent referencing unacknowledged dynamic table entries.");
+  }
+
+  return representations;
+}
+
+std::string QpackEncoder::SecondPassEncode(
+    QpackEncoder::Representations representations,
+    uint64_t required_insert_count) const {
+  QpackInstructionEncoder instruction_encoder;
+  std::string encoded_headers;
+
+  // Header block prefix.
+  instruction_encoder.Encode(
+      Representation::Prefix(QpackEncodeRequiredInsertCount(
+          required_insert_count, header_table_.max_entries())),
+      &encoded_headers);
+
+  const uint64_t base = required_insert_count;
+
+  for (auto& representation : representations) {
+    // Dynamic table references must be transformed from absolute to relative
+    // indices.
+    if ((representation.instruction() == QpackIndexedHeaderFieldInstruction() ||
+         representation.instruction() ==
+             QpackLiteralHeaderFieldNameReferenceInstruction()) &&
+        !representation.s_bit()) {
+      representation.set_varint(QpackAbsoluteIndexToRequestStreamRelativeIndex(
+          representation.varint(), base));
+    }
+    instruction_encoder.Encode(representation, &encoded_headers);
+  }
+
+  return encoded_headers;
+}
+
+std::string QpackEncoder::EncodeHeaderList(
+    QuicStreamId stream_id,
+    const spdy::Http2HeaderBlock& header_list,
+    QuicByteCount* encoder_stream_sent_byte_count) {
+  // Keep track of all dynamic table indices that this header block refers to so
+  // that it can be passed to QpackBlockingManager.
+  QpackBlockingManager::IndexSet referred_indices;
+
+  // First pass: encode into |representations|.
+  Representations representations =
+      FirstPassEncode(stream_id, header_list, &referred_indices,
+                      encoder_stream_sent_byte_count);
+
+  const uint64_t required_insert_count =
+      referred_indices.empty()
+          ? 0
+          : QpackBlockingManager::RequiredInsertCount(referred_indices);
+  if (!referred_indices.empty()) {
+    blocking_manager_.OnHeaderBlockSent(stream_id, std::move(referred_indices));
+  }
+
+  // Second pass.
+  return SecondPassEncode(std::move(representations), required_insert_count);
+}
+
+bool QpackEncoder::SetMaximumDynamicTableCapacity(
+    uint64_t maximum_dynamic_table_capacity) {
+  return header_table_.SetMaximumDynamicTableCapacity(
+      maximum_dynamic_table_capacity);
+}
+
+void QpackEncoder::SetDynamicTableCapacity(uint64_t dynamic_table_capacity) {
+  encoder_stream_sender_.SendSetDynamicTableCapacity(dynamic_table_capacity);
+  // Do not flush encoder stream.  This write can safely be delayed until more
+  // instructions are written.
+
+  bool success = header_table_.SetDynamicTableCapacity(dynamic_table_capacity);
+  QUICHE_DCHECK(success);
+}
+
+bool QpackEncoder::SetMaximumBlockedStreams(uint64_t maximum_blocked_streams) {
+  if (maximum_blocked_streams < maximum_blocked_streams_) {
+    return false;
+  }
+  maximum_blocked_streams_ = maximum_blocked_streams;
+  return true;
+}
+
+void QpackEncoder::OnInsertCountIncrement(uint64_t increment) {
+  if (increment == 0) {
+    OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
+                    "Invalid increment value 0.");
+    return;
+  }
+
+  if (!blocking_manager_.OnInsertCountIncrement(increment)) {
+    OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW,
+                    "Insert Count Increment instruction causes overflow.");
+  }
+
+  if (blocking_manager_.known_received_count() >
+      header_table_.inserted_entry_count()) {
+    OnErrorDetected(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT,
+                    absl::StrCat("Increment value ", increment,
+                                 " raises known received count to ",
+                                 blocking_manager_.known_received_count(),
+                                 " exceeding inserted entry count ",
+                                 header_table_.inserted_entry_count()));
+  }
+}
+
+void QpackEncoder::OnHeaderAcknowledgement(QuicStreamId stream_id) {
+  if (!blocking_manager_.OnHeaderAcknowledgement(stream_id)) {
+    OnErrorDetected(
+        QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT,
+        absl::StrCat("Header Acknowledgement received for stream ", stream_id,
+                     " with no outstanding header blocks."));
+  }
+}
+
+void QpackEncoder::OnStreamCancellation(QuicStreamId stream_id) {
+  blocking_manager_.OnStreamCancellation(stream_id);
+}
+
+void QpackEncoder::OnErrorDetected(QuicErrorCode error_code,
+                                   absl::string_view error_message) {
+  decoder_stream_error_delegate_->OnDecoderStreamError(error_code,
+                                                       error_message);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder.h b/quiche/quic/core/qpack/qpack_encoder.h
new file mode 100644
index 0000000..fedf628
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder.h
@@ -0,0 +1,164 @@
+// Copyright (c) 2018 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_QPACK_QPACK_ENCODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_blocking_manager.h"
+#include "quiche/quic/core/qpack/qpack_decoder_stream_receiver.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+namespace test {
+
+class QpackEncoderPeer;
+
+}  // namespace test
+
+// QPACK encoder class.  Exactly one instance should exist per QUIC connection.
+class QUIC_EXPORT_PRIVATE QpackEncoder
+    : public QpackDecoderStreamReceiver::Delegate {
+ public:
+  // Interface for receiving notification that an error has occurred on the
+  // decoder stream.  This MUST be treated as a connection error of type
+  // HTTP_QPACK_DECODER_STREAM_ERROR.
+  class QUIC_EXPORT_PRIVATE DecoderStreamErrorDelegate {
+   public:
+    virtual ~DecoderStreamErrorDelegate() {}
+
+    virtual void OnDecoderStreamError(QuicErrorCode error_code,
+                                      absl::string_view error_message) = 0;
+  };
+
+  QpackEncoder(DecoderStreamErrorDelegate* decoder_stream_error_delegate);
+  ~QpackEncoder() override;
+
+  // Encode a header list.  If |encoder_stream_sent_byte_count| is not null,
+  // |*encoder_stream_sent_byte_count| will be set to the number of bytes sent
+  // on the encoder stream to insert dynamic table entries.
+  std::string EncodeHeaderList(QuicStreamId stream_id,
+                               const spdy::Http2HeaderBlock& header_list,
+                               QuicByteCount* encoder_stream_sent_byte_count);
+
+  // Set maximum dynamic table capacity to |maximum_dynamic_table_capacity|,
+  // measured in bytes.  Called when SETTINGS_QPACK_MAX_TABLE_CAPACITY is
+  // received.  Encoder needs to know this value so that it can calculate
+  // MaxEntries, used as a modulus to encode Required Insert Count.
+  // Returns true if |maximum_dynamic_table_capacity| is set for the first time
+  // or if it doesn't change current value. The setting is not changed when
+  // returning false.
+  bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
+
+  // Set dynamic table capacity to |dynamic_table_capacity|.
+  // |dynamic_table_capacity| must not exceed maximum dynamic table capacity.
+  // Also sends Set Dynamic Table Capacity instruction on encoder stream.
+  void SetDynamicTableCapacity(uint64_t dynamic_table_capacity);
+
+  // Set maximum number of blocked streams.
+  // Called when SETTINGS_QPACK_BLOCKED_STREAMS is received.
+  // Returns true if |maximum_blocked_streams| doesn't decrease current value.
+  // The setting is not changed when returning false.
+  bool SetMaximumBlockedStreams(uint64_t maximum_blocked_streams);
+
+  // QpackDecoderStreamReceiver::Delegate implementation
+  void OnInsertCountIncrement(uint64_t increment) override;
+  void OnHeaderAcknowledgement(QuicStreamId stream_id) override;
+  void OnStreamCancellation(QuicStreamId stream_id) override;
+  void OnErrorDetected(QuicErrorCode error_code,
+                       absl::string_view error_message) override;
+
+  // delegate must be set if dynamic table capacity is not zero.
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    encoder_stream_sender_.set_qpack_stream_sender_delegate(delegate);
+  }
+
+  QpackStreamReceiver* decoder_stream_receiver() {
+    return &decoder_stream_receiver_;
+  }
+
+  // True if any dynamic table entries have been referenced from a header block.
+  bool dynamic_table_entry_referenced() const {
+    return header_table_.dynamic_table_entry_referenced();
+  }
+
+  uint64_t maximum_blocked_streams() const { return maximum_blocked_streams_; }
+
+  uint64_t MaximumDynamicTableCapacity() const {
+    return header_table_.maximum_dynamic_table_capacity();
+  }
+
+ private:
+  friend class test::QpackEncoderPeer;
+
+  using Representation = QpackInstructionWithValues;
+  using Representations = std::vector<Representation>;
+
+  // Generate indexed header field representation
+  // and optionally update |*referred_indices|.
+  static Representation EncodeIndexedHeaderField(
+      bool is_static,
+      uint64_t index,
+      QpackBlockingManager::IndexSet* referred_indices);
+
+  // Generate literal header field with name reference representation
+  // and optionally update |*referred_indices|.
+  static Representation EncodeLiteralHeaderFieldWithNameReference(
+      bool is_static,
+      uint64_t index,
+      absl::string_view value,
+      QpackBlockingManager::IndexSet* referred_indices);
+
+  // Generate literal header field representation.
+  static Representation EncodeLiteralHeaderField(absl::string_view name,
+                                                 absl::string_view value);
+
+  // Performs first pass of two-pass encoding: represent each header field in
+  // |*header_list| as a reference to an existing entry, the name of an existing
+  // entry with a literal value, or a literal name and value pair.  Sends
+  // necessary instructions on the encoder stream coalesced in a single write.
+  // Records absolute indices of referred dynamic table entries in
+  // |*referred_indices|.  If |encoder_stream_sent_byte_count| is not null, then
+  // sets |*encoder_stream_sent_byte_count| to the number of bytes sent on the
+  // encoder stream to insert dynamic table entries.  Returns list of header
+  // field representations, with all dynamic table entries referred to with
+  // absolute indices.  Returned representation objects may have
+  // absl::string_views pointing to strings owned by |*header_list|.
+  Representations FirstPassEncode(
+      QuicStreamId stream_id,
+      const spdy::Http2HeaderBlock& header_list,
+      QpackBlockingManager::IndexSet* referred_indices,
+      QuicByteCount* encoder_stream_sent_byte_count);
+
+  // Performs second pass of two-pass encoding: serializes representations
+  // generated in first pass, transforming absolute indices of dynamic table
+  // entries to relative indices.
+  std::string SecondPassEncode(Representations representations,
+                               uint64_t required_insert_count) const;
+
+  DecoderStreamErrorDelegate* const decoder_stream_error_delegate_;
+  QpackDecoderStreamReceiver decoder_stream_receiver_;
+  QpackEncoderStreamSender encoder_stream_sender_;
+  QpackEncoderHeaderTable header_table_;
+  uint64_t maximum_blocked_streams_;
+  QpackBlockingManager blocking_manager_;
+  int header_list_count_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_receiver.cc b/quiche/quic/core/qpack/qpack_encoder_stream_receiver.cc
new file mode 100644
index 0000000..579efc2
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_receiver.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackEncoderStreamReceiver::QpackEncoderStreamReceiver(Delegate* delegate)
+    : instruction_decoder_(QpackEncoderStreamLanguage(), this),
+      delegate_(delegate),
+      error_detected_(false) {
+  QUICHE_DCHECK(delegate_);
+}
+
+void QpackEncoderStreamReceiver::Decode(absl::string_view data) {
+  if (data.empty() || error_detected_) {
+    return;
+  }
+
+  instruction_decoder_.Decode(data);
+}
+
+bool QpackEncoderStreamReceiver::OnInstructionDecoded(
+    const QpackInstruction* instruction) {
+  if (instruction == InsertWithNameReferenceInstruction()) {
+    delegate_->OnInsertWithNameReference(instruction_decoder_.s_bit(),
+                                         instruction_decoder_.varint(),
+                                         instruction_decoder_.value());
+    return true;
+  }
+
+  if (instruction == InsertWithoutNameReferenceInstruction()) {
+    delegate_->OnInsertWithoutNameReference(instruction_decoder_.name(),
+                                            instruction_decoder_.value());
+    return true;
+  }
+
+  if (instruction == DuplicateInstruction()) {
+    delegate_->OnDuplicate(instruction_decoder_.varint());
+    return true;
+  }
+
+  QUICHE_DCHECK_EQ(instruction, SetDynamicTableCapacityInstruction());
+  delegate_->OnSetDynamicTableCapacity(instruction_decoder_.varint());
+  return true;
+}
+
+void QpackEncoderStreamReceiver::OnInstructionDecodingError(
+    QpackInstructionDecoder::ErrorCode error_code,
+    absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+
+  error_detected_ = true;
+
+  QuicErrorCode quic_error_code;
+  switch (error_code) {
+    case QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE:
+      quic_error_code = QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE;
+      break;
+    case QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG:
+      quic_error_code = QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG;
+      break;
+    case QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR:
+      quic_error_code = QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR;
+      break;
+    default:
+      quic_error_code = QUIC_INTERNAL_ERROR;
+  }
+
+  delegate_->OnErrorDetected(quic_error_code, error_message);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_receiver.h b/quiche/quic/core/qpack/qpack_encoder_stream_receiver.h
new file mode 100644
index 0000000..879c1b4
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_receiver.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2018 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_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_receiver.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This class decodes data received on the encoder stream.
+class QUIC_EXPORT_PRIVATE QpackEncoderStreamReceiver
+    : public QpackInstructionDecoder::Delegate,
+      public QpackStreamReceiver {
+ public:
+  // An interface for handling instructions decoded from the encoder stream, see
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // 5.2.1. Insert With Name Reference
+    virtual void OnInsertWithNameReference(bool is_static,
+                                           uint64_t name_index,
+                                           absl::string_view value) = 0;
+    // 5.2.2. Insert Without Name Reference
+    virtual void OnInsertWithoutNameReference(absl::string_view name,
+                                              absl::string_view value) = 0;
+    // 5.2.3. Duplicate
+    virtual void OnDuplicate(uint64_t index) = 0;
+    // 5.2.4. Set Dynamic Table Capacity
+    virtual void OnSetDynamicTableCapacity(uint64_t capacity) = 0;
+    // Decoding error
+    virtual void OnErrorDetected(QuicErrorCode error_code,
+                                 absl::string_view error_message) = 0;
+  };
+
+  explicit QpackEncoderStreamReceiver(Delegate* delegate);
+  QpackEncoderStreamReceiver() = delete;
+  QpackEncoderStreamReceiver(const QpackEncoderStreamReceiver&) = delete;
+  QpackEncoderStreamReceiver& operator=(const QpackEncoderStreamReceiver&) =
+      delete;
+  ~QpackEncoderStreamReceiver() override = default;
+
+  // Implements QpackStreamReceiver::Decode().
+  // Decode data and call appropriate Delegate method after each decoded
+  // instruction.  Once an error occurs, Delegate::OnErrorDetected() is called,
+  // and all further data is ignored.
+  void Decode(absl::string_view data) override;
+
+  // QpackInstructionDecoder::Delegate implementation.
+  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
+  void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
+                                  absl::string_view error_message) override;
+
+ private:
+  QpackInstructionDecoder instruction_decoder_;
+  Delegate* const delegate_;
+
+  // True if a decoding error has been detected.
+  bool error_detected_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_receiver_test.cc b/quiche/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
new file mode 100644
index 0000000..77103df
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
@@ -0,0 +1,197 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using testing::Eq;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockDelegate : public QpackEncoderStreamReceiver::Delegate {
+ public:
+  ~MockDelegate() override = default;
+
+  MOCK_METHOD(void,
+              OnInsertWithNameReference,
+              (bool is_static, uint64_t name_index, absl::string_view value),
+              (override));
+  MOCK_METHOD(void,
+              OnInsertWithoutNameReference,
+              (absl::string_view name, absl::string_view value),
+              (override));
+  MOCK_METHOD(void, OnDuplicate, (uint64_t index), (override));
+  MOCK_METHOD(void, OnSetDynamicTableCapacity, (uint64_t capacity), (override));
+  MOCK_METHOD(void,
+              OnErrorDetected,
+              (QuicErrorCode error_code, absl::string_view error_message),
+              (override));
+};
+
+class QpackEncoderStreamReceiverTest : public QuicTest {
+ protected:
+  QpackEncoderStreamReceiverTest() : stream_(&delegate_) {}
+  ~QpackEncoderStreamReceiverTest() override = default;
+
+  void Decode(absl::string_view data) { stream_.Decode(data); }
+  StrictMock<MockDelegate>* delegate() { return &delegate_; }
+
+ private:
+  QpackEncoderStreamReceiver stream_;
+  StrictMock<MockDelegate> delegate_;
+};
+
+TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReference) {
+  // Static, index fits in prefix, empty value.
+  EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 5, Eq("")));
+  // Static, index fits in prefix, Huffman encoded value.
+  EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 2, Eq("foo")));
+  // Not static, index does not fit in prefix, not Huffman encoded value.
+  EXPECT_CALL(*delegate(), OnInsertWithNameReference(false, 137, Eq("bar")));
+  // Value length does not fit in prefix.
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  EXPECT_CALL(*delegate(),
+              OnInsertWithNameReference(false, 42, Eq(std::string(127, 'Z'))));
+
+  Decode(absl::HexStringToBytes(
+      "c500"
+      "c28294e7"
+      "bf4a03626172"
+      "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceIndexTooLarge) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("bfffffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceValueTooLong) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("c57fffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReference) {
+  // Empty name and value.
+  EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq(""), Eq("")));
+  // Huffman encoded short strings.
+  EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("bar"), Eq("bar")));
+  // Not Huffman encoded short strings.
+  EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("foo"), Eq("foo")));
+  // Not Huffman encoded long strings; length does not fit on prefix.
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  EXPECT_CALL(*delegate(),
+              OnInsertWithoutNameReference(Eq(std::string(31, 'Z')),
+                                           Eq(std::string(127, 'Z'))));
+
+  Decode(absl::HexStringToBytes(
+      "4000"
+      "4362617203626172"
+      "6294e78294e7"
+      "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f005a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
+}
+
+// Name Length value is too large for varint decoder to decode.
+TEST_F(QpackEncoderStreamReceiverTest,
+       InsertWithoutNameReferenceNameTooLongForVarintDecoder) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("5fffffffffffffffffffff"));
+}
+
+// Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
+TEST_F(QpackEncoderStreamReceiverTest,
+       InsertWithoutNameReferenceNameExceedsLimit) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
+                              Eq("String literal too long.")));
+
+  Decode(absl::HexStringToBytes("5fffff7f"));
+}
+
+// Value Length value is too large for varint decoder to decode.
+TEST_F(QpackEncoderStreamReceiverTest,
+       InsertWithoutNameReferenceValueTooLongForVarintDecoder) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("436261727fffffffffffffffffffff"));
+}
+
+// Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
+TEST_F(QpackEncoderStreamReceiverTest,
+       InsertWithoutNameReferenceValueExceedsLimit) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
+                              Eq("String literal too long.")));
+
+  Decode(absl::HexStringToBytes("436261727fffff7f"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, Duplicate) {
+  // Small index fits in prefix.
+  EXPECT_CALL(*delegate(), OnDuplicate(17));
+  // Large index requires two extension bytes.
+  EXPECT_CALL(*delegate(), OnDuplicate(500));
+
+  Decode(absl::HexStringToBytes("111fd503"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, DuplicateIndexTooLarge) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("1fffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacity) {
+  // Small capacity fits in prefix.
+  EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(17));
+  // Large capacity requires two extension bytes.
+  EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(500));
+
+  Decode(absl::HexStringToBytes("313fd503"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacityTooLarge) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, InvalidHuffmanEncoding) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR,
+                              Eq("Error in Huffman-encoded string.")));
+
+  Decode(absl::HexStringToBytes("c281ff"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_sender.cc b/quiche/quic/core/qpack/qpack_encoder_stream_sender.cc
new file mode 100644
index 0000000..e9e64b3
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_sender.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+
+#include <cstddef>
+#include <limits>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// If QUIC stream bufferes more that this number of bytes,
+// CanWrite() will return false.
+constexpr uint64_t kMaxBytesBufferedByStream = 64 * 1024;
+
+}  // anonymous namespace
+
+QpackEncoderStreamSender::QpackEncoderStreamSender() : delegate_(nullptr) {}
+
+void QpackEncoderStreamSender::SendInsertWithNameReference(
+    bool is_static,
+    uint64_t name_index,
+    absl::string_view value) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::InsertWithNameReference(is_static, name_index,
+                                                          value),
+      &buffer_);
+}
+
+void QpackEncoderStreamSender::SendInsertWithoutNameReference(
+    absl::string_view name,
+    absl::string_view value) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::InsertWithoutNameReference(name, value),
+      &buffer_);
+}
+
+void QpackEncoderStreamSender::SendDuplicate(uint64_t index) {
+  instruction_encoder_.Encode(QpackInstructionWithValues::Duplicate(index),
+                              &buffer_);
+}
+
+void QpackEncoderStreamSender::SendSetDynamicTableCapacity(uint64_t capacity) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::SetDynamicTableCapacity(capacity), &buffer_);
+}
+
+bool QpackEncoderStreamSender::CanWrite() const {
+  return delegate_ && delegate_->NumBytesBuffered() + buffer_.size() <=
+                          kMaxBytesBufferedByStream;
+}
+
+void QpackEncoderStreamSender::Flush() {
+  if (buffer_.empty()) {
+    return;
+  }
+
+  delegate_->WriteStreamData(buffer_);
+  buffer_.clear();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_sender.h b/quiche/quic/core/qpack/qpack_encoder_stream_sender.h
new file mode 100644
index 0000000..8ad5a13
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_sender.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2018 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_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This class serializes instructions for transmission on the encoder stream.
+// Serialized instructions are buffered until Flush() is called.
+class QUIC_EXPORT_PRIVATE QpackEncoderStreamSender {
+ public:
+  QpackEncoderStreamSender();
+  QpackEncoderStreamSender(const QpackEncoderStreamSender&) = delete;
+  QpackEncoderStreamSender& operator=(const QpackEncoderStreamSender&) = delete;
+
+  // Methods for serializing and buffering instructions, see
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
+
+  // 5.2.1. Insert With Name Reference
+  void SendInsertWithNameReference(bool is_static,
+                                   uint64_t name_index,
+                                   absl::string_view value);
+  // 5.2.2. Insert Without Name Reference
+  void SendInsertWithoutNameReference(absl::string_view name,
+                                      absl::string_view value);
+  // 5.2.3. Duplicate
+  void SendDuplicate(uint64_t index);
+  // 5.2.4. Set Dynamic Table Capacity
+  void SendSetDynamicTableCapacity(uint64_t capacity);
+
+  // Returns number of bytes buffered by this object.
+  // There is no limit on how much data this object is willing to buffer.
+  QuicByteCount BufferedByteCount() const { return buffer_.size(); }
+
+  // Returns whether writing to the encoder stream is allowed.  Writing is
+  // disallowed if the amount of data buffered by the underlying stream exceeds
+  // a hardcoded limit, in order to limit memory consumption in case the encoder
+  // stream is blocked.  CanWrite() returning true does not mean that the
+  // encoder stream is not blocked, it just means the blocked data does not
+  // exceed the threshold.
+  bool CanWrite() const;
+
+  // Writes all buffered instructions on the encoder stream.
+  void Flush();
+
+  // delegate must be set if dynamic table capacity is not zero.
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    delegate_ = delegate;
+  }
+
+ private:
+  QpackStreamSenderDelegate* delegate_;
+  QpackInstructionEncoder instruction_encoder_;
+  std::string buffer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_sender_test.cc b/quiche/quic/core/qpack/qpack_encoder_stream_sender_test.cc
new file mode 100644
index 0000000..5f90e74
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_sender_test.cc
@@ -0,0 +1,179 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::Eq;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QpackEncoderStreamSenderTest : public QuicTest {
+ protected:
+  QpackEncoderStreamSenderTest() {
+    stream_.set_qpack_stream_sender_delegate(&delegate_);
+  }
+  ~QpackEncoderStreamSenderTest() override = default;
+
+  StrictMock<MockQpackStreamSenderDelegate> delegate_;
+  QpackEncoderStreamSender stream_;
+};
+
+TEST_F(QpackEncoderStreamSenderTest, InsertWithNameReference) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Static, index fits in prefix, empty value.
+  std::string expected_encoded_data = absl::HexStringToBytes("c500");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithNameReference(true, 5, "");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Static, index fits in prefix, Huffman encoded value.
+  expected_encoded_data = absl::HexStringToBytes("c28294e7");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithNameReference(true, 2, "foo");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Not static, index does not fit in prefix, not Huffman encoded value.
+  expected_encoded_data = absl::HexStringToBytes("bf4a03626172");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithNameReference(false, 137, "bar");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Value length does not fit in prefix.
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  expected_encoded_data = absl::HexStringToBytes(
+      "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithNameReference(false, 42, std::string(127, 'Z'));
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+}
+
+TEST_F(QpackEncoderStreamSenderTest, InsertWithoutNameReference) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Empty name and value.
+  std::string expected_encoded_data = absl::HexStringToBytes("4000");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithoutNameReference("", "");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Huffman encoded short strings.
+  expected_encoded_data = absl::HexStringToBytes("6294e78294e7");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithoutNameReference("foo", "foo");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Not Huffman encoded short strings.
+  expected_encoded_data = absl::HexStringToBytes("4362617203626172");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithoutNameReference("bar", "bar");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Not Huffman encoded long strings; length does not fit on prefix.
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  expected_encoded_data = absl::HexStringToBytes(
+      "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f"
+      "005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithoutNameReference(std::string(31, 'Z'),
+                                         std::string(127, 'Z'));
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+}
+
+TEST_F(QpackEncoderStreamSenderTest, Duplicate) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Small index fits in prefix.
+  std::string expected_encoded_data = absl::HexStringToBytes("11");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendDuplicate(17);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Large index requires two extension bytes.
+  expected_encoded_data = absl::HexStringToBytes("1fd503");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendDuplicate(500);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+}
+
+TEST_F(QpackEncoderStreamSenderTest, SetDynamicTableCapacity) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Small capacity fits in prefix.
+  std::string expected_encoded_data = absl::HexStringToBytes("31");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendSetDynamicTableCapacity(17);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Large capacity requires two extension bytes.
+  expected_encoded_data = absl::HexStringToBytes("3fd503");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendSetDynamicTableCapacity(500);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+}
+
+// No writes should happen until Flush is called.
+TEST_F(QpackEncoderStreamSenderTest, Coalesce) {
+  // Insert entry with static name reference, empty value.
+  stream_.SendInsertWithNameReference(true, 5, "");
+
+  // Insert entry with static name reference, Huffman encoded value.
+  stream_.SendInsertWithNameReference(true, 2, "foo");
+
+  // Insert literal entry, Huffman encoded short strings.
+  stream_.SendInsertWithoutNameReference("foo", "foo");
+
+  // Duplicate entry.
+  stream_.SendDuplicate(17);
+
+  std::string expected_encoded_data = absl::HexStringToBytes(
+      "c500"          // Insert entry with static name reference.
+      "c28294e7"      // Insert entry with static name reference.
+      "6294e78294e7"  // Insert literal entry.
+      "11");          // Duplicate entry.
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+}
+
+// No writes should happen if QpackEncoderStreamSender::Flush() is called
+// when the buffer is empty.
+TEST_F(QpackEncoderStreamSenderTest, FlushEmpty) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+  stream_.Flush();
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder_test.cc b/quiche/quic/core/qpack/qpack_encoder_test.cc
new file mode 100644
index 0000000..ba3fa29
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_test.cc
@@ -0,0 +1,623 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_encoder.h"
+
+#include <limits>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+// A number larger than kMaxBytesBufferedByStream in
+// qpack_encoder_stream_sender.cc.  Returning this value from NumBytesBuffered()
+// will instruct QpackEncoder not to generate any instructions for the encoder
+// stream.
+constexpr uint64_t kTooManyBytesBuffered = 1024 * 1024;
+
+class QpackEncoderTest : public QuicTest {
+ protected:
+  QpackEncoderTest()
+      : encoder_(&decoder_stream_error_delegate_),
+        encoder_stream_sent_byte_count_(0) {
+    encoder_.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
+    encoder_.SetMaximumBlockedStreams(1);
+  }
+
+  ~QpackEncoderTest() override = default;
+
+  std::string Encode(const spdy::Http2HeaderBlock& header_list) {
+    return encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list,
+                                     &encoder_stream_sent_byte_count_);
+  }
+
+  StrictMock<MockDecoderStreamErrorDelegate> decoder_stream_error_delegate_;
+  StrictMock<MockQpackStreamSenderDelegate> encoder_stream_sender_delegate_;
+  QpackEncoder encoder_;
+  QuicByteCount encoder_stream_sent_byte_count_;
+};
+
+TEST_F(QpackEncoderTest, Empty) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("0000"), output);
+}
+
+TEST_F(QpackEncoderTest, EmptyName) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list[""] = "foo";
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("0000208294e7"), output);
+}
+
+TEST_F(QpackEncoderTest, EmptyValue) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "";
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("00002a94e700"), output);
+}
+
+TEST_F(QpackEncoderTest, EmptyNameAndValue) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list[""] = "";
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("00002000"), output);
+}
+
+TEST_F(QpackEncoderTest, Simple) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("00002a94e703626172"), output);
+}
+
+TEST_F(QpackEncoderTest, Multiple) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  header_list["ZZZZZZZ"] = std::string(127, 'Z');
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(
+      absl::HexStringToBytes(
+          "0000"                // prefix
+          "2a94e703626172"      // foo: bar
+          "27005a5a5a5a5a5a5a"  // 7 octet long header name, the smallest number
+                                // that does not fit on a 3-bit prefix.
+          "7f005a5a5a5a5a5a5a"  // 127 octet long header value, the smallest
+          "5a5a5a5a5a5a5a5a5a"  // number that does not fit on a 7-bit prefix.
+          "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+          "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+          "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+          "5a5a5a5a5a5a5a5a5a"),
+      output);
+}
+
+TEST_F(QpackEncoderTest, StaticTable) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "GET";
+    header_list["accept-encoding"] = "gzip, deflate, br";
+    header_list["location"] = "";
+
+    std::string output = Encode(header_list);
+    EXPECT_EQ(absl::HexStringToBytes("0000d1dfcc"), output);
+  }
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "POST";
+    header_list["accept-encoding"] = "compress";
+    header_list["location"] = "foo";
+
+    std::string output = Encode(header_list);
+    EXPECT_EQ(absl::HexStringToBytes("0000d45f108621e9aec2a11f5c8294e7"),
+              output);
+  }
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "TRACE";
+    header_list["accept-encoding"] = "";
+
+    std::string output = Encode(header_list);
+    EXPECT_EQ(absl::HexStringToBytes("00005f000554524143455f1000"), output);
+  }
+}
+
+TEST_F(QpackEncoderTest, DecoderStreamError) {
+  EXPECT_CALL(decoder_stream_error_delegate_,
+              OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
+                                   Eq("Encoded integer too large.")));
+
+  QpackEncoder encoder(&decoder_stream_error_delegate_);
+  encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
+  encoder.decoder_stream_receiver()->Decode(
+      absl::HexStringToBytes("ffffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderTest, SplitAlongNullCharacter) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("0000"            // prefix
+                                   "2a94e703626172"  // foo: bar
+                                   "2a94e703626172"  // foo: bar
+                                   "2a94e70362617a"  // foo: baz
+                                   ),
+            output);
+}
+
+TEST_F(QpackEncoderTest, ZeroInsertCountIncrement) {
+  // Encoder receives insert count increment with forbidden value 0.
+  EXPECT_CALL(
+      decoder_stream_error_delegate_,
+      OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
+                           Eq("Invalid increment value 0.")));
+  encoder_.OnInsertCountIncrement(0);
+}
+
+TEST_F(QpackEncoderTest, TooLargeInsertCountIncrement) {
+  // Encoder receives insert count increment with value that increases Known
+  // Received Count to a value (one) which is larger than the number of dynamic
+  // table insertions sent (zero).
+  EXPECT_CALL(
+      decoder_stream_error_delegate_,
+      OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT,
+                           Eq("Increment value 1 raises known received count "
+                              "to 1 exceeding inserted entry count 0")));
+  encoder_.OnInsertCountIncrement(1);
+}
+
+// Regression test for https://crbug.com/1014372.
+TEST_F(QpackEncoderTest, InsertCountIncrementOverflow) {
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(&encoder_);
+
+  // Set dynamic table capacity large enough to hold one entry.
+  header_table->SetMaximumDynamicTableCapacity(4096);
+  header_table->SetDynamicTableCapacity(4096);
+  // Insert one entry into the header table.
+  header_table->InsertEntry("foo", "bar");
+
+  // Receive Insert Count Increment instruction with increment value 1.
+  encoder_.OnInsertCountIncrement(1);
+
+  // Receive Insert Count Increment instruction that overflows the known
+  // received count.  This must result in an error instead of a crash.
+  EXPECT_CALL(decoder_stream_error_delegate_,
+              OnDecoderStreamError(
+                  QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW,
+                  Eq("Insert Count Increment instruction causes overflow.")));
+  encoder_.OnInsertCountIncrement(std::numeric_limits<uint64_t>::max());
+}
+
+TEST_F(QpackEncoderTest, InvalidHeaderAcknowledgement) {
+  // Encoder receives header acknowledgement for a stream on which no header
+  // block with dynamic table entries was ever sent.
+  EXPECT_CALL(
+      decoder_stream_error_delegate_,
+      OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT,
+                           Eq("Header Acknowledgement received for stream 0 "
+                              "with no outstanding header blocks.")));
+  encoder_.OnHeaderAcknowledgement(/* stream_id = */ 0);
+}
+
+TEST_F(QpackEncoderTest, DynamicTable) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(4096);
+  encoder_.SetDynamicTableCapacity(4096);
+
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  header_list.AppendValueOrAddHeader("foo",
+                                     "baz");  // name matches dynamic entry
+  header_list["cookie"] = "baz";              // name matches static entry
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+  // Insert three entries into the dynamic table.
+  std::string insert_entries = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172"    // value "bar"
+      "80"          // insert with name reference, dynamic index 0
+      "0362617a"    // value "baz"
+      "c5"          // insert with name reference, static index 5
+      "0362617a");  // value "baz"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(
+                  absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+  EXPECT_EQ(absl::HexStringToBytes(
+                "0400"      // prefix
+                "828180"),  // dynamic entries with relative index 0, 1, and 2
+            Encode(header_list));
+
+  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+}
+
+// There is no room in the dynamic table after inserting the first entry.
+TEST_F(QpackEncoderTest, SmallDynamicTable) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
+  encoder_.SetDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
+
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  header_list.AppendValueOrAddHeader("foo",
+                                     "baz");  // name matches dynamic entry
+  header_list["cookie"] = "baz";              // name matches static entry
+  header_list["bar"] = "baz";                 // no match
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3f07");
+  // Insert one entry into the dynamic table.
+  std::string insert_entry = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172");  // value "bar"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(
+                  Eq(absl::StrCat(set_dyanamic_table_capacity, insert_entry))));
+
+  EXPECT_EQ(absl::HexStringToBytes("0200"  // prefix
+                                   "80"    // dynamic entry 0
+                                   "40"    // reference to dynamic entry 0 name
+                                   "0362617a"  // with literal value "baz"
+                                   "55"  // reference to static entry 5 name
+                                   "0362617a"    // with literal value "baz"
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
+            Encode(header_list));
+
+  EXPECT_EQ(insert_entry.size(), encoder_stream_sent_byte_count_);
+}
+
+TEST_F(QpackEncoderTest, BlockedStream) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(4096);
+  encoder_.SetDynamicTableCapacity(4096);
+
+  spdy::Http2HeaderBlock header_list1;
+  header_list1["foo"] = "bar";
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+  // Insert one entry into the dynamic table.
+  std::string insert_entry1 = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172");  // value "bar"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(
+                  absl::StrCat(set_dyanamic_table_capacity, insert_entry1))));
+
+  EXPECT_EQ(absl::HexStringToBytes("0200"  // prefix
+                                   "80"),  // dynamic entry 0
+            encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list1,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(insert_entry1.size(), encoder_stream_sent_byte_count_);
+
+  // Stream 1 is blocked.  Stream 2 is not allowed to block.
+  spdy::Http2HeaderBlock header_list2;
+  header_list2["foo"] = "bar";  // name and value match dynamic entry
+  header_list2.AppendValueOrAddHeader("foo",
+                                      "baz");  // name matches dynamic entry
+  header_list2["cookie"] = "baz";              // name matches static entry
+  header_list2["bar"] = "baz";                 // no match
+
+  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
+                                   "2a94e7"      // literal name "foo"
+                                   "03626172"    // with literal value "bar"
+                                   "2a94e7"      // literal name "foo"
+                                   "0362617a"    // with literal value "baz"
+                                   "55"          // name of static entry 5
+                                   "0362617a"    // with literal value "baz"
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
+            encoder_.EncodeHeaderList(/* stream_id = */ 2, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+  // Peer acknowledges receipt of one dynamic table entry.
+  // Stream 1 is no longer blocked.
+  encoder_.OnInsertCountIncrement(1);
+
+  // Insert three entries into the dynamic table.
+  std::string insert_entries = absl::HexStringToBytes(
+      "80"          // insert with name reference, dynamic index 0
+      "0362617a"    // value "baz"
+      "c5"          // insert with name reference, static index 5
+      "0362617a"    // value "baz"
+      "43"          // insert without name reference
+      "626172"      // name "bar"
+      "0362617a");  // value "baz"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(insert_entries)));
+
+  EXPECT_EQ(absl::HexStringToBytes("0500"        // prefix
+                                   "83828180"),  // dynamic entries
+            encoder_.EncodeHeaderList(/* stream_id = */ 3, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+
+  // Stream 3 is blocked.  Stream 4 is not allowed to block, but it can
+  // reference already acknowledged dynamic entry 0.
+  EXPECT_EQ(absl::HexStringToBytes("0200"        // prefix
+                                   "80"          // dynamic entry 0
+                                   "2a94e7"      // literal name "foo"
+                                   "0362617a"    // with literal value "baz"
+                                   "2c21cfd4c5"  // literal name "cookie"
+                                   "0362617a"    // with literal value "baz"
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
+            encoder_.EncodeHeaderList(/* stream_id = */ 4, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+  // Peer acknowledges receipt of two more dynamic table entries.
+  // Stream 3 is still blocked.
+  encoder_.OnInsertCountIncrement(2);
+
+  // Stream 5 is not allowed to block, but it can reference already acknowledged
+  // dynamic entries 0, 1, and 2.
+  EXPECT_EQ(absl::HexStringToBytes("0400"        // prefix
+                                   "828180"      // dynamic entries
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
+            encoder_.EncodeHeaderList(/* stream_id = */ 5, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+  // Peer acknowledges decoding header block on stream 3.
+  // Stream 3 is not blocked any longer.
+  encoder_.OnHeaderAcknowledgement(3);
+
+  EXPECT_EQ(absl::HexStringToBytes("0500"        // prefix
+                                   "83828180"),  // dynamic entries
+            encoder_.EncodeHeaderList(/* stream_id = */ 6, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+}
+
+TEST_F(QpackEncoderTest, Draining) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list1;
+  header_list1["one"] = "foo";
+  header_list1["two"] = "foo";
+  header_list1["three"] = "foo";
+  header_list1["four"] = "foo";
+  header_list1["five"] = "foo";
+  header_list1["six"] = "foo";
+  header_list1["seven"] = "foo";
+  header_list1["eight"] = "foo";
+  header_list1["nine"] = "foo";
+  header_list1["ten"] = "foo";
+
+  // Make just enough room in the dynamic table for the header list plus the
+  // first entry duplicated.  This will ensure that the oldest entries are
+  // draining.
+  uint64_t maximum_dynamic_table_capacity = 0;
+  for (const auto& header_field : header_list1) {
+    maximum_dynamic_table_capacity +=
+        QpackEntry::Size(header_field.first, header_field.second);
+  }
+  maximum_dynamic_table_capacity += QpackEntry::Size("one", "foo");
+  encoder_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
+  encoder_.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
+
+  // Set Dynamic Table Capacity instruction and insert ten entries into the
+  // dynamic table.
+  EXPECT_CALL(encoder_stream_sender_delegate_, WriteStreamData(_));
+
+  EXPECT_EQ(absl::HexStringToBytes("0b00"                    // prefix
+                                   "89888786858483828180"),  // dynamic entries
+            Encode(header_list1));
+
+  // Entry is identical to oldest one, which is draining.  It will be
+  // duplicated and referenced.
+  spdy::Http2HeaderBlock header_list2;
+  header_list2["one"] = "foo";
+
+  // Duplicate oldest entry.
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(absl::HexStringToBytes("09"))));
+
+  EXPECT_EQ(absl::HexStringToBytes("0c00"  // prefix
+                                   "80"),  // most recent dynamic table entry
+            Encode(header_list2));
+
+  spdy::Http2HeaderBlock header_list3;
+  // Entry is identical to second oldest one, which is draining.  There is no
+  // room to duplicate, it will be encoded with string literals.
+  header_list3.AppendValueOrAddHeader("two", "foo");
+  // Entry has name identical to second oldest one, which is draining.  There is
+  // no room to insert new entry, it will be encoded with string literals.
+  header_list3.AppendValueOrAddHeader("two", "bar");
+
+  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
+                                   "2374776f"    // literal name "two"
+                                   "8294e7"      // literal value "foo"
+                                   "2374776f"    // literal name "two"
+                                   "03626172"),  // literal value "bar"
+            Encode(header_list3));
+}
+
+TEST_F(QpackEncoderTest, DynamicTableCapacityLessThanMaximum) {
+  encoder_.SetMaximumDynamicTableCapacity(1024);
+  encoder_.SetDynamicTableCapacity(30);
+
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(&encoder_);
+
+  EXPECT_EQ(1024u, header_table->maximum_dynamic_table_capacity());
+  EXPECT_EQ(30u, header_table->dynamic_table_capacity());
+}
+
+TEST_F(QpackEncoderTest, EncoderStreamWritesDisallowedThenAllowed) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(kTooManyBytesBuffered));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(4096);
+  encoder_.SetDynamicTableCapacity(4096);
+
+  spdy::Http2HeaderBlock header_list1;
+  header_list1["foo"] = "bar";
+  header_list1.AppendValueOrAddHeader("foo", "baz");
+  header_list1["cookie"] = "baz";  // name matches static entry
+
+  // Encoder is not allowed to write on the encoder stream.
+  // No Set Dynamic Table Capacity or Insert instructions are sent.
+  // Headers are encoded as string literals.
+  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
+                                   "2a94e7"      // literal name "foo"
+                                   "03626172"    // with literal value "bar"
+                                   "2a94e7"      // literal name "foo"
+                                   "0362617a"    // with literal value "baz"
+                                   "55"          // name of static entry 5
+                                   "0362617a"),  // with literal value "baz"
+            Encode(header_list1));
+
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+  // If number of bytes buffered by encoder stream goes under the threshold,
+  // then QpackEncoder will resume emitting encoder stream instructions.
+  ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+
+  spdy::Http2HeaderBlock header_list2;
+  header_list2["foo"] = "bar";
+  header_list2.AppendValueOrAddHeader("foo",
+                                      "baz");  // name matches dynamic entry
+  header_list2["cookie"] = "baz";              // name matches static entry
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+  // Insert three entries into the dynamic table.
+  std::string insert_entries = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172"    // value "bar"
+      "80"          // insert with name reference, dynamic index 0
+      "0362617a"    // value "baz"
+      "c5"          // insert with name reference, static index 5
+      "0362617a");  // value "baz"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(
+                  absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+  EXPECT_EQ(absl::HexStringToBytes(
+                "0400"      // prefix
+                "828180"),  // dynamic entries with relative index 0, 1, and 2
+            Encode(header_list2));
+
+  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+}
+
+TEST_F(QpackEncoderTest, EncoderStreamWritesAllowedThenDisallowed) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(4096);
+  encoder_.SetDynamicTableCapacity(4096);
+
+  spdy::Http2HeaderBlock header_list1;
+  header_list1["foo"] = "bar";
+  header_list1.AppendValueOrAddHeader("foo",
+                                      "baz");  // name matches dynamic entry
+  header_list1["cookie"] = "baz";              // name matches static entry
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+  // Insert three entries into the dynamic table.
+  std::string insert_entries = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172"    // value "bar"
+      "80"          // insert with name reference, dynamic index 0
+      "0362617a"    // value "baz"
+      "c5"          // insert with name reference, static index 5
+      "0362617a");  // value "baz"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(
+                  absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+  EXPECT_EQ(absl::HexStringToBytes(
+                "0400"      // prefix
+                "828180"),  // dynamic entries with relative index 0, 1, and 2
+            Encode(header_list1));
+
+  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+
+  // If number of bytes buffered by encoder stream goes over the threshold,
+  // then QpackEncoder will stop emitting encoder stream instructions.
+  ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(kTooManyBytesBuffered));
+
+  spdy::Http2HeaderBlock header_list2;
+  header_list2["foo"] = "bar";  // matches previously inserted dynamic entry
+  header_list2["bar"] = "baz";
+  header_list2["cookie"] = "baz";  // name matches static entry
+
+  // Encoder is not allowed to write on the encoder stream.
+  // No Set Dynamic Table Capacity or Insert instructions are sent.
+  // Headers are encoded as string literals.
+  EXPECT_EQ(
+      absl::HexStringToBytes("0400"      // prefix
+                             "82"        // dynamic entry with relative index 0
+                             "23626172"  // literal name "bar"
+                             "0362617a"  // with literal value "baz"
+                             "80"),      // dynamic entry with relative index 2
+      Encode(header_list2));
+
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_header_table.cc b/quiche/quic/core/qpack/qpack_header_table.cc
new file mode 100644
index 0000000..5ee41f6
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_header_table.cc
@@ -0,0 +1,240 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_header_table.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_static_table.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackEncoderHeaderTable::QpackEncoderHeaderTable()
+    : static_index_(ObtainQpackStaticTable().GetStaticIndex()),
+      static_name_index_(ObtainQpackStaticTable().GetStaticNameIndex()) {}
+
+uint64_t QpackEncoderHeaderTable::InsertEntry(absl::string_view name,
+                                              absl::string_view value) {
+  const uint64_t index =
+      QpackHeaderTableBase<QpackEncoderDynamicTable>::InsertEntry(name, value);
+
+  // Make name and value point to the new entry.
+  name = dynamic_entries().back().name();
+  value = dynamic_entries().back().value();
+
+  auto index_result = dynamic_index_.insert(
+      std::make_pair(QpackLookupEntry{name, value}, index));
+  if (!index_result.second) {
+    // An entry with the same name and value already exists.  It needs to be
+    // replaced, because |dynamic_index_| tracks the most recent entry for a
+    // given name and value.
+    QUICHE_DCHECK_GT(index, index_result.first->second);
+    dynamic_index_.erase(index_result.first);
+    auto result = dynamic_index_.insert(
+        std::make_pair(QpackLookupEntry{name, value}, index));
+    QUICHE_CHECK(result.second);
+  }
+
+  auto name_result = dynamic_name_index_.insert({name, index});
+  if (!name_result.second) {
+    // An entry with the same name already exists.  It needs to be replaced,
+    // because |dynamic_name_index_| tracks the most recent entry for a given
+    // name.
+    QUICHE_DCHECK_GT(index, name_result.first->second);
+    dynamic_name_index_.erase(name_result.first);
+    auto result = dynamic_name_index_.insert({name, index});
+    QUICHE_CHECK(result.second);
+  }
+
+  return index;
+}
+
+QpackEncoderHeaderTable::MatchType QpackEncoderHeaderTable::FindHeaderField(
+    absl::string_view name,
+    absl::string_view value,
+    bool* is_static,
+    uint64_t* index) const {
+  QpackLookupEntry query{name, value};
+
+  // Look for exact match in static table.
+  auto index_it = static_index_.find(query);
+  if (index_it != static_index_.end()) {
+    *index = index_it->second;
+    *is_static = true;
+    return MatchType::kNameAndValue;
+  }
+
+  // Look for exact match in dynamic table.
+  index_it = dynamic_index_.find(query);
+  if (index_it != dynamic_index_.end()) {
+    *index = index_it->second;
+    *is_static = false;
+    return MatchType::kNameAndValue;
+  }
+
+  // Look for name match in static table.
+  auto name_index_it = static_name_index_.find(name);
+  if (name_index_it != static_name_index_.end()) {
+    *index = name_index_it->second;
+    *is_static = true;
+    return MatchType::kName;
+  }
+
+  // Look for name match in dynamic table.
+  name_index_it = dynamic_name_index_.find(name);
+  if (name_index_it != dynamic_name_index_.end()) {
+    *index = name_index_it->second;
+    *is_static = false;
+    return MatchType::kName;
+  }
+
+  return MatchType::kNoMatch;
+}
+
+uint64_t QpackEncoderHeaderTable::MaxInsertSizeWithoutEvictingGivenEntry(
+    uint64_t index) const {
+  QUICHE_DCHECK_LE(dropped_entry_count(), index);
+
+  if (index > inserted_entry_count()) {
+    // All entries are allowed to be evicted.
+    return dynamic_table_capacity();
+  }
+
+  // Initialize to current available capacity.
+  uint64_t max_insert_size = dynamic_table_capacity() - dynamic_table_size();
+
+  uint64_t entry_index = dropped_entry_count();
+  for (const auto& entry : dynamic_entries()) {
+    if (entry_index >= index) {
+      break;
+    }
+    ++entry_index;
+    max_insert_size += entry.Size();
+  }
+
+  return max_insert_size;
+}
+
+uint64_t QpackEncoderHeaderTable::draining_index(
+    float draining_fraction) const {
+  QUICHE_DCHECK_LE(0.0, draining_fraction);
+  QUICHE_DCHECK_LE(draining_fraction, 1.0);
+
+  const uint64_t required_space = draining_fraction * dynamic_table_capacity();
+  uint64_t space_above_draining_index =
+      dynamic_table_capacity() - dynamic_table_size();
+
+  if (dynamic_entries().empty() ||
+      space_above_draining_index >= required_space) {
+    return dropped_entry_count();
+  }
+
+  auto it = dynamic_entries().begin();
+  uint64_t entry_index = dropped_entry_count();
+  while (space_above_draining_index < required_space) {
+    space_above_draining_index += it->Size();
+    ++it;
+    ++entry_index;
+    if (it == dynamic_entries().end()) {
+      return inserted_entry_count();
+    }
+  }
+
+  return entry_index;
+}
+
+void QpackEncoderHeaderTable::RemoveEntryFromEnd() {
+  const QpackEntry* const entry = &dynamic_entries().front();
+  const uint64_t index = dropped_entry_count();
+
+  auto index_it = dynamic_index_.find({entry->name(), entry->value()});
+  // Remove |dynamic_index_| entry only if it points to the same
+  // QpackEntry in dynamic_entries().
+  if (index_it != dynamic_index_.end() && index_it->second == index) {
+    dynamic_index_.erase(index_it);
+  }
+
+  auto name_it = dynamic_name_index_.find(entry->name());
+  // Remove |dynamic_name_index_| entry only if it points to the same
+  // QpackEntry in dynamic_entries().
+  if (name_it != dynamic_name_index_.end() && name_it->second == index) {
+    dynamic_name_index_.erase(name_it);
+  }
+
+  QpackHeaderTableBase<QpackEncoderDynamicTable>::RemoveEntryFromEnd();
+}
+
+QpackDecoderHeaderTable::QpackDecoderHeaderTable()
+    : static_entries_(ObtainQpackStaticTable().GetStaticEntries()) {}
+
+QpackDecoderHeaderTable::~QpackDecoderHeaderTable() {
+  for (auto& entry : observers_) {
+    entry.second->Cancel();
+  }
+}
+
+uint64_t QpackDecoderHeaderTable::InsertEntry(absl::string_view name,
+                                              absl::string_view value) {
+  const uint64_t index =
+      QpackHeaderTableBase<QpackDecoderDynamicTable>::InsertEntry(name, value);
+
+  // Notify and deregister observers whose threshold is met, if any.
+  while (!observers_.empty()) {
+    auto it = observers_.begin();
+    if (it->first > inserted_entry_count()) {
+      break;
+    }
+    Observer* observer = it->second;
+    observers_.erase(it);
+    observer->OnInsertCountReachedThreshold();
+  }
+
+  return index;
+}
+
+const QpackEntry* QpackDecoderHeaderTable::LookupEntry(bool is_static,
+                                                       uint64_t index) const {
+  if (is_static) {
+    if (index >= static_entries_.size()) {
+      return nullptr;
+    }
+
+    return &static_entries_[index];
+  }
+
+  if (index < dropped_entry_count()) {
+    return nullptr;
+  }
+
+  index -= dropped_entry_count();
+
+  if (index >= dynamic_entries().size()) {
+    return nullptr;
+  }
+
+  return &dynamic_entries()[index];
+}
+
+void QpackDecoderHeaderTable::RegisterObserver(uint64_t required_insert_count,
+                                               Observer* observer) {
+  QUICHE_DCHECK_GT(required_insert_count, 0u);
+  observers_.insert({required_insert_count, observer});
+}
+
+void QpackDecoderHeaderTable::UnregisterObserver(uint64_t required_insert_count,
+                                                 Observer* observer) {
+  auto it = observers_.lower_bound(required_insert_count);
+  while (it != observers_.end() && it->first == required_insert_count) {
+    if (it->second == observer) {
+      observers_.erase(it);
+      return;
+    }
+    ++it;
+  }
+
+  // |observer| must have been registered.
+  QUIC_NOTREACHED();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_header_table.h b/quiche/quic/core/qpack/qpack_header_table.h
new file mode 100644
index 0000000..75b66a4
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_header_table.h
@@ -0,0 +1,346 @@
+// Copyright (c) 2018 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_QPACK_QPACK_HEADER_TABLE_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
+
+#include <cstdint>
+#include <deque>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/spdy/core/hpack/hpack_entry.h"
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+
+namespace quic {
+
+using QpackEntry = spdy::HpackEntry;
+using QpackLookupEntry = spdy::HpackLookupEntry;
+constexpr size_t kQpackEntrySizeOverhead = spdy::kHpackEntrySizeOverhead;
+
+// Encoder needs pointer stability for |dynamic_index_| and
+// |dynamic_name_index_|.  However, it does not need random access.
+// TODO(b/182349990): Change to a more memory efficient container.
+using QpackEncoderDynamicTable = std::deque<QpackEntry>;
+
+// Decoder needs random access for LookupEntry().
+// However, it does not need pointer stability.
+using QpackDecoderDynamicTable = quiche::QuicheCircularDeque<QpackEntry>;
+
+// This is a base class for encoder and decoder classes that manage the QPACK
+// static and dynamic tables.  For dynamic entries, it only has a concept of
+// absolute indices.  The caller needs to perform the necessary transformations
+// to and from relative indices and post-base indices.
+template <typename DynamicEntryTable>
+class QUIC_EXPORT_PRIVATE QpackHeaderTableBase {
+ public:
+  QpackHeaderTableBase();
+  QpackHeaderTableBase(const QpackHeaderTableBase&) = delete;
+  QpackHeaderTableBase& operator=(const QpackHeaderTableBase&) = delete;
+
+  virtual ~QpackHeaderTableBase() = default;
+
+  // Returns whether an entry with |name| and |value| has a size (including
+  // overhead) that is smaller than or equal to the capacity of the dynamic
+  // table.
+  bool EntryFitsDynamicTableCapacity(absl::string_view name,
+                                     absl::string_view value) const;
+
+  // Inserts (name, value) into the dynamic table.  Entry must not be larger
+  // than the capacity of the dynamic table.  May evict entries.  |name| and
+  // |value| are copied first, therefore it is safe for them to point to an
+  // entry in the dynamic table, even if it is about to be evicted, or even if
+  // the underlying container might move entries around when resizing for
+  // insertion.
+  // Returns the absolute index of the inserted dynamic table entry.
+  virtual uint64_t InsertEntry(absl::string_view name, absl::string_view value);
+
+  // Change dynamic table capacity to |capacity|.  Returns true on success.
+  // Returns false is |capacity| exceeds maximum dynamic table capacity.
+  bool SetDynamicTableCapacity(uint64_t capacity);
+
+  // Set |maximum_dynamic_table_capacity_|.  The initial value is zero.  The
+  // final value is determined by the decoder and is sent to the encoder as
+  // SETTINGS_HEADER_TABLE_SIZE.  Therefore in the decoding context the final
+  // value can be set upon connection establishment, whereas in the encoding
+  // context it can be set when the SETTINGS frame is received.
+  // This method must only be called at most once.
+  // Returns true if |maximum_dynamic_table_capacity| is set for the first time
+  // or if it doesn't change current value. The setting is not changed when
+  // returning false.
+  bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
+
+  uint64_t dynamic_table_size() const { return dynamic_table_size_; }
+  uint64_t dynamic_table_capacity() const { return dynamic_table_capacity_; }
+  uint64_t maximum_dynamic_table_capacity() const {
+    return maximum_dynamic_table_capacity_;
+  }
+  uint64_t max_entries() const { return max_entries_; }
+
+  // The number of entries inserted to the dynamic table (including ones that
+  // were dropped since).  Used for relative indexing on the encoder stream.
+  uint64_t inserted_entry_count() const {
+    return dynamic_entries_.size() + dropped_entry_count_;
+  }
+
+  // The number of entries dropped from the dynamic table.
+  uint64_t dropped_entry_count() const { return dropped_entry_count_; }
+
+  void set_dynamic_table_entry_referenced() {
+    dynamic_table_entry_referenced_ = true;
+  }
+  bool dynamic_table_entry_referenced() const {
+    return dynamic_table_entry_referenced_;
+  }
+
+ protected:
+  // Removes a single entry from the end of the dynamic table, updates
+  // |dynamic_table_size_| and |dropped_entry_count_|.
+  virtual void RemoveEntryFromEnd();
+
+  const DynamicEntryTable& dynamic_entries() const { return dynamic_entries_; }
+
+ private:
+  // Evict entries from the dynamic table until table size is less than or equal
+  // to |capacity|.
+  void EvictDownToCapacity(uint64_t capacity);
+
+  // Dynamic Table entries.
+  DynamicEntryTable dynamic_entries_;
+
+  // Size of the dynamic table.  This is the sum of the size of its entries.
+  uint64_t dynamic_table_size_;
+
+  // Dynamic Table Capacity is the maximum allowed value of
+  // |dynamic_table_size_|.  Entries are evicted if necessary before inserting a
+  // new entry to ensure that dynamic table size never exceeds capacity.
+  // Initial value is |maximum_dynamic_table_capacity_|.  Capacity can be
+  // changed by the encoder, as long as it does not exceed
+  // |maximum_dynamic_table_capacity_|.
+  uint64_t dynamic_table_capacity_;
+
+  // Maximum allowed value of |dynamic_table_capacity|.  The initial value is
+  // zero.  Can be changed by SetMaximumDynamicTableCapacity().
+  uint64_t maximum_dynamic_table_capacity_;
+
+  // MaxEntries, see Section 3.2.2.  Calculated based on
+  // |maximum_dynamic_table_capacity_|.  Used on request streams to encode and
+  // decode Required Insert Count.
+  uint64_t max_entries_;
+
+  // The number of entries dropped from the dynamic table.
+  uint64_t dropped_entry_count_;
+
+  // True if any dynamic table entries have been referenced from a header block.
+  // Set directly by the encoder or decoder.  Used for stats.
+  bool dynamic_table_entry_referenced_;
+};
+
+template <typename DynamicEntryTable>
+QpackHeaderTableBase<DynamicEntryTable>::QpackHeaderTableBase()
+    : dynamic_table_size_(0),
+      dynamic_table_capacity_(0),
+      maximum_dynamic_table_capacity_(0),
+      max_entries_(0),
+      dropped_entry_count_(0),
+      dynamic_table_entry_referenced_(false) {}
+
+template <typename DynamicEntryTable>
+bool QpackHeaderTableBase<DynamicEntryTable>::EntryFitsDynamicTableCapacity(
+    absl::string_view name,
+    absl::string_view value) const {
+  return QpackEntry::Size(name, value) <= dynamic_table_capacity_;
+}
+
+template <typename DynamicEntryTable>
+uint64_t QpackHeaderTableBase<DynamicEntryTable>::InsertEntry(
+    absl::string_view name,
+    absl::string_view value) {
+  QUICHE_DCHECK(EntryFitsDynamicTableCapacity(name, value));
+
+  const uint64_t index = dropped_entry_count_ + dynamic_entries_.size();
+
+  // Copy name and value before modifying the container, because evicting
+  // entries or even inserting a new one might invalidate |name| or |value| if
+  // they point to an entry.
+  QpackEntry new_entry((std::string(name)), (std::string(value)));
+  const size_t entry_size = new_entry.Size();
+
+  EvictDownToCapacity(dynamic_table_capacity_ - entry_size);
+
+  dynamic_table_size_ += entry_size;
+  dynamic_entries_.push_back(std::move(new_entry));
+
+  return index;
+}
+
+template <typename DynamicEntryTable>
+bool QpackHeaderTableBase<DynamicEntryTable>::SetDynamicTableCapacity(
+    uint64_t capacity) {
+  if (capacity > maximum_dynamic_table_capacity_) {
+    return false;
+  }
+
+  dynamic_table_capacity_ = capacity;
+  EvictDownToCapacity(capacity);
+
+  QUICHE_DCHECK_LE(dynamic_table_size_, dynamic_table_capacity_);
+
+  return true;
+}
+
+template <typename DynamicEntryTable>
+bool QpackHeaderTableBase<DynamicEntryTable>::SetMaximumDynamicTableCapacity(
+    uint64_t maximum_dynamic_table_capacity) {
+  if (maximum_dynamic_table_capacity_ == 0) {
+    maximum_dynamic_table_capacity_ = maximum_dynamic_table_capacity;
+    max_entries_ = maximum_dynamic_table_capacity / 32;
+    return true;
+  }
+  // If the value is already set, it should not be changed.
+  return maximum_dynamic_table_capacity == maximum_dynamic_table_capacity_;
+}
+
+template <typename DynamicEntryTable>
+void QpackHeaderTableBase<DynamicEntryTable>::RemoveEntryFromEnd() {
+  const uint64_t entry_size = dynamic_entries_.front().Size();
+  QUICHE_DCHECK_GE(dynamic_table_size_, entry_size);
+  dynamic_table_size_ -= entry_size;
+
+  dynamic_entries_.pop_front();
+  ++dropped_entry_count_;
+}
+
+template <typename DynamicEntryTable>
+void QpackHeaderTableBase<DynamicEntryTable>::EvictDownToCapacity(
+    uint64_t capacity) {
+  while (dynamic_table_size_ > capacity) {
+    QUICHE_DCHECK(!dynamic_entries_.empty());
+    RemoveEntryFromEnd();
+  }
+}
+
+class QUIC_EXPORT_PRIVATE QpackEncoderHeaderTable
+    : public QpackHeaderTableBase<QpackEncoderDynamicTable> {
+ public:
+  // Result of header table lookup.
+  enum class MatchType { kNameAndValue, kName, kNoMatch };
+
+  QpackEncoderHeaderTable();
+  ~QpackEncoderHeaderTable() override = default;
+
+  uint64_t InsertEntry(absl::string_view name,
+                       absl::string_view value) override;
+
+  // Returns the absolute index of an entry with matching name and value if such
+  // exists, otherwise one with matching name is such exists.  |index| is zero
+  // based for both the static and the dynamic table.
+  MatchType FindHeaderField(absl::string_view name,
+                            absl::string_view value,
+                            bool* is_static,
+                            uint64_t* index) const;
+
+  // Returns the size of the largest entry that could be inserted into the
+  // dynamic table without evicting entry |index|.  |index| might be larger than
+  // inserted_entry_count(), in which case the capacity of the table is
+  // returned.  |index| must not be smaller than dropped_entry_count().
+  uint64_t MaxInsertSizeWithoutEvictingGivenEntry(uint64_t index) const;
+
+  // Returns the draining index described at
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#avoiding-blocked-insertions.
+  // Entries with an index larger than or equal to the draining index take up
+  // approximately |1.0 - draining_fraction| of dynamic table capacity.  The
+  // remaining capacity is taken up by draining entries and unused space.
+  // The returned index might not be the index of a valid entry.
+  uint64_t draining_index(float draining_fraction) const;
+
+ protected:
+  void RemoveEntryFromEnd() override;
+
+ private:
+  using NameValueToEntryMap = spdy::HpackHeaderTable::NameValueToEntryMap;
+  using NameToEntryMap = spdy::HpackHeaderTable::NameToEntryMap;
+
+  // Static Table
+
+  // |static_index_| and |static_name_index_| are owned by QpackStaticTable
+  // singleton.
+
+  // Tracks the unique static entry for a given header name and value.
+  const NameValueToEntryMap& static_index_;
+
+  // Tracks the first static entry for a given header name.
+  const NameToEntryMap& static_name_index_;
+
+  // Dynamic Table
+
+  // An unordered set of QpackEntry pointers with a comparison operator that
+  // only cares about name and value.  This allows fast lookup of the most
+  // recently inserted dynamic entry for a given header name and value pair.
+  // Entries point to entries owned by |QpackHeaderTableBase::dynamic_entries_|.
+  NameValueToEntryMap dynamic_index_;
+
+  // An unordered map of QpackEntry pointers keyed off header name.  This allows
+  // fast lookup of the most recently inserted dynamic entry for a given header
+  // name.  Entries point to entries owned by
+  // |QpackHeaderTableBase::dynamic_entries_|.
+  NameToEntryMap dynamic_name_index_;
+};
+
+class QUIC_EXPORT_PRIVATE QpackDecoderHeaderTable
+    : public QpackHeaderTableBase<QpackDecoderDynamicTable> {
+ public:
+  // Observer interface for dynamic table insertion.
+  class QUIC_EXPORT_PRIVATE Observer {
+   public:
+    virtual ~Observer() = default;
+
+    // Called when inserted_entry_count() reaches the threshold the Observer was
+    // registered with.  After this call the Observer automatically gets
+    // deregistered.
+    virtual void OnInsertCountReachedThreshold() = 0;
+
+    // Called when QpackDecoderHeaderTable is destroyed to let the Observer know
+    // that it must not call UnregisterObserver().
+    virtual void Cancel() = 0;
+  };
+
+  QpackDecoderHeaderTable();
+  ~QpackDecoderHeaderTable() override;
+
+  uint64_t InsertEntry(absl::string_view name,
+                       absl::string_view value) override;
+
+  // Returns the entry at absolute index |index| from the static or dynamic
+  // table according to |is_static|.  |index| is zero based for both the static
+  // and the dynamic table.  The returned pointer is valid until the entry is
+  // evicted, even if other entries are inserted into the dynamic table.
+  // Returns nullptr if entry does not exist.
+  const QpackEntry* LookupEntry(bool is_static, uint64_t index) const;
+
+  // Register an observer to be notified when inserted_entry_count() reaches
+  // |required_insert_count|.  After the notification, |observer| automatically
+  // gets unregistered.  Each observer must only be registered at most once.
+  void RegisterObserver(uint64_t required_insert_count, Observer* observer);
+
+  // Unregister previously registered observer.  Must be called with the same
+  // |required_insert_count| value that |observer| was registered with.  Must be
+  // called before an observer still waiting for notification is destroyed,
+  // unless QpackDecoderHeaderTable already called Observer::Cancel(), in which
+  // case this method must not be called.
+  void UnregisterObserver(uint64_t required_insert_count, Observer* observer);
+
+ private:
+  // Static Table entries.  Owned by QpackStaticTable singleton.
+  using StaticEntryTable = spdy::HpackHeaderTable::StaticEntryTable;
+  const StaticEntryTable& static_entries_;
+
+  // Observers waiting to be notified, sorted by required insert count.
+  std::multimap<uint64_t, Observer*> observers_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
diff --git a/quiche/quic/core/qpack/qpack_header_table_test.cc b/quiche/quic/core/qpack/qpack_header_table_test.cc
new file mode 100644
index 0000000..82dd39b
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_header_table_test.cc
@@ -0,0 +1,655 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_header_table.h"
+
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_static_table.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/spdy/core/hpack/hpack_entry.h"
+
+using ::testing::Mock;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const uint64_t kMaximumDynamicTableCapacityForTesting = 1024 * 1024;
+
+template <typename T>
+class QpackHeaderTableTest : public QuicTest {
+ protected:
+  ~QpackHeaderTableTest() override = default;
+
+  void SetUp() override {
+    ASSERT_TRUE(table_.SetMaximumDynamicTableCapacity(
+        kMaximumDynamicTableCapacityForTesting));
+    ASSERT_TRUE(
+        table_.SetDynamicTableCapacity(kMaximumDynamicTableCapacityForTesting));
+  }
+
+  bool EntryFitsDynamicTableCapacity(absl::string_view name,
+                                     absl::string_view value) const {
+    return table_.EntryFitsDynamicTableCapacity(name, value);
+  }
+
+  void InsertEntry(absl::string_view name, absl::string_view value) {
+    table_.InsertEntry(name, value);
+  }
+
+  bool SetDynamicTableCapacity(uint64_t capacity) {
+    return table_.SetDynamicTableCapacity(capacity);
+  }
+
+  uint64_t max_entries() const { return table_.max_entries(); }
+  uint64_t inserted_entry_count() const {
+    return table_.inserted_entry_count();
+  }
+  uint64_t dropped_entry_count() const { return table_.dropped_entry_count(); }
+
+  T table_;
+};
+
+using MyTypes =
+    ::testing::Types<QpackEncoderHeaderTable, QpackDecoderHeaderTable>;
+TYPED_TEST_SUITE(QpackHeaderTableTest, MyTypes);
+
+// MaxEntries is determined by maximum dynamic table capacity,
+// which is set at construction time.
+TYPED_TEST(QpackHeaderTableTest, MaxEntries) {
+  TypeParam table1;
+  table1.SetMaximumDynamicTableCapacity(1024);
+  EXPECT_EQ(32u, table1.max_entries());
+
+  TypeParam table2;
+  table2.SetMaximumDynamicTableCapacity(500);
+  EXPECT_EQ(15u, table2.max_entries());
+}
+
+TYPED_TEST(QpackHeaderTableTest, SetDynamicTableCapacity) {
+  // Dynamic table capacity does not affect MaxEntries.
+  EXPECT_TRUE(this->SetDynamicTableCapacity(1024));
+  EXPECT_EQ(32u * 1024, this->max_entries());
+
+  EXPECT_TRUE(this->SetDynamicTableCapacity(500));
+  EXPECT_EQ(32u * 1024, this->max_entries());
+
+  // Dynamic table capacity cannot exceed maximum dynamic table capacity.
+  EXPECT_FALSE(this->SetDynamicTableCapacity(
+      2 * kMaximumDynamicTableCapacityForTesting));
+}
+
+TYPED_TEST(QpackHeaderTableTest, EntryFitsDynamicTableCapacity) {
+  EXPECT_TRUE(this->SetDynamicTableCapacity(39));
+
+  EXPECT_TRUE(this->EntryFitsDynamicTableCapacity("foo", "bar"));
+  EXPECT_TRUE(this->EntryFitsDynamicTableCapacity("foo", "bar2"));
+  EXPECT_FALSE(this->EntryFitsDynamicTableCapacity("foo", "bar12"));
+}
+
+class QpackEncoderHeaderTableTest
+    : public QpackHeaderTableTest<QpackEncoderHeaderTable> {
+ protected:
+  ~QpackEncoderHeaderTableTest() override = default;
+
+  void ExpectMatch(absl::string_view name,
+                   absl::string_view value,
+                   QpackEncoderHeaderTable::MatchType expected_match_type,
+                   bool expected_is_static,
+                   uint64_t expected_index) const {
+    // Initialize outparams to a value different from the expected to ensure
+    // that FindHeaderField() sets them.
+    bool is_static = !expected_is_static;
+    uint64_t index = expected_index + 1;
+
+    QpackEncoderHeaderTable::MatchType matchtype =
+        table_.FindHeaderField(name, value, &is_static, &index);
+
+    EXPECT_EQ(expected_match_type, matchtype) << name << ": " << value;
+    EXPECT_EQ(expected_is_static, is_static) << name << ": " << value;
+    EXPECT_EQ(expected_index, index) << name << ": " << value;
+  }
+
+  void ExpectNoMatch(absl::string_view name, absl::string_view value) const {
+    bool is_static = false;
+    uint64_t index = 0;
+
+    QpackEncoderHeaderTable::MatchType matchtype =
+        table_.FindHeaderField(name, value, &is_static, &index);
+
+    EXPECT_EQ(QpackEncoderHeaderTable::MatchType::kNoMatch, matchtype)
+        << name << ": " << value;
+  }
+
+  uint64_t MaxInsertSizeWithoutEvictingGivenEntry(uint64_t index) const {
+    return table_.MaxInsertSizeWithoutEvictingGivenEntry(index);
+  }
+
+  uint64_t draining_index(float draining_fraction) const {
+    return table_.draining_index(draining_fraction);
+  }
+};
+
+TEST_F(QpackEncoderHeaderTableTest, FindStaticHeaderField) {
+  // A header name that has multiple entries with different values.
+  ExpectMatch(":method", "GET",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 17u);
+
+  ExpectMatch(":method", "POST",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 20u);
+
+  ExpectMatch(":method", "TRACE", QpackEncoderHeaderTable::MatchType::kName,
+              true, 15u);
+
+  // A header name that has a single entry with non-empty value.
+  ExpectMatch("accept-encoding", "gzip, deflate, br",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 31u);
+
+  ExpectMatch("accept-encoding", "compress",
+              QpackEncoderHeaderTable::MatchType::kName, true, 31u);
+
+  ExpectMatch("accept-encoding", "", QpackEncoderHeaderTable::MatchType::kName,
+              true, 31u);
+
+  // A header name that has a single entry with empty value.
+  ExpectMatch("location", "", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              true, 12u);
+
+  ExpectMatch("location", "foo", QpackEncoderHeaderTable::MatchType::kName,
+              true, 12u);
+
+  // No matching header name.
+  ExpectNoMatch("foo", "");
+  ExpectNoMatch("foo", "bar");
+}
+
+TEST_F(QpackEncoderHeaderTableTest, FindDynamicHeaderField) {
+  // Dynamic table is initially entry.
+  ExpectNoMatch("foo", "bar");
+  ExpectNoMatch("foo", "baz");
+
+  // Insert one entry.
+  InsertEntry("foo", "bar");
+
+  // Match name and value.
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              false, 0u);
+
+  // Match name only.
+  ExpectMatch("foo", "baz", QpackEncoderHeaderTable::MatchType::kName, false,
+              0u);
+
+  // Insert an identical entry.  FindHeaderField() should return the index of
+  // the most recently inserted matching entry.
+  InsertEntry("foo", "bar");
+
+  // Match name and value.
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              false, 1u);
+
+  // Match name only.
+  ExpectMatch("foo", "baz", QpackEncoderHeaderTable::MatchType::kName, false,
+              1u);
+}
+
+TEST_F(QpackEncoderHeaderTableTest, FindHeaderFieldPrefersStaticTable) {
+  // Insert an entry to the dynamic table that exists in the static table.
+  InsertEntry(":method", "GET");
+
+  // FindHeaderField() prefers static table if both have name-and-value match.
+  ExpectMatch(":method", "GET",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 17u);
+
+  // FindHeaderField() prefers static table if both have name match but no value
+  // match, and prefers the first entry with matching name.
+  ExpectMatch(":method", "TRACE", QpackEncoderHeaderTable::MatchType::kName,
+              true, 15u);
+
+  // Add new entry to the dynamic table.
+  InsertEntry(":method", "TRACE");
+
+  // FindHeaderField prefers name-and-value match in dynamic table over name
+  // only match in static table.
+  ExpectMatch(":method", "TRACE",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, false, 1u);
+}
+
+TEST_F(QpackEncoderHeaderTableTest, EvictByInsertion) {
+  EXPECT_TRUE(SetDynamicTableCapacity(40));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(1u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 0u);
+
+  // Inserting second entry evicts the first one.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoMatch("foo", "bar");
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+}
+
+TEST_F(QpackEncoderHeaderTableTest, EvictByUpdateTableSize) {
+  // Entry size is 3 + 3 + 32 = 38.
+  InsertEntry("foo", "bar");
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 0u);
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+
+  EXPECT_TRUE(SetDynamicTableCapacity(40));
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoMatch("foo", "bar");
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+
+  EXPECT_TRUE(SetDynamicTableCapacity(20));
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(2u, dropped_entry_count());
+
+  ExpectNoMatch("foo", "bar");
+  ExpectNoMatch("baz", "qux");
+}
+
+TEST_F(QpackEncoderHeaderTableTest, EvictOldestOfIdentical) {
+  EXPECT_TRUE(SetDynamicTableCapacity(80));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  // Insert same entry twice.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  // Find most recently inserted entry.
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+
+  // Inserting third entry evicts the first one, not the second.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(3u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 2u);
+}
+
+TEST_F(QpackEncoderHeaderTableTest, EvictOldestOfSameName) {
+  EXPECT_TRUE(SetDynamicTableCapacity(80));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  // Insert two entries with same name but different values.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "baz");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  // Find most recently inserted entry with matching name.
+  ExpectMatch("foo", "foo", QpackEncoderHeaderTable::MatchType::kName,
+              /* expected_is_static = */ false, 1u);
+
+  // Inserting third entry evicts the first one, not the second.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(3u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectMatch("foo", "foo", QpackEncoderHeaderTable::MatchType::kName,
+              /* expected_is_static = */ false, 1u);
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 2u);
+}
+
+// Returns the size of the largest entry that could be inserted into the
+// dynamic table without evicting entry |index|.
+TEST_F(QpackEncoderHeaderTableTest, MaxInsertSizeWithoutEvictingGivenEntry) {
+  const uint64_t dynamic_table_capacity = 100;
+  EXPECT_TRUE(SetDynamicTableCapacity(dynamic_table_capacity));
+
+  // Empty table can take an entry up to its capacity.
+  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(0));
+
+  const uint64_t entry_size1 = QpackEntry::Size("foo", "bar");
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(dynamic_table_capacity - entry_size1,
+            MaxInsertSizeWithoutEvictingGivenEntry(0));
+  // Table can take an entry up to its capacity if all entries are allowed to be
+  // evicted.
+  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(1));
+
+  const uint64_t entry_size2 = QpackEntry::Size("baz", "foobar");
+  InsertEntry("baz", "foobar");
+  // Table can take an entry up to its capacity if all entries are allowed to be
+  // evicted.
+  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(2));
+  // Second entry must stay.
+  EXPECT_EQ(dynamic_table_capacity - entry_size2,
+            MaxInsertSizeWithoutEvictingGivenEntry(1));
+  // First and second entry must stay.
+  EXPECT_EQ(dynamic_table_capacity - entry_size2 - entry_size1,
+            MaxInsertSizeWithoutEvictingGivenEntry(0));
+
+  // Third entry evicts first one.
+  const uint64_t entry_size3 = QpackEntry::Size("last", "entry");
+  InsertEntry("last", "entry");
+  EXPECT_EQ(1u, dropped_entry_count());
+  // Table can take an entry up to its capacity if all entries are allowed to be
+  // evicted.
+  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(3));
+  // Third entry must stay.
+  EXPECT_EQ(dynamic_table_capacity - entry_size3,
+            MaxInsertSizeWithoutEvictingGivenEntry(2));
+  // Second and third entry must stay.
+  EXPECT_EQ(dynamic_table_capacity - entry_size3 - entry_size2,
+            MaxInsertSizeWithoutEvictingGivenEntry(1));
+}
+
+TEST_F(QpackEncoderHeaderTableTest, DrainingIndex) {
+  EXPECT_TRUE(SetDynamicTableCapacity(4 * QpackEntry::Size("foo", "bar")));
+
+  // Empty table: no draining entry.
+  EXPECT_EQ(0u, draining_index(0.0));
+  EXPECT_EQ(0u, draining_index(1.0));
+
+  // Table with one entry.
+  InsertEntry("foo", "bar");
+  // Any entry can be referenced if none of the table is draining.
+  EXPECT_EQ(0u, draining_index(0.0));
+  // No entry can be referenced if all of the table is draining.
+  EXPECT_EQ(1u, draining_index(1.0));
+
+  // Table with two entries is at half capacity.
+  InsertEntry("foo", "bar");
+  // Any entry can be referenced if at most half of the table is draining,
+  // because current entries only take up half of total capacity.
+  EXPECT_EQ(0u, draining_index(0.0));
+  EXPECT_EQ(0u, draining_index(0.5));
+  // No entry can be referenced if all of the table is draining.
+  EXPECT_EQ(2u, draining_index(1.0));
+
+  // Table with four entries is full.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  // Any entry can be referenced if none of the table is draining.
+  EXPECT_EQ(0u, draining_index(0.0));
+  // In a full table with identically sized entries, |draining_fraction| of all
+  // entries are draining.
+  EXPECT_EQ(2u, draining_index(0.5));
+  // No entry can be referenced if all of the table is draining.
+  EXPECT_EQ(4u, draining_index(1.0));
+}
+
+class MockObserver : public QpackDecoderHeaderTable::Observer {
+ public:
+  ~MockObserver() override = default;
+
+  MOCK_METHOD(void, OnInsertCountReachedThreshold, (), (override));
+  MOCK_METHOD(void, Cancel, (), (override));
+};
+
+class QpackDecoderHeaderTableTest
+    : public QpackHeaderTableTest<QpackDecoderHeaderTable> {
+ protected:
+  ~QpackDecoderHeaderTableTest() override = default;
+
+  void ExpectEntryAtIndex(bool is_static,
+                          uint64_t index,
+                          absl::string_view expected_name,
+                          absl::string_view expected_value) const {
+    const auto* entry = table_.LookupEntry(is_static, index);
+    ASSERT_TRUE(entry);
+    EXPECT_EQ(expected_name, entry->name());
+    EXPECT_EQ(expected_value, entry->value());
+  }
+
+  void ExpectNoEntryAtIndex(bool is_static, uint64_t index) const {
+    EXPECT_FALSE(table_.LookupEntry(is_static, index));
+  }
+
+  void RegisterObserver(uint64_t required_insert_count,
+                        QpackDecoderHeaderTable::Observer* observer) {
+    table_.RegisterObserver(required_insert_count, observer);
+  }
+
+  void UnregisterObserver(uint64_t required_insert_count,
+                          QpackDecoderHeaderTable::Observer* observer) {
+    table_.UnregisterObserver(required_insert_count, observer);
+  }
+};
+
+TEST_F(QpackDecoderHeaderTableTest, LookupStaticEntry) {
+  ExpectEntryAtIndex(/* is_static = */ true, 0, ":authority", "");
+
+  ExpectEntryAtIndex(/* is_static = */ true, 1, ":path", "/");
+
+  // 98 is the last entry.
+  ExpectEntryAtIndex(/* is_static = */ true, 98, "x-frame-options",
+                     "sameorigin");
+
+  ASSERT_EQ(99u, QpackStaticTableVector().size());
+  ExpectNoEntryAtIndex(/* is_static = */ true, 99);
+}
+
+TEST_F(QpackDecoderHeaderTableTest, InsertAndLookupDynamicEntry) {
+  // Dynamic table is initially entry.
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 1);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
+
+  // Insert one entry.
+  InsertEntry("foo", "bar");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 1);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
+
+  // Insert a different entry.
+  InsertEntry("baz", "bing");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 1, "baz", "bing");
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
+
+  // Insert an entry identical to the most recently inserted one.
+  InsertEntry("baz", "bing");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 1, "baz", "bing");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 2, "baz", "bing");
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
+}
+
+TEST_F(QpackDecoderHeaderTableTest, EvictByInsertion) {
+  EXPECT_TRUE(SetDynamicTableCapacity(40));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(1u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
+
+  // Inserting second entry evicts the first one.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
+}
+
+TEST_F(QpackDecoderHeaderTableTest, EvictByUpdateTableSize) {
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 1u);
+
+  // Entry size is 3 + 3 + 32 = 38.
+  InsertEntry("foo", "bar");
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
+
+  EXPECT_TRUE(SetDynamicTableCapacity(40));
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
+
+  EXPECT_TRUE(SetDynamicTableCapacity(20));
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(2u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 1u);
+}
+
+TEST_F(QpackDecoderHeaderTableTest, EvictOldestOfIdentical) {
+  EXPECT_TRUE(SetDynamicTableCapacity(80));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  // Insert same entry twice.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "bar");
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2u);
+
+  // Inserting third entry evicts the first one, not the second.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(3u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "bar");
+  ExpectEntryAtIndex(/* is_static = */ false, 2u, "baz", "qux");
+}
+
+TEST_F(QpackDecoderHeaderTableTest, EvictOldestOfSameName) {
+  EXPECT_TRUE(SetDynamicTableCapacity(80));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  // Insert two entries with same name but different values.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "baz");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "baz");
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2u);
+
+  // Inserting third entry evicts the first one, not the second.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(3u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "baz");
+  ExpectEntryAtIndex(/* is_static = */ false, 2u, "baz", "qux");
+}
+
+TEST_F(QpackDecoderHeaderTableTest, RegisterObserver) {
+  StrictMock<MockObserver> observer1;
+  RegisterObserver(1, &observer1);
+  EXPECT_CALL(observer1, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(1u, inserted_entry_count());
+  Mock::VerifyAndClearExpectations(&observer1);
+
+  // Registration order does not matter.
+  StrictMock<MockObserver> observer2;
+  StrictMock<MockObserver> observer3;
+  RegisterObserver(3, &observer3);
+  RegisterObserver(2, &observer2);
+
+  EXPECT_CALL(observer2, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(2u, inserted_entry_count());
+  Mock::VerifyAndClearExpectations(&observer3);
+
+  EXPECT_CALL(observer3, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(3u, inserted_entry_count());
+  Mock::VerifyAndClearExpectations(&observer2);
+
+  // Multiple observers with identical |required_insert_count| should all be
+  // notified.
+  StrictMock<MockObserver> observer4;
+  StrictMock<MockObserver> observer5;
+  RegisterObserver(4, &observer4);
+  RegisterObserver(4, &observer5);
+
+  EXPECT_CALL(observer4, OnInsertCountReachedThreshold);
+  EXPECT_CALL(observer5, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(4u, inserted_entry_count());
+  Mock::VerifyAndClearExpectations(&observer4);
+  Mock::VerifyAndClearExpectations(&observer5);
+}
+
+TEST_F(QpackDecoderHeaderTableTest, UnregisterObserver) {
+  StrictMock<MockObserver> observer1;
+  StrictMock<MockObserver> observer2;
+  StrictMock<MockObserver> observer3;
+  StrictMock<MockObserver> observer4;
+  RegisterObserver(1, &observer1);
+  RegisterObserver(2, &observer2);
+  RegisterObserver(2, &observer3);
+  RegisterObserver(3, &observer4);
+
+  UnregisterObserver(2, &observer3);
+
+  EXPECT_CALL(observer1, OnInsertCountReachedThreshold);
+  EXPECT_CALL(observer2, OnInsertCountReachedThreshold);
+  EXPECT_CALL(observer4, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(3u, inserted_entry_count());
+}
+
+TEST_F(QpackDecoderHeaderTableTest, Cancel) {
+  StrictMock<MockObserver> observer;
+  auto table = std::make_unique<QpackDecoderHeaderTable>();
+  table->RegisterObserver(1, &observer);
+
+  EXPECT_CALL(observer, Cancel);
+  table.reset();
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_index_conversions.cc b/quiche/quic/core/qpack/qpack_index_conversions.cc
new file mode 100644
index 0000000..b71d024
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_index_conversions.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/qpack_index_conversions.h"
+
+#include <limits>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+uint64_t QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+    uint64_t absolute_index,
+    uint64_t inserted_entry_count) {
+  QUICHE_DCHECK_LT(absolute_index, inserted_entry_count);
+
+  return inserted_entry_count - absolute_index - 1;
+}
+
+uint64_t QpackAbsoluteIndexToRequestStreamRelativeIndex(uint64_t absolute_index,
+                                                        uint64_t base) {
+  QUICHE_DCHECK_LT(absolute_index, base);
+
+  return base - absolute_index - 1;
+}
+
+bool QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+    uint64_t relative_index,
+    uint64_t inserted_entry_count,
+    uint64_t* absolute_index) {
+  if (relative_index >= inserted_entry_count) {
+    return false;
+  }
+
+  *absolute_index = inserted_entry_count - relative_index - 1;
+  return true;
+}
+
+bool QpackRequestStreamRelativeIndexToAbsoluteIndex(uint64_t relative_index,
+                                                    uint64_t base,
+                                                    uint64_t* absolute_index) {
+  if (relative_index >= base) {
+    return false;
+  }
+
+  *absolute_index = base - relative_index - 1;
+  return true;
+}
+
+bool QpackPostBaseIndexToAbsoluteIndex(uint64_t post_base_index,
+                                       uint64_t base,
+                                       uint64_t* absolute_index) {
+  if (post_base_index >= std::numeric_limits<uint64_t>::max() - base) {
+    return false;
+  }
+
+  *absolute_index = base + post_base_index;
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_index_conversions.h b/quiche/quic/core/qpack/qpack_index_conversions.h
new file mode 100644
index 0000000..d5d02c8
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_index_conversions.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2019 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.
+
+// Utility methods to convert between absolute indexing (used in the dynamic
+// table), relative indexing used on the encoder stream, and relative indexing
+// and post-base indexing used on request streams (in header blocks).  See:
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#indexing
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#relative-indexing
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#post-base
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
+
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Conversion functions used in the encoder do not check for overflow/underflow.
+// Since the maximum index is limited by maximum dynamic table capacity
+// (represented on uint64_t) divided by minimum header field size (defined to be
+// 32 bytes), overflow is not possible.  The caller is responsible for providing
+// input that does not underflow.
+
+QUIC_EXPORT_PRIVATE uint64_t
+QpackAbsoluteIndexToEncoderStreamRelativeIndex(uint64_t absolute_index,
+                                               uint64_t inserted_entry_count);
+
+QUIC_EXPORT_PRIVATE uint64_t
+QpackAbsoluteIndexToRequestStreamRelativeIndex(uint64_t absolute_index,
+                                               uint64_t base);
+
+// Conversion functions used in the decoder operate on input received from the
+// network.  These functions return false on overflow or underflow.
+
+QUIC_EXPORT_PRIVATE bool QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+    uint64_t relative_index,
+    uint64_t inserted_entry_count,
+    uint64_t* absolute_index);
+
+// On success, |*absolute_index| is guaranteed to be strictly less than
+// std::numeric_limits<uint64_t>::max().
+QUIC_EXPORT_PRIVATE bool QpackRequestStreamRelativeIndexToAbsoluteIndex(
+    uint64_t relative_index,
+    uint64_t base,
+    uint64_t* absolute_index);
+
+// On success, |*absolute_index| is guaranteed to be strictly less than
+// std::numeric_limits<uint64_t>::max().
+QUIC_EXPORT_PRIVATE bool QpackPostBaseIndexToAbsoluteIndex(
+    uint64_t post_base_index,
+    uint64_t base,
+    uint64_t* absolute_index);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
diff --git a/quiche/quic/core/qpack/qpack_index_conversions_test.cc b/quiche/quic/core/qpack/qpack_index_conversions_test.cc
new file mode 100644
index 0000000..80162df
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_index_conversions_test.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/qpack_index_conversions.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+struct {
+  uint64_t relative_index;
+  uint64_t inserted_entry_count;
+  uint64_t expected_absolute_index;
+} kEncoderStreamRelativeIndexTestData[] = {{0, 1, 0},  {0, 2, 1},  {1, 2, 0},
+                                           {0, 10, 9}, {5, 10, 4}, {9, 10, 0}};
+
+TEST(QpackIndexConversions, EncoderStreamRelativeIndex) {
+  for (const auto& test_data : kEncoderStreamRelativeIndexTestData) {
+    uint64_t absolute_index = 42;
+    EXPECT_TRUE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+        test_data.relative_index, test_data.inserted_entry_count,
+        &absolute_index));
+    EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
+
+    EXPECT_EQ(test_data.relative_index,
+              QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+                  absolute_index, test_data.inserted_entry_count));
+  }
+}
+
+struct {
+  uint64_t relative_index;
+  uint64_t base;
+  uint64_t expected_absolute_index;
+} kRequestStreamRelativeIndexTestData[] = {{0, 1, 0},  {0, 2, 1},  {1, 2, 0},
+                                           {0, 10, 9}, {5, 10, 4}, {9, 10, 0}};
+
+TEST(QpackIndexConversions, RequestStreamRelativeIndex) {
+  for (const auto& test_data : kRequestStreamRelativeIndexTestData) {
+    uint64_t absolute_index = 42;
+    EXPECT_TRUE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
+        test_data.relative_index, test_data.base, &absolute_index));
+    EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
+
+    EXPECT_EQ(test_data.relative_index,
+              QpackAbsoluteIndexToRequestStreamRelativeIndex(absolute_index,
+                                                             test_data.base));
+  }
+}
+
+struct {
+  uint64_t post_base_index;
+  uint64_t base;
+  uint64_t expected_absolute_index;
+} kPostBaseIndexTestData[] = {{0, 1, 1}, {1, 0, 1}, {2, 0, 2},
+                              {1, 1, 2}, {0, 2, 2}, {1, 2, 3}};
+
+TEST(QpackIndexConversions, PostBaseIndex) {
+  for (const auto& test_data : kPostBaseIndexTestData) {
+    uint64_t absolute_index = 42;
+    EXPECT_TRUE(QpackPostBaseIndexToAbsoluteIndex(
+        test_data.post_base_index, test_data.base, &absolute_index));
+    EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
+  }
+}
+
+TEST(QpackIndexConversions, EncoderStreamRelativeIndexUnderflow) {
+  uint64_t absolute_index;
+  EXPECT_FALSE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+      /* relative_index = */ 10,
+      /* inserted_entry_count = */ 10, &absolute_index));
+  EXPECT_FALSE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+      /* relative_index = */ 12,
+      /* inserted_entry_count = */ 10, &absolute_index));
+}
+
+TEST(QpackIndexConversions, RequestStreamRelativeIndexUnderflow) {
+  uint64_t absolute_index;
+  EXPECT_FALSE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
+      /* relative_index = */ 10,
+      /* base = */ 10, &absolute_index));
+  EXPECT_FALSE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
+      /* relative_index = */ 12,
+      /* base = */ 10, &absolute_index));
+}
+
+TEST(QpackIndexConversions, QpackPostBaseIndexToAbsoluteIndexOverflow) {
+  uint64_t absolute_index;
+  EXPECT_FALSE(QpackPostBaseIndexToAbsoluteIndex(
+      /* post_base_index = */ 20,
+      /* base = */ std::numeric_limits<uint64_t>::max() - 10, &absolute_index));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instruction_decoder.cc b/quiche/quic/core/qpack/qpack_instruction_decoder.cc
new file mode 100644
index 0000000..bc22db0
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_decoder.cc
@@ -0,0 +1,332 @@
+// Copyright 2018 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 "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Maximum length of header name and header value.  This limits the amount of
+// memory the peer can make the decoder allocate when sending string literals.
+const size_t kStringLiteralLengthLimit = 1024 * 1024;
+
+}  // namespace
+
+QpackInstructionDecoder::QpackInstructionDecoder(const QpackLanguage* language,
+                                                 Delegate* delegate)
+    : language_(language),
+      delegate_(delegate),
+      s_bit_(false),
+      varint_(0),
+      varint2_(0),
+      is_huffman_encoded_(false),
+      string_length_(0),
+      error_detected_(false),
+      state_(State::kStartInstruction) {}
+
+bool QpackInstructionDecoder::Decode(absl::string_view data) {
+  QUICHE_DCHECK(!data.empty());
+  QUICHE_DCHECK(!error_detected_);
+
+  while (true) {
+    bool success = true;
+    size_t bytes_consumed = 0;
+
+    switch (state_) {
+      case State::kStartInstruction:
+        success = DoStartInstruction(data);
+        break;
+      case State::kStartField:
+        success = DoStartField();
+        break;
+      case State::kReadBit:
+        success = DoReadBit(data);
+        break;
+      case State::kVarintStart:
+        success = DoVarintStart(data, &bytes_consumed);
+        break;
+      case State::kVarintResume:
+        success = DoVarintResume(data, &bytes_consumed);
+        break;
+      case State::kVarintDone:
+        success = DoVarintDone();
+        break;
+      case State::kReadString:
+        success = DoReadString(data, &bytes_consumed);
+        break;
+      case State::kReadStringDone:
+        success = DoReadStringDone();
+        break;
+    }
+
+    if (!success) {
+      return false;
+    }
+
+    // |success| must be false if an error is detected.
+    QUICHE_DCHECK(!error_detected_);
+
+    QUICHE_DCHECK_LE(bytes_consumed, data.size());
+
+    data = absl::string_view(data.data() + bytes_consumed,
+                             data.size() - bytes_consumed);
+
+    // Stop processing if no more data but next state would require it.
+    if (data.empty() && (state_ != State::kStartField) &&
+        (state_ != State::kVarintDone) && (state_ != State::kReadStringDone)) {
+      return true;
+    }
+  }
+}
+
+bool QpackInstructionDecoder::AtInstructionBoundary() const {
+  return state_ == State::kStartInstruction;
+}
+
+bool QpackInstructionDecoder::DoStartInstruction(absl::string_view data) {
+  QUICHE_DCHECK(!data.empty());
+
+  instruction_ = LookupOpcode(data[0]);
+  field_ = instruction_->fields.begin();
+
+  state_ = State::kStartField;
+  return true;
+}
+
+bool QpackInstructionDecoder::DoStartField() {
+  if (field_ == instruction_->fields.end()) {
+    // Completed decoding this instruction.
+
+    if (!delegate_->OnInstructionDecoded(instruction_)) {
+      return false;
+    }
+
+    state_ = State::kStartInstruction;
+    return true;
+  }
+
+  switch (field_->type) {
+    case QpackInstructionFieldType::kSbit:
+    case QpackInstructionFieldType::kName:
+    case QpackInstructionFieldType::kValue:
+      state_ = State::kReadBit;
+      return true;
+    case QpackInstructionFieldType::kVarint:
+    case QpackInstructionFieldType::kVarint2:
+      state_ = State::kVarintStart;
+      return true;
+    default:
+      QUIC_BUG(quic_bug_10767_1) << "Invalid field type.";
+      return false;
+  }
+}
+
+bool QpackInstructionDecoder::DoReadBit(absl::string_view data) {
+  QUICHE_DCHECK(!data.empty());
+
+  switch (field_->type) {
+    case QpackInstructionFieldType::kSbit: {
+      const uint8_t bitmask = field_->param;
+      s_bit_ = (data[0] & bitmask) == bitmask;
+
+      ++field_;
+      state_ = State::kStartField;
+
+      return true;
+    }
+    case QpackInstructionFieldType::kName:
+    case QpackInstructionFieldType::kValue: {
+      const uint8_t prefix_length = field_->param;
+      QUICHE_DCHECK_GE(7, prefix_length);
+      const uint8_t bitmask = 1 << prefix_length;
+      is_huffman_encoded_ = (data[0] & bitmask) == bitmask;
+
+      state_ = State::kVarintStart;
+
+      return true;
+    }
+    default:
+      QUIC_BUG(quic_bug_10767_2) << "Invalid field type.";
+      return false;
+  }
+}
+
+bool QpackInstructionDecoder::DoVarintStart(absl::string_view data,
+                                            size_t* bytes_consumed) {
+  QUICHE_DCHECK(!data.empty());
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
+                field_->type == QpackInstructionFieldType::kVarint2 ||
+                field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  http2::DecodeBuffer buffer(data.data() + 1, data.size() - 1);
+  http2::DecodeStatus status =
+      varint_decoder_.Start(data[0], field_->param, &buffer);
+
+  *bytes_consumed = 1 + buffer.Offset();
+  switch (status) {
+    case http2::DecodeStatus::kDecodeDone:
+      state_ = State::kVarintDone;
+      return true;
+    case http2::DecodeStatus::kDecodeInProgress:
+      state_ = State::kVarintResume;
+      return true;
+    case http2::DecodeStatus::kDecodeError:
+      OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
+      return false;
+    default:
+      QUIC_BUG(quic_bug_10767_3) << "Unknown decode status " << status;
+      return false;
+  }
+}
+
+bool QpackInstructionDecoder::DoVarintResume(absl::string_view data,
+                                             size_t* bytes_consumed) {
+  QUICHE_DCHECK(!data.empty());
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
+                field_->type == QpackInstructionFieldType::kVarint2 ||
+                field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  http2::DecodeBuffer buffer(data);
+  http2::DecodeStatus status = varint_decoder_.Resume(&buffer);
+
+  *bytes_consumed = buffer.Offset();
+  switch (status) {
+    case http2::DecodeStatus::kDecodeDone:
+      state_ = State::kVarintDone;
+      return true;
+    case http2::DecodeStatus::kDecodeInProgress:
+      QUICHE_DCHECK_EQ(*bytes_consumed, data.size());
+      QUICHE_DCHECK(buffer.Empty());
+      return true;
+    case http2::DecodeStatus::kDecodeError:
+      OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
+      return false;
+    default:
+      QUIC_BUG(quic_bug_10767_4) << "Unknown decode status " << status;
+      return false;
+  }
+}
+
+bool QpackInstructionDecoder::DoVarintDone() {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
+                field_->type == QpackInstructionFieldType::kVarint2 ||
+                field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  if (field_->type == QpackInstructionFieldType::kVarint) {
+    varint_ = varint_decoder_.value();
+
+    ++field_;
+    state_ = State::kStartField;
+    return true;
+  }
+
+  if (field_->type == QpackInstructionFieldType::kVarint2) {
+    varint2_ = varint_decoder_.value();
+
+    ++field_;
+    state_ = State::kStartField;
+    return true;
+  }
+
+  string_length_ = varint_decoder_.value();
+  if (string_length_ > kStringLiteralLengthLimit) {
+    OnError(ErrorCode::STRING_LITERAL_TOO_LONG, "String literal too long.");
+    return false;
+  }
+
+  std::string* const string =
+      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
+  string->clear();
+
+  if (string_length_ == 0) {
+    ++field_;
+    state_ = State::kStartField;
+    return true;
+  }
+
+  string->reserve(string_length_);
+
+  state_ = State::kReadString;
+  return true;
+}
+
+bool QpackInstructionDecoder::DoReadString(absl::string_view data,
+                                           size_t* bytes_consumed) {
+  QUICHE_DCHECK(!data.empty());
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  std::string* const string =
+      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
+  QUICHE_DCHECK_LT(string->size(), string_length_);
+
+  *bytes_consumed = std::min(string_length_ - string->size(), data.size());
+  string->append(data.data(), *bytes_consumed);
+
+  QUICHE_DCHECK_LE(string->size(), string_length_);
+  if (string->size() == string_length_) {
+    state_ = State::kReadStringDone;
+  }
+  return true;
+}
+
+bool QpackInstructionDecoder::DoReadStringDone() {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  std::string* const string =
+      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
+  QUICHE_DCHECK_EQ(string->size(), string_length_);
+
+  if (is_huffman_encoded_) {
+    huffman_decoder_.Reset();
+    // HpackHuffmanDecoder::Decode() cannot perform in-place decoding.
+    std::string decoded_value;
+    huffman_decoder_.Decode(*string, &decoded_value);
+    if (!huffman_decoder_.InputProperlyTerminated()) {
+      OnError(ErrorCode::HUFFMAN_ENCODING_ERROR,
+              "Error in Huffman-encoded string.");
+      return false;
+    }
+    *string = std::move(decoded_value);
+  }
+
+  ++field_;
+  state_ = State::kStartField;
+  return true;
+}
+
+const QpackInstruction* QpackInstructionDecoder::LookupOpcode(
+    uint8_t byte) const {
+  for (const auto* instruction : *language_) {
+    if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
+      return instruction;
+    }
+  }
+  // |language_| should be defined such that instruction opcodes cover every
+  // possible input.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+void QpackInstructionDecoder::OnError(ErrorCode error_code,
+                                      absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+
+  error_detected_ = true;
+  delegate_->OnInstructionDecodingError(error_code, error_message);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instruction_decoder.h b/quiche/quic/core/qpack/qpack_instruction_decoder.h
new file mode 100644
index 0000000..e8aa5ef
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_decoder.h
@@ -0,0 +1,161 @@
+// Copyright 2018 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_QPACK_QPACK_INSTRUCTION_DECODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/huffman/hpack_huffman_decoder.h"
+#include "quiche/http2/hpack/varint/hpack_varint_decoder.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Generic instruction decoder class.  Takes a QpackLanguage that describes a
+// language, that is, a set of instruction opcodes together with a list of
+// fields that follow each instruction.
+class QUIC_EXPORT_PRIVATE QpackInstructionDecoder {
+ public:
+  enum class ErrorCode {
+    INTEGER_TOO_LARGE,
+    STRING_LITERAL_TOO_LONG,
+    HUFFMAN_ENCODING_ERROR,
+  };
+
+  // Delegate is notified each time an instruction is decoded or when an error
+  // occurs.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // Called when an instruction (including all its fields) is decoded.
+    // |instruction| points to an entry in |language|.
+    // Returns true if decoded fields are valid.
+    // Returns false otherwise, in which case QpackInstructionDecoder stops
+    // decoding: Delegate methods will not be called, and Decode() must not be
+    // called.  Implementations are allowed to destroy the
+    // QpackInstructionDecoder instance synchronously if OnInstructionDecoded()
+    // returns false.
+    virtual bool OnInstructionDecoded(const QpackInstruction* instruction) = 0;
+
+    // Called by QpackInstructionDecoder if an error has occurred.
+    // No more data is processed afterwards.
+    // Implementations are allowed to destroy the QpackInstructionDecoder
+    // instance synchronously.
+    virtual void OnInstructionDecodingError(
+        ErrorCode error_code,
+        absl::string_view error_message) = 0;
+  };
+
+  // Both |*language| and |*delegate| must outlive this object.
+  QpackInstructionDecoder(const QpackLanguage* language, Delegate* delegate);
+  QpackInstructionDecoder() = delete;
+  QpackInstructionDecoder(const QpackInstructionDecoder&) = delete;
+  QpackInstructionDecoder& operator=(const QpackInstructionDecoder&) = delete;
+
+  // Provide a data fragment to decode.  Must not be called after an error has
+  // occurred.  Must not be called with empty |data|.  Return true on success,
+  // false on error (in which case Delegate::OnInstructionDecodingError() is
+  // called synchronously).
+  bool Decode(absl::string_view data);
+
+  // Returns true if no decoding has taken place yet or if the last instruction
+  // has been entirely parsed.
+  bool AtInstructionBoundary() const;
+
+  // Accessors for decoded values.  Should only be called for fields that are
+  // part of the most recently decoded instruction, and only after |this| calls
+  // Delegate::OnInstructionDecoded() but before Decode() is called again.
+  bool s_bit() const { return s_bit_; }
+  uint64_t varint() const { return varint_; }
+  uint64_t varint2() const { return varint2_; }
+  const std::string& name() const { return name_; }
+  const std::string& value() const { return value_; }
+
+ private:
+  enum class State {
+    // Identify instruction.
+    kStartInstruction,
+    // Start decoding next field.
+    kStartField,
+    // Read a single bit.
+    kReadBit,
+    // Start reading integer.
+    kVarintStart,
+    // Resume reading integer.
+    kVarintResume,
+    // Done reading integer.
+    kVarintDone,
+    // Read string.
+    kReadString,
+    // Done reading string.
+    kReadStringDone
+  };
+
+  // One method for each state.  They each return true on success, false on
+  // error (in which case |this| might already be destroyed).  Some take input
+  // data and set |*bytes_consumed| to the number of octets processed.  Some
+  // take input data but do not consume any bytes.  Some do not take any
+  // arguments because they only change internal state.
+  bool DoStartInstruction(absl::string_view data);
+  bool DoStartField();
+  bool DoReadBit(absl::string_view data);
+  bool DoVarintStart(absl::string_view data, size_t* bytes_consumed);
+  bool DoVarintResume(absl::string_view data, size_t* bytes_consumed);
+  bool DoVarintDone();
+  bool DoReadString(absl::string_view data, size_t* bytes_consumed);
+  bool DoReadStringDone();
+
+  // Identify instruction based on opcode encoded in |byte|.
+  // Returns a pointer to an element of |*language_|.
+  const QpackInstruction* LookupOpcode(uint8_t byte) const;
+
+  // Stops decoding and calls Delegate::OnInstructionDecodingError().
+  void OnError(ErrorCode error_code, absl::string_view error_message);
+
+  // Describes the language used for decoding.
+  const QpackLanguage* const language_;
+
+  // The Delegate to notify of decoded instructions and errors.
+  Delegate* const delegate_;
+
+  // Storage for decoded field values.
+  bool s_bit_;
+  uint64_t varint_;
+  uint64_t varint2_;
+  std::string name_;
+  std::string value_;
+  // Whether the currently decoded header name or value is Huffman encoded.
+  bool is_huffman_encoded_;
+  // Length of string being read into |name_| or |value_|.
+  size_t string_length_;
+
+  // Decoder instance for decoding integers.
+  http2::HpackVarintDecoder varint_decoder_;
+
+  // Decoder instance for decoding Huffman encoded strings.
+  http2::HpackHuffmanDecoder huffman_decoder_;
+
+  // True if a decoding error has been detected by QpackInstructionDecoder.
+  // Only used in QUICHE_DCHECKs.
+  bool error_detected_;
+
+  // Decoding state.
+  State state_;
+
+  // Instruction currently being decoded.
+  const QpackInstruction* instruction_;
+
+  // Field currently being decoded.
+  QpackInstructionFields::const_iterator field_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
diff --git a/quiche/quic/core/qpack/qpack_instruction_decoder_test.cc b/quiche/quic/core/qpack/qpack_instruction_decoder_test.cc
new file mode 100644
index 0000000..d5c753d
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_decoder_test.cc
@@ -0,0 +1,226 @@
+// Copyright 2018 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 "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+
+#include <algorithm>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Expectation;
+using ::testing::InvokeWithoutArgs;
+using ::testing::Return;
+using ::testing::StrictMock;
+using ::testing::Values;
+
+namespace quic {
+namespace test {
+namespace {
+
+// This instruction has three fields: an S bit and two varints.
+const QpackInstruction* TestInstruction1() {
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{QpackInstructionOpcode{0x00, 0x80},
+                           {{QpackInstructionFieldType::kSbit, 0x40},
+                            {QpackInstructionFieldType::kVarint, 6},
+                            {QpackInstructionFieldType::kVarint2, 8}}};
+  return instruction;
+}
+
+// This instruction has two fields: a header name with a 6-bit prefix, and a
+// header value with a 7-bit prefix, both preceded by a Huffman bit.
+const QpackInstruction* TestInstruction2() {
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{QpackInstructionOpcode{0x80, 0x80},
+                           {{QpackInstructionFieldType::kName, 6},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackLanguage* TestLanguage() {
+  static const QpackLanguage* const language =
+      new QpackLanguage{TestInstruction1(), TestInstruction2()};
+  return language;
+}
+
+class MockDelegate : public QpackInstructionDecoder::Delegate {
+ public:
+  MockDelegate() {
+    ON_CALL(*this, OnInstructionDecoded(_)).WillByDefault(Return(true));
+  }
+
+  MockDelegate(const MockDelegate&) = delete;
+  MockDelegate& operator=(const MockDelegate&) = delete;
+  ~MockDelegate() override = default;
+
+  MOCK_METHOD(bool,
+              OnInstructionDecoded,
+              (const QpackInstruction*),
+              (override));
+  MOCK_METHOD(void,
+              OnInstructionDecodingError,
+              (QpackInstructionDecoder::ErrorCode error_code,
+               absl::string_view error_message),
+              (override));
+};
+
+class QpackInstructionDecoderTest : public QuicTestWithParam<FragmentMode> {
+ protected:
+  QpackInstructionDecoderTest()
+      : decoder_(std::make_unique<QpackInstructionDecoder>(TestLanguage(),
+                                                           &delegate_)),
+        fragment_mode_(GetParam()) {}
+  ~QpackInstructionDecoderTest() override = default;
+
+  void SetUp() override {
+    // Destroy QpackInstructionDecoder on error to test that it does not crash.
+    // See https://crbug.com/1025209.
+    ON_CALL(delegate_, OnInstructionDecodingError(_, _))
+        .WillByDefault(InvokeWithoutArgs([this]() { decoder_.reset(); }));
+  }
+
+  // Decode one full instruction with fragment sizes dictated by
+  // |fragment_mode_|.
+  // Assumes that |data| is a single complete instruction, and accordingly
+  // verifies that AtInstructionBoundary() returns true before and after the
+  // instruction, and returns false while decoding is in progress.
+  // Assumes that delegate methods destroy |decoder_| if they return false.
+  void DecodeInstruction(absl::string_view data) {
+    EXPECT_TRUE(decoder_->AtInstructionBoundary());
+
+    FragmentSizeGenerator fragment_size_generator =
+        FragmentModeToFragmentSizeGenerator(fragment_mode_);
+
+    while (!data.empty()) {
+      size_t fragment_size = std::min(fragment_size_generator(), data.size());
+      bool success = decoder_->Decode(data.substr(0, fragment_size));
+      if (!decoder_) {
+        EXPECT_FALSE(success);
+        return;
+      }
+      EXPECT_TRUE(success);
+      data = data.substr(fragment_size);
+      if (!data.empty()) {
+        EXPECT_FALSE(decoder_->AtInstructionBoundary());
+      }
+    }
+
+    EXPECT_TRUE(decoder_->AtInstructionBoundary());
+  }
+
+  StrictMock<MockDelegate> delegate_;
+  std::unique_ptr<QpackInstructionDecoder> decoder_;
+
+ private:
+  const FragmentMode fragment_mode_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         QpackInstructionDecoderTest,
+                         Values(FragmentMode::kSingleChunk,
+                                FragmentMode::kOctetByOctet));
+
+TEST_P(QpackInstructionDecoderTest, SBitAndVarint2) {
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
+  DecodeInstruction(absl::HexStringToBytes("7f01ff65"));
+
+  EXPECT_TRUE(decoder_->s_bit());
+  EXPECT_EQ(64u, decoder_->varint());
+  EXPECT_EQ(356u, decoder_->varint2());
+
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
+  DecodeInstruction(absl::HexStringToBytes("05c8"));
+
+  EXPECT_FALSE(decoder_->s_bit());
+  EXPECT_EQ(5u, decoder_->varint());
+  EXPECT_EQ(200u, decoder_->varint2());
+}
+
+TEST_P(QpackInstructionDecoderTest, NameAndValue) {
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
+  DecodeInstruction(absl::HexStringToBytes("83666f6f03626172"));
+
+  EXPECT_EQ("foo", decoder_->name());
+  EXPECT_EQ("bar", decoder_->value());
+
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
+  DecodeInstruction(absl::HexStringToBytes("8000"));
+
+  EXPECT_EQ("", decoder_->name());
+  EXPECT_EQ("", decoder_->value());
+
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
+  DecodeInstruction(absl::HexStringToBytes("c294e7838c767f"));
+
+  EXPECT_EQ("foo", decoder_->name());
+  EXPECT_EQ("bar", decoder_->value());
+}
+
+TEST_P(QpackInstructionDecoderTest, InvalidHuffmanEncoding) {
+  EXPECT_CALL(delegate_,
+              OnInstructionDecodingError(
+                  QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR,
+                  Eq("Error in Huffman-encoded string.")));
+  DecodeInstruction(absl::HexStringToBytes("c1ff"));
+}
+
+TEST_P(QpackInstructionDecoderTest, InvalidVarintEncoding) {
+  EXPECT_CALL(delegate_,
+              OnInstructionDecodingError(
+                  QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE,
+                  Eq("Encoded integer too large.")));
+  DecodeInstruction(absl::HexStringToBytes("ffffffffffffffffffffff"));
+}
+
+TEST_P(QpackInstructionDecoderTest, StringLiteralTooLong) {
+  EXPECT_CALL(delegate_,
+              OnInstructionDecodingError(
+                  QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG,
+                  Eq("String literal too long.")));
+  DecodeInstruction(absl::HexStringToBytes("bfffff7f"));
+}
+
+TEST_P(QpackInstructionDecoderTest, DelegateSignalsError) {
+  // First instruction is valid.
+  Expectation first_call =
+      EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
+          .WillOnce(InvokeWithoutArgs([this]() -> bool {
+            EXPECT_EQ(1u, decoder_->varint());
+            return true;
+          }));
+
+  // Second instruction is invalid.  Decoding must halt.
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
+      .After(first_call)
+      .WillOnce(InvokeWithoutArgs([this]() -> bool {
+        EXPECT_EQ(2u, decoder_->varint());
+        return false;
+      }));
+
+  EXPECT_FALSE(
+      decoder_->Decode(absl::HexStringToBytes("01000200030004000500")));
+}
+
+// QpackInstructionDecoder must not crash if it is destroyed from a
+// Delegate::OnInstructionDecoded() call as long as it returns false.
+TEST_P(QpackInstructionDecoderTest, DelegateSignalsErrorAndDestroysDecoder) {
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
+      .WillOnce(InvokeWithoutArgs([this]() -> bool {
+        EXPECT_EQ(1u, decoder_->varint());
+        decoder_.reset();
+        return false;
+      }));
+  DecodeInstruction(absl::HexStringToBytes("0100"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instruction_encoder.cc b/quiche/quic/core/qpack/qpack_instruction_encoder.cc
new file mode 100644
index 0000000..2922c00
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_encoder.cc
@@ -0,0 +1,177 @@
+// Copyright 2018 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 "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+
+#include <limits>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/huffman/hpack_huffman_encoder.h"
+#include "quiche/http2/hpack/varint/hpack_varint_encoder.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackInstructionEncoder::QpackInstructionEncoder()
+    : use_huffman_(false),
+      string_length_(0),
+      byte_(0),
+      state_(State::kOpcode),
+      instruction_(nullptr) {}
+
+void QpackInstructionEncoder::Encode(
+    const QpackInstructionWithValues& instruction_with_values,
+    std::string* output) {
+  QUICHE_DCHECK(instruction_with_values.instruction());
+
+  state_ = State::kOpcode;
+  instruction_ = instruction_with_values.instruction();
+  field_ = instruction_->fields.begin();
+
+  // Field list must not be empty.
+  QUICHE_DCHECK(field_ != instruction_->fields.end());
+
+  do {
+    switch (state_) {
+      case State::kOpcode:
+        DoOpcode();
+        break;
+      case State::kStartField:
+        DoStartField();
+        break;
+      case State::kSbit:
+        DoSBit(instruction_with_values.s_bit());
+        break;
+      case State::kVarintEncode:
+        DoVarintEncode(instruction_with_values.varint(),
+                       instruction_with_values.varint2(), output);
+        break;
+      case State::kStartString:
+        DoStartString(instruction_with_values.name(),
+                      instruction_with_values.value());
+        break;
+      case State::kWriteString:
+        DoWriteString(instruction_with_values.name(),
+                      instruction_with_values.value(), output);
+        break;
+    }
+  } while (field_ != instruction_->fields.end());
+
+  QUICHE_DCHECK(state_ == State::kStartField);
+}
+
+void QpackInstructionEncoder::DoOpcode() {
+  QUICHE_DCHECK_EQ(0u, byte_);
+
+  byte_ = instruction_->opcode.value;
+
+  state_ = State::kStartField;
+}
+
+void QpackInstructionEncoder::DoStartField() {
+  switch (field_->type) {
+    case QpackInstructionFieldType::kSbit:
+      state_ = State::kSbit;
+      return;
+    case QpackInstructionFieldType::kVarint:
+    case QpackInstructionFieldType::kVarint2:
+      state_ = State::kVarintEncode;
+      return;
+    case QpackInstructionFieldType::kName:
+    case QpackInstructionFieldType::kValue:
+      state_ = State::kStartString;
+      return;
+  }
+}
+
+void QpackInstructionEncoder::DoSBit(bool s_bit) {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kSbit);
+
+  if (s_bit) {
+    QUICHE_DCHECK_EQ(0, byte_ & field_->param);
+
+    byte_ |= field_->param;
+  }
+
+  ++field_;
+  state_ = State::kStartField;
+}
+
+void QpackInstructionEncoder::DoVarintEncode(uint64_t varint,
+                                             uint64_t varint2,
+                                             std::string* output) {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
+                field_->type == QpackInstructionFieldType::kVarint2 ||
+                field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+  uint64_t integer_to_encode;
+  switch (field_->type) {
+    case QpackInstructionFieldType::kVarint:
+      integer_to_encode = varint;
+      break;
+    case QpackInstructionFieldType::kVarint2:
+      integer_to_encode = varint2;
+      break;
+    default:
+      integer_to_encode = string_length_;
+      break;
+  }
+
+  http2::HpackVarintEncoder::Encode(byte_, field_->param, integer_to_encode,
+                                    output);
+  byte_ = 0;
+
+  if (field_->type == QpackInstructionFieldType::kVarint ||
+      field_->type == QpackInstructionFieldType::kVarint2) {
+    ++field_;
+    state_ = State::kStartField;
+    return;
+  }
+
+  state_ = State::kWriteString;
+}
+
+void QpackInstructionEncoder::DoStartString(absl::string_view name,
+                                            absl::string_view value) {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  absl::string_view string_to_write =
+      (field_->type == QpackInstructionFieldType::kName) ? name : value;
+  string_length_ = string_to_write.size();
+
+  size_t encoded_size = http2::HuffmanSize(string_to_write);
+  use_huffman_ = encoded_size < string_length_;
+
+  if (use_huffman_) {
+    QUICHE_DCHECK_EQ(0, byte_ & (1 << field_->param));
+    byte_ |= (1 << field_->param);
+
+    string_length_ = encoded_size;
+  }
+
+  state_ = State::kVarintEncode;
+}
+
+void QpackInstructionEncoder::DoWriteString(absl::string_view name,
+                                            absl::string_view value,
+                                            std::string* output) {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  absl::string_view string_to_write =
+      (field_->type == QpackInstructionFieldType::kName) ? name : value;
+  if (use_huffman_) {
+    http2::HuffmanEncodeFast(string_to_write, string_length_, output);
+  } else {
+    absl::StrAppend(output, string_to_write);
+  }
+
+  ++field_;
+  state_ = State::kStartField;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instruction_encoder.h b/quiche/quic/core/qpack/qpack_instruction_encoder.h
new file mode 100644
index 0000000..25f707a
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_encoder.h
@@ -0,0 +1,84 @@
+// Copyright 2018 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_QPACK_QPACK_INSTRUCTION_ENCODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Generic instruction encoder class.  Takes a QpackLanguage that describes a
+// language, that is, a set of instruction opcodes together with a list of
+// fields that follow each instruction.
+class QUIC_EXPORT_PRIVATE QpackInstructionEncoder {
+ public:
+  QpackInstructionEncoder();
+  QpackInstructionEncoder(const QpackInstructionEncoder&) = delete;
+  QpackInstructionEncoder& operator=(const QpackInstructionEncoder&) = delete;
+
+  // Append encoded instruction to |output|.
+  void Encode(const QpackInstructionWithValues& instruction_with_values,
+              std::string* output);
+
+ private:
+  enum class State {
+    // Write instruction opcode to |byte_|.
+    kOpcode,
+    // Select state based on type of current field.
+    kStartField,
+    // Write static bit to |byte_|.
+    kSbit,
+    // Encode an integer (|varint_| or |varint2_| or string length) with a
+    // prefix, using |byte_| for the high bits.
+    kVarintEncode,
+    // Determine if Huffman encoding should be used for the header name or
+    // value, set |use_huffman_| and |string_length_| appropriately, write the
+    // Huffman bit to |byte_|.
+    kStartString,
+    // Write header name or value, performing Huffman encoding if |use_huffman_|
+    // is true.
+    kWriteString
+  };
+
+  // One method for each state.  Some append encoded bytes to |output|.
+  // Some only change internal state.
+  void DoOpcode();
+  void DoStartField();
+  void DoSBit(bool s_bit);
+  void DoVarintEncode(uint64_t varint, uint64_t varint2, std::string* output);
+  void DoStartString(absl::string_view name, absl::string_view value);
+  void DoWriteString(absl::string_view name,
+                     absl::string_view value,
+                     std::string* output);
+
+  // True if name or value should be Huffman encoded.
+  bool use_huffman_;
+
+  // Length of name or value string to be written.
+  // If |use_huffman_| is true, length is after Huffman encoding.
+  size_t string_length_;
+
+  // Storage for a single byte that contains multiple fields, that is, multiple
+  // states are writing it.
+  uint8_t byte_;
+
+  // Encoding state.
+  State state_;
+
+  // Instruction currently being decoded.
+  const QpackInstruction* instruction_;
+
+  // Field currently being decoded.
+  QpackInstructionFields::const_iterator field_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
diff --git a/quiche/quic/core/qpack/qpack_instruction_encoder_test.cc b/quiche/quic/core/qpack/qpack_instruction_encoder_test.cc
new file mode 100644
index 0000000..dfdec9e
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_encoder_test.cc
@@ -0,0 +1,204 @@
+// Copyright 2018 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 "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QpackInstructionWithValuesPeer {
+ public:
+  static QpackInstructionWithValues CreateQpackInstructionWithValues(
+      const QpackInstruction* instruction) {
+    QpackInstructionWithValues instruction_with_values;
+    instruction_with_values.instruction_ = instruction;
+    return instruction_with_values;
+  }
+
+  static void set_s_bit(QpackInstructionWithValues* instruction_with_values,
+                        bool s_bit) {
+    instruction_with_values->s_bit_ = s_bit;
+  }
+
+  static void set_varint(QpackInstructionWithValues* instruction_with_values,
+                         uint64_t varint) {
+    instruction_with_values->varint_ = varint;
+  }
+
+  static void set_varint2(QpackInstructionWithValues* instruction_with_values,
+                          uint64_t varint2) {
+    instruction_with_values->varint2_ = varint2;
+  }
+
+  static void set_name(QpackInstructionWithValues* instruction_with_values,
+                       absl::string_view name) {
+    instruction_with_values->name_ = name;
+  }
+
+  static void set_value(QpackInstructionWithValues* instruction_with_values,
+                        absl::string_view value) {
+    instruction_with_values->value_ = value;
+  }
+};
+
+namespace {
+
+class QpackInstructionEncoderTest : public QuicTest {
+ protected:
+  QpackInstructionEncoderTest() : verified_position_(0) {}
+  ~QpackInstructionEncoderTest() override = default;
+
+  // Append encoded |instruction| to |output_|.
+  void EncodeInstruction(
+      const QpackInstructionWithValues& instruction_with_values) {
+    encoder_.Encode(instruction_with_values, &output_);
+  }
+
+  // Compare substring appended to |output_| since last EncodedSegmentMatches()
+  // call against hex-encoded argument.
+  bool EncodedSegmentMatches(absl::string_view hex_encoded_expected_substring) {
+    auto recently_encoded =
+        absl::string_view(output_).substr(verified_position_);
+    auto expected = absl::HexStringToBytes(hex_encoded_expected_substring);
+    verified_position_ = output_.size();
+    return recently_encoded == expected;
+  }
+
+ private:
+  QpackInstructionEncoder encoder_;
+  std::string output_;
+  std::string::size_type verified_position_;
+};
+
+TEST_F(QpackInstructionEncoderTest, Varint) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0x00, 0x80},
+                                     {{QpackInstructionFieldType::kVarint, 7}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 5);
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("05"));
+
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 127);
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("7f00"));
+}
+
+TEST_F(QpackInstructionEncoderTest, SBitAndTwoVarint2) {
+  const QpackInstruction instruction{
+      QpackInstructionOpcode{0x80, 0xc0},
+      {{QpackInstructionFieldType::kSbit, 0x20},
+       {QpackInstructionFieldType::kVarint, 5},
+       {QpackInstructionFieldType::kVarint2, 8}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 5);
+  QpackInstructionWithValuesPeer::set_varint2(&instruction_with_values, 200);
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("a5c8"));
+
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 31);
+  QpackInstructionWithValuesPeer::set_varint2(&instruction_with_values, 356);
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("9f00ff65"));
+}
+
+TEST_F(QpackInstructionEncoderTest, SBitAndVarintAndValue) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0xc0, 0xc0},
+                                     {{QpackInstructionFieldType::kSbit, 0x20},
+                                      {QpackInstructionFieldType::kVarint, 5},
+                                      {QpackInstructionFieldType::kValue, 7}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 100);
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "foo");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("ff458294e7"));
+
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 3);
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("c303626172"));
+}
+
+TEST_F(QpackInstructionEncoderTest, Name) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0xe0, 0xe0},
+                                     {{QpackInstructionFieldType::kName, 4}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("e0"));
+
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "foo");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("f294e7"));
+
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "bar");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("e3626172"));
+}
+
+TEST_F(QpackInstructionEncoderTest, Value) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
+                                     {{QpackInstructionFieldType::kValue, 3}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("f0"));
+
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "foo");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("fa94e7"));
+
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("f3626172"));
+}
+
+TEST_F(QpackInstructionEncoderTest, SBitAndNameAndValue) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
+                                     {{QpackInstructionFieldType::kSbit, 0x08},
+                                      {QpackInstructionFieldType::kName, 2},
+                                      {QpackInstructionFieldType::kValue, 7}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "");
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("f000"));
+
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "foo");
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("fe94e703626172"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instructions.cc b/quiche/quic/core/qpack/qpack_instructions.cc
new file mode 100644
index 0000000..ee80897
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instructions.cc
@@ -0,0 +1,333 @@
+// Copyright 2018 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 "quiche/quic/core/qpack/qpack_instructions.h"
+
+#include <limits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Validate that
+//  * in each instruction, the bits of |value| that are zero in |mask| are zero;
+//  * every byte matches exactly one opcode.
+void ValidateLangague(const QpackLanguage* language) {
+#ifndef NDEBUG
+  for (const auto* instruction : *language) {
+    QUICHE_DCHECK_EQ(0, instruction->opcode.value & ~instruction->opcode.mask);
+  }
+
+  for (uint8_t byte = 0; byte < std::numeric_limits<uint8_t>::max(); ++byte) {
+    size_t match_count = 0;
+    for (const auto* instruction : *language) {
+      if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
+        ++match_count;
+      }
+    }
+    QUICHE_DCHECK_EQ(1u, match_count) << static_cast<int>(byte);
+  }
+#else
+  (void)language;
+#endif
+}
+
+}  // namespace
+
+bool operator==(const QpackInstructionOpcode& a,
+                const QpackInstructionOpcode& b) {
+  return std::tie(a.value, a.mask) == std::tie(b.value, b.mask);
+}
+
+const QpackInstruction* InsertWithNameReferenceInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b10000000, 0b10000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kSbit, 0b01000000},
+                            {QpackInstructionFieldType::kVarint, 6},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* InsertWithoutNameReferenceInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b01000000, 0b11000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kName, 5},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* DuplicateInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00000000, 0b11100000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 5}}};
+  return instruction;
+}
+
+const QpackInstruction* SetDynamicTableCapacityInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00100000, 0b11100000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 5}}};
+  return instruction;
+}
+
+const QpackLanguage* QpackEncoderStreamLanguage() {
+  static const QpackLanguage* const language = new QpackLanguage{
+      InsertWithNameReferenceInstruction(),
+      InsertWithoutNameReferenceInstruction(), DuplicateInstruction(),
+      SetDynamicTableCapacityInstruction()};
+  ValidateLangague(language);
+  return language;
+}
+
+const QpackInstruction* InsertCountIncrementInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00000000, 0b11000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 6}}};
+  return instruction;
+}
+
+const QpackInstruction* HeaderAcknowledgementInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b10000000, 0b10000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* StreamCancellationInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b01000000, 0b11000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 6}}};
+  return instruction;
+}
+
+const QpackLanguage* QpackDecoderStreamLanguage() {
+  static const QpackLanguage* const language = new QpackLanguage{
+      InsertCountIncrementInstruction(), HeaderAcknowledgementInstruction(),
+      StreamCancellationInstruction()};
+  ValidateLangague(language);
+  return language;
+}
+
+const QpackInstruction* QpackPrefixInstruction() {
+  // This opcode matches every input.
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00000000, 0b00000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kVarint, 8},
+                            {QpackInstructionFieldType::kSbit, 0b10000000},
+                            {QpackInstructionFieldType::kVarint2, 7}}};
+  return instruction;
+}
+
+const QpackLanguage* QpackPrefixLanguage() {
+  static const QpackLanguage* const language =
+      new QpackLanguage{QpackPrefixInstruction()};
+  ValidateLangague(language);
+  return language;
+}
+
+const QpackInstruction* QpackIndexedHeaderFieldInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b10000000, 0b10000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kSbit, 0b01000000},
+                            {QpackInstructionFieldType::kVarint, 6}}};
+  return instruction;
+}
+
+const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00010000, 0b11110000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 4}}};
+  return instruction;
+}
+
+const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b01000000, 0b11000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kSbit, 0b00010000},
+                            {QpackInstructionFieldType::kVarint, 4},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00000000, 0b11110000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kVarint, 3},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* QpackLiteralHeaderFieldInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00100000, 0b11100000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kName, 3},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackLanguage* QpackRequestStreamLanguage() {
+  static const QpackLanguage* const language =
+      new QpackLanguage{QpackIndexedHeaderFieldInstruction(),
+                        QpackIndexedHeaderFieldPostBaseInstruction(),
+                        QpackLiteralHeaderFieldNameReferenceInstruction(),
+                        QpackLiteralHeaderFieldPostBaseInstruction(),
+                        QpackLiteralHeaderFieldInstruction()};
+  ValidateLangague(language);
+  return language;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::InsertWithNameReference(
+    bool is_static,
+    uint64_t name_index,
+    absl::string_view value) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = InsertWithNameReferenceInstruction();
+  instruction_with_values.s_bit_ = is_static;
+  instruction_with_values.varint_ = name_index;
+  instruction_with_values.value_ = value;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues
+QpackInstructionWithValues::InsertWithoutNameReference(
+    absl::string_view name,
+    absl::string_view value) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ =
+      InsertWithoutNameReferenceInstruction();
+  instruction_with_values.name_ = name;
+  instruction_with_values.value_ = value;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::Duplicate(
+    uint64_t index) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = DuplicateInstruction();
+  instruction_with_values.varint_ = index;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::SetDynamicTableCapacity(
+    uint64_t capacity) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = SetDynamicTableCapacityInstruction();
+  instruction_with_values.varint_ = capacity;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::InsertCountIncrement(
+    uint64_t increment) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = InsertCountIncrementInstruction();
+  instruction_with_values.varint_ = increment;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::HeaderAcknowledgement(
+    uint64_t stream_id) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = HeaderAcknowledgementInstruction();
+  instruction_with_values.varint_ = stream_id;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::StreamCancellation(
+    uint64_t stream_id) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = StreamCancellationInstruction();
+  instruction_with_values.varint_ = stream_id;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::Prefix(
+    uint64_t required_insert_count) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = QpackPrefixInstruction();
+  instruction_with_values.varint_ = required_insert_count;
+  instruction_with_values.varint2_ = 0;    // Delta Base.
+  instruction_with_values.s_bit_ = false;  // Delta Base sign.
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::IndexedHeaderField(
+    bool is_static,
+    uint64_t index) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = QpackIndexedHeaderFieldInstruction();
+  instruction_with_values.s_bit_ = is_static;
+  instruction_with_values.varint_ = index;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues
+QpackInstructionWithValues::LiteralHeaderFieldNameReference(
+    bool is_static,
+    uint64_t index,
+    absl::string_view value) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ =
+      QpackLiteralHeaderFieldNameReferenceInstruction();
+  instruction_with_values.s_bit_ = is_static;
+  instruction_with_values.varint_ = index;
+  instruction_with_values.value_ = value;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::LiteralHeaderField(
+    absl::string_view name,
+    absl::string_view value) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = QpackLiteralHeaderFieldInstruction();
+  instruction_with_values.name_ = name;
+  instruction_with_values.value_ = value;
+
+  return instruction_with_values;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instructions.h b/quiche/quic/core/qpack/qpack_instructions.h
new file mode 100644
index 0000000..e66651e
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instructions.h
@@ -0,0 +1,207 @@
+// Copyright (c) 2018 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_QPACK_QPACK_INSTRUCTIONS_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
+
+#include <cstdint>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QpackInstructionWithValuesPeer;
+}  // namespace test
+
+// Each instruction is identified with an opcode in the first byte.
+// |mask| determines which bits are part of the opcode.
+// |value| is the value of these bits.  (Other bits in value must be zero.)
+struct QUIC_EXPORT_PRIVATE QpackInstructionOpcode {
+  uint8_t value;
+  uint8_t mask;
+};
+
+bool operator==(const QpackInstructionOpcode& a,
+                const QpackInstructionOpcode& b);
+
+// Possible types of an instruction field.  Decoding a static bit does not
+// consume the current byte.  Decoding an integer or a length-prefixed string
+// literal consumes all bytes containing the field value.
+enum class QpackInstructionFieldType {
+  // A single bit indicating whether the index refers to the static table, or
+  // indicating the sign of Delta Base.  Called "S" bit because both "static"
+  // and "sign" start with the letter "S".
+  kSbit,
+  // An integer encoded with variable length encoding.  This could be an index,
+  // stream ID, maximum size, or Encoded Required Insert Count.
+  kVarint,
+  // A second integer encoded with variable length encoding.  This could be
+  // Delta Base.
+  kVarint2,
+  // A header name or header value encoded as:
+  //   a bit indicating whether it is Huffman encoded;
+  //   the encoded length of the string;
+  //   the header name or value optionally Huffman encoded.
+  kName,
+  kValue
+};
+
+// Each instruction field has a type and a parameter.
+// The meaning of the parameter depends on the field type.
+struct QUIC_EXPORT_PRIVATE QpackInstructionField {
+  QpackInstructionFieldType type;
+  // For a kSbit field, |param| is a mask with exactly one bit set.
+  // For kVarint fields, |param| is the prefix length of the integer encoding.
+  // For kName and kValue fields, |param| is the prefix length of the length of
+  // the string, and the bit immediately preceding the prefix is interpreted as
+  // the Huffman bit.
+  uint8_t param;
+};
+
+using QpackInstructionFields = std::vector<QpackInstructionField>;
+
+// A QPACK instruction consists of an opcode identifying the instruction,
+// followed by a non-empty list of fields.  The last field must be integer or
+// string literal type to guarantee that all bytes of the instruction are
+// consumed.
+struct QUIC_EXPORT_PRIVATE QpackInstruction {
+  QpackInstruction(const QpackInstruction&) = delete;
+  const QpackInstruction& operator=(const QpackInstruction&) = delete;
+
+  QpackInstructionOpcode opcode;
+  QpackInstructionFields fields;
+};
+
+// A language is a collection of instructions.  The order does not matter.
+// Every possible input must match exactly one instruction.
+using QpackLanguage = std::vector<const QpackInstruction*>;
+
+// Wire format defined in
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5
+
+// 5.2 Encoder stream instructions
+
+// 5.2.1 Insert With Name Reference
+const QpackInstruction* InsertWithNameReferenceInstruction();
+
+// 5.2.2 Insert Without Name Reference
+const QpackInstruction* InsertWithoutNameReferenceInstruction();
+
+// 5.2.3 Duplicate
+const QpackInstruction* DuplicateInstruction();
+
+// 5.2.4 Dynamic Table Size Update
+const QpackInstruction* SetDynamicTableCapacityInstruction();
+
+// Encoder stream language.
+const QpackLanguage* QpackEncoderStreamLanguage();
+
+// 5.3 Decoder stream instructions
+
+// 5.3.1 Insert Count Increment
+const QpackInstruction* InsertCountIncrementInstruction();
+
+// 5.3.2 Header Acknowledgement
+const QpackInstruction* HeaderAcknowledgementInstruction();
+
+// 5.3.3 Stream Cancellation
+const QpackInstruction* StreamCancellationInstruction();
+
+// Decoder stream language.
+const QpackLanguage* QpackDecoderStreamLanguage();
+
+// 5.4.1. Header data prefix instructions
+
+const QpackInstruction* QpackPrefixInstruction();
+
+const QpackLanguage* QpackPrefixLanguage();
+
+// 5.4.2. Request and push stream instructions
+
+// 5.4.2.1. Indexed Header Field
+const QpackInstruction* QpackIndexedHeaderFieldInstruction();
+
+// 5.4.2.2. Indexed Header Field With Post-Base Index
+const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction();
+
+// 5.4.2.3. Literal Header Field With Name Reference
+const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction();
+
+// 5.4.2.4. Literal Header Field With Post-Base Name Reference
+const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction();
+
+// 5.4.2.5. Literal Header Field Without Name Reference
+const QpackInstruction* QpackLiteralHeaderFieldInstruction();
+
+// Request and push stream language.
+const QpackLanguage* QpackRequestStreamLanguage();
+
+// Storage for instruction and field values to be encoded.
+// This class can only be instantiated using factory methods that take exactly
+// the arguments that the corresponding instruction needs.
+class QUIC_EXPORT_PRIVATE QpackInstructionWithValues {
+ public:
+  // 5.2 Encoder stream instructions
+  static QpackInstructionWithValues InsertWithNameReference(
+      bool is_static,
+      uint64_t name_index,
+      absl::string_view value);
+  static QpackInstructionWithValues InsertWithoutNameReference(
+      absl::string_view name,
+      absl::string_view value);
+  static QpackInstructionWithValues Duplicate(uint64_t index);
+  static QpackInstructionWithValues SetDynamicTableCapacity(uint64_t capacity);
+
+  // 5.3 Decoder stream instructions
+  static QpackInstructionWithValues InsertCountIncrement(uint64_t increment);
+  static QpackInstructionWithValues HeaderAcknowledgement(uint64_t stream_id);
+  static QpackInstructionWithValues StreamCancellation(uint64_t stream_id);
+
+  // 5.4.1. Header data prefix.  Delta Base is hardcoded to be zero.
+  static QpackInstructionWithValues Prefix(uint64_t required_insert_count);
+
+  // 5.4.2. Request and push stream instructions
+  static QpackInstructionWithValues IndexedHeaderField(bool is_static,
+                                                       uint64_t index);
+  static QpackInstructionWithValues LiteralHeaderFieldNameReference(
+      bool is_static,
+      uint64_t index,
+      absl::string_view value);
+  static QpackInstructionWithValues LiteralHeaderField(absl::string_view name,
+                                                       absl::string_view value);
+
+  const QpackInstruction* instruction() const { return instruction_; }
+  bool s_bit() const { return s_bit_; }
+  uint64_t varint() const { return varint_; }
+  uint64_t varint2() const { return varint2_; }
+  absl::string_view name() const { return name_; }
+  absl::string_view value() const { return value_; }
+
+  // Used by QpackEncoder, because in the first pass it stores absolute indices,
+  // which are converted into relative indices in the second pass after base is
+  // determined.
+  void set_varint(uint64_t varint) { varint_ = varint; }
+
+ private:
+  friend test::QpackInstructionWithValuesPeer;
+
+  QpackInstructionWithValues() = default;
+
+  // |*instruction| is not owned.
+  const QpackInstruction* instruction_ = nullptr;
+  bool s_bit_ = false;
+  uint64_t varint_ = 0;
+  uint64_t varint2_ = 0;
+  absl::string_view name_;
+  absl::string_view value_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
diff --git a/quiche/quic/core/qpack/qpack_offline_decoder_bin.cc b/quiche/quic/core/qpack/qpack_offline_decoder_bin.cc
new file mode 100644
index 0000000..a5cbc85
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_offline_decoder_bin.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2018 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 <cstddef>
+#include <iostream>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/test_tools/qpack/qpack_offline_decoder.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+int main(int argc, char* argv[]) {
+  const char* usage =
+      "Usage: qpack_offline_decoder input_filename expected_headers_filename "
+      "....";
+  std::vector<std::string> args =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+
+  if (args.size() < 2 || args.size() % 2 != 0) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    return 1;
+  }
+
+  size_t i;
+  size_t success_count = 0;
+  for (i = 0; 2 * i < args.size(); ++i) {
+    const absl::string_view input_filename(args[2 * i]);
+    const absl::string_view expected_headers_filename(args[2 * i + 1]);
+
+    // Every file represents a different connection,
+    // therefore every file needs a fresh decoding context.
+    quic::QpackOfflineDecoder decoder;
+    if (decoder.DecodeAndVerifyOfflineData(input_filename,
+                                           expected_headers_filename)) {
+      ++success_count;
+    }
+  }
+
+  std::cout << "Processed " << i << " pairs of input files, " << success_count
+            << " passed, " << (i - success_count) << " failed." << std::endl;
+
+  // Return success if all input files pass.
+  return (success_count == i) ? 0 : 1;
+}
diff --git a/quiche/quic/core/qpack/qpack_progressive_decoder.cc b/quiche/quic/core/qpack/qpack_progressive_decoder.cc
new file mode 100644
index 0000000..1a326d5
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_progressive_decoder.cc
@@ -0,0 +1,428 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_progressive_decoder.h"
+
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_index_conversions.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/core/qpack/qpack_required_insert_count.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// The value argument passed to OnHeaderDecoded() is from an entry in the static
+// table.
+constexpr bool kValueFromStaticTable = true;
+
+}  // anonymous namespace
+
+QpackProgressiveDecoder::QpackProgressiveDecoder(
+    QuicStreamId stream_id, BlockedStreamLimitEnforcer* enforcer,
+    DecodingCompletedVisitor* visitor, QpackDecoderHeaderTable* header_table,
+    HeadersHandlerInterface* handler)
+    : stream_id_(stream_id),
+      prefix_decoder_(std::make_unique<QpackInstructionDecoder>(
+          QpackPrefixLanguage(), this)),
+      instruction_decoder_(QpackRequestStreamLanguage(), this),
+      enforcer_(enforcer),
+      visitor_(visitor),
+      header_table_(header_table),
+      handler_(handler),
+      required_insert_count_(0),
+      base_(0),
+      required_insert_count_so_far_(0),
+      prefix_decoded_(false),
+      blocked_(false),
+      decoding_(true),
+      error_detected_(false),
+      cancelled_(false) {}
+
+QpackProgressiveDecoder::~QpackProgressiveDecoder() {
+  if (blocked_ && !cancelled_) {
+    header_table_->UnregisterObserver(required_insert_count_, this);
+  }
+}
+
+void QpackProgressiveDecoder::Decode(absl::string_view data) {
+  QUICHE_DCHECK(decoding_);
+
+  if (data.empty() || error_detected_) {
+    return;
+  }
+
+  // Decode prefix byte by byte until the first (and only) instruction is
+  // decoded.
+  while (!prefix_decoded_) {
+    QUICHE_DCHECK(!blocked_);
+
+    if (!prefix_decoder_->Decode(data.substr(0, 1))) {
+      return;
+    }
+
+    // |prefix_decoder_->Decode()| must return false if an error is detected.
+    QUICHE_DCHECK(!error_detected_);
+
+    data = data.substr(1);
+    if (data.empty()) {
+      return;
+    }
+  }
+
+  if (blocked_) {
+    buffer_.append(data.data(), data.size());
+  } else {
+    QUICHE_DCHECK(buffer_.empty());
+
+    instruction_decoder_.Decode(data);
+  }
+}
+
+void QpackProgressiveDecoder::EndHeaderBlock() {
+  QUICHE_DCHECK(decoding_);
+  decoding_ = false;
+
+  if (!blocked_) {
+    FinishDecoding();
+  }
+}
+
+bool QpackProgressiveDecoder::OnInstructionDecoded(
+    const QpackInstruction* instruction) {
+  if (instruction == QpackPrefixInstruction()) {
+    return DoPrefixInstruction();
+  }
+
+  QUICHE_DCHECK(prefix_decoded_);
+  QUICHE_DCHECK_LE(required_insert_count_,
+                   header_table_->inserted_entry_count());
+
+  if (instruction == QpackIndexedHeaderFieldInstruction()) {
+    return DoIndexedHeaderFieldInstruction();
+  }
+  if (instruction == QpackIndexedHeaderFieldPostBaseInstruction()) {
+    return DoIndexedHeaderFieldPostBaseInstruction();
+  }
+  if (instruction == QpackLiteralHeaderFieldNameReferenceInstruction()) {
+    return DoLiteralHeaderFieldNameReferenceInstruction();
+  }
+  if (instruction == QpackLiteralHeaderFieldPostBaseInstruction()) {
+    return DoLiteralHeaderFieldPostBaseInstruction();
+  }
+  QUICHE_DCHECK_EQ(instruction, QpackLiteralHeaderFieldInstruction());
+  return DoLiteralHeaderFieldInstruction();
+}
+
+void QpackProgressiveDecoder::OnInstructionDecodingError(
+    QpackInstructionDecoder::ErrorCode /* error_code */,
+    absl::string_view error_message) {
+  // Ignore |error_code| and always use QUIC_QPACK_DECOMPRESSION_FAILED to avoid
+  // having to define a new QuicErrorCode for every instruction decoder error.
+  OnError(QUIC_QPACK_DECOMPRESSION_FAILED, error_message);
+}
+
+void QpackProgressiveDecoder::OnInsertCountReachedThreshold() {
+  QUICHE_DCHECK(blocked_);
+
+  // Clear |blocked_| before calling instruction_decoder_.Decode() below,
+  // because that might destroy |this| and ~QpackProgressiveDecoder() needs to
+  // know not to call UnregisterObserver().
+  blocked_ = false;
+  enforcer_->OnStreamUnblocked(stream_id_);
+
+  if (!buffer_.empty()) {
+    std::string buffer(std::move(buffer_));
+    buffer_.clear();
+    if (!instruction_decoder_.Decode(buffer)) {
+      // |this| might be destroyed.
+      return;
+    }
+  }
+
+  if (!decoding_) {
+    FinishDecoding();
+  }
+}
+
+void QpackProgressiveDecoder::Cancel() {
+  cancelled_ = true;
+}
+
+bool QpackProgressiveDecoder::DoIndexedHeaderFieldInstruction() {
+  if (!instruction_decoder_.s_bit()) {
+    uint64_t absolute_index;
+    if (!QpackRequestStreamRelativeIndexToAbsoluteIndex(
+            instruction_decoder_.varint(), base_, &absolute_index)) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid relative index.");
+      return false;
+    }
+
+    if (absolute_index >= required_insert_count_) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Absolute Index must be smaller than Required Insert Count.");
+      return false;
+    }
+
+    QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
+    required_insert_count_so_far_ =
+        std::max(required_insert_count_so_far_, absolute_index + 1);
+
+    auto entry =
+        header_table_->LookupEntry(/* is_static = */ false, absolute_index);
+    if (!entry) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Dynamic table entry already evicted.");
+      return false;
+    }
+
+    header_table_->set_dynamic_table_entry_referenced();
+    return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
+                           entry->value());
+  }
+
+  auto entry = header_table_->LookupEntry(/* is_static = */ true,
+                                          instruction_decoder_.varint());
+  if (!entry) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Static table entry not found.");
+    return false;
+  }
+
+  return OnHeaderDecoded(kValueFromStaticTable, entry->name(), entry->value());
+}
+
+bool QpackProgressiveDecoder::DoIndexedHeaderFieldPostBaseInstruction() {
+  uint64_t absolute_index;
+  if (!QpackPostBaseIndexToAbsoluteIndex(instruction_decoder_.varint(), base_,
+                                         &absolute_index)) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid post-base index.");
+    return false;
+  }
+
+  if (absolute_index >= required_insert_count_) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Absolute Index must be smaller than Required Insert Count.");
+    return false;
+  }
+
+  QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
+  required_insert_count_so_far_ =
+      std::max(required_insert_count_so_far_, absolute_index + 1);
+
+  auto entry =
+      header_table_->LookupEntry(/* is_static = */ false, absolute_index);
+  if (!entry) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Dynamic table entry already evicted.");
+    return false;
+  }
+
+  header_table_->set_dynamic_table_entry_referenced();
+  return OnHeaderDecoded(!kValueFromStaticTable, entry->name(), entry->value());
+}
+
+bool QpackProgressiveDecoder::DoLiteralHeaderFieldNameReferenceInstruction() {
+  if (!instruction_decoder_.s_bit()) {
+    uint64_t absolute_index;
+    if (!QpackRequestStreamRelativeIndexToAbsoluteIndex(
+            instruction_decoder_.varint(), base_, &absolute_index)) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid relative index.");
+      return false;
+    }
+
+    if (absolute_index >= required_insert_count_) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Absolute Index must be smaller than Required Insert Count.");
+      return false;
+    }
+
+    QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
+    required_insert_count_so_far_ =
+        std::max(required_insert_count_so_far_, absolute_index + 1);
+
+    auto entry =
+        header_table_->LookupEntry(/* is_static = */ false, absolute_index);
+    if (!entry) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Dynamic table entry already evicted.");
+      return false;
+    }
+
+    header_table_->set_dynamic_table_entry_referenced();
+    return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
+                           instruction_decoder_.value());
+  }
+
+  auto entry = header_table_->LookupEntry(/* is_static = */ true,
+                                          instruction_decoder_.varint());
+  if (!entry) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Static table entry not found.");
+    return false;
+  }
+
+  return OnHeaderDecoded(kValueFromStaticTable, entry->name(),
+                         instruction_decoder_.value());
+}
+
+bool QpackProgressiveDecoder::DoLiteralHeaderFieldPostBaseInstruction() {
+  uint64_t absolute_index;
+  if (!QpackPostBaseIndexToAbsoluteIndex(instruction_decoder_.varint(), base_,
+                                         &absolute_index)) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid post-base index.");
+    return false;
+  }
+
+  if (absolute_index >= required_insert_count_) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Absolute Index must be smaller than Required Insert Count.");
+    return false;
+  }
+
+  QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
+  required_insert_count_so_far_ =
+      std::max(required_insert_count_so_far_, absolute_index + 1);
+
+  auto entry =
+      header_table_->LookupEntry(/* is_static = */ false, absolute_index);
+  if (!entry) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Dynamic table entry already evicted.");
+    return false;
+  }
+
+  header_table_->set_dynamic_table_entry_referenced();
+  return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
+                         instruction_decoder_.value());
+}
+
+bool QpackProgressiveDecoder::DoLiteralHeaderFieldInstruction() {
+  return OnHeaderDecoded(!kValueFromStaticTable, instruction_decoder_.name(),
+                         instruction_decoder_.value());
+}
+
+bool QpackProgressiveDecoder::DoPrefixInstruction() {
+  QUICHE_DCHECK(!prefix_decoded_);
+
+  if (!QpackDecodeRequiredInsertCount(
+          prefix_decoder_->varint(), header_table_->max_entries(),
+          header_table_->inserted_entry_count(), &required_insert_count_)) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Error decoding Required Insert Count.");
+    return false;
+  }
+
+  const bool sign = prefix_decoder_->s_bit();
+  const uint64_t delta_base = prefix_decoder_->varint2();
+  if (!DeltaBaseToBase(sign, delta_base, &base_)) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Error calculating Base.");
+    return false;
+  }
+
+  prefix_decoded_ = true;
+
+  if (required_insert_count_ > header_table_->inserted_entry_count()) {
+    if (!enforcer_->OnStreamBlocked(stream_id_)) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Limit on number of blocked streams exceeded.");
+      return false;
+    }
+    blocked_ = true;
+    header_table_->RegisterObserver(required_insert_count_, this);
+  }
+
+  return true;
+}
+
+bool QpackProgressiveDecoder::OnHeaderDecoded(bool value_from_static_table,
+                                              absl::string_view name,
+                                              absl::string_view value) {
+  // Skip test for static table entries as they are all known to be valid.
+  if (!value_from_static_table) {
+    // According to Section 10.3 of
+    // https://quicwg.org/base-drafts/draft-ietf-quic-http.html,
+    // "[...] HTTP/3 can transport field values that are not valid. While most
+    // values that can be encoded will not alter field parsing, carriage return
+    // (CR, ASCII 0x0d), line feed (LF, ASCII 0x0a), and the zero character
+    // (NUL, ASCII 0x00) might be exploited by an attacker if they are
+    // translated verbatim. Any request or response that contains a character
+    // not permitted in a field value MUST be treated as malformed [...]"
+    for (const auto c : value) {
+      if (c == '\0' || c == '\n' || c == '\r') {
+        OnError(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE,
+                "Invalid character in field value.");
+        return false;
+      }
+    }
+  }
+
+  handler_->OnHeaderDecoded(name, value);
+  return true;
+}
+
+void QpackProgressiveDecoder::FinishDecoding() {
+  QUICHE_DCHECK(buffer_.empty());
+  QUICHE_DCHECK(!blocked_);
+  QUICHE_DCHECK(!decoding_);
+
+  if (error_detected_) {
+    return;
+  }
+
+  if (!instruction_decoder_.AtInstructionBoundary()) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Incomplete header block.");
+    return;
+  }
+
+  if (!prefix_decoded_) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Incomplete header data prefix.");
+    return;
+  }
+
+  if (required_insert_count_ != required_insert_count_so_far_) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Required Insert Count too large.");
+    return;
+  }
+
+  visitor_->OnDecodingCompleted(stream_id_, required_insert_count_);
+  handler_->OnDecodingCompleted();
+}
+
+void QpackProgressiveDecoder::OnError(QuicErrorCode error_code,
+                                      absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+
+  error_detected_ = true;
+  // Might destroy |this|.
+  handler_->OnDecodingErrorDetected(error_code, error_message);
+}
+
+bool QpackProgressiveDecoder::DeltaBaseToBase(bool sign,
+                                              uint64_t delta_base,
+                                              uint64_t* base) {
+  if (sign) {
+    if (delta_base == std::numeric_limits<uint64_t>::max() ||
+        required_insert_count_ < delta_base + 1) {
+      return false;
+    }
+    *base = required_insert_count_ - delta_base - 1;
+    return true;
+  }
+
+  if (delta_base >
+      std::numeric_limits<uint64_t>::max() - required_insert_count_) {
+    return false;
+  }
+  *base = required_insert_count_ + delta_base;
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_progressive_decoder.h b/quiche/quic/core/qpack/qpack_progressive_decoder.h
new file mode 100644
index 0000000..7616376
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_progressive_decoder.h
@@ -0,0 +1,183 @@
+// Copyright (c) 2018 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_QPACK_QPACK_PROGRESSIVE_DECODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QpackDecoderHeaderTable;
+
+// Class to decode a single header block.
+class QUIC_EXPORT_PRIVATE QpackProgressiveDecoder
+    : public QpackInstructionDecoder::Delegate,
+      public QpackDecoderHeaderTable::Observer {
+ public:
+  // Interface for receiving decoded header block from the decoder.
+  class QUIC_EXPORT_PRIVATE HeadersHandlerInterface {
+   public:
+    virtual ~HeadersHandlerInterface() {}
+
+    // Called when a new header name-value pair is decoded.  Multiple values for
+    // a given name will be emitted as multiple calls to OnHeader.
+    virtual void OnHeaderDecoded(absl::string_view name,
+                                 absl::string_view value) = 0;
+
+    // Called when the header block is completely decoded.
+    // Indicates the total number of bytes in this block.
+    // The decoder will not access the handler after this call.
+    // Note that this method might not be called synchronously when the header
+    // block is received on the wire, in case decoding is blocked on receiving
+    // entries on the encoder stream.
+    virtual void OnDecodingCompleted() = 0;
+
+    // Called when a decoding error has occurred.  No other methods will be
+    // called afterwards.  Implementations are allowed to destroy
+    // the QpackProgressiveDecoder instance synchronously.
+    virtual void OnDecodingErrorDetected(QuicErrorCode error_code,
+                                         absl::string_view error_message) = 0;
+  };
+
+  // Interface for keeping track of blocked streams for the purpose of enforcing
+  // the limit communicated to peer via QPACK_BLOCKED_STREAMS settings.
+  class QUIC_EXPORT_PRIVATE BlockedStreamLimitEnforcer {
+   public:
+    virtual ~BlockedStreamLimitEnforcer() {}
+
+    // Called when the stream becomes blocked.  Returns true if allowed. Returns
+    // false if limit is violated, in which case QpackProgressiveDecoder signals
+    // an error.
+    // Stream must not be already blocked.
+    virtual bool OnStreamBlocked(QuicStreamId stream_id) = 0;
+
+    // Called when the stream becomes unblocked.
+    // Stream must be blocked.
+    virtual void OnStreamUnblocked(QuicStreamId stream_id) = 0;
+  };
+
+  // Visitor to be notified when decoding is completed.
+  class QUIC_EXPORT_PRIVATE DecodingCompletedVisitor {
+   public:
+    virtual ~DecodingCompletedVisitor() = default;
+
+    // Called when decoding is completed, with Required Insert Count of the
+    // decoded header block.  Required Insert Count is defined at
+    // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams.
+    virtual void OnDecodingCompleted(QuicStreamId stream_id,
+                                     uint64_t required_insert_count) = 0;
+  };
+
+  QpackProgressiveDecoder() = delete;
+  QpackProgressiveDecoder(QuicStreamId stream_id,
+                          BlockedStreamLimitEnforcer* enforcer,
+                          DecodingCompletedVisitor* visitor,
+                          QpackDecoderHeaderTable* header_table,
+                          HeadersHandlerInterface* handler);
+  QpackProgressiveDecoder(const QpackProgressiveDecoder&) = delete;
+  QpackProgressiveDecoder& operator=(const QpackProgressiveDecoder&) = delete;
+  ~QpackProgressiveDecoder() override;
+
+  // Provide a data fragment to decode.
+  void Decode(absl::string_view data);
+
+  // Signal that the entire header block has been received and passed in
+  // through Decode().  No methods must be called afterwards.
+  void EndHeaderBlock();
+
+  // QpackInstructionDecoder::Delegate implementation.
+  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
+  void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
+                                  absl::string_view error_message) override;
+
+  // QpackDecoderHeaderTable::Observer implementation.
+  void OnInsertCountReachedThreshold() override;
+  void Cancel() override;
+
+ private:
+  bool DoIndexedHeaderFieldInstruction();
+  bool DoIndexedHeaderFieldPostBaseInstruction();
+  bool DoLiteralHeaderFieldNameReferenceInstruction();
+  bool DoLiteralHeaderFieldPostBaseInstruction();
+  bool DoLiteralHeaderFieldInstruction();
+  bool DoPrefixInstruction();
+
+  // Called when an entry is decoded.  Performs validation and calls
+  // HeadersHandlerInterface::OnHeaderDecoded() or OnError() as needed.  Returns
+  // true if header value is valid, false otherwise.  Skips validation if
+  // |value_from_static_table| is true, because static table entries are always
+  // valid.
+  bool OnHeaderDecoded(bool value_from_static_table, absl::string_view name,
+                       absl::string_view value);
+
+  // Called as soon as EndHeaderBlock() is called and decoding is not blocked.
+  void FinishDecoding();
+
+  // Called on error.
+  void OnError(QuicErrorCode error_code, absl::string_view error_message);
+
+  // Calculates Base from |required_insert_count_|, which must be set before
+  // calling this method, and sign bit and Delta Base in the Header Data Prefix,
+  // which are passed in as arguments.  Returns true on success, false on
+  // failure due to overflow/underflow.
+  bool DeltaBaseToBase(bool sign, uint64_t delta_base, uint64_t* base);
+
+  const QuicStreamId stream_id_;
+
+  // |prefix_decoder_| only decodes a handful of bytes then it can be
+  // destroyed to conserve memory.  |instruction_decoder_|, on the other hand,
+  // is used until the entire header block is decoded.
+  std::unique_ptr<QpackInstructionDecoder> prefix_decoder_;
+  QpackInstructionDecoder instruction_decoder_;
+
+  BlockedStreamLimitEnforcer* const enforcer_;
+  DecodingCompletedVisitor* const visitor_;
+  QpackDecoderHeaderTable* const header_table_;
+  HeadersHandlerInterface* const handler_;
+
+  // Required Insert Count and Base are decoded from the Header Data Prefix.
+  uint64_t required_insert_count_;
+  uint64_t base_;
+
+  // Required Insert Count is one larger than the largest absolute index of all
+  // referenced dynamic table entries, or zero if no dynamic table entries are
+  // referenced.  |required_insert_count_so_far_| starts out as zero and keeps
+  // track of the Required Insert Count based on entries decoded so far.
+  // After decoding is completed, it is compared to |required_insert_count_|.
+  uint64_t required_insert_count_so_far_;
+
+  // False until prefix is fully read and decoded.
+  bool prefix_decoded_;
+
+  // True if waiting for dynamic table entries to arrive.
+  bool blocked_;
+
+  // Buffer the entire header block after the prefix while decoding is blocked.
+  std::string buffer_;
+
+  // True until EndHeaderBlock() is called.
+  bool decoding_;
+
+  // True if a decoding error has been detected.
+  bool error_detected_;
+
+  // True if QpackDecoderHeaderTable has been destroyed
+  // while decoding is still blocked.
+  bool cancelled_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
diff --git a/quiche/quic/core/qpack/qpack_receive_stream.cc b/quiche/quic/core/qpack/qpack_receive_stream.cc
new file mode 100644
index 0000000..b00a06f
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_receive_stream.cc
@@ -0,0 +1,33 @@
+// Copyright 2019 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 "quiche/quic/core/qpack/qpack_receive_stream.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_session.h"
+
+namespace quic {
+QpackReceiveStream::QpackReceiveStream(PendingStream* pending,
+                                       QuicSession* session,
+                                       QpackStreamReceiver* receiver)
+    : QuicStream(pending, session, /*is_static=*/true), receiver_(receiver) {}
+
+void QpackReceiveStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+      "RESET_STREAM received for QPACK receive stream");
+}
+
+void QpackReceiveStream::OnDataAvailable() {
+  iovec iov;
+  while (!reading_stopped() && sequencer()->GetReadableRegion(&iov)) {
+    QUICHE_DCHECK(!sequencer()->IsClosed());
+
+    receiver_->Decode(absl::string_view(
+        reinterpret_cast<const char*>(iov.iov_base), iov.iov_len));
+    sequencer()->MarkConsumed(iov.iov_len);
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_receive_stream.h b/quiche/quic/core/qpack/qpack_receive_stream.h
new file mode 100644
index 0000000..0509fae
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_receive_stream.h
@@ -0,0 +1,42 @@
+// Copyright 2019 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_QPACK_QPACK_RECEIVE_STREAM_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
+
+#include "quiche/quic/core/qpack/qpack_stream_receiver.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicSession;
+
+// QPACK 4.2.1 Encoder and Decoder Streams.
+// The QPACK receive stream is peer initiated and is read only.
+class QUIC_EXPORT_PRIVATE QpackReceiveStream : public QuicStream {
+ public:
+  // Construct receive stream from pending stream, the |pending| object needs
+  // to be deleted after the construction.
+  QpackReceiveStream(PendingStream* pending,
+                     QuicSession* session,
+                     QpackStreamReceiver* receiver);
+  QpackReceiveStream(const QpackReceiveStream&) = delete;
+  QpackReceiveStream& operator=(const QpackReceiveStream&) = delete;
+  ~QpackReceiveStream() override = default;
+
+  // Overriding QuicStream::OnStreamReset to make sure QPACK stream is never
+  // closed before connection.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+  // Implementation of QuicStream.
+  void OnDataAvailable() override;
+
+ private:
+  QpackStreamReceiver* receiver_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
diff --git a/quiche/quic/core/qpack/qpack_receive_stream_test.cc b/quiche/quic/core/qpack/qpack_receive_stream_test.cc
new file mode 100644
index 0000000..c148510
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_receive_stream_test.cc
@@ -0,0 +1,98 @@
+// Copyright 2019 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 "quiche/quic/core/qpack/qpack_receive_stream.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::StrictMock;
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams: version: "
+                   << ParsedQuicVersionToString(version)
+                   << ", perspective: " << perspective;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (const auto& version : AllSupportedVersions()) {
+    if (!VersionUsesHttp3(version.transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(version, p);
+    }
+  }
+  return params;
+}
+
+class QpackReceiveStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QpackReceiveStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_,
+            &alarm_factory_,
+            perspective(),
+            SupportedVersions(GetParam().version))),
+        session_(connection_) {
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    QuicStreamId id = perspective() == Perspective::IS_SERVER
+                          ? GetNthClientInitiatedUnidirectionalStreamId(
+                                session_.transport_version(), 3)
+                          : GetNthServerInitiatedUnidirectionalStreamId(
+                                session_.transport_version(), 3);
+    char type[] = {0x03};
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_.OnStreamFrame(data1);
+    qpack_receive_stream_ =
+        QuicSpdySessionPeer::GetQpackDecoderReceiveStream(&session_);
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QpackReceiveStream* qpack_receive_stream_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QpackReceiveStreamTest,
+                         ::testing::ValuesIn(GetTestParams()));
+
+TEST_P(QpackReceiveStreamTest, ResetQpackReceiveStream) {
+  EXPECT_TRUE(qpack_receive_stream_->is_static());
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId,
+                               qpack_receive_stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
+  qpack_receive_stream_->OnStreamReset(rst_frame);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_required_insert_count.cc b/quiche/quic/core/qpack/qpack_required_insert_count.cc
new file mode 100644
index 0000000..544dffe
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_required_insert_count.cc
@@ -0,0 +1,71 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/qpack_required_insert_count.h"
+
+#include <limits>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+uint64_t QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
+                                        uint64_t max_entries) {
+  if (required_insert_count == 0) {
+    return 0;
+  }
+
+  return required_insert_count % (2 * max_entries) + 1;
+}
+
+bool QpackDecodeRequiredInsertCount(uint64_t encoded_required_insert_count,
+                                    uint64_t max_entries,
+                                    uint64_t total_number_of_inserts,
+                                    uint64_t* required_insert_count) {
+  if (encoded_required_insert_count == 0) {
+    *required_insert_count = 0;
+    return true;
+  }
+
+  // |max_entries| is calculated by dividing an unsigned 64-bit integer by 32,
+  // precluding all calculations in this method from overflowing.
+  QUICHE_DCHECK_LE(max_entries, std::numeric_limits<uint64_t>::max() / 32);
+
+  if (encoded_required_insert_count > 2 * max_entries) {
+    return false;
+  }
+
+  *required_insert_count = encoded_required_insert_count - 1;
+  QUICHE_DCHECK_LT(*required_insert_count,
+                   std::numeric_limits<uint64_t>::max() / 16);
+
+  uint64_t current_wrapped = total_number_of_inserts % (2 * max_entries);
+  QUICHE_DCHECK_LT(current_wrapped, std::numeric_limits<uint64_t>::max() / 16);
+
+  if (current_wrapped >= *required_insert_count + max_entries) {
+    // Required Insert Count wrapped around 1 extra time.
+    *required_insert_count += 2 * max_entries;
+  } else if (current_wrapped + max_entries < *required_insert_count) {
+    // Decoder wrapped around 1 extra time.
+    current_wrapped += 2 * max_entries;
+  }
+
+  if (*required_insert_count >
+      std::numeric_limits<uint64_t>::max() - total_number_of_inserts) {
+    return false;
+  }
+
+  *required_insert_count += total_number_of_inserts;
+
+  // Prevent underflow, also disallow invalid value 0 for Required Insert Count.
+  if (current_wrapped >= *required_insert_count) {
+    return false;
+  }
+
+  *required_insert_count -= current_wrapped;
+
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_required_insert_count.h b/quiche/quic/core/qpack/qpack_required_insert_count.h
new file mode 100644
index 0000000..9b4252e
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_required_insert_count.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2019 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_QPACK_REQUIRED_INSERT_COUNT_H_
+#define QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
+
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Calculate Encoded Required Insert Count from Required Insert Count and
+// MaxEntries according to
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.
+QUIC_EXPORT_PRIVATE uint64_t
+QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
+                               uint64_t max_entries);
+
+// Calculate Required Insert Count from Encoded Required Insert Count,
+// MaxEntries, and total number of dynamic table insertions according to
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.  Returns true
+// on success, false on invalid input or overflow/underflow.
+QUIC_EXPORT_PRIVATE bool QpackDecodeRequiredInsertCount(
+    uint64_t encoded_required_insert_count,
+    uint64_t max_entries,
+    uint64_t total_number_of_inserts,
+    uint64_t* required_insert_count);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
diff --git a/quiche/quic/core/qpack/qpack_required_insert_count_test.cc b/quiche/quic/core/qpack/qpack_required_insert_count_test.cc
new file mode 100644
index 0000000..95456b9
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_required_insert_count_test.cc
@@ -0,0 +1,125 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/qpack_required_insert_count.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(QpackRequiredInsertCountTest, QpackEncodeRequiredInsertCount) {
+  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 0));
+  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 8));
+  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 1024));
+
+  EXPECT_EQ(2u, QpackEncodeRequiredInsertCount(1, 8));
+  EXPECT_EQ(5u, QpackEncodeRequiredInsertCount(20, 8));
+  EXPECT_EQ(7u, QpackEncodeRequiredInsertCount(106, 10));
+}
+
+// For testing valid decodings, the Encoded Required Insert Count is calculated
+// from Required Insert Count, so that there is an expected value to compare
+// the decoded value against, and so that intricate inequalities can be
+// documented.
+struct {
+  uint64_t required_insert_count;
+  uint64_t max_entries;
+  uint64_t total_number_of_inserts;
+} kTestData[] = {
+    // Maximum dynamic table capacity is zero.
+    {0, 0, 0},
+    // No dynamic entries in header.
+    {0, 100, 0},
+    {0, 100, 500},
+    // Required Insert Count has not wrapped around yet, no entries evicted.
+    {15, 100, 25},
+    {20, 100, 10},
+    // Required Insert Count has not wrapped around yet, some entries evicted.
+    {90, 100, 110},
+    // Required Insert Count has wrapped around.
+    {234, 100, 180},
+    // Required Insert Count has wrapped around many times.
+    {5678, 100, 5701},
+    // Lowest and highest possible Required Insert Count values
+    // for given MaxEntries and total number of insertions.
+    {401, 100, 500},
+    {600, 100, 500}};
+
+TEST(QpackRequiredInsertCountTest, QpackDecodeRequiredInsertCount) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
+    const uint64_t required_insert_count = kTestData[i].required_insert_count;
+    const uint64_t max_entries = kTestData[i].max_entries;
+    const uint64_t total_number_of_inserts =
+        kTestData[i].total_number_of_inserts;
+
+    if (required_insert_count != 0) {
+      // Dynamic entries cannot be referenced if dynamic table capacity is zero.
+      ASSERT_LT(0u, max_entries) << i;
+      // Entry |total_number_of_inserts - 1 - max_entries| and earlier entries
+      // are evicted.  Entry |required_insert_count - 1| is referenced.  No
+      // evicted entry can be referenced.
+      ASSERT_LT(total_number_of_inserts, required_insert_count + max_entries)
+          << i;
+      // Entry |required_insert_count - 1 - max_entries| and earlier entries are
+      // evicted, entry |total_number_of_inserts - 1| is the last acknowledged
+      // entry.  Every evicted entry must be acknowledged.
+      ASSERT_LE(required_insert_count, total_number_of_inserts + max_entries)
+          << i;
+    }
+
+    uint64_t encoded_required_insert_count =
+        QpackEncodeRequiredInsertCount(required_insert_count, max_entries);
+
+    // Initialize to a value different from the expected output to confirm that
+    // QpackDecodeRequiredInsertCount() modifies the value of
+    // |decoded_required_insert_count|.
+    uint64_t decoded_required_insert_count = required_insert_count + 1;
+    EXPECT_TRUE(QpackDecodeRequiredInsertCount(
+        encoded_required_insert_count, max_entries, total_number_of_inserts,
+        &decoded_required_insert_count))
+        << i;
+
+    EXPECT_EQ(decoded_required_insert_count, required_insert_count) << i;
+  }
+}
+
+// Failures are tested with hardcoded values for encoded required insert count,
+// to provide test coverage for values that would never be produced by a well
+// behaved encoding function.
+struct {
+  uint64_t encoded_required_insert_count;
+  uint64_t max_entries;
+  uint64_t total_number_of_inserts;
+} kInvalidTestData[] = {
+    // Maximum dynamic table capacity is zero, yet header block
+    // claims to have a reference to a dynamic table entry.
+    {1, 0, 0},
+    {9, 0, 0},
+    // Examples from
+    // https://github.com/quicwg/base-drafts/issues/2112#issue-389626872.
+    {1, 10, 2},
+    {18, 10, 2},
+    // Encoded Required Insert Count value too small or too large
+    // for given MaxEntries and total number of insertions.
+    {400, 100, 500},
+    {601, 100, 500}};
+
+TEST(QpackRequiredInsertCountTest, DecodeRequiredInsertCountError) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kInvalidTestData); ++i) {
+    uint64_t decoded_required_insert_count = 0;
+    EXPECT_FALSE(QpackDecodeRequiredInsertCount(
+        kInvalidTestData[i].encoded_required_insert_count,
+        kInvalidTestData[i].max_entries,
+        kInvalidTestData[i].total_number_of_inserts,
+        &decoded_required_insert_count))
+        << i;
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_round_trip_test.cc b/quiche/quic/core/qpack/qpack_round_trip_test.cc
new file mode 100644
index 0000000..d729793
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_round_trip_test.cc
@@ -0,0 +1,137 @@
+// Copyright (c) 2018 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 <string>
+#include <tuple>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+using ::testing::Values;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QpackRoundTripTest : public QuicTestWithParam<FragmentMode> {
+ public:
+  QpackRoundTripTest() = default;
+  ~QpackRoundTripTest() override = default;
+
+  spdy::Http2HeaderBlock EncodeThenDecode(
+      const spdy::Http2HeaderBlock& header_list) {
+    NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
+    NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
+    QpackEncoder encoder(&decoder_stream_error_delegate);
+    encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate);
+    std::string encoded_header_block =
+        encoder.EncodeHeaderList(/* stream_id = */ 1, header_list, nullptr);
+
+    TestHeadersHandler handler;
+    NoopEncoderStreamErrorDelegate encoder_stream_error_delegate;
+    NoopQpackStreamSenderDelegate decoder_stream_sender_delegate;
+    // TODO(b/112770235): Test dynamic table and blocked streams.
+    QpackDecode(
+        /* maximum_dynamic_table_capacity = */ 0,
+        /* maximum_blocked_streams = */ 0, &encoder_stream_error_delegate,
+        &decoder_stream_sender_delegate, &handler,
+        FragmentModeToFragmentSizeGenerator(GetParam()), encoded_header_block);
+
+    EXPECT_TRUE(handler.decoding_completed());
+    EXPECT_FALSE(handler.decoding_error_detected());
+
+    return handler.ReleaseHeaderList();
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         QpackRoundTripTest,
+                         Values(FragmentMode::kSingleChunk,
+                                FragmentMode::kOctetByOctet));
+
+TEST_P(QpackRoundTripTest, Empty) {
+  spdy::Http2HeaderBlock header_list;
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+TEST_P(QpackRoundTripTest, EmptyName) {
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  header_list[""] = "bar";
+
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+TEST_P(QpackRoundTripTest, EmptyValue) {
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "";
+  header_list[""] = "";
+
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+TEST_P(QpackRoundTripTest, MultipleWithLongEntries) {
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  header_list[":path"] = "/";
+  header_list["foobaar"] = std::string(127, 'Z');
+  header_list[std::string(1000, 'b')] = std::string(1000, 'c');
+
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+TEST_P(QpackRoundTripTest, StaticTable) {
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "GET";
+    header_list["accept-encoding"] = "gzip, deflate";
+    header_list["cache-control"] = "";
+    header_list["foo"] = "bar";
+    header_list[":path"] = "/";
+
+    spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+    EXPECT_EQ(header_list, output);
+  }
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "POST";
+    header_list["accept-encoding"] = "brotli";
+    header_list["cache-control"] = "foo";
+    header_list["foo"] = "bar";
+    header_list[":path"] = "/";
+
+    spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+    EXPECT_EQ(header_list, output);
+  }
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "CONNECT";
+    header_list["accept-encoding"] = "";
+    header_list["foo"] = "bar";
+    header_list[":path"] = "/";
+
+    spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+    EXPECT_EQ(header_list, output);
+  }
+}
+
+TEST_P(QpackRoundTripTest, ValueHasNullCharacter) {
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
+
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_send_stream.cc b/quiche/quic/core/qpack/qpack_send_stream.cc
new file mode 100644
index 0000000..c7be858
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_send_stream.cc
@@ -0,0 +1,52 @@
+// Copyright 2019 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 "quiche/quic/core/qpack/qpack_send_stream.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_session.h"
+
+namespace quic {
+QpackSendStream::QpackSendStream(QuicStreamId id,
+                                 QuicSession* session,
+                                 uint64_t http3_stream_type)
+    : QuicStream(id, session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
+      http3_stream_type_(http3_stream_type),
+      stream_type_sent_(false) {}
+
+void QpackSendStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  QUIC_BUG(quic_bug_10805_1)
+      << "OnStreamReset() called for write unidirectional stream.";
+}
+
+bool QpackSendStream::OnStopSending(QuicResetStreamError /* code */) {
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+      "STOP_SENDING received for QPACK send stream");
+  return false;
+}
+
+void QpackSendStream::WriteStreamData(absl::string_view data) {
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  MaybeSendStreamType();
+  WriteOrBufferData(data, false, nullptr);
+}
+
+uint64_t QpackSendStream::NumBytesBuffered() const {
+  return QuicStream::BufferedDataBytes();
+}
+
+void QpackSendStream::MaybeSendStreamType() {
+  if (!stream_type_sent_) {
+    char type[sizeof(http3_stream_type_)];
+    QuicDataWriter writer(ABSL_ARRAYSIZE(type), type);
+    writer.WriteVarInt62(http3_stream_type_);
+    WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
+                      nullptr);
+    stream_type_sent_ = true;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_send_stream.h b/quiche/quic/core/qpack/qpack_send_stream.h
new file mode 100644
index 0000000..51cb25f
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_send_stream.h
@@ -0,0 +1,60 @@
+// Copyright 2019 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_QPACK_QPACK_SEND_STREAM_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicSession;
+
+// QPACK 4.2.1 Encoder and Decoder Streams.
+// The QPACK send stream is self initiated and is write only.
+class QUIC_EXPORT_PRIVATE QpackSendStream : public QuicStream,
+                                            public QpackStreamSenderDelegate {
+ public:
+  // |session| can't be nullptr, and the ownership is not passed. |session| owns
+  // this stream.
+  QpackSendStream(QuicStreamId id,
+                  QuicSession* session,
+                  uint64_t http3_stream_type);
+  QpackSendStream(const QpackSendStream&) = delete;
+  QpackSendStream& operator=(const QpackSendStream&) = delete;
+  ~QpackSendStream() override = default;
+
+  // Overriding QuicStream::OnStopSending() to make sure QPACK stream is never
+  // closed before connection.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+  bool OnStopSending(QuicResetStreamError code) override;
+
+  // The send QPACK stream is write unidirectional, so this method
+  // should never be called.
+  void OnDataAvailable() override { QUIC_NOTREACHED(); }
+
+  // Writes the instructions to peer. The stream type will be sent
+  // before the first instruction so that the peer can open an qpack stream.
+  void WriteStreamData(absl::string_view data) override;
+
+  // Return the number of bytes buffered due to underlying stream being blocked.
+  uint64_t NumBytesBuffered() const override;
+
+  // TODO(b/112770235): Remove this method once QuicStreamIdManager supports
+  // creating HTTP/3 unidirectional streams dynamically.
+  void MaybeSendStreamType();
+
+ private:
+  const uint64_t http3_stream_type_;
+  bool stream_type_sent_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
diff --git a/quiche/quic/core/qpack/qpack_send_stream_test.cc b/quiche/quic/core/qpack/qpack_send_stream_test.cc
new file mode 100644
index 0000000..40d679d
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_send_stream_test.cc
@@ -0,0 +1,136 @@
+// Copyright 2019 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 "quiche/quic/core/qpack/qpack_send_stream.h"
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Invoke;
+using ::testing::StrictMock;
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams: version: "
+                   << ParsedQuicVersionToString(version)
+                   << ", perspective: " << perspective;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& tp) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(tp.version), "_",
+      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (const auto& version : AllSupportedVersions()) {
+    if (!VersionUsesHttp3(version.transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(version, p);
+    }
+  }
+  return params;
+}
+
+class QpackSendStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QpackSendStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_,
+            &alarm_factory_,
+            perspective(),
+            SupportedVersions(GetParam().version))),
+        session_(connection_) {
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    if (connection_->version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(connection_);
+    }
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3);
+    session_.OnConfigNegotiated();
+
+    qpack_send_stream_ =
+        QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
+
+    ON_CALL(session_, WritevData(_, _, _, _, _, _))
+        .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QpackSendStream* qpack_send_stream_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QpackSendStreamTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QpackSendStreamTest, WriteStreamTypeOnlyFirstTime) {
+  std::string data = "data";
+  EXPECT_CALL(session_, WritevData(_, 1, _, _, _, _));
+  EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
+  qpack_send_stream_->WriteStreamData(absl::string_view(data));
+
+  EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
+  qpack_send_stream_->WriteStreamData(absl::string_view(data));
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
+  qpack_send_stream_->MaybeSendStreamType();
+}
+
+TEST_P(QpackSendStreamTest, StopSendingQpackStream) {
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
+  qpack_send_stream_->OnStopSending(
+      QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED));
+}
+
+TEST_P(QpackSendStreamTest, ReceiveDataOnSendStream) {
+  QuicStreamFrame frame(qpack_send_stream_->id(), false, 0, "test");
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _));
+  qpack_send_stream_->OnStreamFrame(frame);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_static_table.cc b/quiche/quic/core/qpack/qpack_static_table.cc
new file mode 100644
index 0000000..fc85667
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_static_table.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_static_table.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// The "constructor" for a QpackStaticEntry that computes the lengths at
+// compile time.
+#define STATIC_ENTRY(name, value) \
+  { name, ABSL_ARRAYSIZE(name) - 1, value, ABSL_ARRAYSIZE(value) - 1 }
+
+const std::vector<QpackStaticEntry>& QpackStaticTableVector() {
+  static const auto* kQpackStaticTable = new std::vector<QpackStaticEntry>{
+      STATIC_ENTRY(":authority", ""),                                     // 0
+      STATIC_ENTRY(":path", "/"),                                         // 1
+      STATIC_ENTRY("age", "0"),                                           // 2
+      STATIC_ENTRY("content-disposition", ""),                            // 3
+      STATIC_ENTRY("content-length", "0"),                                // 4
+      STATIC_ENTRY("cookie", ""),                                         // 5
+      STATIC_ENTRY("date", ""),                                           // 6
+      STATIC_ENTRY("etag", ""),                                           // 7
+      STATIC_ENTRY("if-modified-since", ""),                              // 8
+      STATIC_ENTRY("if-none-match", ""),                                  // 9
+      STATIC_ENTRY("last-modified", ""),                                  // 10
+      STATIC_ENTRY("link", ""),                                           // 11
+      STATIC_ENTRY("location", ""),                                       // 12
+      STATIC_ENTRY("referer", ""),                                        // 13
+      STATIC_ENTRY("set-cookie", ""),                                     // 14
+      STATIC_ENTRY(":method", "CONNECT"),                                 // 15
+      STATIC_ENTRY(":method", "DELETE"),                                  // 16
+      STATIC_ENTRY(":method", "GET"),                                     // 17
+      STATIC_ENTRY(":method", "HEAD"),                                    // 18
+      STATIC_ENTRY(":method", "OPTIONS"),                                 // 19
+      STATIC_ENTRY(":method", "POST"),                                    // 20
+      STATIC_ENTRY(":method", "PUT"),                                     // 21
+      STATIC_ENTRY(":scheme", "http"),                                    // 22
+      STATIC_ENTRY(":scheme", "https"),                                   // 23
+      STATIC_ENTRY(":status", "103"),                                     // 24
+      STATIC_ENTRY(":status", "200"),                                     // 25
+      STATIC_ENTRY(":status", "304"),                                     // 26
+      STATIC_ENTRY(":status", "404"),                                     // 27
+      STATIC_ENTRY(":status", "503"),                                     // 28
+      STATIC_ENTRY("accept", "*/*"),                                      // 29
+      STATIC_ENTRY("accept", "application/dns-message"),                  // 30
+      STATIC_ENTRY("accept-encoding", "gzip, deflate, br"),               // 31
+      STATIC_ENTRY("accept-ranges", "bytes"),                             // 32
+      STATIC_ENTRY("access-control-allow-headers", "cache-control"),      // 33
+      STATIC_ENTRY("access-control-allow-headers", "content-type"),       // 35
+      STATIC_ENTRY("access-control-allow-origin", "*"),                   // 35
+      STATIC_ENTRY("cache-control", "max-age=0"),                         // 36
+      STATIC_ENTRY("cache-control", "max-age=2592000"),                   // 37
+      STATIC_ENTRY("cache-control", "max-age=604800"),                    // 38
+      STATIC_ENTRY("cache-control", "no-cache"),                          // 39
+      STATIC_ENTRY("cache-control", "no-store"),                          // 40
+      STATIC_ENTRY("cache-control", "public, max-age=31536000"),          // 41
+      STATIC_ENTRY("content-encoding", "br"),                             // 42
+      STATIC_ENTRY("content-encoding", "gzip"),                           // 43
+      STATIC_ENTRY("content-type", "application/dns-message"),            // 44
+      STATIC_ENTRY("content-type", "application/javascript"),             // 45
+      STATIC_ENTRY("content-type", "application/json"),                   // 46
+      STATIC_ENTRY("content-type", "application/x-www-form-urlencoded"),  // 47
+      STATIC_ENTRY("content-type", "image/gif"),                          // 48
+      STATIC_ENTRY("content-type", "image/jpeg"),                         // 49
+      STATIC_ENTRY("content-type", "image/png"),                          // 50
+      STATIC_ENTRY("content-type", "text/css"),                           // 51
+      STATIC_ENTRY("content-type", "text/html; charset=utf-8"),           // 52
+      STATIC_ENTRY("content-type", "text/plain"),                         // 53
+      STATIC_ENTRY("content-type", "text/plain;charset=utf-8"),           // 54
+      STATIC_ENTRY("range", "bytes=0-"),                                  // 55
+      STATIC_ENTRY("strict-transport-security", "max-age=31536000"),      // 56
+      STATIC_ENTRY("strict-transport-security",
+                   "max-age=31536000; includesubdomains"),  // 57
+      STATIC_ENTRY("strict-transport-security",
+                   "max-age=31536000; includesubdomains; preload"),        // 58
+      STATIC_ENTRY("vary", "accept-encoding"),                             // 59
+      STATIC_ENTRY("vary", "origin"),                                      // 60
+      STATIC_ENTRY("x-content-type-options", "nosniff"),                   // 61
+      STATIC_ENTRY("x-xss-protection", "1; mode=block"),                   // 62
+      STATIC_ENTRY(":status", "100"),                                      // 63
+      STATIC_ENTRY(":status", "204"),                                      // 64
+      STATIC_ENTRY(":status", "206"),                                      // 65
+      STATIC_ENTRY(":status", "302"),                                      // 66
+      STATIC_ENTRY(":status", "400"),                                      // 67
+      STATIC_ENTRY(":status", "403"),                                      // 68
+      STATIC_ENTRY(":status", "421"),                                      // 69
+      STATIC_ENTRY(":status", "425"),                                      // 70
+      STATIC_ENTRY(":status", "500"),                                      // 71
+      STATIC_ENTRY("accept-language", ""),                                 // 72
+      STATIC_ENTRY("access-control-allow-credentials", "FALSE"),           // 73
+      STATIC_ENTRY("access-control-allow-credentials", "TRUE"),            // 74
+      STATIC_ENTRY("access-control-allow-headers", "*"),                   // 75
+      STATIC_ENTRY("access-control-allow-methods", "get"),                 // 76
+      STATIC_ENTRY("access-control-allow-methods", "get, post, options"),  // 77
+      STATIC_ENTRY("access-control-allow-methods", "options"),             // 78
+      STATIC_ENTRY("access-control-expose-headers", "content-length"),     // 79
+      STATIC_ENTRY("access-control-request-headers", "content-type"),      // 80
+      STATIC_ENTRY("access-control-request-method", "get"),                // 81
+      STATIC_ENTRY("access-control-request-method", "post"),               // 82
+      STATIC_ENTRY("alt-svc", "clear"),                                    // 83
+      STATIC_ENTRY("authorization", ""),                                   // 84
+      STATIC_ENTRY(
+          "content-security-policy",
+          "script-src 'none'; object-src 'none'; base-uri 'none'"),  // 85
+      STATIC_ENTRY("early-data", "1"),                               // 86
+      STATIC_ENTRY("expect-ct", ""),                                 // 87
+      STATIC_ENTRY("forwarded", ""),                                 // 88
+      STATIC_ENTRY("if-range", ""),                                  // 89
+      STATIC_ENTRY("origin", ""),                                    // 90
+      STATIC_ENTRY("purpose", "prefetch"),                           // 91
+      STATIC_ENTRY("server", ""),                                    // 92
+      STATIC_ENTRY("timing-allow-origin", "*"),                      // 93
+      STATIC_ENTRY("upgrade-insecure-requests", "1"),                // 94
+      STATIC_ENTRY("user-agent", ""),                                // 95
+      STATIC_ENTRY("x-forwarded-for", ""),                           // 96
+      STATIC_ENTRY("x-frame-options", "deny"),                       // 97
+      STATIC_ENTRY("x-frame-options", "sameorigin"),                 // 98
+  };
+  return *kQpackStaticTable;
+}
+
+#undef STATIC_ENTRY
+
+const QpackStaticTable& ObtainQpackStaticTable() {
+  static const QpackStaticTable* const shared_static_table = []() {
+    auto* table = new QpackStaticTable();
+    table->Initialize(QpackStaticTableVector().data(),
+                      QpackStaticTableVector().size());
+    QUICHE_CHECK(table->IsInitialized());
+    return table;
+  }();
+  return *shared_static_table;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_static_table.h b/quiche/quic/core/qpack/qpack_static_table.h
new file mode 100644
index 0000000..43fd297
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_static_table.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2018 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_QPACK_QPACK_STATIC_TABLE_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
+
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+#include "quiche/spdy/core/hpack/hpack_static_table.h"
+
+namespace quic {
+
+using QpackStaticEntry = spdy::HpackStaticEntry;
+using QpackStaticTable = spdy::HpackStaticTable;
+
+// QPACK static table defined at
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#static-table.
+QUIC_EXPORT_PRIVATE const std::vector<QpackStaticEntry>&
+QpackStaticTableVector();
+
+// Returns a QpackStaticTable instance initialized with kQpackStaticTable.
+// The instance is read-only, has static lifetime, and is safe to share amoung
+// threads. This function is thread-safe.
+QUIC_EXPORT_PRIVATE const QpackStaticTable& ObtainQpackStaticTable();
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
diff --git a/quiche/quic/core/qpack/qpack_static_table_test.cc b/quiche/quic/core/qpack/qpack_static_table_test.cc
new file mode 100644
index 0000000..67cd9c0
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_static_table_test.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2018 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 "quiche/quic/core/qpack/qpack_static_table.h"
+
+#include <set>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+// Check that an initialized instance has the right number of entries.
+TEST(QpackStaticTableTest, Initialize) {
+  QpackStaticTable table;
+  EXPECT_FALSE(table.IsInitialized());
+
+  table.Initialize(QpackStaticTableVector().data(),
+                   QpackStaticTableVector().size());
+  EXPECT_TRUE(table.IsInitialized());
+
+  const auto& static_entries = table.GetStaticEntries();
+  EXPECT_EQ(QpackStaticTableVector().size(), static_entries.size());
+
+  const auto& static_index = table.GetStaticIndex();
+  EXPECT_EQ(QpackStaticTableVector().size(), static_index.size());
+
+  const auto& static_name_index = table.GetStaticNameIndex();
+  // Count distinct names in static table.
+  std::set<absl::string_view> names;
+  for (const auto& entry : static_entries) {
+    names.insert(entry.name());
+  }
+  EXPECT_EQ(names.size(), static_name_index.size());
+}
+
+// Test that ObtainQpackStaticTable returns the same instance every time.
+TEST(QpackStaticTableTest, IsSingleton) {
+  const QpackStaticTable* static_table_one = &ObtainQpackStaticTable();
+  const QpackStaticTable* static_table_two = &ObtainQpackStaticTable();
+  EXPECT_EQ(static_table_one, static_table_two);
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_stream_receiver.h b/quiche/quic/core/qpack/qpack_stream_receiver.h
new file mode 100644
index 0000000..ad95cce
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_stream_receiver.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2019 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_QPACK_QPACK_STREAM_RECEIVER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This interface decodes QPACK data that are received on a QpackReceiveStream.
+class QUIC_EXPORT_PRIVATE QpackStreamReceiver {
+ public:
+  virtual ~QpackStreamReceiver() = default;
+
+  // Decode data.
+  virtual void Decode(absl::string_view data) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
diff --git a/quiche/quic/core/qpack/qpack_stream_sender_delegate.h b/quiche/quic/core/qpack/qpack_stream_sender_delegate.h
new file mode 100644
index 0000000..8e267db
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_stream_sender_delegate.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2019 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_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This interface writes encoder/decoder data to peer.
+class QUIC_EXPORT_PRIVATE QpackStreamSenderDelegate {
+ public:
+  virtual ~QpackStreamSenderDelegate() = default;
+
+  // Write data on the unidirectional stream.
+  virtual void WriteStreamData(absl::string_view data) = 0;
+
+  // Return the number of bytes buffered due to underlying stream being blocked.
+  virtual uint64_t NumBytesBuffered() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
diff --git a/quiche/quic/core/qpack/value_splitting_header_list.cc b/quiche/quic/core/qpack/value_splitting_header_list.cc
new file mode 100644
index 0000000..41fd4c0
--- /dev/null
+++ b/quiche/quic/core/qpack/value_splitting_header_list.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/value_splitting_header_list.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace {
+
+const char kCookieKey[] = "cookie";
+const char kCookieSeparator = ';';
+const char kOptionalSpaceAfterCookieSeparator = ' ';
+const char kNonCookieSeparator = '\0';
+
+}  // namespace
+
+ValueSplittingHeaderList::const_iterator::const_iterator(
+    const spdy::Http2HeaderBlock* header_list,
+    spdy::Http2HeaderBlock::const_iterator header_list_iterator)
+    : header_list_(header_list),
+      header_list_iterator_(header_list_iterator),
+      value_start_(0) {
+  UpdateHeaderField();
+}
+
+bool ValueSplittingHeaderList::const_iterator::operator==(
+    const const_iterator& other) const {
+  return header_list_iterator_ == other.header_list_iterator_ &&
+         value_start_ == other.value_start_;
+}
+
+bool ValueSplittingHeaderList::const_iterator::operator!=(
+    const const_iterator& other) const {
+  return !(*this == other);
+}
+
+const ValueSplittingHeaderList::const_iterator&
+ValueSplittingHeaderList::const_iterator::operator++() {
+  if (value_end_ == absl::string_view::npos) {
+    // This was the last frament within |*header_list_iterator_|,
+    // move on to the next header element of |header_list_|.
+    ++header_list_iterator_;
+    value_start_ = 0;
+  } else {
+    // Find the next fragment within |*header_list_iterator_|.
+    value_start_ = value_end_ + 1;
+  }
+  UpdateHeaderField();
+
+  return *this;
+}
+
+const ValueSplittingHeaderList::value_type&
+    ValueSplittingHeaderList::const_iterator::operator*() const {
+  return header_field_;
+}
+const ValueSplittingHeaderList::value_type*
+    ValueSplittingHeaderList::const_iterator::operator->() const {
+  return &header_field_;
+}
+
+void ValueSplittingHeaderList::const_iterator::UpdateHeaderField() {
+  QUICHE_DCHECK(value_start_ != absl::string_view::npos);
+
+  if (header_list_iterator_ == header_list_->end()) {
+    return;
+  }
+
+  const absl::string_view name = header_list_iterator_->first;
+  const absl::string_view original_value = header_list_iterator_->second;
+
+  if (name == kCookieKey) {
+    value_end_ = original_value.find(kCookieSeparator, value_start_);
+  } else {
+    value_end_ = original_value.find(kNonCookieSeparator, value_start_);
+  }
+
+  const absl::string_view value =
+      original_value.substr(value_start_, value_end_ - value_start_);
+  header_field_ = std::make_pair(name, value);
+
+  // Skip character after ';' separator if it is a space.
+  if (name == kCookieKey && value_end_ != absl::string_view::npos &&
+      value_end_ + 1 < original_value.size() &&
+      original_value[value_end_ + 1] == kOptionalSpaceAfterCookieSeparator) {
+    ++value_end_;
+  }
+}
+
+ValueSplittingHeaderList::ValueSplittingHeaderList(
+    const spdy::Http2HeaderBlock* header_list)
+    : header_list_(header_list) {
+  QUICHE_DCHECK(header_list_);
+}
+
+ValueSplittingHeaderList::const_iterator ValueSplittingHeaderList::begin()
+    const {
+  return const_iterator(header_list_, header_list_->begin());
+}
+
+ValueSplittingHeaderList::const_iterator ValueSplittingHeaderList::end() const {
+  return const_iterator(header_list_, header_list_->end());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/value_splitting_header_list.h b/quiche/quic/core/qpack/value_splitting_header_list.h
new file mode 100644
index 0000000..cc9939a
--- /dev/null
+++ b/quiche/quic/core/qpack/value_splitting_header_list.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2019 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_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
+#define QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+// A wrapper class around Http2HeaderBlock that splits header values along ';'
+// separators (while also removing optional space following separator) for
+// cookies and along '\0' separators for other header fields.
+class QUIC_EXPORT_PRIVATE ValueSplittingHeaderList {
+ public:
+  using value_type = spdy::Http2HeaderBlock::value_type;
+
+  class QUIC_EXPORT_PRIVATE const_iterator {
+   public:
+    // |header_list| must outlive this object.
+    const_iterator(const spdy::Http2HeaderBlock* header_list,
+                   spdy::Http2HeaderBlock::const_iterator header_list_iterator);
+    const_iterator(const const_iterator&) = default;
+    const_iterator& operator=(const const_iterator&) = delete;
+
+    bool operator==(const const_iterator& other) const;
+    bool operator!=(const const_iterator& other) const;
+
+    const const_iterator& operator++();
+
+    const value_type& operator*() const;
+    const value_type* operator->() const;
+
+   private:
+    // Find next separator; update |value_end_| and |header_field_|.
+    void UpdateHeaderField();
+
+    const spdy::Http2HeaderBlock* const header_list_;
+    spdy::Http2HeaderBlock::const_iterator header_list_iterator_;
+    absl::string_view::size_type value_start_;
+    absl::string_view::size_type value_end_;
+    value_type header_field_;
+  };
+
+  // |header_list| must outlive this object.
+  explicit ValueSplittingHeaderList(const spdy::Http2HeaderBlock* header_list);
+  ValueSplittingHeaderList(const ValueSplittingHeaderList&) = delete;
+  ValueSplittingHeaderList& operator=(const ValueSplittingHeaderList&) = delete;
+
+  const_iterator begin() const;
+  const_iterator end() const;
+
+ private:
+  const spdy::Http2HeaderBlock* const header_list_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
diff --git a/quiche/quic/core/qpack/value_splitting_header_list_test.cc b/quiche/quic/core/qpack/value_splitting_header_list_test.cc
new file mode 100644
index 0000000..a3aae0a
--- /dev/null
+++ b/quiche/quic/core/qpack/value_splitting_header_list_test.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2019 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 "quiche/quic/core/qpack/value_splitting_header_list.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::Pair;
+
+TEST(ValueSplittingHeaderListTest, Comparison) {
+  spdy::Http2HeaderBlock block;
+  block["foo"] = absl::string_view("bar\0baz", 7);
+  block["baz"] = "qux";
+  block["cookie"] = "foo; bar";
+
+  ValueSplittingHeaderList headers(&block);
+  ValueSplittingHeaderList::const_iterator it1 = headers.begin();
+  const int kEnd = 6;
+  for (int i = 0; i < kEnd; ++i) {
+    // Compare to begin().
+    if (i == 0) {
+      EXPECT_TRUE(it1 == headers.begin());
+      EXPECT_TRUE(headers.begin() == it1);
+      EXPECT_FALSE(it1 != headers.begin());
+      EXPECT_FALSE(headers.begin() != it1);
+    } else {
+      EXPECT_FALSE(it1 == headers.begin());
+      EXPECT_FALSE(headers.begin() == it1);
+      EXPECT_TRUE(it1 != headers.begin());
+      EXPECT_TRUE(headers.begin() != it1);
+    }
+
+    // Compare to end().
+    if (i == kEnd - 1) {
+      EXPECT_TRUE(it1 == headers.end());
+      EXPECT_TRUE(headers.end() == it1);
+      EXPECT_FALSE(it1 != headers.end());
+      EXPECT_FALSE(headers.end() != it1);
+    } else {
+      EXPECT_FALSE(it1 == headers.end());
+      EXPECT_FALSE(headers.end() == it1);
+      EXPECT_TRUE(it1 != headers.end());
+      EXPECT_TRUE(headers.end() != it1);
+    }
+
+    // Compare to another iterator walking through the container.
+    ValueSplittingHeaderList::const_iterator it2 = headers.begin();
+    for (int j = 0; j < kEnd; ++j) {
+      if (i == j) {
+        EXPECT_TRUE(it1 == it2);
+        EXPECT_FALSE(it1 != it2);
+      } else {
+        EXPECT_FALSE(it1 == it2);
+        EXPECT_TRUE(it1 != it2);
+      }
+      if (j < kEnd - 1) {
+        ASSERT_NE(it2, headers.end());
+        ++it2;
+      }
+    }
+
+    if (i < kEnd - 1) {
+      ASSERT_NE(it1, headers.end());
+      ++it1;
+    }
+  }
+}
+
+TEST(ValueSplittingHeaderListTest, Empty) {
+  spdy::Http2HeaderBlock block;
+
+  ValueSplittingHeaderList headers(&block);
+  EXPECT_THAT(headers, ElementsAre());
+  EXPECT_EQ(headers.begin(), headers.end());
+}
+
+TEST(ValueSplittingHeaderListTest, Split) {
+  struct {
+    const char* name;
+    absl::string_view value;
+    std::vector<const char*> expected_values;
+  } kTestData[]{
+      // Empty value.
+      {"foo", "", {""}},
+      // Trivial case.
+      {"foo", "bar", {"bar"}},
+      // Simple split.
+      {"foo", {"bar\0baz", 7}, {"bar", "baz"}},
+      {"cookie", "foo;bar", {"foo", "bar"}},
+      {"cookie", "foo; bar", {"foo", "bar"}},
+      // Empty fragments with \0 separator.
+      {"foo", {"\0", 1}, {"", ""}},
+      {"bar", {"foo\0", 4}, {"foo", ""}},
+      {"baz", {"\0bar", 4}, {"", "bar"}},
+      {"qux", {"\0foobar\0", 8}, {"", "foobar", ""}},
+      // Empty fragments with ";" separator.
+      {"cookie", ";", {"", ""}},
+      {"cookie", "foo;", {"foo", ""}},
+      {"cookie", ";bar", {"", "bar"}},
+      {"cookie", ";foobar;", {"", "foobar", ""}},
+      // Empty fragments with "; " separator.
+      {"cookie", "; ", {"", ""}},
+      {"cookie", "foo; ", {"foo", ""}},
+      {"cookie", "; bar", {"", "bar"}},
+      {"cookie", "; foobar; ", {"", "foobar", ""}},
+  };
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
+    spdy::Http2HeaderBlock block;
+    block[kTestData[i].name] = kTestData[i].value;
+
+    ValueSplittingHeaderList headers(&block);
+    auto it = headers.begin();
+    for (const char* expected_value : kTestData[i].expected_values) {
+      ASSERT_NE(it, headers.end());
+      EXPECT_EQ(it->first, kTestData[i].name);
+      EXPECT_EQ(it->second, expected_value);
+      ++it;
+    }
+    EXPECT_EQ(it, headers.end());
+  }
+}
+
+TEST(ValueSplittingHeaderListTest, MultipleFields) {
+  spdy::Http2HeaderBlock block;
+  block["foo"] = absl::string_view("bar\0baz\0", 8);
+  block["cookie"] = "foo; bar";
+  block["bar"] = absl::string_view("qux\0foo", 7);
+
+  ValueSplittingHeaderList headers(&block);
+  EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("foo", "baz"),
+                                   Pair("foo", ""), Pair("cookie", "foo"),
+                                   Pair("cookie", "bar"), Pair("bar", "qux"),
+                                   Pair("bar", "foo")));
+}
+
+TEST(ValueSplittingHeaderListTest, CookieStartsWithSpace) {
+  spdy::Http2HeaderBlock block;
+  block["foo"] = "bar";
+  block["cookie"] = " foo";
+  block["bar"] = "baz";
+
+  ValueSplittingHeaderList headers(&block);
+  EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("cookie", " foo"),
+                                   Pair("bar", "baz")));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_ack_listener_interface.cc b/quiche/quic/core/quic_ack_listener_interface.cc
new file mode 100644
index 0000000..f3c9d14
--- /dev/null
+++ b/quiche/quic/core/quic_ack_listener_interface.cc
@@ -0,0 +1,11 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_ack_listener_interface.h"
+
+namespace quic {
+
+QuicAckListenerInterface::~QuicAckListenerInterface() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_ack_listener_interface.h b/quiche/quic/core/quic_ack_listener_interface.h
new file mode 100644
index 0000000..edf4fd3
--- /dev/null
+++ b/quiche/quic/core/quic_ack_listener_interface.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2016 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_ACK_LISTENER_INTERFACE_H_
+#define QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+// Pure virtual class to listen for packet acknowledgements.
+class QUIC_EXPORT_PRIVATE QuicAckListenerInterface
+    : public quiche::QuicheReferenceCounted {
+ public:
+  QuicAckListenerInterface() {}
+
+  // Called when a packet is acked.  Called once per packet.
+  // |acked_bytes| is the number of data bytes acked.
+  virtual void OnPacketAcked(int acked_bytes,
+                             QuicTime::Delta ack_delay_time) = 0;
+
+  // Called when a packet is retransmitted.  Called once per packet.
+  // |retransmitted_bytes| is the number of data bytes retransmitted.
+  virtual void OnPacketRetransmitted(int retransmitted_bytes) = 0;
+
+ protected:
+  // Delegates are ref counted.
+  ~QuicAckListenerInterface() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
diff --git a/quiche/quic/core/quic_alarm.cc b/quiche/quic/core/quic_alarm.cc
new file mode 100644
index 0000000..f53b987
--- /dev/null
+++ b/quiche/quic/core/quic_alarm.cc
@@ -0,0 +1,107 @@
+// Copyright 2013 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 "quiche/quic/core/quic_alarm.h"
+
+#include <atomic>
+
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+
+namespace quic {
+
+QuicAlarm::QuicAlarm(QuicArenaScopedPtr<Delegate> delegate)
+    : delegate_(std::move(delegate)), deadline_(QuicTime::Zero()) {}
+
+QuicAlarm::~QuicAlarm() {
+  if (IsSet()) {
+    QUIC_CODE_COUNT(quic_alarm_not_cancelled_in_dtor);
+  }
+}
+
+void QuicAlarm::Set(QuicTime new_deadline) {
+  QUICHE_DCHECK(!IsSet());
+  QUICHE_DCHECK(new_deadline.IsInitialized());
+
+  if (IsPermanentlyCancelled()) {
+    QUIC_BUG(quic_alarm_illegal_set)
+        << "Set called after alarm is permanently cancelled. new_deadline:"
+        << new_deadline;
+    return;
+  }
+
+  deadline_ = new_deadline;
+  SetImpl();
+}
+
+void QuicAlarm::CancelInternal(bool permanent) {
+  if (IsSet()) {
+    deadline_ = QuicTime::Zero();
+    CancelImpl();
+  }
+
+  if (permanent) {
+    delegate_.reset();
+  }
+}
+
+bool QuicAlarm::IsPermanentlyCancelled() const { return delegate_ == nullptr; }
+
+void QuicAlarm::Update(QuicTime new_deadline, QuicTime::Delta granularity) {
+  if (IsPermanentlyCancelled()) {
+    QUIC_BUG(quic_alarm_illegal_update)
+        << "Update called after alarm is permanently cancelled. new_deadline:"
+        << new_deadline << ", granularity:" << granularity;
+    return;
+  }
+
+  if (!new_deadline.IsInitialized()) {
+    Cancel();
+    return;
+  }
+  if (std::abs((new_deadline - deadline_).ToMicroseconds()) <
+      granularity.ToMicroseconds()) {
+    return;
+  }
+  const bool was_set = IsSet();
+  deadline_ = new_deadline;
+  if (was_set) {
+    UpdateImpl();
+  } else {
+    SetImpl();
+  }
+}
+
+bool QuicAlarm::IsSet() const {
+  return deadline_.IsInitialized();
+}
+
+void QuicAlarm::Fire() {
+  if (!IsSet()) {
+    return;
+  }
+
+  deadline_ = QuicTime::Zero();
+  if (!IsPermanentlyCancelled()) {
+    QuicConnectionContextSwitcher context_switcher(
+        delegate_->GetConnectionContext());
+    delegate_->OnAlarm();
+  }
+}
+
+void QuicAlarm::UpdateImpl() {
+  // CancelImpl and SetImpl take the new deadline by way of the deadline_
+  // member, so save and restore deadline_ before canceling.
+  const QuicTime new_deadline = deadline_;
+
+  deadline_ = QuicTime::Zero();
+  CancelImpl();
+
+  deadline_ = new_deadline;
+  SetImpl();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_alarm.h b/quiche/quic/core/quic_alarm.h
new file mode 100644
index 0000000..4352a44
--- /dev/null
+++ b/quiche/quic/core/quic_alarm.h
@@ -0,0 +1,125 @@
+// Copyright 2013 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_ALARM_H_
+#define QUICHE_QUIC_CORE_QUIC_ALARM_H_
+
+#include "quiche/quic/core/quic_arena_scoped_ptr.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Abstract class which represents an alarm which will go off at a
+// scheduled time, and execute the |OnAlarm| method of the delegate.
+// An alarm may be cancelled, in which case it may or may not be
+// removed from the underlying scheduling system, but in either case
+// the task will not be executed.
+class QUIC_EXPORT_PRIVATE QuicAlarm {
+ public:
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // If the alarm belongs to a single QuicConnection, return the corresponding
+    // QuicConnection.context_. Note the context_ is the first member of
+    // QuicConnection, so it should outlive the delegate.
+    // Otherwise return nullptr.
+    // The OnAlarm function will be called under the connection context, if any.
+    virtual QuicConnectionContext* GetConnectionContext() = 0;
+
+    // Invoked when the alarm fires.
+    virtual void OnAlarm() = 0;
+  };
+
+  // DelegateWithContext is a Delegate with a QuicConnectionContext* stored as a
+  // member variable.
+  class QUIC_EXPORT_PRIVATE DelegateWithContext : public Delegate {
+   public:
+    explicit DelegateWithContext(QuicConnectionContext* context)
+        : context_(context) {}
+    ~DelegateWithContext() override {}
+    QuicConnectionContext* GetConnectionContext() override { return context_; }
+
+   private:
+    QuicConnectionContext* context_;
+  };
+
+  // DelegateWithoutContext is a Delegate that does not have a corresponding
+  // context. Typically this means one object of the child class deals with many
+  // connections.
+  class QUIC_EXPORT_PRIVATE DelegateWithoutContext : public Delegate {
+   public:
+    ~DelegateWithoutContext() override {}
+    QuicConnectionContext* GetConnectionContext() override { return nullptr; }
+  };
+
+  explicit QuicAlarm(QuicArenaScopedPtr<Delegate> delegate);
+  QuicAlarm(const QuicAlarm&) = delete;
+  QuicAlarm& operator=(const QuicAlarm&) = delete;
+  virtual ~QuicAlarm();
+
+  // Sets the alarm to fire at |deadline|.  Must not be called while
+  // the alarm is set.  To reschedule an alarm, call Cancel() first,
+  // then Set().
+  void Set(QuicTime new_deadline);
+
+  // Both PermanentCancel() and Cancel() can cancel the alarm. If permanent,
+  // future calls to Set() and Update() will become no-op except emitting an
+  // error log.
+  //
+  // Both may be called repeatedly.  Does not guarantee that the underlying
+  // scheduling system will remove the alarm's associated task, but guarantees
+  // that the delegates OnAlarm method will not be called.
+  void PermanentCancel() { CancelInternal(true); }
+  void Cancel() { CancelInternal(false); }
+
+  // Return true if PermanentCancel() has been called.
+  bool IsPermanentlyCancelled() const;
+
+  // Cancels and sets the alarm if the |deadline| is farther from the current
+  // deadline than |granularity|, and otherwise does nothing.  If |deadline| is
+  // not initialized, the alarm is cancelled.
+  void Update(QuicTime new_deadline, QuicTime::Delta granularity);
+
+  // Returns true if |deadline_| has been set to a non-zero time.
+  bool IsSet() const;
+
+  QuicTime deadline() const { return deadline_; }
+
+ protected:
+  // Subclasses implement this method to perform the platform-specific
+  // scheduling of the alarm.  Is called from Set() or Fire(), after the
+  // deadline has been updated.
+  virtual void SetImpl() = 0;
+
+  // Subclasses implement this method to perform the platform-specific
+  // cancelation of the alarm.
+  virtual void CancelImpl() = 0;
+
+  // Subclasses implement this method to perform the platform-specific update of
+  // the alarm if there exists a more optimal implementation than calling
+  // CancelImpl() and SetImpl().
+  virtual void UpdateImpl();
+
+  // Called by subclasses when the alarm fires.  Invokes the
+  // delegates |OnAlarm| if a delegate is set, and if the deadline
+  // has been exceeded.  Implementations which do not remove the
+  // alarm from the underlying scheduler on Cancel() may need to handle
+  // the situation where the task executes before the deadline has been
+  // reached, in which case they need to reschedule the task and must not
+  // call invoke this method.
+  void Fire();
+
+ private:
+  void CancelInternal(bool permanent);
+
+  QuicArenaScopedPtr<Delegate> delegate_;
+  QuicTime deadline_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ALARM_H_
diff --git a/quiche/quic/core/quic_alarm_factory.h b/quiche/quic/core/quic_alarm_factory.h
new file mode 100644
index 0000000..b1ce54c
--- /dev/null
+++ b/quiche/quic/core/quic_alarm_factory.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2015 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_ALARM_FACTORY_H_
+#define QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Creates platform-specific alarms used throughout QUIC.
+class QUIC_EXPORT_PRIVATE QuicAlarmFactory {
+ public:
+  virtual ~QuicAlarmFactory() {}
+
+  // Creates a new platform-specific alarm which will be configured to notify
+  // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
+  // Caller takes ownership of the new alarm, which will not yet be "set" to
+  // fire.
+  virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) = 0;
+
+  // Creates a new platform-specific alarm which will be configured to notify
+  // |delegate| when the alarm fires. Caller takes ownership of the new alarm,
+  // which will not yet be "set" to fire. If |arena| is null, then the alarm
+  // will be created on the heap. Otherwise, it will be created in |arena|.
+  virtual QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+      QuicConnectionArena* arena) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
diff --git a/quiche/quic/core/quic_alarm_test.cc b/quiche/quic/core/quic_alarm_test.cc
new file mode 100644
index 0000000..d9980eb
--- /dev/null
+++ b/quiche/quic/core/quic_alarm_test.cc
@@ -0,0 +1,261 @@
+// Copyright 2013 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 "quiche/quic/core/quic_alarm.h"
+
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using testing::ElementsAre;
+using testing::Invoke;
+using testing::Return;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TraceCollector : public QuicConnectionTracer {
+ public:
+  ~TraceCollector() override = default;
+
+  void PrintLiteral(const char* literal) override { trace_.push_back(literal); }
+
+  void PrintString(absl::string_view s) override {
+    trace_.push_back(std::string(s));
+  }
+
+  const std::vector<std::string>& trace() const { return trace_; }
+
+ private:
+  std::vector<std::string> trace_;
+};
+
+class MockDelegate : public QuicAlarm::Delegate {
+ public:
+  MOCK_METHOD(QuicConnectionContext*, GetConnectionContext, (), (override));
+  MOCK_METHOD(void, OnAlarm, (), (override));
+};
+
+class DestructiveDelegate : public QuicAlarm::DelegateWithoutContext {
+ public:
+  DestructiveDelegate() : alarm_(nullptr) {}
+
+  void set_alarm(QuicAlarm* alarm) { alarm_ = alarm; }
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(alarm_);
+    delete alarm_;
+  }
+
+ private:
+  QuicAlarm* alarm_;
+};
+
+class TestAlarm : public QuicAlarm {
+ public:
+  explicit TestAlarm(QuicAlarm::Delegate* delegate)
+      : QuicAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate)) {}
+
+  bool scheduled() const { return scheduled_; }
+
+  void FireAlarm() {
+    scheduled_ = false;
+    Fire();
+  }
+
+ protected:
+  void SetImpl() override {
+    QUICHE_DCHECK(deadline().IsInitialized());
+    scheduled_ = true;
+  }
+
+  void CancelImpl() override {
+    QUICHE_DCHECK(!deadline().IsInitialized());
+    scheduled_ = false;
+  }
+
+ private:
+  bool scheduled_;
+};
+
+class DestructiveAlarm : public QuicAlarm {
+ public:
+  explicit DestructiveAlarm(DestructiveDelegate* delegate)
+      : QuicAlarm(QuicArenaScopedPtr<DestructiveDelegate>(delegate)) {}
+
+  void FireAlarm() { Fire(); }
+
+ protected:
+  void SetImpl() override {}
+
+  void CancelImpl() override {}
+};
+
+class QuicAlarmTest : public QuicTest {
+ public:
+  QuicAlarmTest()
+      : delegate_(new MockDelegate()),
+        alarm_(delegate_),
+        deadline_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(7)),
+        deadline2_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(14)),
+        new_deadline_(QuicTime::Zero()) {}
+
+  void ResetAlarm() { alarm_.Set(new_deadline_); }
+
+  MockDelegate* delegate_;  // not owned
+  TestAlarm alarm_;
+  QuicTime deadline_;
+  QuicTime deadline2_;
+  QuicTime new_deadline_;
+};
+
+TEST_F(QuicAlarmTest, IsSet) {
+  EXPECT_FALSE(alarm_.IsSet());
+}
+
+TEST_F(QuicAlarmTest, Set) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  EXPECT_TRUE(alarm_.IsSet());
+  EXPECT_TRUE(alarm_.scheduled());
+  EXPECT_EQ(deadline, alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, Cancel) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  alarm_.Cancel();
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, PermanentCancel) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  alarm_.PermanentCancel();
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+
+  EXPECT_QUIC_BUG(alarm_.Set(deadline),
+                  "Set called after alarm is permanently cancelled");
+  EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+
+  EXPECT_QUIC_BUG(alarm_.Update(deadline, QuicTime::Delta::Zero()),
+                  "Update called after alarm is permanently cancelled");
+  EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, Update) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  QuicTime new_deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(8);
+  alarm_.Update(new_deadline, QuicTime::Delta::Zero());
+  EXPECT_TRUE(alarm_.IsSet());
+  EXPECT_TRUE(alarm_.scheduled());
+  EXPECT_EQ(new_deadline, alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, UpdateWithZero) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  alarm_.Update(QuicTime::Zero(), QuicTime::Delta::Zero());
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, Fire) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  EXPECT_CALL(*delegate_, OnAlarm());
+  alarm_.FireAlarm();
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, FireAndResetViaSet) {
+  alarm_.Set(deadline_);
+  new_deadline_ = deadline2_;
+  EXPECT_CALL(*delegate_, OnAlarm())
+      .WillOnce(Invoke(this, &QuicAlarmTest::ResetAlarm));
+  alarm_.FireAlarm();
+  EXPECT_TRUE(alarm_.IsSet());
+  EXPECT_TRUE(alarm_.scheduled());
+  EXPECT_EQ(deadline2_, alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, FireDestroysAlarm) {
+  DestructiveDelegate* delegate(new DestructiveDelegate);
+  DestructiveAlarm* alarm = new DestructiveAlarm(delegate);
+  delegate->set_alarm(alarm);
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm->Set(deadline);
+  // This should not crash, even though it will destroy alarm.
+  alarm->FireAlarm();
+}
+
+TEST_F(QuicAlarmTest, NullAlarmContext) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+
+  EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(nullptr));
+
+  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
+    QUIC_TRACELITERAL("Alarm fired.");
+  }));
+  alarm_.FireAlarm();
+}
+
+TEST_F(QuicAlarmTest, AlarmContextWithNullTracer) {
+  QuicConnectionContext context;
+  ASSERT_EQ(context.tracer, nullptr);
+
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+
+  EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
+
+  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
+    QUIC_TRACELITERAL("Alarm fired.");
+  }));
+  alarm_.FireAlarm();
+}
+
+TEST_F(QuicAlarmTest, AlarmContextWithTracer) {
+  QuicConnectionContext context;
+  std::unique_ptr<TraceCollector> tracer = std::make_unique<TraceCollector>();
+  const TraceCollector& tracer_ref = *tracer;
+  context.tracer = std::move(tracer);
+
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+
+  EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
+
+  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
+    QUIC_TRACELITERAL("Alarm fired.");
+  }));
+
+  // Since |context| is not installed in the current thread, the messages before
+  // and after FireAlarm() should not be collected by |tracer|.
+  QUIC_TRACELITERAL("Should not be collected before alarm.");
+  alarm_.FireAlarm();
+  QUIC_TRACELITERAL("Should not be collected after alarm.");
+
+  EXPECT_THAT(tracer_ref.trace(), ElementsAre("Alarm fired."));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_arena_scoped_ptr.h b/quiche/quic/core/quic_arena_scoped_ptr.h
new file mode 100644
index 0000000..a0c4ed8
--- /dev/null
+++ b/quiche/quic/core/quic_arena_scoped_ptr.h
@@ -0,0 +1,208 @@
+// Copyright (c) 2016 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.
+
+// unique_ptr-style pointer that stores values that may be from an arena. Takes
+// up the same storage as the platform's native pointer type. Takes ownership
+// of the value it's constructed with; if holding a value in an arena, and the
+// type has a non-trivial destructor, the arena must outlive the
+// QuicArenaScopedPtr. Does not support array overloads.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
+#define QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
+
+#include <cstdint>  // for uintptr_t
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+template <typename T>
+class QUIC_NO_EXPORT QuicArenaScopedPtr {
+  static_assert(alignof(T*) > 1,
+                "QuicArenaScopedPtr can only store objects that are aligned to "
+                "greater than 1 byte.");
+
+ public:
+  // Constructs an empty QuicArenaScopedPtr.
+  QuicArenaScopedPtr();
+
+  // Constructs a QuicArenaScopedPtr referencing the heap-allocated memory
+  // provided.
+  explicit QuicArenaScopedPtr(T* value);
+
+  template <typename U>
+  QuicArenaScopedPtr(QuicArenaScopedPtr<U>&& other);  // NOLINT
+  template <typename U>
+  QuicArenaScopedPtr& operator=(QuicArenaScopedPtr<U>&& other);
+  ~QuicArenaScopedPtr();
+
+  // Returns a pointer to the value.
+  T* get() const;
+
+  // Returns a reference to the value.
+  T& operator*() const;
+
+  // Returns a pointer to the value.
+  T* operator->() const;
+
+  // Swaps the value of this pointer with |other|.
+  void swap(QuicArenaScopedPtr& other);
+
+  // Resets the held value to |value|.
+  void reset(T* value = nullptr);
+
+  // Returns true if |this| came from an arena. Primarily exposed for testing
+  // and assertions.
+  bool is_from_arena();
+
+ private:
+  // Friends with other derived types of QuicArenaScopedPtr, to support the
+  // derived-types case.
+  template <typename U>
+  friend class QuicArenaScopedPtr;
+  // Also befriend all known arenas, only to prevent misuse.
+  template <uint32_t ArenaSize>
+  friend class QuicOneBlockArena;
+
+  // Tag to denote that a QuicArenaScopedPtr is being explicitly created by an
+  // arena.
+  enum class ConstructFrom { kHeap, kArena };
+
+  // Constructs a QuicArenaScopedPtr with the given representation.
+  QuicArenaScopedPtr(void* value, ConstructFrom from);
+  QuicArenaScopedPtr(const QuicArenaScopedPtr&) = delete;
+  QuicArenaScopedPtr& operator=(const QuicArenaScopedPtr&) = delete;
+
+  // Low-order bits of value_ that determine if the pointer came from an arena.
+  static const uintptr_t kFromArenaMask = 0x1;
+
+  // Every platform we care about has at least 4B aligned integers, so store the
+  // is_from_arena bit in the least significant bit.
+  void* value_;
+};
+
+template <typename T>
+bool operator==(const QuicArenaScopedPtr<T>& left,
+                const QuicArenaScopedPtr<T>& right) {
+  return left.get() == right.get();
+}
+
+template <typename T>
+bool operator!=(const QuicArenaScopedPtr<T>& left,
+                const QuicArenaScopedPtr<T>& right) {
+  return left.get() != right.get();
+}
+
+template <typename T>
+bool operator==(std::nullptr_t, const QuicArenaScopedPtr<T>& right) {
+  return nullptr == right.get();
+}
+
+template <typename T>
+bool operator!=(std::nullptr_t, const QuicArenaScopedPtr<T>& right) {
+  return nullptr != right.get();
+}
+
+template <typename T>
+bool operator==(const QuicArenaScopedPtr<T>& left, std::nullptr_t) {
+  return left.get() == nullptr;
+}
+
+template <typename T>
+bool operator!=(const QuicArenaScopedPtr<T>& left, std::nullptr_t) {
+  return left.get() != nullptr;
+}
+
+template <typename T>
+QuicArenaScopedPtr<T>::QuicArenaScopedPtr() : value_(nullptr) {}
+
+template <typename T>
+QuicArenaScopedPtr<T>::QuicArenaScopedPtr(T* value)
+    : QuicArenaScopedPtr(value, ConstructFrom::kHeap) {}
+
+template <typename T>
+template <typename U>
+QuicArenaScopedPtr<T>::QuicArenaScopedPtr(QuicArenaScopedPtr<U>&& other)
+    : value_(other.value_) {
+  static_assert(
+      std::is_base_of<T, U>::value || std::is_same<T, U>::value,
+      "Cannot construct QuicArenaScopedPtr; type is not derived or same.");
+  other.value_ = nullptr;
+}
+
+template <typename T>
+template <typename U>
+QuicArenaScopedPtr<T>& QuicArenaScopedPtr<T>::operator=(
+    QuicArenaScopedPtr<U>&& other) {
+  static_assert(
+      std::is_base_of<T, U>::value || std::is_same<T, U>::value,
+      "Cannot assign QuicArenaScopedPtr; type is not derived or same.");
+  swap(other);
+  return *this;
+}
+
+template <typename T>
+QuicArenaScopedPtr<T>::~QuicArenaScopedPtr() {
+  reset();
+}
+
+template <typename T>
+T* QuicArenaScopedPtr<T>::get() const {
+  return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(value_) &
+                              ~kFromArenaMask);
+}
+
+template <typename T>
+T& QuicArenaScopedPtr<T>::operator*() const {
+  return *get();
+}
+
+template <typename T>
+T* QuicArenaScopedPtr<T>::operator->() const {
+  return get();
+}
+
+template <typename T>
+void QuicArenaScopedPtr<T>::swap(QuicArenaScopedPtr& other) {
+  using std::swap;
+  swap(value_, other.value_);
+}
+
+template <typename T>
+bool QuicArenaScopedPtr<T>::is_from_arena() {
+  return (reinterpret_cast<uintptr_t>(value_) & kFromArenaMask) != 0;
+}
+
+template <typename T>
+void QuicArenaScopedPtr<T>::reset(T* value) {
+  if (value_ != nullptr) {
+    if (is_from_arena()) {
+      // Manually invoke the destructor.
+      get()->~T();
+    } else {
+      delete get();
+    }
+  }
+  QUICHE_DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(value) & kFromArenaMask);
+  value_ = value;
+}
+
+template <typename T>
+QuicArenaScopedPtr<T>::QuicArenaScopedPtr(void* value, ConstructFrom from_arena)
+    : value_(value) {
+  QUICHE_DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(value_) & kFromArenaMask);
+  switch (from_arena) {
+    case ConstructFrom::kHeap:
+      break;
+    case ConstructFrom::kArena:
+      value_ = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(value_) |
+                                       QuicArenaScopedPtr<T>::kFromArenaMask);
+      break;
+  }
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
diff --git a/quiche/quic/core/quic_arena_scoped_ptr_test.cc b/quiche/quic/core/quic_arena_scoped_ptr_test.cc
new file mode 100644
index 0000000..18d4fdf
--- /dev/null
+++ b/quiche/quic/core/quic_arena_scoped_ptr_test.cc
@@ -0,0 +1,115 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_arena_scoped_ptr.h"
+
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+enum class TestParam { kFromHeap, kFromArena };
+
+struct TestObject {
+  explicit TestObject(uintptr_t value) : value(value) { buffer.resize(1024); }
+  uintptr_t value;
+
+  // Ensure that we have a non-trivial destructor that will leak memory if it's
+  // not called.
+  std::vector<char> buffer;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParam& p) {
+  switch (p) {
+    case TestParam::kFromHeap:
+      return "heap";
+    case TestParam::kFromArena:
+      return "arena";
+  }
+  QUICHE_DCHECK(false);
+  return "?";
+}
+
+class QuicArenaScopedPtrParamTest : public QuicTestWithParam<TestParam> {
+ protected:
+  QuicArenaScopedPtr<TestObject> CreateObject(uintptr_t value) {
+    QuicArenaScopedPtr<TestObject> ptr;
+    switch (GetParam()) {
+      case TestParam::kFromHeap:
+        ptr = QuicArenaScopedPtr<TestObject>(new TestObject(value));
+        QUICHE_CHECK(!ptr.is_from_arena());
+        break;
+      case TestParam::kFromArena:
+        ptr = arena_.New<TestObject>(value);
+        QUICHE_CHECK(ptr.is_from_arena());
+        break;
+    }
+    return ptr;
+  }
+
+ private:
+  QuicOneBlockArena<1024> arena_;
+};
+
+INSTANTIATE_TEST_SUITE_P(QuicArenaScopedPtrParamTest,
+                         QuicArenaScopedPtrParamTest,
+                         testing::Values(TestParam::kFromHeap,
+                                         TestParam::kFromArena),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicArenaScopedPtrParamTest, NullObjects) {
+  QuicArenaScopedPtr<TestObject> def;
+  QuicArenaScopedPtr<TestObject> null(nullptr);
+  EXPECT_EQ(def, null);
+  EXPECT_EQ(def, nullptr);
+  EXPECT_EQ(null, nullptr);
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, FromArena) {
+  QuicOneBlockArena<1024> arena_;
+  EXPECT_TRUE(arena_.New<TestObject>(0).is_from_arena());
+  EXPECT_FALSE(
+      QuicArenaScopedPtr<TestObject>(new TestObject(0)).is_from_arena());
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, Assign) {
+  QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
+  ptr = CreateObject(54321);
+  EXPECT_EQ(54321u, ptr->value);
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, MoveConstruct) {
+  QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
+  QuicArenaScopedPtr<TestObject> ptr2(std::move(ptr1));
+  EXPECT_EQ(nullptr, ptr1);
+  EXPECT_EQ(12345u, ptr2->value);
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, Accessors) {
+  QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
+  EXPECT_EQ(12345u, (*ptr).value);
+  EXPECT_EQ(12345u, ptr->value);
+  // We explicitly want to test that get() returns a valid pointer to the data,
+  // but the call looks redundant.
+  EXPECT_EQ(12345u, ptr.get()->value);  // NOLINT
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, Reset) {
+  QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
+  ptr.reset(new TestObject(54321));
+  EXPECT_EQ(54321u, ptr->value);
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, Swap) {
+  QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
+  QuicArenaScopedPtr<TestObject> ptr2 = CreateObject(54321);
+  ptr1.swap(ptr2);
+  EXPECT_EQ(12345u, ptr2->value);
+  EXPECT_EQ(54321u, ptr1->value);
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_bandwidth.cc b/quiche/quic/core/quic_bandwidth.cc
new file mode 100644
index 0000000..4b25432
--- /dev/null
+++ b/quiche/quic/core/quic_bandwidth.cc
@@ -0,0 +1,41 @@
+// 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 "quiche/quic/core/quic_bandwidth.h"
+
+#include <cinttypes>
+#include <string>
+
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+
+namespace quic {
+
+std::string QuicBandwidth::ToDebuggingValue() const {
+  if (bits_per_second_ < 80000) {
+    return absl::StrFormat("%d bits/s (%d bytes/s)", bits_per_second_,
+                           bits_per_second_ / 8);
+  }
+
+  double divisor;
+  char unit;
+  if (bits_per_second_ < 8 * 1000 * 1000) {
+    divisor = 1e3;
+    unit = 'k';
+  } else if (bits_per_second_ < INT64_C(8) * 1000 * 1000 * 1000) {
+    divisor = 1e6;
+    unit = 'M';
+  } else {
+    divisor = 1e9;
+    unit = 'G';
+  }
+
+  double bits_per_second_with_unit = bits_per_second_ / divisor;
+  double bytes_per_second_with_unit = bits_per_second_with_unit / 8;
+  return absl::StrFormat("%.2f %cbits/s (%.2f %cbytes/s)",
+                         bits_per_second_with_unit, unit,
+                         bytes_per_second_with_unit, unit);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_bandwidth.h b/quiche/quic/core/quic_bandwidth.h
new file mode 100644
index 0000000..26956b2
--- /dev/null
+++ b/quiche/quic/core/quic_bandwidth.h
@@ -0,0 +1,164 @@
+// 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.
+
+// QuicBandwidth represents a bandwidth, stored in bits per second resolution.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
+#define QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
+
+#include <cmath>
+#include <cstdint>
+#include <limits>
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicBandwidth {
+ public:
+  // Creates a new QuicBandwidth with an internal value of 0.
+  static constexpr QuicBandwidth Zero() { return QuicBandwidth(0); }
+
+  // Creates a new QuicBandwidth with an internal value of INT64_MAX.
+  static constexpr QuicBandwidth Infinite() {
+    return QuicBandwidth(std::numeric_limits<int64_t>::max());
+  }
+
+  // Create a new QuicBandwidth holding the bits per second.
+  static constexpr QuicBandwidth FromBitsPerSecond(int64_t bits_per_second) {
+    return QuicBandwidth(bits_per_second);
+  }
+
+  // Create a new QuicBandwidth holding the kilo bits per second.
+  static constexpr QuicBandwidth FromKBitsPerSecond(int64_t k_bits_per_second) {
+    return QuicBandwidth(k_bits_per_second * 1000);
+  }
+
+  // Create a new QuicBandwidth holding the bytes per second.
+  static constexpr QuicBandwidth FromBytesPerSecond(int64_t bytes_per_second) {
+    return QuicBandwidth(bytes_per_second * 8);
+  }
+
+  // Create a new QuicBandwidth holding the kilo bytes per second.
+  static constexpr QuicBandwidth FromKBytesPerSecond(
+      int64_t k_bytes_per_second) {
+    return QuicBandwidth(k_bytes_per_second * 8000);
+  }
+
+  // Create a new QuicBandwidth based on the bytes per the elapsed delta.
+  static QuicBandwidth FromBytesAndTimeDelta(QuicByteCount bytes,
+                                             QuicTime::Delta delta) {
+    if (bytes == 0) {
+      return QuicBandwidth(0);
+    }
+
+    // 1 bit is 1000000 micro bits.
+    int64_t num_micro_bits = 8 * bytes * kNumMicrosPerSecond;
+    if (num_micro_bits < delta.ToMicroseconds()) {
+      return QuicBandwidth(1);
+    }
+
+    return QuicBandwidth(num_micro_bits / delta.ToMicroseconds());
+  }
+
+  int64_t ToBitsPerSecond() const { return bits_per_second_; }
+
+  int64_t ToKBitsPerSecond() const { return bits_per_second_ / 1000; }
+
+  int64_t ToBytesPerSecond() const { return bits_per_second_ / 8; }
+
+  int64_t ToKBytesPerSecond() const { return bits_per_second_ / 8000; }
+
+  QuicByteCount ToBytesPerPeriod(QuicTime::Delta time_period) const {
+    return bits_per_second_ * time_period.ToMicroseconds() / 8 /
+           kNumMicrosPerSecond;
+  }
+
+  int64_t ToKBytesPerPeriod(QuicTime::Delta time_period) const {
+    return bits_per_second_ * time_period.ToMicroseconds() / 8000 /
+           kNumMicrosPerSecond;
+  }
+
+  bool IsZero() const { return bits_per_second_ == 0; }
+  bool IsInfinite() const {
+    return bits_per_second_ == Infinite().ToBitsPerSecond();
+  }
+
+  QuicTime::Delta TransferTime(QuicByteCount bytes) const {
+    if (bits_per_second_ == 0) {
+      return QuicTime::Delta::Zero();
+    }
+    return QuicTime::Delta::FromMicroseconds(bytes * 8 * kNumMicrosPerSecond /
+                                             bits_per_second_);
+  }
+
+  std::string ToDebuggingValue() const;
+
+ private:
+  explicit constexpr QuicBandwidth(int64_t bits_per_second)
+      : bits_per_second_(bits_per_second >= 0 ? bits_per_second : 0) {}
+
+  int64_t bits_per_second_;
+
+  friend QuicBandwidth operator+(QuicBandwidth lhs, QuicBandwidth rhs);
+  friend QuicBandwidth operator-(QuicBandwidth lhs, QuicBandwidth rhs);
+  friend QuicBandwidth operator*(QuicBandwidth lhs, float factor);
+};
+
+// Non-member relational operators for QuicBandwidth.
+inline bool operator==(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return lhs.ToBitsPerSecond() == rhs.ToBitsPerSecond();
+}
+inline bool operator!=(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return lhs.ToBitsPerSecond() < rhs.ToBitsPerSecond();
+}
+inline bool operator>(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return !(lhs < rhs);
+}
+
+// Non-member arithmetic operators for QuicBandwidth.
+inline QuicBandwidth operator+(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return QuicBandwidth(lhs.bits_per_second_ + rhs.bits_per_second_);
+}
+inline QuicBandwidth operator-(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return QuicBandwidth(lhs.bits_per_second_ - rhs.bits_per_second_);
+}
+inline QuicBandwidth operator*(QuicBandwidth lhs, float rhs) {
+  return QuicBandwidth(
+      static_cast<int64_t>(std::llround(lhs.bits_per_second_ * rhs)));
+}
+inline QuicBandwidth operator*(float lhs, QuicBandwidth rhs) {
+  return rhs * lhs;
+}
+inline QuicByteCount operator*(QuicBandwidth lhs, QuicTime::Delta rhs) {
+  return lhs.ToBytesPerPeriod(rhs);
+}
+inline QuicByteCount operator*(QuicTime::Delta lhs, QuicBandwidth rhs) {
+  return rhs * lhs;
+}
+
+// Override stream output operator for gtest.
+inline std::ostream& operator<<(std::ostream& output,
+                                const QuicBandwidth bandwidth) {
+  output << bandwidth.ToDebuggingValue();
+  return output;
+}
+
+}  // namespace quic
+#endif  // QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
diff --git a/quiche/quic/core/quic_bandwidth_test.cc b/quiche/quic/core/quic_bandwidth_test.cc
new file mode 100644
index 0000000..5f32f11
--- /dev/null
+++ b/quiche/quic/core/quic_bandwidth_test.cc
@@ -0,0 +1,151 @@
+// 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 "quiche/quic/core/quic_bandwidth.h"
+
+#include <limits>
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QuicBandwidthTest : public QuicTest {};
+
+TEST_F(QuicBandwidthTest, FromTo) {
+  EXPECT_EQ(QuicBandwidth::FromKBitsPerSecond(1),
+            QuicBandwidth::FromBitsPerSecond(1000));
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1),
+            QuicBandwidth::FromBytesPerSecond(1000));
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(8000),
+            QuicBandwidth::FromBytesPerSecond(1000));
+  EXPECT_EQ(QuicBandwidth::FromKBitsPerSecond(8),
+            QuicBandwidth::FromKBytesPerSecond(1));
+
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToBitsPerSecond());
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToKBitsPerSecond());
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToBytesPerSecond());
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToKBytesPerSecond());
+
+  EXPECT_EQ(1, QuicBandwidth::FromBitsPerSecond(1000).ToKBitsPerSecond());
+  EXPECT_EQ(1000, QuicBandwidth::FromKBitsPerSecond(1).ToBitsPerSecond());
+  EXPECT_EQ(1, QuicBandwidth::FromBytesPerSecond(1000).ToKBytesPerSecond());
+  EXPECT_EQ(1000, QuicBandwidth::FromKBytesPerSecond(1).ToBytesPerSecond());
+}
+
+TEST_F(QuicBandwidthTest, Add) {
+  QuicBandwidth bandwidht_1 = QuicBandwidth::FromKBitsPerSecond(1);
+  QuicBandwidth bandwidht_2 = QuicBandwidth::FromKBytesPerSecond(1);
+
+  EXPECT_EQ(9000, (bandwidht_1 + bandwidht_2).ToBitsPerSecond());
+  EXPECT_EQ(9000, (bandwidht_2 + bandwidht_1).ToBitsPerSecond());
+}
+
+TEST_F(QuicBandwidthTest, Subtract) {
+  QuicBandwidth bandwidht_1 = QuicBandwidth::FromKBitsPerSecond(1);
+  QuicBandwidth bandwidht_2 = QuicBandwidth::FromKBytesPerSecond(1);
+
+  EXPECT_EQ(7000, (bandwidht_2 - bandwidht_1).ToBitsPerSecond());
+}
+
+TEST_F(QuicBandwidthTest, TimeDelta) {
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1000),
+            QuicBandwidth::FromBytesAndTimeDelta(
+                1000, QuicTime::Delta::FromMilliseconds(1)));
+
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(10),
+            QuicBandwidth::FromBytesAndTimeDelta(
+                1000, QuicTime::Delta::FromMilliseconds(100)));
+
+  EXPECT_EQ(QuicBandwidth::Zero(), QuicBandwidth::FromBytesAndTimeDelta(
+                                       0, QuicTime::Delta::FromSeconds(9)));
+
+  EXPECT_EQ(
+      QuicBandwidth::FromBitsPerSecond(1),
+      QuicBandwidth::FromBytesAndTimeDelta(1, QuicTime::Delta::FromSeconds(9)));
+}
+
+TEST_F(QuicBandwidthTest, Scale) {
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(500),
+            QuicBandwidth::FromKBytesPerSecond(1000) * 0.5f);
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(750),
+            0.75f * QuicBandwidth::FromKBytesPerSecond(1000));
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1250),
+            QuicBandwidth::FromKBytesPerSecond(1000) * 1.25f);
+
+  // Ensure we are rounding correctly within a 1bps level of precision.
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(5),
+            QuicBandwidth::FromBitsPerSecond(9) * 0.5f);
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(2),
+            QuicBandwidth::FromBitsPerSecond(12) * 0.2f);
+}
+
+TEST_F(QuicBandwidthTest, BytesPerPeriod) {
+  EXPECT_EQ(2000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
+                       QuicTime::Delta::FromMilliseconds(1)));
+  EXPECT_EQ(2u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
+                    QuicTime::Delta::FromMilliseconds(1)));
+  EXPECT_EQ(200000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
+                         QuicTime::Delta::FromMilliseconds(100)));
+  EXPECT_EQ(200u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
+                      QuicTime::Delta::FromMilliseconds(100)));
+
+  // 1599 * 1001 = 1600599 bits/ms = 200.074875 bytes/s.
+  EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToBytesPerPeriod(
+                      QuicTime::Delta::FromMilliseconds(1001)));
+
+  EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToKBytesPerPeriod(
+                      QuicTime::Delta::FromSeconds(1001)));
+}
+
+TEST_F(QuicBandwidthTest, TransferTime) {
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
+            QuicBandwidth::FromKBytesPerSecond(1).TransferTime(1000));
+  EXPECT_EQ(QuicTime::Delta::Zero(), QuicBandwidth::Zero().TransferTime(1000));
+}
+
+TEST_F(QuicBandwidthTest, RelOps) {
+  const QuicBandwidth b1 = QuicBandwidth::FromKBitsPerSecond(1);
+  const QuicBandwidth b2 = QuicBandwidth::FromKBytesPerSecond(2);
+  EXPECT_EQ(b1, b1);
+  EXPECT_NE(b1, b2);
+  EXPECT_LT(b1, b2);
+  EXPECT_GT(b2, b1);
+  EXPECT_LE(b1, b1);
+  EXPECT_LE(b1, b2);
+  EXPECT_GE(b1, b1);
+  EXPECT_GE(b2, b1);
+}
+
+TEST_F(QuicBandwidthTest, DebuggingValue) {
+  EXPECT_EQ("128 bits/s (16 bytes/s)",
+            QuicBandwidth::FromBytesPerSecond(16).ToDebuggingValue());
+  EXPECT_EQ("4096 bits/s (512 bytes/s)",
+            QuicBandwidth::FromBytesPerSecond(512).ToDebuggingValue());
+
+  QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(1000 * 50);
+  EXPECT_EQ("400.00 kbits/s (50.00 kbytes/s)", bandwidth.ToDebuggingValue());
+
+  bandwidth = bandwidth * 1000;
+  EXPECT_EQ("400.00 Mbits/s (50.00 Mbytes/s)", bandwidth.ToDebuggingValue());
+
+  bandwidth = bandwidth * 1000;
+  EXPECT_EQ("400.00 Gbits/s (50.00 Gbytes/s)", bandwidth.ToDebuggingValue());
+}
+
+TEST_F(QuicBandwidthTest, SpecialValues) {
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToBitsPerSecond());
+  EXPECT_EQ(std::numeric_limits<int64_t>::max(),
+            QuicBandwidth::Infinite().ToBitsPerSecond());
+
+  EXPECT_TRUE(QuicBandwidth::Zero().IsZero());
+  EXPECT_FALSE(QuicBandwidth::Zero().IsInfinite());
+
+  EXPECT_TRUE(QuicBandwidth::Infinite().IsInfinite());
+  EXPECT_FALSE(QuicBandwidth::Infinite().IsZero());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_blocked_writer_interface.h b/quiche/quic/core/quic_blocked_writer_interface.h
new file mode 100644
index 0000000..062b5cc
--- /dev/null
+++ b/quiche/quic/core/quic_blocked_writer_interface.h
@@ -0,0 +1,29 @@
+// 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.
+
+// This is an interface for all objects that want to be notified that
+// the underlying UDP socket is available for writing (not write blocked
+// anymore).
+
+#ifndef QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
+#define QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicBlockedWriterInterface {
+ public:
+  virtual ~QuicBlockedWriterInterface() {}
+
+  // Called by the PacketWriter when the underlying socket becomes writable
+  // so that the BlockedWriter can go ahead and try writing.
+  virtual void OnBlockedWriterCanWrite() = 0;
+
+  virtual bool IsWriterBlocked() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
diff --git a/quiche/quic/core/quic_buffered_packet_store.cc b/quiche/quic/core/quic_buffered_packet_store.cc
new file mode 100644
index 0000000..f9c6cf6
--- /dev/null
+++ b/quiche/quic/core/quic_buffered_packet_store.cc
@@ -0,0 +1,283 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_buffered_packet_store.h"
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
+using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
+using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
+
+// Max number of connections this store can keep track.
+static const size_t kDefaultMaxConnectionsInStore = 100;
+// Up to half of the capacity can be used for storing non-CHLO packets.
+static const size_t kMaxConnectionsWithoutCHLO =
+    kDefaultMaxConnectionsInStore / 2;
+
+namespace {
+
+// This alarm removes expired entries in map each time this alarm fires.
+class ConnectionExpireAlarm : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit ConnectionExpireAlarm(QuicBufferedPacketStore* store)
+      : connection_store_(store) {}
+
+  void OnAlarm() override { connection_store_->OnExpirationTimeout(); }
+
+  ConnectionExpireAlarm(const ConnectionExpireAlarm&) = delete;
+  ConnectionExpireAlarm& operator=(const ConnectionExpireAlarm&) = delete;
+
+ private:
+  QuicBufferedPacketStore* connection_store_;
+};
+
+}  // namespace
+
+BufferedPacket::BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
+                               QuicSocketAddress self_address,
+                               QuicSocketAddress peer_address)
+    : packet(std::move(packet)),
+      self_address(self_address),
+      peer_address(peer_address) {}
+
+BufferedPacket::BufferedPacket(BufferedPacket&& other) = default;
+
+BufferedPacket& BufferedPacket::operator=(BufferedPacket&& other) = default;
+
+BufferedPacket::~BufferedPacket() {}
+
+BufferedPacketList::BufferedPacketList()
+    : creation_time(QuicTime::Zero()),
+      ietf_quic(false),
+      version(ParsedQuicVersion::Unsupported()) {}
+
+BufferedPacketList::BufferedPacketList(BufferedPacketList&& other) = default;
+
+BufferedPacketList& BufferedPacketList::operator=(BufferedPacketList&& other) =
+    default;
+
+BufferedPacketList::~BufferedPacketList() {}
+
+QuicBufferedPacketStore::QuicBufferedPacketStore(
+    VisitorInterface* visitor,
+    const QuicClock* clock,
+    QuicAlarmFactory* alarm_factory)
+    : connection_life_span_(
+          QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)),
+      visitor_(visitor),
+      clock_(clock),
+      expiration_alarm_(
+          alarm_factory->CreateAlarm(new ConnectionExpireAlarm(this))) {}
+
+QuicBufferedPacketStore::~QuicBufferedPacketStore() {
+  if (expiration_alarm_ != nullptr) {
+    expiration_alarm_->PermanentCancel();
+  }
+}
+
+EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket(
+    QuicConnectionId connection_id, bool ietf_quic,
+    const QuicReceivedPacket& packet, QuicSocketAddress self_address,
+    QuicSocketAddress peer_address, const ParsedQuicVersion& version,
+    absl::optional<ParsedClientHello> parsed_chlo) {
+  const bool is_chlo = parsed_chlo.has_value();
+  QUIC_BUG_IF(quic_bug_12410_1, !GetQuicFlag(FLAGS_quic_allow_chlo_buffering))
+      << "Shouldn't buffer packets if disabled via flag.";
+  QUIC_BUG_IF(quic_bug_12410_2,
+              is_chlo && connections_with_chlo_.contains(connection_id))
+      << "Shouldn't buffer duplicated CHLO on connection " << connection_id;
+  QUIC_BUG_IF(quic_bug_12410_4, is_chlo && !version.IsKnown())
+      << "Should have version for CHLO packet.";
+
+  const bool is_first_packet = !undecryptable_packets_.contains(connection_id);
+  if (is_first_packet) {
+    if (ShouldNotBufferPacket(is_chlo)) {
+      // Drop the packet if the upper limit of undecryptable packets has been
+      // reached or the whole capacity of the store has been reached.
+      return TOO_MANY_CONNECTIONS;
+    }
+    undecryptable_packets_.emplace(
+        std::make_pair(connection_id, BufferedPacketList()));
+    undecryptable_packets_.back().second.ietf_quic = ietf_quic;
+    undecryptable_packets_.back().second.version = version;
+  }
+  QUICHE_CHECK(undecryptable_packets_.contains(connection_id));
+  BufferedPacketList& queue =
+      undecryptable_packets_.find(connection_id)->second;
+
+  if (!is_chlo) {
+    // If current packet is not CHLO, it might not be buffered because store
+    // only buffers certain number of undecryptable packets per connection.
+    size_t num_non_chlo_packets = connections_with_chlo_.contains(connection_id)
+                                      ? (queue.buffered_packets.size() - 1)
+                                      : queue.buffered_packets.size();
+    if (num_non_chlo_packets >= kDefaultMaxUndecryptablePackets) {
+      // If there are kMaxBufferedPacketsPerConnection packets buffered up for
+      // this connection, drop the current packet.
+      return TOO_MANY_PACKETS;
+    }
+  }
+
+  if (queue.buffered_packets.empty()) {
+    // If this is the first packet arrived on a new connection, initialize the
+    // creation time.
+    queue.creation_time = clock_->ApproximateNow();
+  }
+
+  BufferedPacket new_entry(std::unique_ptr<QuicReceivedPacket>(packet.Clone()),
+                           self_address, peer_address);
+  if (is_chlo) {
+    // Add CHLO to the beginning of buffered packets so that it can be delivered
+    // first later.
+    queue.buffered_packets.push_front(std::move(new_entry));
+    queue.parsed_chlo = std::move(parsed_chlo);
+    connections_with_chlo_[connection_id] = false;  // Dummy value.
+    // Set the version of buffered packets of this connection on CHLO.
+    queue.version = version;
+  } else {
+    // Buffer non-CHLO packets in arrival order.
+    queue.buffered_packets.push_back(std::move(new_entry));
+
+    // Attempt to parse multi-packet TLS CHLOs.
+    if (is_first_packet) {
+      queue.tls_chlo_extractor.IngestPacket(version, packet);
+      // Since this is the first packet and it's not a CHLO, the
+      // TlsChloExtractor should not have the entire CHLO.
+      QUIC_BUG_IF(quic_bug_12410_5,
+                  queue.tls_chlo_extractor.HasParsedFullChlo())
+          << "First packet in list should not contain full CHLO";
+    }
+    // TODO(b/154857081) Reorder CHLO packets ahead of other ones.
+  }
+
+  MaybeSetExpirationAlarm();
+  return SUCCESS;
+}
+
+bool QuicBufferedPacketStore::HasBufferedPackets(
+    QuicConnectionId connection_id) const {
+  return undecryptable_packets_.contains(connection_id);
+}
+
+bool QuicBufferedPacketStore::HasChlosBuffered() const {
+  return !connections_with_chlo_.empty();
+}
+
+BufferedPacketList QuicBufferedPacketStore::DeliverPackets(
+    QuicConnectionId connection_id) {
+  BufferedPacketList packets_to_deliver;
+  auto it = undecryptable_packets_.find(connection_id);
+  if (it != undecryptable_packets_.end()) {
+    packets_to_deliver = std::move(it->second);
+    undecryptable_packets_.erase(connection_id);
+  }
+  return packets_to_deliver;
+}
+
+void QuicBufferedPacketStore::DiscardPackets(QuicConnectionId connection_id) {
+  undecryptable_packets_.erase(connection_id);
+  connections_with_chlo_.erase(connection_id);
+}
+
+void QuicBufferedPacketStore::DiscardAllPackets() {
+  undecryptable_packets_.clear();
+  connections_with_chlo_.clear();
+  expiration_alarm_->Cancel();
+}
+
+void QuicBufferedPacketStore::OnExpirationTimeout() {
+  QuicTime expiration_time = clock_->ApproximateNow() - connection_life_span_;
+  while (!undecryptable_packets_.empty()) {
+    auto& entry = undecryptable_packets_.front();
+    if (entry.second.creation_time > expiration_time) {
+      break;
+    }
+    QuicConnectionId connection_id = entry.first;
+    visitor_->OnExpiredPackets(connection_id, std::move(entry.second));
+    undecryptable_packets_.pop_front();
+    connections_with_chlo_.erase(connection_id);
+  }
+  if (!undecryptable_packets_.empty()) {
+    MaybeSetExpirationAlarm();
+  }
+}
+
+void QuicBufferedPacketStore::MaybeSetExpirationAlarm() {
+  if (!expiration_alarm_->IsSet()) {
+    expiration_alarm_->Set(clock_->ApproximateNow() + connection_life_span_);
+  }
+}
+
+bool QuicBufferedPacketStore::ShouldNotBufferPacket(bool is_chlo) {
+  bool is_store_full =
+      undecryptable_packets_.size() >= kDefaultMaxConnectionsInStore;
+
+  if (is_chlo) {
+    return is_store_full;
+  }
+
+  size_t num_connections_without_chlo =
+      undecryptable_packets_.size() - connections_with_chlo_.size();
+  bool reach_non_chlo_limit =
+      num_connections_without_chlo >= kMaxConnectionsWithoutCHLO;
+
+  return is_store_full || reach_non_chlo_limit;
+}
+
+BufferedPacketList QuicBufferedPacketStore::DeliverPacketsForNextConnection(
+    QuicConnectionId* connection_id) {
+  if (connections_with_chlo_.empty()) {
+    // Returns empty list if no CHLO has been buffered.
+    return BufferedPacketList();
+  }
+  *connection_id = connections_with_chlo_.front().first;
+  connections_with_chlo_.pop_front();
+
+  BufferedPacketList packets = DeliverPackets(*connection_id);
+  QUICHE_DCHECK(!packets.buffered_packets.empty() &&
+                packets.parsed_chlo.has_value())
+      << "Try to deliver connectons without CHLO. # packets:"
+      << packets.buffered_packets.size()
+      << ", has_parsed_chlo:" << packets.parsed_chlo.has_value();
+  return packets;
+}
+
+bool QuicBufferedPacketStore::HasChloForConnection(
+    QuicConnectionId connection_id) {
+  return connections_with_chlo_.contains(connection_id);
+}
+
+bool QuicBufferedPacketStore::IngestPacketForTlsChloExtraction(
+    const QuicConnectionId& connection_id, const ParsedQuicVersion& version,
+    const QuicReceivedPacket& packet, std::vector<std::string>* out_alpns,
+    std::string* out_sni, bool* out_resumption_attempted,
+    bool* out_early_data_attempted) {
+  QUICHE_DCHECK_NE(out_alpns, nullptr);
+  QUICHE_DCHECK_NE(out_sni, nullptr);
+  QUICHE_DCHECK_EQ(version.handshake_protocol, PROTOCOL_TLS1_3);
+  auto it = undecryptable_packets_.find(connection_id);
+  if (it == undecryptable_packets_.end()) {
+    QUIC_BUG(quic_bug_10838_1)
+        << "Cannot ingest packet for unknown connection ID " << connection_id;
+    return false;
+  }
+  it->second.tls_chlo_extractor.IngestPacket(version, packet);
+  if (!it->second.tls_chlo_extractor.HasParsedFullChlo()) {
+    return false;
+  }
+  const TlsChloExtractor& tls_chlo_extractor = it->second.tls_chlo_extractor;
+  *out_alpns = tls_chlo_extractor.alpns();
+  *out_sni = tls_chlo_extractor.server_name();
+  *out_resumption_attempted = tls_chlo_extractor.resumption_attempted();
+  *out_early_data_attempted = tls_chlo_extractor.early_data_attempted();
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_buffered_packet_store.h b/quiche/quic/core/quic_buffered_packet_store.h
new file mode 100644
index 0000000..34fd1ab
--- /dev/null
+++ b/quiche/quic/core/quic_buffered_packet_store.h
@@ -0,0 +1,194 @@
+// Copyright (c) 2016 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_BUFFERED_PACKET_STORE_H_
+#define QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
+
+#include <list>
+#include <string>
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/tls_chlo_extractor.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+namespace test {
+class QuicBufferedPacketStorePeer;
+}  // namespace test
+
+// This class buffers packets for each connection until either
+// 1) They are requested to be delivered via
+//    DeliverPacket()/DeliverPacketsForNextConnection(), or
+// 2) They expire after exceeding their lifetime in the store.
+//
+// It can only buffer packets on certain number of connections. It has two pools
+// of connections: connections with CHLO buffered and those without CHLO. The
+// latter has its own upper limit along with the max number of connections this
+// store can hold. The former pool can grow till this store is full.
+class QUIC_NO_EXPORT QuicBufferedPacketStore {
+ public:
+  enum EnqueuePacketResult {
+    SUCCESS = 0,
+    TOO_MANY_PACKETS,  // Too many packets stored up for a certain connection.
+    TOO_MANY_CONNECTIONS  // Too many connections stored up in the store.
+  };
+
+  struct QUIC_NO_EXPORT BufferedPacket {
+    BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
+                   QuicSocketAddress self_address,
+                   QuicSocketAddress peer_address);
+    BufferedPacket(BufferedPacket&& other);
+
+    BufferedPacket& operator=(BufferedPacket&& other);
+
+    ~BufferedPacket();
+
+    std::unique_ptr<QuicReceivedPacket> packet;
+    QuicSocketAddress self_address;
+    QuicSocketAddress peer_address;
+  };
+
+  // A queue of BufferedPackets for a connection.
+  struct QUIC_NO_EXPORT BufferedPacketList {
+    BufferedPacketList();
+    BufferedPacketList(BufferedPacketList&& other);
+
+    BufferedPacketList& operator=(BufferedPacketList&& other);
+
+    ~BufferedPacketList();
+
+    std::list<BufferedPacket> buffered_packets;
+    QuicTime creation_time;
+    // |parsed_chlo| is set iff the entire CHLO has been received.
+    absl::optional<ParsedClientHello> parsed_chlo;
+    // Indicating whether this is an IETF QUIC connection.
+    bool ietf_quic;
+    // If buffered_packets contains the CHLO, it is the version of the CHLO.
+    // Otherwise, it is the version of the first packet in |buffered_packets|.
+    ParsedQuicVersion version;
+    TlsChloExtractor tls_chlo_extractor;
+  };
+
+  using BufferedPacketMap = quiche::QuicheLinkedHashMap<QuicConnectionId,
+                                                        BufferedPacketList,
+                                                        QuicConnectionIdHash>;
+
+  class QUIC_NO_EXPORT VisitorInterface {
+   public:
+    virtual ~VisitorInterface() {}
+
+    // Called for each expired connection when alarm fires.
+    virtual void OnExpiredPackets(QuicConnectionId connection_id,
+                                  BufferedPacketList early_arrived_packets) = 0;
+  };
+
+  QuicBufferedPacketStore(VisitorInterface* visitor, const QuicClock* clock,
+                          QuicAlarmFactory* alarm_factory);
+
+  QuicBufferedPacketStore(const QuicBufferedPacketStore&) = delete;
+
+  ~QuicBufferedPacketStore();
+
+  QuicBufferedPacketStore& operator=(const QuicBufferedPacketStore&) = delete;
+
+  // Adds a copy of packet into the packet queue for given connection. If the
+  // packet is the last one of the CHLO, |parsed_chlo| will contain a parsed
+  // version of the CHLO.
+  EnqueuePacketResult EnqueuePacket(
+      QuicConnectionId connection_id, bool ietf_quic,
+      const QuicReceivedPacket& packet, QuicSocketAddress self_address,
+      QuicSocketAddress peer_address, const ParsedQuicVersion& version,
+      absl::optional<ParsedClientHello> parsed_chlo);
+
+  // Returns true if there are any packets buffered for |connection_id|.
+  bool HasBufferedPackets(QuicConnectionId connection_id) const;
+
+  // Ingests this packet into the corresponding TlsChloExtractor. This should
+  // only be called when HasBufferedPackets(connection_id) is true.
+  // Returns whether we've now parsed a full multi-packet TLS CHLO.
+  // When this returns true, |out_alpns| is populated with the list of ALPNs
+  // extracted from the CHLO. |out_sni| is populated with the SNI tag in CHLO.
+  // |out_resumption_attempted| is populated if the CHLO has the
+  // 'pre_shared_key' TLS extension. |out_early_data_attempted| is populated if
+  // the CHLO has the 'early_data' TLS extension.
+  bool IngestPacketForTlsChloExtraction(const QuicConnectionId& connection_id,
+                                        const ParsedQuicVersion& version,
+                                        const QuicReceivedPacket& packet,
+                                        std::vector<std::string>* out_alpns,
+                                        std::string* out_sni,
+                                        bool* out_resumption_attempted,
+                                        bool* out_early_data_attempted);
+
+  // Returns the list of buffered packets for |connection_id| and removes them
+  // from the store. Returns an empty list if no early arrived packets for this
+  // connection are present.
+  BufferedPacketList DeliverPackets(QuicConnectionId connection_id);
+
+  // Discards packets buffered for |connection_id|, if any.
+  void DiscardPackets(QuicConnectionId connection_id);
+
+  // Discards all the packets.
+  void DiscardAllPackets();
+
+  // Examines how long packets have been buffered in the store for each
+  // connection. If they stay too long, removes them for new coming packets and
+  // calls |visitor_|'s OnPotentialConnectionExpire().
+  // Resets the alarm at the end.
+  void OnExpirationTimeout();
+
+  // Delivers buffered packets for next connection with CHLO to open.
+  // Return connection id for next connection in |connection_id|
+  // and all buffered packets including CHLO.
+  // The returned list should at least has one packet(CHLO) if
+  // store does have any connection to open. If no connection in the store has
+  // received CHLO yet, empty list will be returned.
+  BufferedPacketList DeliverPacketsForNextConnection(
+      QuicConnectionId* connection_id);
+
+  // Is given connection already buffered in the store?
+  bool HasChloForConnection(QuicConnectionId connection_id);
+
+  // Is there any CHLO buffered in the store?
+  bool HasChlosBuffered() const;
+
+ private:
+  friend class test::QuicBufferedPacketStorePeer;
+
+  // Set expiration alarm if it hasn't been set.
+  void MaybeSetExpirationAlarm();
+
+  // Return true if add an extra packet will go beyond allowed max connection
+  // limit. The limit for non-CHLO packet and CHLO packet is different.
+  bool ShouldNotBufferPacket(bool is_chlo);
+
+  // A map to store packet queues with creation time for each connection.
+  BufferedPacketMap undecryptable_packets_;
+
+  // The max time the packets of a connection can be buffer in the store.
+  const QuicTime::Delta connection_life_span_;
+
+  VisitorInterface* visitor_;  // Unowned.
+
+  const QuicClock* clock_;  // Unowned.
+
+  // This alarm fires every |connection_life_span_| to clean up
+  // packets staying in the store for too long.
+  std::unique_ptr<QuicAlarm> expiration_alarm_;
+
+  // Keeps track of connection with CHLO buffered up already and the order they
+  // arrive.
+  quiche::QuicheLinkedHashMap<QuicConnectionId, bool, QuicConnectionIdHash>
+      connections_with_chlo_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
diff --git a/quiche/quic/core/quic_buffered_packet_store_test.cc b/quiche/quic/core/quic_buffered_packet_store_test.cc
new file mode 100644
index 0000000..b6d65e1
--- /dev/null
+++ b/quiche/quic/core/quic_buffered_packet_store_test.cc
@@ -0,0 +1,502 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_buffered_packet_store.h"
+
+#include <list>
+#include <string>
+
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/first_flight.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_buffered_packet_store_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+static const size_t kDefaultMaxConnectionsInStore = 100;
+static const size_t kMaxConnectionsWithoutCHLO =
+    kDefaultMaxConnectionsInStore / 2;
+
+namespace test {
+namespace {
+
+const absl::optional<ParsedClientHello> kNoParsedChlo;
+const absl::optional<ParsedClientHello> kDefaultParsedChlo =
+    absl::make_optional<ParsedClientHello>();
+
+using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
+using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
+using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
+using ::testing::ElementsAre;
+class QuicBufferedPacketStoreVisitor
+    : public QuicBufferedPacketStore::VisitorInterface {
+ public:
+  QuicBufferedPacketStoreVisitor() {}
+
+  ~QuicBufferedPacketStoreVisitor() override {}
+
+  void OnExpiredPackets(QuicConnectionId /*connection_id*/,
+                        BufferedPacketList early_arrived_packets) override {
+    last_expired_packet_queue_ = std::move(early_arrived_packets);
+  }
+
+  // The packets queue for most recently expirect connection.
+  BufferedPacketList last_expired_packet_queue_;
+};
+
+class QuicBufferedPacketStoreTest : public QuicTest {
+ public:
+  QuicBufferedPacketStoreTest()
+      : store_(&visitor_, &clock_, &alarm_factory_),
+        self_address_(QuicIpAddress::Any6(), 65535),
+        peer_address_(QuicIpAddress::Any6(), 65535),
+        packet_content_("some encrypted content"),
+        packet_time_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(42)),
+        packet_(packet_content_.data(), packet_content_.size(), packet_time_),
+        invalid_version_(UnsupportedQuicVersion()),
+        valid_version_(CurrentSupportedVersions().front()) {}
+
+ protected:
+  QuicBufferedPacketStoreVisitor visitor_;
+  MockClock clock_;
+  MockAlarmFactory alarm_factory_;
+  QuicBufferedPacketStore store_;
+  QuicSocketAddress self_address_;
+  QuicSocketAddress peer_address_;
+  std::string packet_content_;
+  QuicTime packet_time_;
+  QuicReceivedPacket packet_;
+  const ParsedQuicVersion invalid_version_;
+  const ParsedQuicVersion valid_version_;
+};
+
+TEST_F(QuicBufferedPacketStoreTest, SimpleEnqueueAndDeliverPacket) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+  auto packets = store_.DeliverPackets(connection_id);
+  const std::list<BufferedPacket>& queue = packets.buffered_packets;
+  ASSERT_EQ(1u, queue.size());
+  ASSERT_FALSE(packets.parsed_chlo.has_value());
+  // There is no valid version because CHLO has not arrived.
+  EXPECT_EQ(invalid_version_, packets.version);
+  // Check content of the only packet in the queue.
+  EXPECT_EQ(packet_content_, queue.front().packet->AsStringPiece());
+  EXPECT_EQ(packet_time_, queue.front().packet->receipt_time());
+  EXPECT_EQ(peer_address_, queue.front().peer_address);
+  EXPECT_EQ(self_address_, queue.front().self_address);
+  // No more packets on connection 1 should remain in the store.
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+}
+
+TEST_F(QuicBufferedPacketStoreTest, DifferentPacketAddressOnOneConnection) {
+  QuicSocketAddress addr_with_new_port(QuicIpAddress::Any4(), 256);
+  QuicConnectionId connection_id = TestConnectionId(1);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       addr_with_new_port, invalid_version_, kNoParsedChlo);
+  std::list<BufferedPacket> queue =
+      store_.DeliverPackets(connection_id).buffered_packets;
+  ASSERT_EQ(2u, queue.size());
+  // The address migration path should be preserved.
+  EXPECT_EQ(peer_address_, queue.front().peer_address);
+  EXPECT_EQ(addr_with_new_port, queue.back().peer_address);
+}
+
+TEST_F(QuicBufferedPacketStoreTest,
+       EnqueueAndDeliverMultiplePacketsOnMultipleConnections) {
+  size_t num_connections = 10;
+  for (uint64_t conn_id = 1; conn_id <= num_connections; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                         peer_address_, invalid_version_, kNoParsedChlo);
+    store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                         peer_address_, invalid_version_, kNoParsedChlo);
+  }
+
+  // Deliver packets in reversed order.
+  for (uint64_t conn_id = num_connections; conn_id > 0; --conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    std::list<BufferedPacket> queue =
+        store_.DeliverPackets(connection_id).buffered_packets;
+    ASSERT_EQ(2u, queue.size());
+  }
+}
+
+TEST_F(QuicBufferedPacketStoreTest,
+       FailToBufferTooManyPacketsOnExistingConnection) {
+  // Tests that for one connection, only limited number of packets can be
+  // buffered.
+  size_t num_packets = kDefaultMaxUndecryptablePackets + 1;
+  QuicConnectionId connection_id = TestConnectionId(1);
+  // Arrived CHLO packet shouldn't affect how many non-CHLO pacekts store can
+  // keep.
+  EXPECT_EQ(
+      QuicBufferedPacketStore::SUCCESS,
+      store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                           peer_address_, valid_version_, kDefaultParsedChlo));
+  for (size_t i = 1; i <= num_packets; ++i) {
+    // Only first |kDefaultMaxUndecryptablePackets packets| will be buffered.
+    EnqueuePacketResult result =
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, invalid_version_, kNoParsedChlo);
+    if (i <= kDefaultMaxUndecryptablePackets) {
+      EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
+    } else {
+      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_PACKETS, result);
+    }
+  }
+
+  // Only first |kDefaultMaxUndecryptablePackets| non-CHLO packets and CHLO are
+  // buffered.
+  EXPECT_EQ(kDefaultMaxUndecryptablePackets + 1,
+            store_.DeliverPackets(connection_id).buffered_packets.size());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, ReachNonChloConnectionUpperLimit) {
+  // Tests that store can only keep early arrived packets for limited number of
+  // connections.
+  const size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
+  for (uint64_t conn_id = 1; conn_id <= kNumConnections; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EnqueuePacketResult result =
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, invalid_version_, kNoParsedChlo);
+    if (conn_id <= kMaxConnectionsWithoutCHLO) {
+      EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
+    } else {
+      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, result);
+    }
+  }
+  // Store only keeps early arrived packets upto |kNumConnections| connections.
+  for (uint64_t conn_id = 1; conn_id <= kNumConnections; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    std::list<BufferedPacket> queue =
+        store_.DeliverPackets(connection_id).buffered_packets;
+    if (conn_id <= kMaxConnectionsWithoutCHLO) {
+      EXPECT_EQ(1u, queue.size());
+    } else {
+      EXPECT_EQ(0u, queue.size());
+    }
+  }
+}
+
+TEST_F(QuicBufferedPacketStoreTest,
+       FullStoreFailToBufferDataPacketOnNewConnection) {
+  // Send enough CHLOs so that store gets full before number of connections
+  // without CHLO reaches its upper limit.
+  size_t num_chlos =
+      kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO + 1;
+  for (uint64_t conn_id = 1; conn_id <= num_chlos; ++conn_id) {
+    EXPECT_EQ(EnqueuePacketResult::SUCCESS,
+              store_.EnqueuePacket(TestConnectionId(conn_id), false, packet_,
+                                   self_address_, peer_address_, valid_version_,
+                                   kDefaultParsedChlo));
+  }
+
+  // Send data packets on another |kMaxConnectionsWithoutCHLO| connections.
+  // Store should only be able to buffer till it's full.
+  for (uint64_t conn_id = num_chlos + 1;
+       conn_id <= (kDefaultMaxConnectionsInStore + 1); ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EnqueuePacketResult result =
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, valid_version_, kDefaultParsedChlo);
+    if (conn_id <= kDefaultMaxConnectionsInStore) {
+      EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
+    } else {
+      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, result);
+    }
+  }
+}
+
+TEST_F(QuicBufferedPacketStoreTest, EnqueueChloOnTooManyDifferentConnections) {
+  // Buffer data packets on different connections upto limit.
+  for (uint64_t conn_id = 1; conn_id <= kMaxConnectionsWithoutCHLO; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EXPECT_EQ(
+        EnqueuePacketResult::SUCCESS,
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, invalid_version_, kNoParsedChlo));
+  }
+
+  // Buffer CHLOs on other connections till store is full.
+  for (size_t i = kMaxConnectionsWithoutCHLO + 1;
+       i <= kDefaultMaxConnectionsInStore + 1; ++i) {
+    QuicConnectionId connection_id = TestConnectionId(i);
+    EnqueuePacketResult rs =
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, valid_version_, kDefaultParsedChlo);
+    if (i <= kDefaultMaxConnectionsInStore) {
+      EXPECT_EQ(EnqueuePacketResult::SUCCESS, rs);
+      EXPECT_TRUE(store_.HasChloForConnection(connection_id));
+    } else {
+      // Last CHLO can't be buffered because store is full.
+      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, rs);
+      EXPECT_FALSE(store_.HasChloForConnection(connection_id));
+    }
+  }
+
+  // But buffering a CHLO belonging to a connection already has data packet
+  // buffered in the store should success. This is the connection should be
+  // delivered at last.
+  EXPECT_EQ(
+      EnqueuePacketResult::SUCCESS,
+      store_.EnqueuePacket(
+          /*connection_id=*/TestConnectionId(1), false, packet_, self_address_,
+          peer_address_, valid_version_, kDefaultParsedChlo));
+  EXPECT_TRUE(store_.HasChloForConnection(
+      /*connection_id=*/TestConnectionId(1)));
+
+  QuicConnectionId delivered_conn_id;
+  for (size_t i = 0;
+       i < kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO + 1;
+       ++i) {
+    if (i < kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO) {
+      // Only CHLO is buffered.
+      EXPECT_EQ(1u, store_.DeliverPacketsForNextConnection(&delivered_conn_id)
+                        .buffered_packets.size());
+      EXPECT_EQ(TestConnectionId(i + kMaxConnectionsWithoutCHLO + 1),
+                delivered_conn_id);
+    } else {
+      EXPECT_EQ(2u, store_.DeliverPacketsForNextConnection(&delivered_conn_id)
+                        .buffered_packets.size());
+      EXPECT_EQ(TestConnectionId(1u), delivered_conn_id);
+    }
+  }
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+// Tests that store expires long-staying connections appropriately for
+// connections both with and without CHLOs.
+TEST_F(QuicBufferedPacketStoreTest, PacketQueueExpiredBeforeDelivery) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  EXPECT_EQ(
+      EnqueuePacketResult::SUCCESS,
+      store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                           peer_address_, valid_version_, kDefaultParsedChlo));
+  QuicConnectionId connection_id2 = TestConnectionId(2);
+  EXPECT_EQ(
+      EnqueuePacketResult::SUCCESS,
+      store_.EnqueuePacket(connection_id2, false, packet_, self_address_,
+                           peer_address_, invalid_version_, kNoParsedChlo));
+
+  // CHLO on connection 3 arrives 1ms later.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  QuicConnectionId connection_id3 = TestConnectionId(3);
+  // Use different client address to differetiate packets from different
+  // connections.
+  QuicSocketAddress another_client_address(QuicIpAddress::Any4(), 255);
+  store_.EnqueuePacket(connection_id3, false, packet_, self_address_,
+                       another_client_address, valid_version_,
+                       kDefaultParsedChlo);
+
+  // Advance clock to the time when connection 1 and 2 expires.
+  clock_.AdvanceTime(
+      QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline() -
+      clock_.ApproximateNow());
+  ASSERT_GE(clock_.ApproximateNow(),
+            QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline());
+  // Fire alarm to remove long-staying connection 1 and 2 packets.
+  alarm_factory_.FireAlarm(
+      QuicBufferedPacketStorePeer::expiration_alarm(&store_));
+  EXPECT_EQ(1u, visitor_.last_expired_packet_queue_.buffered_packets.size());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id2));
+
+  // Try to deliver packets, but packet queue has been removed so no
+  // packets can be returned.
+  ASSERT_EQ(0u, store_.DeliverPackets(connection_id).buffered_packets.size());
+  ASSERT_EQ(0u, store_.DeliverPackets(connection_id2).buffered_packets.size());
+  QuicConnectionId delivered_conn_id;
+  auto queue = store_.DeliverPacketsForNextConnection(&delivered_conn_id)
+                   .buffered_packets;
+  // Connection 3 is the next to be delivered as connection 1 already expired.
+  EXPECT_EQ(connection_id3, delivered_conn_id);
+  ASSERT_EQ(1u, queue.size());
+  // Packets in connection 3 should use another peer address.
+  EXPECT_EQ(another_client_address, queue.front().peer_address);
+
+  // Test the alarm is reset by enqueueing 2 packets for 4th connection and wait
+  // for them to expire.
+  QuicConnectionId connection_id4 = TestConnectionId(4);
+  store_.EnqueuePacket(connection_id4, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id4, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  clock_.AdvanceTime(
+      QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline() -
+      clock_.ApproximateNow());
+  alarm_factory_.FireAlarm(
+      QuicBufferedPacketStorePeer::expiration_alarm(&store_));
+  // |last_expired_packet_queue_| should be updated.
+  EXPECT_EQ(2u, visitor_.last_expired_packet_queue_.buffered_packets.size());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, SimpleDiscardPackets) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+
+  // Enqueue some packets
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+
+  // Dicard the packets
+  store_.DiscardPackets(connection_id);
+
+  // No packets on connection 1 should remain in the store
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+
+  // Check idempotency
+  store_.DiscardPackets(connection_id);
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, DiscardWithCHLOs) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+
+  // Enqueue some packets, which include a CHLO
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, valid_version_, kDefaultParsedChlo);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+  EXPECT_TRUE(store_.HasChlosBuffered());
+
+  // Dicard the packets
+  store_.DiscardPackets(connection_id);
+
+  // No packets on connection 1 should remain in the store
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+
+  // Check idempotency
+  store_.DiscardPackets(connection_id);
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, MultipleDiscardPackets) {
+  QuicConnectionId connection_id_1 = TestConnectionId(1);
+  QuicConnectionId connection_id_2 = TestConnectionId(2);
+
+  // Enqueue some packets for two connection IDs
+  store_.EnqueuePacket(connection_id_1, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id_1, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+
+  ParsedClientHello parsed_chlo;
+  parsed_chlo.alpns.push_back("h3");
+  parsed_chlo.sni = TestHostname();
+  store_.EnqueuePacket(connection_id_2, false, packet_, self_address_,
+                       peer_address_, valid_version_, parsed_chlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id_1));
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id_2));
+  EXPECT_TRUE(store_.HasChlosBuffered());
+
+  // Discard the packets for connection 1
+  store_.DiscardPackets(connection_id_1);
+
+  // No packets on connection 1 should remain in the store
+  EXPECT_TRUE(store_.DeliverPackets(connection_id_1).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id_1));
+  EXPECT_TRUE(store_.HasChlosBuffered());
+
+  // Packets on connection 2 should remain
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id_2));
+  auto packets = store_.DeliverPackets(connection_id_2);
+  EXPECT_EQ(1u, packets.buffered_packets.size());
+  ASSERT_EQ(1u, packets.parsed_chlo->alpns.size());
+  EXPECT_EQ("h3", packets.parsed_chlo->alpns[0]);
+  EXPECT_EQ(TestHostname(), packets.parsed_chlo->sni);
+  // Since connection_id_2's chlo arrives, verify version is set.
+  EXPECT_EQ(valid_version_, packets.version);
+  EXPECT_TRUE(store_.HasChlosBuffered());
+
+  // Discard the packets for connection 2
+  store_.DiscardPackets(connection_id_2);
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, DiscardPacketsEmpty) {
+  // Check that DiscardPackets on an unknown connection ID is safe and does
+  // nothing.
+  QuicConnectionId connection_id = TestConnectionId(11235);
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+  store_.DiscardPackets(connection_id);
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, IngestPacketForTlsChloExtraction) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+  std::vector<std::string> alpns;
+  std::string sni;
+  bool resumption_attempted = false;
+  bool early_data_attempted = false;
+  QuicConfig config;
+
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, valid_version_, kNoParsedChlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+
+  // The packet in 'packet_' is not a TLS CHLO packet.
+  EXPECT_FALSE(store_.IngestPacketForTlsChloExtraction(
+      connection_id, valid_version_, packet_, &alpns, &sni,
+      &resumption_attempted, &early_data_attempted));
+
+  store_.DiscardPackets(connection_id);
+
+  // Force the TLS CHLO to span multiple packets.
+  constexpr auto kCustomParameterId =
+      static_cast<TransportParameters::TransportParameterId>(0xff33);
+  std::string kCustomParameterValue(2000, '-');
+  config.custom_transport_parameters_to_send()[kCustomParameterId] =
+      kCustomParameterValue;
+  auto packets = GetFirstFlightOfPackets(valid_version_, config);
+  ASSERT_EQ(packets.size(), 2u);
+
+  store_.EnqueuePacket(connection_id, false, *packets[0], self_address_,
+                       peer_address_, valid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id, false, *packets[1], self_address_,
+                       peer_address_, valid_version_, kNoParsedChlo);
+
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.IngestPacketForTlsChloExtraction(
+      connection_id, valid_version_, *packets[0], &alpns, &sni,
+      &resumption_attempted, &early_data_attempted));
+  EXPECT_TRUE(store_.IngestPacketForTlsChloExtraction(
+      connection_id, valid_version_, *packets[1], &alpns, &sni,
+      &resumption_attempted, &early_data_attempted));
+
+  EXPECT_THAT(alpns, ElementsAre(AlpnForVersion(valid_version_)));
+  EXPECT_EQ(sni, TestHostname());
+
+  EXPECT_FALSE(resumption_attempted);
+  EXPECT_FALSE(early_data_attempted);
+}
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_chaos_protector.cc b/quiche/quic/core/quic_chaos_protector.cc
new file mode 100644
index 0000000..dd25b9e
--- /dev/null
+++ b/quiche/quic/core/quic_chaos_protector.cc
@@ -0,0 +1,232 @@
+// Copyright (c) 2021 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 "quiche/quic/core/quic_chaos_protector.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/frames/quic_padding_frame.h"
+#include "quiche/quic/core/frames/quic_ping_frame.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+QuicChaosProtector::QuicChaosProtector(const QuicCryptoFrame& crypto_frame,
+                                       int num_padding_bytes,
+                                       size_t packet_size,
+                                       QuicFramer* framer,
+                                       QuicRandom* random)
+    : packet_size_(packet_size),
+      crypto_data_length_(crypto_frame.data_length),
+      crypto_buffer_offset_(crypto_frame.offset),
+      level_(crypto_frame.level),
+      remaining_padding_bytes_(num_padding_bytes),
+      framer_(framer),
+      random_(random) {
+  QUICHE_DCHECK_NE(framer_, nullptr);
+  QUICHE_DCHECK_NE(framer_->data_producer(), nullptr);
+  QUICHE_DCHECK_NE(random_, nullptr);
+}
+
+QuicChaosProtector::~QuicChaosProtector() {
+  DeleteFrames(&frames_);
+}
+
+absl::optional<size_t> QuicChaosProtector::BuildDataPacket(
+    const QuicPacketHeader& header,
+    char* buffer) {
+  if (!CopyCryptoDataToLocalBuffer()) {
+    return absl::nullopt;
+  }
+  SplitCryptoFrame();
+  AddPingFrames();
+  SpreadPadding();
+  ReorderFrames();
+  return BuildPacket(header, buffer);
+}
+
+WriteStreamDataResult QuicChaosProtector::WriteStreamData(
+    QuicStreamId id,
+    QuicStreamOffset offset,
+    QuicByteCount data_length,
+    QuicDataWriter* /*writer*/) {
+  QUIC_BUG(chaos stream) << "This should never be called; id " << id
+                         << " offset " << offset << " data_length "
+                         << data_length;
+  return STREAM_MISSING;
+}
+
+bool QuicChaosProtector::WriteCryptoData(EncryptionLevel level,
+                                         QuicStreamOffset offset,
+                                         QuicByteCount data_length,
+                                         QuicDataWriter* writer) {
+  if (level != level_) {
+    QUIC_BUG(chaos bad level) << "Unexpected " << level << " != " << level_;
+    return false;
+  }
+  // This is `offset + data_length > buffer_offset_ + buffer_length_`
+  // but with integer overflow protection.
+  if (offset < crypto_buffer_offset_ || data_length > crypto_data_length_ ||
+      offset - crypto_buffer_offset_ > crypto_data_length_ - data_length) {
+    QUIC_BUG(chaos bad lengths)
+        << "Unexpected buffer_offset_ " << crypto_buffer_offset_ << " offset "
+        << offset << " buffer_length_ " << crypto_data_length_
+        << " data_length " << data_length;
+    return false;
+  }
+  writer->WriteBytes(&crypto_data_buffer_[offset - crypto_buffer_offset_],
+                     data_length);
+  return true;
+}
+
+bool QuicChaosProtector::CopyCryptoDataToLocalBuffer() {
+  crypto_frame_buffer_ = std::make_unique<char[]>(packet_size_);
+  frames_.push_back(QuicFrame(
+      new QuicCryptoFrame(level_, crypto_buffer_offset_, crypto_data_length_)));
+  // We use |framer_| to serialize the CRYPTO frame in order to extract its
+  // data from the crypto data producer. This ensures that we reuse the
+  // usual serialization code path, but has the downside that we then need to
+  // parse the offset and length in order to skip over those fields.
+  QuicDataWriter writer(packet_size_, crypto_frame_buffer_.get());
+  if (!framer_->AppendCryptoFrame(*frames_.front().crypto_frame, &writer)) {
+    QUIC_BUG(chaos write crypto data);
+    return false;
+  }
+  QuicDataReader reader(crypto_frame_buffer_.get(), writer.length());
+  uint64_t parsed_offset, parsed_length;
+  if (!reader.ReadVarInt62(&parsed_offset) ||
+      !reader.ReadVarInt62(&parsed_length)) {
+    QUIC_BUG(chaos parse crypto frame);
+    return false;
+  }
+
+  absl::string_view crypto_data = reader.ReadRemainingPayload();
+  crypto_data_buffer_ = crypto_data.data();
+
+  QUICHE_DCHECK_EQ(parsed_offset, crypto_buffer_offset_);
+  QUICHE_DCHECK_EQ(parsed_length, crypto_data_length_);
+  QUICHE_DCHECK_EQ(parsed_length, crypto_data.length());
+
+  return true;
+}
+
+void QuicChaosProtector::SplitCryptoFrame() {
+  const int max_overhead_of_adding_a_crypto_frame =
+      static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
+          crypto_buffer_offset_ + crypto_data_length_, crypto_data_length_));
+  // Pick a random number of CRYPTO frames to add.
+  constexpr uint64_t kMaxAddedCryptoFrames = 10;
+  const uint64_t num_added_crypto_frames =
+      random_->InsecureRandUint64() % (kMaxAddedCryptoFrames + 1);
+  for (uint64_t i = 0; i < num_added_crypto_frames; i++) {
+    if (remaining_padding_bytes_ < max_overhead_of_adding_a_crypto_frame) {
+      break;
+    }
+    // Pick a random frame and split it by shrinking the picked frame and
+    // moving the second half of its data to a new frame that is then appended
+    // to |frames|.
+    size_t frame_to_split_index =
+        random_->InsecureRandUint64() % frames_.size();
+    QuicCryptoFrame* frame_to_split =
+        frames_[frame_to_split_index].crypto_frame;
+    if (frame_to_split->data_length <= 1) {
+      continue;
+    }
+    const int frame_to_split_old_overhead =
+        static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
+            frame_to_split->offset, frame_to_split->data_length));
+    const QuicPacketLength frame_to_split_new_data_length =
+        1 + (random_->InsecureRandUint64() % (frame_to_split->data_length - 1));
+    const QuicPacketLength new_frame_data_length =
+        frame_to_split->data_length - frame_to_split_new_data_length;
+    const QuicStreamOffset new_frame_offset =
+        frame_to_split->offset + frame_to_split_new_data_length;
+    frame_to_split->data_length -= new_frame_data_length;
+    frames_.push_back(QuicFrame(
+        new QuicCryptoFrame(level_, new_frame_offset, new_frame_data_length)));
+    const int frame_to_split_new_overhead =
+        static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
+            frame_to_split->offset, frame_to_split->data_length));
+    const int new_frame_overhead =
+        static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
+            new_frame_offset, new_frame_data_length));
+    QUICHE_DCHECK_LE(frame_to_split_new_overhead, frame_to_split_old_overhead);
+    // Readjust padding based on increased overhead.
+    remaining_padding_bytes_ -= new_frame_overhead;
+    remaining_padding_bytes_ -= frame_to_split_new_overhead;
+    remaining_padding_bytes_ += frame_to_split_old_overhead;
+  }
+}
+
+void QuicChaosProtector::AddPingFrames() {
+  if (remaining_padding_bytes_ == 0) {
+    return;
+  }
+  constexpr uint64_t kMaxAddedPingFrames = 10;
+  const uint64_t num_ping_frames =
+      random_->InsecureRandUint64() %
+      std::min<uint64_t>(kMaxAddedPingFrames, remaining_padding_bytes_);
+  for (uint64_t i = 0; i < num_ping_frames; i++) {
+    frames_.push_back(QuicFrame(QuicPingFrame()));
+  }
+  remaining_padding_bytes_ -= static_cast<int>(num_ping_frames);
+}
+
+void QuicChaosProtector::ReorderFrames() {
+  // Walk the array backwards and swap each frame with a random earlier one.
+  for (size_t i = frames_.size() - 1; i > 0; i--) {
+    std::swap(frames_[i], frames_[random_->InsecureRandUint64() % (i + 1)]);
+  }
+}
+
+void QuicChaosProtector::SpreadPadding() {
+  for (auto it = frames_.begin(); it != frames_.end(); ++it) {
+    const int padding_bytes_in_this_frame =
+        random_->InsecureRandUint64() % (remaining_padding_bytes_ + 1);
+    if (padding_bytes_in_this_frame <= 0) {
+      continue;
+    }
+    it = frames_.insert(
+        it, QuicFrame(QuicPaddingFrame(padding_bytes_in_this_frame)));
+    ++it;  // Skip over the padding frame we just added.
+    remaining_padding_bytes_ -= padding_bytes_in_this_frame;
+  }
+  if (remaining_padding_bytes_ > 0) {
+    frames_.push_back(QuicFrame(QuicPaddingFrame(remaining_padding_bytes_)));
+  }
+}
+
+absl::optional<size_t> QuicChaosProtector::BuildPacket(
+    const QuicPacketHeader& header,
+    char* buffer) {
+  QuicStreamFrameDataProducer* original_data_producer =
+      framer_->data_producer();
+  framer_->set_data_producer(this);
+
+  size_t length =
+      framer_->BuildDataPacket(header, frames_, buffer, packet_size_, level_);
+
+  framer_->set_data_producer(original_data_producer);
+  if (length == 0) {
+    return absl::nullopt;
+  }
+  return length;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_chaos_protector.h b/quiche/quic/core/quic_chaos_protector.h
new file mode 100644
index 0000000..e5fec03
--- /dev/null
+++ b/quiche/quic/core/quic_chaos_protector.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2021 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_CHAOS_PROTECTOR_H_
+#define QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+namespace test {
+class QuicChaosProtectorTest;
+}
+
+// QuicChaosProtector will take a crypto frame and an amount of padding and
+// build a data packet that will parse to something equivalent.
+class QUIC_EXPORT_PRIVATE QuicChaosProtector
+    : public QuicStreamFrameDataProducer {
+ public:
+  // |framer| and |random| must be valid for the lifetime of QuicChaosProtector.
+  explicit QuicChaosProtector(const QuicCryptoFrame& crypto_frame,
+                              int num_padding_bytes,
+                              size_t packet_size,
+                              QuicFramer* framer,
+                              QuicRandom* random);
+
+  ~QuicChaosProtector() override;
+
+  QuicChaosProtector(const QuicChaosProtector&) = delete;
+  QuicChaosProtector(QuicChaosProtector&&) = delete;
+  QuicChaosProtector& operator=(const QuicChaosProtector&) = delete;
+  QuicChaosProtector& operator=(QuicChaosProtector&&) = delete;
+
+  // Attempts to build a data packet with chaos protection. If an error occurs,
+  // then absl::nullopt is returned. Otherwise returns the serialized length.
+  absl::optional<size_t> BuildDataPacket(const QuicPacketHeader& header,
+                                         char* buffer);
+
+  // From QuicStreamFrameDataProducer.
+  WriteStreamDataResult WriteStreamData(QuicStreamId id,
+                                        QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        QuicDataWriter* /*writer*/) override;
+  bool WriteCryptoData(EncryptionLevel level,
+                       QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer) override;
+
+ private:
+  friend class test::QuicChaosProtectorTest;
+
+  // Allocate the crypto data buffer, create the CRYPTO frame and write the
+  // crypto data to our buffer.
+  bool CopyCryptoDataToLocalBuffer();
+
+  // Split the CRYPTO frame in |frames_| into one or more CRYPTO frames that
+  // collectively represent the same data. Adjusts padding to compensate.
+  void SplitCryptoFrame();
+
+  // Add a random number of PING frames to |frames_| and adjust padding.
+  void AddPingFrames();
+
+  // Randomly reorder |frames_|.
+  void ReorderFrames();
+
+  // Add PADDING frames randomly between all other frames.
+  void SpreadPadding();
+
+  // Serialize |frames_| using |framer_|.
+  absl::optional<size_t> BuildPacket(const QuicPacketHeader& header,
+                                     char* buffer);
+
+  size_t packet_size_;
+  std::unique_ptr<char[]> crypto_frame_buffer_;
+  const char* crypto_data_buffer_ = nullptr;
+  QuicByteCount crypto_data_length_;
+  QuicStreamOffset crypto_buffer_offset_;
+  EncryptionLevel level_;
+  int remaining_padding_bytes_;
+  QuicFrames frames_;   // Inner frames owned, will be deleted by destructor.
+  QuicFramer* framer_;  // Unowned.
+  QuicRandom* random_;  // Unowned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
diff --git a/quiche/quic/core/quic_chaos_protector_test.cc b/quiche/quic/core/quic_chaos_protector_test.cc
new file mode 100644
index 0000000..2ea3cd2
--- /dev/null
+++ b/quiche/quic/core/quic_chaos_protector_test.cc
@@ -0,0 +1,230 @@
+// Copyright (c) 2021 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 "quiche/quic/core/quic_chaos_protector.h"
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_quic_framer.h"
+
+namespace quic {
+namespace test {
+
+class QuicChaosProtectorTest : public QuicTestWithParam<ParsedQuicVersion>,
+                               public QuicStreamFrameDataProducer {
+ public:
+  QuicChaosProtectorTest()
+      : version_(GetParam()),
+        framer_({version_}, QuicTime::Zero(), Perspective::IS_CLIENT,
+                kQuicDefaultConnectionIdLength),
+        validation_framer_({version_}),
+        random_(/*base=*/3),
+        level_(ENCRYPTION_INITIAL),
+        crypto_offset_(0),
+        crypto_data_length_(100),
+        crypto_frame_(level_, crypto_offset_, crypto_data_length_),
+        num_padding_bytes_(50),
+        packet_size_(1000),
+        packet_buffer_(std::make_unique<char[]>(packet_size_)) {
+    ReCreateChaosProtector();
+  }
+
+  void ReCreateChaosProtector() {
+    chaos_protector_ = std::make_unique<QuicChaosProtector>(
+        crypto_frame_, num_padding_bytes_, packet_size_,
+        SetupHeaderAndFramers(), &random_);
+  }
+
+  // From QuicStreamFrameDataProducer.
+  WriteStreamDataResult WriteStreamData(QuicStreamId /*id*/,
+                                        QuicStreamOffset /*offset*/,
+                                        QuicByteCount /*data_length*/,
+                                        QuicDataWriter* /*writer*/) override {
+    ADD_FAILURE() << "This should never be called";
+    return STREAM_MISSING;
+  }
+
+  // From QuicStreamFrameDataProducer.
+  bool WriteCryptoData(EncryptionLevel level,
+                       QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer) override {
+    EXPECT_EQ(level, level);
+    EXPECT_EQ(offset, crypto_offset_);
+    EXPECT_EQ(data_length, crypto_data_length_);
+    for (QuicByteCount i = 0; i < data_length; i++) {
+      EXPECT_TRUE(writer->WriteUInt8(static_cast<uint8_t>(i & 0xFF)));
+    }
+    return true;
+  }
+
+ protected:
+  QuicFramer* SetupHeaderAndFramers() {
+    // Setup header.
+    header_.destination_connection_id = TestConnectionId();
+    header_.destination_connection_id_included = CONNECTION_ID_PRESENT;
+    header_.source_connection_id = EmptyQuicConnectionId();
+    header_.source_connection_id_included = CONNECTION_ID_PRESENT;
+    header_.reset_flag = false;
+    header_.version_flag = true;
+    header_.has_possible_stateless_reset_token = false;
+    header_.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
+    header_.version = version_;
+    header_.packet_number = QuicPacketNumber(1);
+    header_.form = IETF_QUIC_LONG_HEADER_PACKET;
+    header_.long_packet_type = INITIAL;
+    header_.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header_.length_length = kQuicDefaultLongHeaderLengthLength;
+    // Setup validation framer.
+    validation_framer_.framer()->SetInitialObfuscators(
+        header_.destination_connection_id);
+    // Setup framer.
+    framer_.SetInitialObfuscators(header_.destination_connection_id);
+    framer_.set_data_producer(this);
+    return &framer_;
+  }
+
+  void BuildEncryptAndParse() {
+    absl::optional<size_t> length =
+        chaos_protector_->BuildDataPacket(header_, packet_buffer_.get());
+    ASSERT_TRUE(length.has_value());
+    ASSERT_GT(length.value(), 0u);
+    size_t encrypted_length = framer_.EncryptInPlace(
+        level_, header_.packet_number,
+        GetStartOfEncryptedData(framer_.transport_version(), header_),
+        length.value(), packet_size_, packet_buffer_.get());
+    ASSERT_GT(encrypted_length, 0u);
+    ASSERT_TRUE(validation_framer_.ProcessPacket(QuicEncryptedPacket(
+        absl::string_view(packet_buffer_.get(), encrypted_length))));
+  }
+
+  void ResetOffset(QuicStreamOffset offset) {
+    crypto_offset_ = offset;
+    crypto_frame_.offset = offset;
+    ReCreateChaosProtector();
+  }
+
+  void ResetLength(QuicByteCount length) {
+    crypto_data_length_ = length;
+    crypto_frame_.data_length = length;
+    ReCreateChaosProtector();
+  }
+
+  ParsedQuicVersion version_;
+  QuicPacketHeader header_;
+  QuicFramer framer_;
+  SimpleQuicFramer validation_framer_;
+  MockRandom random_;
+  EncryptionLevel level_;
+  QuicStreamOffset crypto_offset_;
+  QuicByteCount crypto_data_length_;
+  QuicCryptoFrame crypto_frame_;
+  int num_padding_bytes_;
+  size_t packet_size_;
+  std::unique_ptr<char[]> packet_buffer_;
+  std::unique_ptr<QuicChaosProtector> chaos_protector_;
+};
+
+namespace {
+
+ParsedQuicVersionVector TestVersions() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.UsesCryptoFrames()) {
+      versions.push_back(version);
+    }
+  }
+  return versions;
+}
+
+INSTANTIATE_TEST_SUITE_P(QuicChaosProtectorTests,
+                         QuicChaosProtectorTest,
+                         ::testing::ValuesIn(TestVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicChaosProtectorTest, Main) {
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, 0u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 1u);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 3u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 7u);
+  EXPECT_EQ(validation_framer_.padding_frames()[0].num_padding_bytes, 3);
+}
+
+TEST_P(QuicChaosProtectorTest, DifferentRandom) {
+  random_.ResetBase(4);
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 4u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 8u);
+}
+
+TEST_P(QuicChaosProtectorTest, RandomnessZero) {
+  random_.ResetBase(0);
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 1u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length,
+            crypto_data_length_);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 1u);
+}
+
+TEST_P(QuicChaosProtectorTest, Offset) {
+  ResetOffset(123);
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 1u);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 3u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 7u);
+  EXPECT_EQ(validation_framer_.padding_frames()[0].num_padding_bytes, 3);
+}
+
+TEST_P(QuicChaosProtectorTest, OffsetAndRandomnessZero) {
+  ResetOffset(123);
+  random_.ResetBase(0);
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 1u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length,
+            crypto_data_length_);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 1u);
+}
+
+TEST_P(QuicChaosProtectorTest, ZeroRemainingBytesAfterSplit) {
+  QuicPacketLength new_length = 63;
+  num_padding_bytes_ = QuicFramer::GetMinCryptoFrameSize(
+      crypto_frame_.offset + new_length, new_length);
+  ResetLength(new_length);
+  BuildEncryptAndParse();
+
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 2u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 4);
+  EXPECT_EQ(validation_framer_.crypto_frames()[1]->offset, crypto_offset_ + 4);
+  EXPECT_EQ(validation_framer_.crypto_frames()[1]->data_length,
+            crypto_data_length_ - 4);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_clock.cc b/quiche/quic/core/quic_clock.cc
new file mode 100644
index 0000000..94ca72f
--- /dev/null
+++ b/quiche/quic/core/quic_clock.cc
@@ -0,0 +1,70 @@
+// 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 "quiche/quic/core/quic_clock.h"
+
+#include <limits>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicClock::QuicClock()
+    : is_calibrated_(false), calibration_offset_(QuicTime::Delta::Zero()) {}
+
+QuicClock::~QuicClock() {}
+
+QuicTime::Delta QuicClock::ComputeCalibrationOffset() const {
+  // In the ideal world, all we need to do is to return the difference of
+  // WallNow() and Now(). In the real world, things like context switch may
+  // happen between the calls to WallNow() and Now(), causing their difference
+  // to be arbitrarily large, so we repeat the calculation many times and use
+  // the one with the minimum difference as the true offset.
+  int64_t min_offset_us = std::numeric_limits<int64_t>::max();
+
+  for (int i = 0; i < 128; ++i) {
+    int64_t now_in_us = (Now() - QuicTime::Zero()).ToMicroseconds();
+    int64_t wallnow_in_us =
+        static_cast<int64_t>(WallNow().ToUNIXMicroseconds());
+
+    int64_t offset_us = wallnow_in_us - now_in_us;
+    if (offset_us < min_offset_us) {
+      min_offset_us = offset_us;
+    }
+  }
+
+  return QuicTime::Delta::FromMicroseconds(min_offset_us);
+}
+
+void QuicClock::SetCalibrationOffset(QuicTime::Delta offset) {
+  QUICHE_DCHECK(!is_calibrated_) << "A clock should only be calibrated once";
+  calibration_offset_ = offset;
+  is_calibrated_ = true;
+}
+
+QuicTime QuicClock::ConvertWallTimeToQuicTime(
+    const QuicWallTime& walltime) const {
+  if (is_calibrated_) {
+    int64_t time_in_us = static_cast<int64_t>(walltime.ToUNIXMicroseconds()) -
+                         calibration_offset_.ToMicroseconds();
+    return QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(time_in_us);
+  }
+
+  //     ..........................
+  //     |            |           |
+  // unix epoch   |walltime|   WallNow()
+  //     ..........................
+  //            |     |           |
+  //     clock epoch  |         Now()
+  //               result
+  //
+  // result = Now() - (WallNow() - walltime)
+  return Now() - QuicTime::Delta::FromMicroseconds(
+                     WallNow()
+                         .Subtract(QuicTime::Delta::FromMicroseconds(
+                             walltime.ToUNIXMicroseconds()))
+                         .ToUNIXMicroseconds());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_clock.h b/quiche/quic/core/quic_clock.h
new file mode 100644
index 0000000..f128f9e
--- /dev/null
+++ b/quiche/quic/core/quic_clock.h
@@ -0,0 +1,72 @@
+// 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_CLOCK_H_
+#define QUICHE_QUIC_CORE_QUIC_CLOCK_H_
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+/* API_DESCRIPTION
+ QuicClock is used by QUIC core to get current time. Its instance is created by
+ applications and passed into QuicDispatcher and QuicConnectionHelperInterface.
+ API-DESCRIPTION */
+
+namespace quic {
+
+// Interface for retrieving the current time.
+class QUIC_EXPORT_PRIVATE QuicClock {
+ public:
+  QuicClock();
+  virtual ~QuicClock();
+
+  QuicClock(const QuicClock&) = delete;
+  QuicClock& operator=(const QuicClock&) = delete;
+
+  // Compute the offset between this clock with the Unix Epoch clock.
+  // Return the calibrated offset between WallNow() and Now(), in the form of
+  // (wallnow_in_us - now_in_us).
+  // The return value can be used by SetCalibrationOffset() to actually
+  // calibrate the clock, or all instances of this clock type.
+  QuicTime::Delta ComputeCalibrationOffset() const;
+
+  // Calibrate this clock. A calibrated clock guarantees that the
+  // ConvertWallTimeToQuicTime() function always return the same result for the
+  // same walltime.
+  // Should not be called more than once for each QuicClock.
+  void SetCalibrationOffset(QuicTime::Delta offset);
+
+  // Returns the approximate current time as a QuicTime object.
+  virtual QuicTime ApproximateNow() const = 0;
+
+  // Returns the current time as a QuicTime object.
+  // Note: this use significant resources please use only if needed.
+  virtual QuicTime Now() const = 0;
+
+  // WallNow returns the current wall-time - a time that is consistent across
+  // different clocks.
+  virtual QuicWallTime WallNow() const = 0;
+
+  // Converts |walltime| to a QuicTime relative to this clock's epoch.
+  virtual QuicTime ConvertWallTimeToQuicTime(
+      const QuicWallTime& walltime) const;
+
+ protected:
+  // Creates a new QuicTime using |time_us| as the internal value.
+  QuicTime CreateTimeFromMicroseconds(uint64_t time_us) const {
+    return QuicTime(time_us);
+  }
+
+ private:
+  // True if |calibration_offset_| is valid.
+  bool is_calibrated_;
+  // If |is_calibrated_|, |calibration_offset_| is the (fixed) offset between
+  // the Unix Epoch clock and this clock.
+  // In other words, the offset between WallNow() and Now().
+  QuicTime::Delta calibration_offset_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CLOCK_H_
diff --git a/quiche/quic/core/quic_coalesced_packet.cc b/quiche/quic/core/quic_coalesced_packet.cc
new file mode 100644
index 0000000..1983b2c
--- /dev/null
+++ b/quiche/quic/core/quic_coalesced_packet.cc
@@ -0,0 +1,197 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_coalesced_packet.h"
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QuicCoalescedPacket::QuicCoalescedPacket()
+    : length_(0), max_packet_length_(0) {}
+
+QuicCoalescedPacket::~QuicCoalescedPacket() {
+  Clear();
+}
+
+bool QuicCoalescedPacket::MaybeCoalescePacket(
+    const SerializedPacket& packet, const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    quiche::QuicheBufferAllocator* allocator,
+    QuicPacketLength current_max_packet_length) {
+  if (packet.encrypted_length == 0) {
+    QUIC_BUG(quic_bug_10611_1) << "Trying to coalesce an empty packet";
+    return true;
+  }
+  if (length_ == 0) {
+#ifndef NDEBUG
+    for (const auto& buffer : encrypted_buffers_) {
+      QUICHE_DCHECK(buffer.empty());
+    }
+#endif
+    QUICHE_DCHECK(initial_packet_ == nullptr);
+    // This is the first packet, set max_packet_length and self/peer
+    // addresses.
+    max_packet_length_ = current_max_packet_length;
+    self_address_ = self_address;
+    peer_address_ = peer_address;
+  } else {
+    if (self_address_ != self_address || peer_address_ != peer_address) {
+      // Do not coalesce packet with different self/peer addresses.
+      QUIC_DLOG(INFO)
+          << "Cannot coalesce packet because self/peer address changed";
+      return false;
+    }
+    if (max_packet_length_ != current_max_packet_length) {
+      QUIC_BUG(quic_bug_10611_2)
+          << "Max packet length changes in the middle of the write path";
+      return false;
+    }
+    if (ContainsPacketOfEncryptionLevel(packet.encryption_level)) {
+      // Do not coalesce packets of the same encryption level.
+      return false;
+    }
+  }
+
+  if (length_ + packet.encrypted_length > max_packet_length_) {
+    // Packet does not fit.
+    return false;
+  }
+  QUIC_DVLOG(1) << "Successfully coalesced packet: encryption_level: "
+                << packet.encryption_level
+                << ", encrypted_length: " << packet.encrypted_length
+                << ", current length: " << length_
+                << ", max_packet_length: " << max_packet_length_;
+  if (length_ > 0) {
+    QUIC_CODE_COUNT(QUIC_SUCCESSFULLY_COALESCED_MULTIPLE_PACKETS);
+  }
+  length_ += packet.encrypted_length;
+  transmission_types_[packet.encryption_level] = packet.transmission_type;
+  if (packet.encryption_level == ENCRYPTION_INITIAL) {
+    // Save a copy of ENCRYPTION_INITIAL packet (excluding encrypted buffer, as
+    // the packet will be re-serialized later).
+    initial_packet_ = absl::WrapUnique<SerializedPacket>(
+        CopySerializedPacket(packet, allocator, /*copy_buffer=*/false));
+    return true;
+  }
+  // Copy encrypted buffer of packets with other encryption levels.
+  encrypted_buffers_[packet.encryption_level] =
+      std::string(packet.encrypted_buffer, packet.encrypted_length);
+  return true;
+}
+
+void QuicCoalescedPacket::Clear() {
+  self_address_ = QuicSocketAddress();
+  peer_address_ = QuicSocketAddress();
+  length_ = 0;
+  max_packet_length_ = 0;
+  for (auto& packet : encrypted_buffers_) {
+    packet.clear();
+  }
+  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    transmission_types_[i] = NOT_RETRANSMISSION;
+  }
+  initial_packet_ = nullptr;
+}
+
+void QuicCoalescedPacket::NeuterInitialPacket() {
+  if (initial_packet_ == nullptr) {
+    return;
+  }
+  if (length_ < initial_packet_->encrypted_length) {
+    QUIC_BUG(quic_bug_10611_3)
+        << "length_: " << length_ << ", is less than initial packet length: "
+        << initial_packet_->encrypted_length;
+    Clear();
+    return;
+  }
+  length_ -= initial_packet_->encrypted_length;
+  if (length_ == 0) {
+    Clear();
+    return;
+  }
+  transmission_types_[ENCRYPTION_INITIAL] = NOT_RETRANSMISSION;
+  initial_packet_ = nullptr;
+}
+
+bool QuicCoalescedPacket::CopyEncryptedBuffers(char* buffer,
+                                               size_t buffer_len,
+                                               size_t* length_copied) const {
+  *length_copied = 0;
+  for (const auto& packet : encrypted_buffers_) {
+    if (packet.empty()) {
+      continue;
+    }
+    if (packet.length() > buffer_len) {
+      return false;
+    }
+    memcpy(buffer, packet.data(), packet.length());
+    buffer += packet.length();
+    buffer_len -= packet.length();
+    *length_copied += packet.length();
+  }
+  return true;
+}
+
+bool QuicCoalescedPacket::ContainsPacketOfEncryptionLevel(
+    EncryptionLevel level) const {
+  return !encrypted_buffers_[level].empty() ||
+         (level == ENCRYPTION_INITIAL && initial_packet_ != nullptr);
+}
+
+TransmissionType QuicCoalescedPacket::TransmissionTypeOfPacket(
+    EncryptionLevel level) const {
+  if (!ContainsPacketOfEncryptionLevel(level)) {
+    QUIC_BUG(quic_bug_10611_4)
+        << "Coalesced packet does not contain packet of encryption level: "
+        << EncryptionLevelToString(level);
+    return NOT_RETRANSMISSION;
+  }
+  return transmission_types_[level];
+}
+
+size_t QuicCoalescedPacket::NumberOfPackets() const {
+  size_t num_of_packets = 0;
+  for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
+      ++num_of_packets;
+    }
+  }
+  return num_of_packets;
+}
+
+std::string QuicCoalescedPacket::ToString(size_t serialized_length) const {
+  // Total length and padding size.
+  std::string info = absl::StrCat(
+      "total_length: ", serialized_length,
+      " padding_size: ", serialized_length - length_, " packets: {");
+  // Packets' encryption levels.
+  bool first_packet = true;
+  for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
+      absl::StrAppend(&info, first_packet ? "" : ", ",
+                      EncryptionLevelToString(static_cast<EncryptionLevel>(i)));
+      first_packet = false;
+    }
+  }
+  absl::StrAppend(&info, "}");
+  return info;
+}
+
+std::vector<size_t> QuicCoalescedPacket::packet_lengths() const {
+  std::vector<size_t> lengths;
+  for (const auto& packet : encrypted_buffers_) {
+    if (lengths.empty()) {
+      lengths.push_back(
+          initial_packet_ == nullptr ? 0 : initial_packet_->encrypted_length);
+    } else {
+      lengths.push_back(packet.length());
+    }
+  }
+  return lengths;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_coalesced_packet.h b/quiche/quic/core/quic_coalesced_packet.h
new file mode 100644
index 0000000..364d3aa
--- /dev/null
+++ b/quiche/quic/core/quic_coalesced_packet.h
@@ -0,0 +1,97 @@
+// Copyright (c) 2019 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_COALESCED_PACKET_H_
+#define QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
+
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+namespace test {
+class QuicCoalescedPacketPeer;
+}
+
+// QuicCoalescedPacket is used to buffer multiple packets which can be coalesced
+// into the same UDP datagram.
+class QUIC_EXPORT_PRIVATE QuicCoalescedPacket {
+ public:
+  QuicCoalescedPacket();
+  ~QuicCoalescedPacket();
+
+  // Returns true if |packet| is successfully coalesced with existing packets.
+  // Returns false otherwise.
+  bool MaybeCoalescePacket(const SerializedPacket& packet,
+                           const QuicSocketAddress& self_address,
+                           const QuicSocketAddress& peer_address,
+                           quiche::QuicheBufferAllocator* allocator,
+                           QuicPacketLength current_max_packet_length);
+
+  // Clears this coalesced packet.
+  void Clear();
+
+  // Clears all state associated with initial_packet_.
+  void NeuterInitialPacket();
+
+  // Copies encrypted_buffers_ to |buffer| and sets |length_copied| to the
+  // copied amount. Returns false if copy fails (i.e., |buffer_len| is not
+  // enough).
+  bool CopyEncryptedBuffers(char* buffer,
+                            size_t buffer_len,
+                            size_t* length_copied) const;
+
+  std::string ToString(size_t serialized_length) const;
+
+  // Returns true if this coalesced packet contains packet of |level|.
+  bool ContainsPacketOfEncryptionLevel(EncryptionLevel level) const;
+
+  // Returns transmission type of packet of |level|. This should only be called
+  // when this coalesced packet contains packet of |level|.
+  TransmissionType TransmissionTypeOfPacket(EncryptionLevel level) const;
+
+  // Returns number of packets contained in this coalesced packet.
+  size_t NumberOfPackets() const;
+
+  const SerializedPacket* initial_packet() const {
+    return initial_packet_.get();
+  }
+
+  const QuicSocketAddress& self_address() const { return self_address_; }
+
+  const QuicSocketAddress& peer_address() const { return peer_address_; }
+
+  QuicPacketLength length() const { return length_; }
+
+  QuicPacketLength max_packet_length() const { return max_packet_length_; }
+
+  std::vector<size_t> packet_lengths() const;
+
+ private:
+  friend class test::QuicCoalescedPacketPeer;
+
+  // self/peer addresses are set when trying to coalesce the first packet.
+  // Packets with different self/peer addresses cannot be coalesced.
+  QuicSocketAddress self_address_;
+  QuicSocketAddress peer_address_;
+  // Length of this coalesced packet.
+  QuicPacketLength length_;
+  // Max packet length. Do not try to coalesce packet when max packet length
+  // changes (e.g., with MTU discovery).
+  QuicPacketLength max_packet_length_;
+  // Copies of packets' encrypted buffers according to different encryption
+  // levels.
+  std::string encrypted_buffers_[NUM_ENCRYPTION_LEVELS];
+  // Recorded transmission type according to different encryption levels.
+  TransmissionType transmission_types_[NUM_ENCRYPTION_LEVELS];
+
+  // A copy of ENCRYPTION_INITIAL packet if this coalesced packet contains one.
+  // Null otherwise. Please note, the encrypted_buffer field is not copied. The
+  // frames are copied to allow it be re-serialized when this coalesced packet
+  // gets sent.
+  std::unique_ptr<SerializedPacket> initial_packet_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
diff --git a/quiche/quic/core/quic_coalesced_packet_test.cc b/quiche/quic/core/quic_coalesced_packet_test.cc
new file mode 100644
index 0000000..eb69372
--- /dev/null
+++ b/quiche/quic/core/quic_coalesced_packet_test.cc
@@ -0,0 +1,213 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_coalesced_packet.h"
+
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(QuicCoalescedPacketTest, MaybeCoalescePacket) {
+  QuicCoalescedPacket coalesced;
+  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
+            coalesced.ToString(0));
+  quiche::SimpleBufferAllocator allocator;
+  EXPECT_EQ(0u, coalesced.length());
+  EXPECT_EQ(0u, coalesced.NumberOfPackets());
+  char buffer[1000];
+  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
+  SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet1.transmission_type = PTO_RETRANSMISSION;
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  packet1.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
+  packet1.retransmittable_frames.push_back(
+      QuicFrame(QuicStreamFrame(1, true, 0, 100)));
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(PTO_RETRANSMISSION,
+            coalesced.TransmissionTypeOfPacket(ENCRYPTION_INITIAL));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(500u, coalesced.length());
+  EXPECT_EQ(1u, coalesced.NumberOfPackets());
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_INITIAL}",
+      coalesced.ToString(1500));
+
+  // Cannot coalesce packet of the same encryption level.
+  SerializedPacket packet2(QuicPacketNumber(2), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  EXPECT_FALSE(coalesced.MaybeCoalescePacket(packet2, self_address,
+                                             peer_address, &allocator, 1500));
+
+  SerializedPacket packet3(QuicPacketNumber(3), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet3.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(100)));
+  packet3.encryption_level = ENCRYPTION_ZERO_RTT;
+  packet3.transmission_type = LOSS_RETRANSMISSION;
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet3, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1000u, coalesced.length());
+  EXPECT_EQ(2u, coalesced.NumberOfPackets());
+  EXPECT_EQ(LOSS_RETRANSMISSION,
+            coalesced.TransmissionTypeOfPacket(ENCRYPTION_ZERO_RTT));
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 500 packets: {ENCRYPTION_INITIAL, "
+      "ENCRYPTION_ZERO_RTT}",
+      coalesced.ToString(1500));
+
+  SerializedPacket packet4(QuicPacketNumber(4), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet4.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  // Cannot coalesce packet of changed self/peer address.
+  EXPECT_FALSE(coalesced.MaybeCoalescePacket(
+      packet4, QuicSocketAddress(QuicIpAddress::Loopback4(), 3), peer_address,
+      &allocator, 1500));
+
+  // Packet does not fit.
+  SerializedPacket packet5(QuicPacketNumber(5), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 501, false, false);
+  packet5.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  EXPECT_FALSE(coalesced.MaybeCoalescePacket(packet5, self_address,
+                                             peer_address, &allocator, 1500));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1000u, coalesced.length());
+  EXPECT_EQ(2u, coalesced.NumberOfPackets());
+
+  // Max packet number length changed.
+  SerializedPacket packet6(QuicPacketNumber(6), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 100, false, false);
+  packet6.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  EXPECT_QUIC_BUG(coalesced.MaybeCoalescePacket(packet6, self_address,
+                                                peer_address, &allocator, 1000),
+                  "Max packet length changes in the middle of the write path");
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1000u, coalesced.length());
+  EXPECT_EQ(2u, coalesced.NumberOfPackets());
+}
+
+TEST(QuicCoalescedPacketTest, CopyEncryptedBuffers) {
+  QuicCoalescedPacket coalesced;
+  quiche::SimpleBufferAllocator allocator;
+  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
+  std::string buffer(500, 'a');
+  std::string buffer2(500, 'b');
+  SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer.data(), 500,
+                           /*has_ack=*/false, /*has_stop_waiting=*/false);
+  packet1.encryption_level = ENCRYPTION_ZERO_RTT;
+  SerializedPacket packet2(QuicPacketNumber(2), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer2.data(), 500,
+                           /*has_ack=*/false, /*has_stop_waiting=*/false);
+  packet2.encryption_level = ENCRYPTION_FORWARD_SECURE;
+
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
+                                            &allocator, 1500));
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet2, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(1000u, coalesced.length());
+
+  char copy_buffer[1000];
+  size_t length_copied = 0;
+  EXPECT_FALSE(
+      coalesced.CopyEncryptedBuffers(copy_buffer, 900, &length_copied));
+  ASSERT_TRUE(
+      coalesced.CopyEncryptedBuffers(copy_buffer, 1000, &length_copied));
+  EXPECT_EQ(1000u, length_copied);
+  char expected[1000];
+  memset(expected, 'a', 500);
+  memset(expected + 500, 'b', 500);
+  quiche::test::CompareCharArraysWithHexError("copied buffers", copy_buffer,
+                                              length_copied, expected, 1000);
+}
+
+TEST(QuicCoalescedPacketTest, NeuterInitialPacket) {
+  QuicCoalescedPacket coalesced;
+  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
+            coalesced.ToString(0));
+  // Noop when neutering initial packet on a empty coalescer.
+  coalesced.NeuterInitialPacket();
+  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
+            coalesced.ToString(0));
+
+  quiche::SimpleBufferAllocator allocator;
+  EXPECT_EQ(0u, coalesced.length());
+  char buffer[1000];
+  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
+  SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet1.transmission_type = PTO_RETRANSMISSION;
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  packet1.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
+  packet1.retransmittable_frames.push_back(
+      QuicFrame(QuicStreamFrame(1, true, 0, 100)));
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(PTO_RETRANSMISSION,
+            coalesced.TransmissionTypeOfPacket(ENCRYPTION_INITIAL));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(500u, coalesced.length());
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_INITIAL}",
+      coalesced.ToString(1500));
+  // Neuter initial packet.
+  coalesced.NeuterInitialPacket();
+  EXPECT_EQ(0u, coalesced.max_packet_length());
+  EXPECT_EQ(0u, coalesced.length());
+  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
+            coalesced.ToString(0));
+
+  // Coalesce initial packet again.
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
+                                            &allocator, 1500));
+
+  SerializedPacket packet2(QuicPacketNumber(3), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet2.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(100)));
+  packet2.encryption_level = ENCRYPTION_ZERO_RTT;
+  packet2.transmission_type = LOSS_RETRANSMISSION;
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet2, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1000u, coalesced.length());
+  EXPECT_EQ(LOSS_RETRANSMISSION,
+            coalesced.TransmissionTypeOfPacket(ENCRYPTION_ZERO_RTT));
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 500 packets: {ENCRYPTION_INITIAL, "
+      "ENCRYPTION_ZERO_RTT}",
+      coalesced.ToString(1500));
+
+  // Neuter initial packet.
+  coalesced.NeuterInitialPacket();
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(500u, coalesced.length());
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_ZERO_RTT}",
+      coalesced.ToString(1500));
+
+  SerializedPacket packet3(QuicPacketNumber(5), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 501, false, false);
+  packet3.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  EXPECT_TRUE(coalesced.MaybeCoalescePacket(packet3, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1001u, coalesced.length());
+  // Neuter initial packet.
+  coalesced.NeuterInitialPacket();
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1001u, coalesced.length());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_config.cc b/quiche/quic/core/quic_config.cc
new file mode 100644
index 0000000..d6f2acd
--- /dev/null
+++ b/quiche/quic/core/quic_config.cc
@@ -0,0 +1,1424 @@
+// Copyright (c) 2013 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 "quiche/quic/core/quic_config.h"
+
+#include <algorithm>
+#include <cstring>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// Reads the value corresponding to |name_| from |msg| into |out|. If the
+// |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set
+// to |default_value|.
+QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
+                         QuicTag tag,
+                         QuicConfigPresence presence,
+                         uint32_t default_value,
+                         uint32_t* out,
+                         std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  QuicErrorCode error = msg.GetUint32(tag, out);
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence == PRESENCE_REQUIRED) {
+        *error_details = "Missing " + QuicTagToString(tag);
+        break;
+      }
+      error = QUIC_NO_ERROR;
+      *out = default_value;
+      break;
+    case QUIC_NO_ERROR:
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag);
+      break;
+  }
+  return error;
+}
+
+QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
+    : tag_(tag), presence_(presence) {}
+QuicConfigValue::~QuicConfigValue() {}
+
+QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
+    : QuicConfigValue(tag, presence),
+      has_send_value_(false),
+      has_receive_value_(false) {}
+QuicFixedUint32::~QuicFixedUint32() {}
+
+bool QuicFixedUint32::HasSendValue() const {
+  return has_send_value_;
+}
+
+uint32_t QuicFixedUint32::GetSendValue() const {
+  QUIC_BUG_IF(quic_bug_12743_1, !has_send_value_)
+      << "No send value to get for tag:" << QuicTagToString(tag_);
+  return send_value_;
+}
+
+void QuicFixedUint32::SetSendValue(uint32_t value) {
+  has_send_value_ = true;
+  send_value_ = value;
+}
+
+bool QuicFixedUint32::HasReceivedValue() const {
+  return has_receive_value_;
+}
+
+uint32_t QuicFixedUint32::GetReceivedValue() const {
+  QUIC_BUG_IF(quic_bug_12743_2, !has_receive_value_)
+      << "No receive value to get for tag:" << QuicTagToString(tag_);
+  return receive_value_;
+}
+
+void QuicFixedUint32::SetReceivedValue(uint32_t value) {
+  has_receive_value_ = true;
+  receive_value_ = value;
+}
+
+void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
+  if (tag_ == 0) {
+    QUIC_BUG(quic_bug_12743_3)
+        << "This parameter does not support writing to CryptoHandshakeMessage";
+    return;
+  }
+  if (has_send_value_) {
+    out->SetValue(tag_, send_value_);
+  }
+}
+
+QuicErrorCode QuicFixedUint32::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  if (tag_ == 0) {
+    *error_details =
+        "This parameter does not support reading from CryptoHandshakeMessage";
+    QUIC_BUG(quic_bug_10575_1) << *error_details;
+    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  }
+  QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_);
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence_ == PRESENCE_OPTIONAL) {
+        return QUIC_NO_ERROR;
+      }
+      *error_details = "Missing " + QuicTagToString(tag_);
+      break;
+    case QUIC_NO_ERROR:
+      has_receive_value_ = true;
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag_);
+      break;
+  }
+  return error;
+}
+
+QuicFixedUint62::QuicFixedUint62(QuicTag name, QuicConfigPresence presence)
+    : QuicConfigValue(name, presence),
+      has_send_value_(false),
+      has_receive_value_(false) {}
+
+QuicFixedUint62::~QuicFixedUint62() {}
+
+bool QuicFixedUint62::HasSendValue() const {
+  return has_send_value_;
+}
+
+uint64_t QuicFixedUint62::GetSendValue() const {
+  if (!has_send_value_) {
+    QUIC_BUG(quic_bug_10575_2)
+        << "No send value to get for tag:" << QuicTagToString(tag_);
+    return 0;
+  }
+  return send_value_;
+}
+
+void QuicFixedUint62::SetSendValue(uint64_t value) {
+  if (value > kVarInt62MaxValue) {
+    QUIC_BUG(quic_bug_10575_3) << "QuicFixedUint62 invalid value " << value;
+    value = kVarInt62MaxValue;
+  }
+  has_send_value_ = true;
+  send_value_ = value;
+}
+
+bool QuicFixedUint62::HasReceivedValue() const {
+  return has_receive_value_;
+}
+
+uint64_t QuicFixedUint62::GetReceivedValue() const {
+  if (!has_receive_value_) {
+    QUIC_BUG(quic_bug_10575_4)
+        << "No receive value to get for tag:" << QuicTagToString(tag_);
+    return 0;
+  }
+  return receive_value_;
+}
+
+void QuicFixedUint62::SetReceivedValue(uint64_t value) {
+  has_receive_value_ = true;
+  receive_value_ = value;
+}
+
+void QuicFixedUint62::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
+  if (!has_send_value_) {
+    return;
+  }
+  uint32_t send_value32;
+  if (send_value_ > std::numeric_limits<uint32_t>::max()) {
+    QUIC_BUG(quic_bug_10575_5) << "Attempting to send " << send_value_
+                               << " for tag:" << QuicTagToString(tag_);
+    send_value32 = std::numeric_limits<uint32_t>::max();
+  } else {
+    send_value32 = static_cast<uint32_t>(send_value_);
+  }
+  out->SetValue(tag_, send_value32);
+}
+
+QuicErrorCode QuicFixedUint62::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  uint32_t receive_value32;
+  QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value32);
+  // GetUint32 is guaranteed to always initialize receive_value32.
+  receive_value_ = receive_value32;
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence_ == PRESENCE_OPTIONAL) {
+        return QUIC_NO_ERROR;
+      }
+      *error_details = "Missing " + QuicTagToString(tag_);
+      break;
+    case QUIC_NO_ERROR:
+      has_receive_value_ = true;
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag_);
+      break;
+  }
+  return error;
+}
+
+QuicFixedStatelessResetToken::QuicFixedStatelessResetToken(
+    QuicTag tag,
+    QuicConfigPresence presence)
+    : QuicConfigValue(tag, presence),
+      has_send_value_(false),
+      has_receive_value_(false) {}
+QuicFixedStatelessResetToken::~QuicFixedStatelessResetToken() {}
+
+bool QuicFixedStatelessResetToken::HasSendValue() const {
+  return has_send_value_;
+}
+
+const StatelessResetToken& QuicFixedStatelessResetToken::GetSendValue() const {
+  QUIC_BUG_IF(quic_bug_12743_4, !has_send_value_)
+      << "No send value to get for tag:" << QuicTagToString(tag_);
+  return send_value_;
+}
+
+void QuicFixedStatelessResetToken::SetSendValue(
+    const StatelessResetToken& value) {
+  has_send_value_ = true;
+  send_value_ = value;
+}
+
+bool QuicFixedStatelessResetToken::HasReceivedValue() const {
+  return has_receive_value_;
+}
+
+const StatelessResetToken& QuicFixedStatelessResetToken::GetReceivedValue()
+    const {
+  QUIC_BUG_IF(quic_bug_12743_5, !has_receive_value_)
+      << "No receive value to get for tag:" << QuicTagToString(tag_);
+  return receive_value_;
+}
+
+void QuicFixedStatelessResetToken::SetReceivedValue(
+    const StatelessResetToken& value) {
+  has_receive_value_ = true;
+  receive_value_ = value;
+}
+
+void QuicFixedStatelessResetToken::ToHandshakeMessage(
+    CryptoHandshakeMessage* out) const {
+  if (has_send_value_) {
+    out->SetValue(tag_, send_value_);
+  }
+}
+
+QuicErrorCode QuicFixedStatelessResetToken::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  QuicErrorCode error =
+      peer_hello.GetStatelessResetToken(tag_, &receive_value_);
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence_ == PRESENCE_OPTIONAL) {
+        return QUIC_NO_ERROR;
+      }
+      *error_details = "Missing " + QuicTagToString(tag_);
+      break;
+    case QUIC_NO_ERROR:
+      has_receive_value_ = true;
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag_);
+      break;
+  }
+  return error;
+}
+
+QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
+                                       QuicConfigPresence presence)
+    : QuicConfigValue(name, presence),
+      has_send_values_(false),
+      has_receive_values_(false) {}
+
+QuicFixedTagVector::QuicFixedTagVector(const QuicFixedTagVector& other) =
+    default;
+
+QuicFixedTagVector::~QuicFixedTagVector() {}
+
+bool QuicFixedTagVector::HasSendValues() const {
+  return has_send_values_;
+}
+
+const QuicTagVector& QuicFixedTagVector::GetSendValues() const {
+  QUIC_BUG_IF(quic_bug_12743_6, !has_send_values_)
+      << "No send values to get for tag:" << QuicTagToString(tag_);
+  return send_values_;
+}
+
+void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) {
+  has_send_values_ = true;
+  send_values_ = values;
+}
+
+bool QuicFixedTagVector::HasReceivedValues() const {
+  return has_receive_values_;
+}
+
+const QuicTagVector& QuicFixedTagVector::GetReceivedValues() const {
+  QUIC_BUG_IF(quic_bug_12743_7, !has_receive_values_)
+      << "No receive value to get for tag:" << QuicTagToString(tag_);
+  return receive_values_;
+}
+
+void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) {
+  has_receive_values_ = true;
+  receive_values_ = values;
+}
+
+void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
+  if (has_send_values_) {
+    out->SetVector(tag_, send_values_);
+  }
+}
+
+QuicErrorCode QuicFixedTagVector::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  QuicTagVector values;
+  QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence_ == PRESENCE_OPTIONAL) {
+        return QUIC_NO_ERROR;
+      }
+      *error_details = "Missing " + QuicTagToString(tag_);
+      break;
+    case QUIC_NO_ERROR:
+      QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
+      has_receive_values_ = true;
+      receive_values_.insert(receive_values_.end(), values.begin(),
+                             values.end());
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag_);
+      break;
+  }
+  return error;
+}
+
+QuicFixedSocketAddress::QuicFixedSocketAddress(QuicTag tag,
+                                               QuicConfigPresence presence)
+    : QuicConfigValue(tag, presence),
+      has_send_value_(false),
+      has_receive_value_(false) {}
+
+QuicFixedSocketAddress::~QuicFixedSocketAddress() {}
+
+bool QuicFixedSocketAddress::HasSendValue() const {
+  return has_send_value_;
+}
+
+const QuicSocketAddress& QuicFixedSocketAddress::GetSendValue() const {
+  QUIC_BUG_IF(quic_bug_12743_8, !has_send_value_)
+      << "No send value to get for tag:" << QuicTagToString(tag_);
+  return send_value_;
+}
+
+void QuicFixedSocketAddress::SetSendValue(const QuicSocketAddress& value) {
+  has_send_value_ = true;
+  send_value_ = value;
+}
+
+bool QuicFixedSocketAddress::HasReceivedValue() const {
+  return has_receive_value_;
+}
+
+const QuicSocketAddress& QuicFixedSocketAddress::GetReceivedValue() const {
+  QUIC_BUG_IF(quic_bug_12743_9, !has_receive_value_)
+      << "No receive value to get for tag:" << QuicTagToString(tag_);
+  return receive_value_;
+}
+
+void QuicFixedSocketAddress::SetReceivedValue(const QuicSocketAddress& value) {
+  has_receive_value_ = true;
+  receive_value_ = value;
+}
+
+void QuicFixedSocketAddress::ToHandshakeMessage(
+    CryptoHandshakeMessage* out) const {
+  if (has_send_value_) {
+    QuicSocketAddressCoder address_coder(send_value_);
+    out->SetStringPiece(tag_, address_coder.Encode());
+  }
+}
+
+QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  absl::string_view address;
+  if (!peer_hello.GetStringPiece(tag_, &address)) {
+    if (presence_ == PRESENCE_REQUIRED) {
+      *error_details = "Missing " + QuicTagToString(tag_);
+      return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+    }
+  } else {
+    QuicSocketAddressCoder address_coder;
+    if (address_coder.Decode(address.data(), address.length())) {
+      SetReceivedValue(
+          QuicSocketAddress(address_coder.ip(), address_coder.port()));
+    }
+  }
+  return QUIC_NO_ERROR;
+}
+
+QuicConfig::QuicConfig()
+    : negotiated_(false),
+      max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
+      max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
+      max_undecryptable_packets_(0),
+      connection_options_(kCOPT, PRESENCE_OPTIONAL),
+      client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
+      max_idle_timeout_to_send_(QuicTime::Delta::Infinite()),
+      max_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED),
+      max_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
+      bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
+      initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
+      initial_max_stream_data_bytes_incoming_bidirectional_(0,
+                                                            PRESENCE_OPTIONAL),
+      initial_max_stream_data_bytes_outgoing_bidirectional_(0,
+                                                            PRESENCE_OPTIONAL),
+      initial_max_stream_data_bytes_unidirectional_(0, PRESENCE_OPTIONAL),
+      initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
+      initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
+      connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
+      alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
+      alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
+      stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
+      max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
+      min_ack_delay_ms_(0, PRESENCE_OPTIONAL),
+      ack_delay_exponent_(kADE, PRESENCE_OPTIONAL),
+      max_udp_payload_size_(0, PRESENCE_OPTIONAL),
+      max_datagram_frame_size_(0, PRESENCE_OPTIONAL),
+      active_connection_id_limit_(0, PRESENCE_OPTIONAL) {
+  SetDefaults();
+}
+
+QuicConfig::QuicConfig(const QuicConfig& other) = default;
+
+QuicConfig::~QuicConfig() {}
+
+bool QuicConfig::SetInitialReceivedConnectionOptions(
+    const QuicTagVector& tags) {
+  if (HasReceivedConnectionOptions()) {
+    // If we have already received connection options (via handshake or due to
+    // a previous call), don't re-initialize.
+    return false;
+  }
+  connection_options_.SetReceivedValues(tags);
+  return true;
+}
+
+void QuicConfig::SetConnectionOptionsToSend(
+    const QuicTagVector& connection_options) {
+  connection_options_.SetSendValues(connection_options);
+}
+
+bool QuicConfig::HasReceivedConnectionOptions() const {
+  return connection_options_.HasReceivedValues();
+}
+
+const QuicTagVector& QuicConfig::ReceivedConnectionOptions() const {
+  return connection_options_.GetReceivedValues();
+}
+
+bool QuicConfig::HasSendConnectionOptions() const {
+  return connection_options_.HasSendValues();
+}
+
+const QuicTagVector& QuicConfig::SendConnectionOptions() const {
+  return connection_options_.GetSendValues();
+}
+
+bool QuicConfig::HasClientSentConnectionOption(QuicTag tag,
+                                               Perspective perspective) const {
+  if (perspective == Perspective::IS_SERVER) {
+    if (HasReceivedConnectionOptions() &&
+        ContainsQuicTag(ReceivedConnectionOptions(), tag)) {
+      return true;
+    }
+  } else if (HasSendConnectionOptions() &&
+             ContainsQuicTag(SendConnectionOptions(), tag)) {
+    return true;
+  }
+  return false;
+}
+
+void QuicConfig::SetClientConnectionOptions(
+    const QuicTagVector& client_connection_options) {
+  client_connection_options_.SetSendValues(client_connection_options);
+}
+
+bool QuicConfig::HasClientRequestedIndependentOption(
+    QuicTag tag,
+    Perspective perspective) const {
+  if (perspective == Perspective::IS_SERVER) {
+    return (HasReceivedConnectionOptions() &&
+            ContainsQuicTag(ReceivedConnectionOptions(), tag));
+  }
+
+  return (client_connection_options_.HasSendValues() &&
+          ContainsQuicTag(client_connection_options_.GetSendValues(), tag));
+}
+
+const QuicTagVector& QuicConfig::ClientRequestedIndependentOptions(
+    Perspective perspective) const {
+  static const QuicTagVector* no_options = new QuicTagVector;
+  if (perspective == Perspective::IS_SERVER) {
+    return HasReceivedConnectionOptions() ? ReceivedConnectionOptions()
+                                          : *no_options;
+  }
+
+  return client_connection_options_.HasSendValues()
+             ? client_connection_options_.GetSendValues()
+             : *no_options;
+}
+
+void QuicConfig::SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout) {
+  if (idle_network_timeout.ToMicroseconds() <= 0) {
+    QUIC_BUG(quic_bug_10575_6)
+        << "Invalid idle network timeout " << idle_network_timeout;
+    return;
+  }
+  max_idle_timeout_to_send_ = idle_network_timeout;
+}
+
+QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
+  // TODO(b/152032210) add a QUIC_BUG to ensure that is not called before we've
+  // received the peer's values. This is true in production code but not in all
+  // of our tests that use a fake QuicConfig.
+  if (!received_max_idle_timeout_.has_value()) {
+    return max_idle_timeout_to_send_;
+  }
+  return received_max_idle_timeout_.value();
+}
+
+void QuicConfig::SetMaxBidirectionalStreamsToSend(uint32_t max_streams) {
+  max_bidirectional_streams_.SetSendValue(max_streams);
+}
+
+uint32_t QuicConfig::GetMaxBidirectionalStreamsToSend() const {
+  return max_bidirectional_streams_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxBidirectionalStreams() const {
+  return max_bidirectional_streams_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedMaxBidirectionalStreams() const {
+  return max_bidirectional_streams_.GetReceivedValue();
+}
+
+void QuicConfig::SetMaxUnidirectionalStreamsToSend(uint32_t max_streams) {
+  max_unidirectional_streams_.SetSendValue(max_streams);
+}
+
+uint32_t QuicConfig::GetMaxUnidirectionalStreamsToSend() const {
+  return max_unidirectional_streams_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxUnidirectionalStreams() const {
+  return max_unidirectional_streams_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedMaxUnidirectionalStreams() const {
+  return max_unidirectional_streams_.GetReceivedValue();
+}
+
+void QuicConfig::SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms) {
+  max_ack_delay_ms_.SetSendValue(max_ack_delay_ms);
+}
+
+uint32_t QuicConfig::GetMaxAckDelayToSendMs() const {
+  return max_ack_delay_ms_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxAckDelayMs() const {
+  return max_ack_delay_ms_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedMaxAckDelayMs() const {
+  return max_ack_delay_ms_.GetReceivedValue();
+}
+
+void QuicConfig::SetMinAckDelayMs(uint32_t min_ack_delay_ms) {
+  min_ack_delay_ms_.SetSendValue(min_ack_delay_ms);
+}
+
+uint32_t QuicConfig::GetMinAckDelayToSendMs() const {
+  return min_ack_delay_ms_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMinAckDelayMs() const {
+  return min_ack_delay_ms_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedMinAckDelayMs() const {
+  return min_ack_delay_ms_.GetReceivedValue();
+}
+
+void QuicConfig::SetAckDelayExponentToSend(uint32_t exponent) {
+  ack_delay_exponent_.SetSendValue(exponent);
+}
+
+uint32_t QuicConfig::GetAckDelayExponentToSend() const {
+  return ack_delay_exponent_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedAckDelayExponent() const {
+  return ack_delay_exponent_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedAckDelayExponent() const {
+  return ack_delay_exponent_.GetReceivedValue();
+}
+
+void QuicConfig::SetMaxPacketSizeToSend(uint64_t max_udp_payload_size) {
+  max_udp_payload_size_.SetSendValue(max_udp_payload_size);
+}
+
+uint64_t QuicConfig::GetMaxPacketSizeToSend() const {
+  return max_udp_payload_size_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxPacketSize() const {
+  return max_udp_payload_size_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedMaxPacketSize() const {
+  return max_udp_payload_size_.GetReceivedValue();
+}
+
+void QuicConfig::SetMaxDatagramFrameSizeToSend(
+    uint64_t max_datagram_frame_size) {
+  max_datagram_frame_size_.SetSendValue(max_datagram_frame_size);
+}
+
+uint64_t QuicConfig::GetMaxDatagramFrameSizeToSend() const {
+  return max_datagram_frame_size_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxDatagramFrameSize() const {
+  return max_datagram_frame_size_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedMaxDatagramFrameSize() const {
+  return max_datagram_frame_size_.GetReceivedValue();
+}
+
+void QuicConfig::SetActiveConnectionIdLimitToSend(
+    uint64_t active_connection_id_limit) {
+  active_connection_id_limit_.SetSendValue(active_connection_id_limit);
+}
+
+uint64_t QuicConfig::GetActiveConnectionIdLimitToSend() const {
+  return active_connection_id_limit_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedActiveConnectionIdLimit() const {
+  return active_connection_id_limit_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedActiveConnectionIdLimit() const {
+  return active_connection_id_limit_.GetReceivedValue();
+}
+
+bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
+  return bytes_for_connection_id_.HasSendValue();
+}
+
+void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
+  bytes_for_connection_id_.SetSendValue(bytes);
+}
+
+bool QuicConfig::HasReceivedBytesForConnectionId() const {
+  return bytes_for_connection_id_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
+  return bytes_for_connection_id_.GetReceivedValue();
+}
+
+void QuicConfig::SetInitialRoundTripTimeUsToSend(uint64_t rtt) {
+  initial_round_trip_time_us_.SetSendValue(rtt);
+}
+
+bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
+  return initial_round_trip_time_us_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
+  return initial_round_trip_time_us_.GetReceivedValue();
+}
+
+bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
+  return initial_round_trip_time_us_.HasSendValue();
+}
+
+uint64_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
+  return initial_round_trip_time_us_.GetSendValue();
+}
+
+void QuicConfig::SetInitialStreamFlowControlWindowToSend(
+    uint64_t window_bytes) {
+  if (window_bytes < kMinimumFlowControlSendWindow) {
+    QUIC_BUG(quic_bug_10575_7)
+        << "Initial stream flow control receive window (" << window_bytes
+        << ") cannot be set lower than minimum ("
+        << kMinimumFlowControlSendWindow << ").";
+    window_bytes = kMinimumFlowControlSendWindow;
+  }
+  initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
+  return initial_stream_flow_control_window_bytes_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
+  return initial_stream_flow_control_window_bytes_.GetReceivedValue();
+}
+
+void QuicConfig::SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+    uint64_t window_bytes) {
+  initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue(
+      window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()
+    const {
+  if (initial_max_stream_data_bytes_incoming_bidirectional_.HasSendValue()) {
+    return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
+  }
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()
+    const {
+  return initial_max_stream_data_bytes_incoming_bidirectional_
+      .HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesIncomingBidirectional()
+    const {
+  return initial_max_stream_data_bytes_incoming_bidirectional_
+      .GetReceivedValue();
+}
+
+void QuicConfig::SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+    uint64_t window_bytes) {
+  initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue(
+      window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()
+    const {
+  if (initial_max_stream_data_bytes_outgoing_bidirectional_.HasSendValue()) {
+    return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
+  }
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
+    const {
+  return initial_max_stream_data_bytes_outgoing_bidirectional_
+      .HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
+    const {
+  return initial_max_stream_data_bytes_outgoing_bidirectional_
+      .GetReceivedValue();
+}
+
+void QuicConfig::SetInitialMaxStreamDataBytesUnidirectionalToSend(
+    uint64_t window_bytes) {
+  initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const {
+  if (initial_max_stream_data_bytes_unidirectional_.HasSendValue()) {
+    return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
+  }
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const {
+  return initial_max_stream_data_bytes_unidirectional_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesUnidirectional() const {
+  return initial_max_stream_data_bytes_unidirectional_.GetReceivedValue();
+}
+
+void QuicConfig::SetInitialSessionFlowControlWindowToSend(
+    uint64_t window_bytes) {
+  if (window_bytes < kMinimumFlowControlSendWindow) {
+    QUIC_BUG(quic_bug_10575_8)
+        << "Initial session flow control receive window (" << window_bytes
+        << ") cannot be set lower than default ("
+        << kMinimumFlowControlSendWindow << ").";
+    window_bytes = kMinimumFlowControlSendWindow;
+  }
+  initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
+  return initial_session_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
+  return initial_session_flow_control_window_bytes_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
+  return initial_session_flow_control_window_bytes_.GetReceivedValue();
+}
+
+void QuicConfig::SetDisableConnectionMigration() {
+  connection_migration_disabled_.SetSendValue(1);
+}
+
+bool QuicConfig::DisableConnectionMigration() const {
+  return connection_migration_disabled_.HasReceivedValue();
+}
+
+void QuicConfig::SetIPv6AlternateServerAddressToSend(
+    const QuicSocketAddress& alternate_server_address_ipv6) {
+  if (!alternate_server_address_ipv6.host().IsIPv6()) {
+    QUIC_BUG(quic_bug_10575_9)
+        << "Cannot use SetIPv6AlternateServerAddressToSend with "
+        << alternate_server_address_ipv6;
+    return;
+  }
+  alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
+}
+
+void QuicConfig::SetIPv6AlternateServerAddressToSend(
+    const QuicSocketAddress& alternate_server_address_ipv6,
+    const QuicConnectionId& connection_id,
+    const StatelessResetToken& stateless_reset_token) {
+  if (!alternate_server_address_ipv6.host().IsIPv6()) {
+    QUIC_BUG(quic_bug_10575_10)
+        << "Cannot use SetIPv6AlternateServerAddressToSend with "
+        << alternate_server_address_ipv6;
+    return;
+  }
+  alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
+  preferred_address_connection_id_and_token_ =
+      std::make_pair(connection_id, stateless_reset_token);
+}
+
+bool QuicConfig::HasReceivedIPv6AlternateServerAddress() const {
+  return alternate_server_address_ipv6_.HasReceivedValue();
+}
+
+const QuicSocketAddress& QuicConfig::ReceivedIPv6AlternateServerAddress()
+    const {
+  return alternate_server_address_ipv6_.GetReceivedValue();
+}
+
+void QuicConfig::SetIPv4AlternateServerAddressToSend(
+    const QuicSocketAddress& alternate_server_address_ipv4) {
+  if (!alternate_server_address_ipv4.host().IsIPv4()) {
+    QUIC_BUG(quic_bug_10575_11)
+        << "Cannot use SetIPv4AlternateServerAddressToSend with "
+        << alternate_server_address_ipv4;
+    return;
+  }
+  alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
+}
+
+void QuicConfig::SetIPv4AlternateServerAddressToSend(
+    const QuicSocketAddress& alternate_server_address_ipv4,
+    const QuicConnectionId& connection_id,
+    const StatelessResetToken& stateless_reset_token) {
+  if (!alternate_server_address_ipv4.host().IsIPv4()) {
+    QUIC_BUG(quic_bug_10575_12)
+        << "Cannot use SetIPv4AlternateServerAddressToSend with "
+        << alternate_server_address_ipv4;
+    return;
+  }
+  alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
+  preferred_address_connection_id_and_token_ =
+      std::make_pair(connection_id, stateless_reset_token);
+}
+
+bool QuicConfig::HasReceivedIPv4AlternateServerAddress() const {
+  return alternate_server_address_ipv4_.HasReceivedValue();
+}
+
+const QuicSocketAddress& QuicConfig::ReceivedIPv4AlternateServerAddress()
+    const {
+  return alternate_server_address_ipv4_.GetReceivedValue();
+}
+
+bool QuicConfig::HasReceivedPreferredAddressConnectionIdAndToken() const {
+  return (HasReceivedIPv6AlternateServerAddress() ||
+          HasReceivedIPv4AlternateServerAddress()) &&
+         preferred_address_connection_id_and_token_.has_value();
+}
+
+const std::pair<QuicConnectionId, StatelessResetToken>&
+QuicConfig::ReceivedPreferredAddressConnectionIdAndToken() const {
+  QUICHE_DCHECK(HasReceivedPreferredAddressConnectionIdAndToken());
+  return *preferred_address_connection_id_and_token_;
+}
+
+void QuicConfig::SetOriginalConnectionIdToSend(
+    const QuicConnectionId& original_destination_connection_id) {
+  original_destination_connection_id_to_send_ =
+      original_destination_connection_id;
+}
+
+bool QuicConfig::HasReceivedOriginalConnectionId() const {
+  return received_original_destination_connection_id_.has_value();
+}
+
+QuicConnectionId QuicConfig::ReceivedOriginalConnectionId() const {
+  if (!HasReceivedOriginalConnectionId()) {
+    QUIC_BUG(quic_bug_10575_13) << "No received original connection ID";
+    return EmptyQuicConnectionId();
+  }
+  return received_original_destination_connection_id_.value();
+}
+
+void QuicConfig::SetInitialSourceConnectionIdToSend(
+    const QuicConnectionId& initial_source_connection_id) {
+  initial_source_connection_id_to_send_ = initial_source_connection_id;
+}
+
+bool QuicConfig::HasReceivedInitialSourceConnectionId() const {
+  return received_initial_source_connection_id_.has_value();
+}
+
+QuicConnectionId QuicConfig::ReceivedInitialSourceConnectionId() const {
+  if (!HasReceivedInitialSourceConnectionId()) {
+    QUIC_BUG(quic_bug_10575_14) << "No received initial source connection ID";
+    return EmptyQuicConnectionId();
+  }
+  return received_initial_source_connection_id_.value();
+}
+
+void QuicConfig::SetRetrySourceConnectionIdToSend(
+    const QuicConnectionId& retry_source_connection_id) {
+  retry_source_connection_id_to_send_ = retry_source_connection_id;
+}
+
+bool QuicConfig::HasReceivedRetrySourceConnectionId() const {
+  return received_retry_source_connection_id_.has_value();
+}
+
+QuicConnectionId QuicConfig::ReceivedRetrySourceConnectionId() const {
+  if (!HasReceivedRetrySourceConnectionId()) {
+    QUIC_BUG(quic_bug_10575_15) << "No received retry source connection ID";
+    return EmptyQuicConnectionId();
+  }
+  return received_retry_source_connection_id_.value();
+}
+
+void QuicConfig::SetStatelessResetTokenToSend(
+    const StatelessResetToken& stateless_reset_token) {
+  stateless_reset_token_.SetSendValue(stateless_reset_token);
+}
+
+bool QuicConfig::HasReceivedStatelessResetToken() const {
+  return stateless_reset_token_.HasReceivedValue();
+}
+
+const StatelessResetToken& QuicConfig::ReceivedStatelessResetToken() const {
+  return stateless_reset_token_.GetReceivedValue();
+}
+
+bool QuicConfig::negotiated() const {
+  return negotiated_;
+}
+
+void QuicConfig::SetCreateSessionTagIndicators(QuicTagVector tags) {
+  create_session_tag_indicators_ = std::move(tags);
+}
+
+const QuicTagVector& QuicConfig::create_session_tag_indicators() const {
+  return create_session_tag_indicators_;
+}
+
+void QuicConfig::SetDefaults() {
+  SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+  SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+  SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+  max_time_before_crypto_handshake_ =
+      QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs);
+  max_idle_time_before_crypto_handshake_ =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs);
+  max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
+
+  SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
+  SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
+  SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
+  SetAckDelayExponentToSend(kDefaultAckDelayExponent);
+  SetMaxPacketSizeToSend(kMaxIncomingPacketSize);
+  SetMaxDatagramFrameSizeToSend(kMaxAcceptedDatagramFrameSize);
+}
+
+void QuicConfig::ToHandshakeMessage(
+    CryptoHandshakeMessage* out,
+    QuicTransportVersion transport_version) const {
+  // Idle timeout has custom rules that are different from other values.
+  // We configure ourselves with the minumum value between the one sent and
+  // the one received. Additionally, when QUIC_CRYPTO is used, the server
+  // MUST send an idle timeout no greater than the idle timeout it received
+  // from the client. We therefore send the received value if it is lower.
+  QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
+  uint32_t max_idle_timeout_to_send_seconds =
+      max_idle_timeout_to_send_.ToSeconds();
+  if (received_max_idle_timeout_.has_value() &&
+      received_max_idle_timeout_->ToSeconds() <
+          max_idle_timeout_to_send_seconds) {
+    max_idle_timeout_to_send_seconds = received_max_idle_timeout_->ToSeconds();
+  }
+  max_idle_timeout_seconds.SetSendValue(max_idle_timeout_to_send_seconds);
+  max_idle_timeout_seconds.ToHandshakeMessage(out);
+
+  // Do not need a version check here, max...bi... will encode
+  // as "MIDS" -- the max initial dynamic streams tag -- if
+  // doing some version other than IETF QUIC.
+  max_bidirectional_streams_.ToHandshakeMessage(out);
+  if (VersionHasIetfQuicFrames(transport_version)) {
+    max_unidirectional_streams_.ToHandshakeMessage(out);
+    ack_delay_exponent_.ToHandshakeMessage(out);
+  }
+  if (max_ack_delay_ms_.GetSendValue() != kDefaultDelayedAckTimeMs) {
+    // Only send max ack delay if it is using a non-default value, because
+    // the default value is used by QuicSentPacketManager if it is not
+    // sent during the handshake, and we want to save bytes.
+    max_ack_delay_ms_.ToHandshakeMessage(out);
+  }
+  bytes_for_connection_id_.ToHandshakeMessage(out);
+  initial_round_trip_time_us_.ToHandshakeMessage(out);
+  initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
+  initial_session_flow_control_window_bytes_.ToHandshakeMessage(out);
+  connection_migration_disabled_.ToHandshakeMessage(out);
+  connection_options_.ToHandshakeMessage(out);
+  if (alternate_server_address_ipv6_.HasSendValue()) {
+    alternate_server_address_ipv6_.ToHandshakeMessage(out);
+  } else {
+    alternate_server_address_ipv4_.ToHandshakeMessage(out);
+  }
+  stateless_reset_token_.ToHandshakeMessage(out);
+}
+
+QuicErrorCode QuicConfig::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType hello_type,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  QuicErrorCode error = QUIC_NO_ERROR;
+  if (error == QUIC_NO_ERROR) {
+    // Idle timeout has custom rules that are different from other values.
+    // We configure ourselves with the minumum value between the one sent and
+    // the one received. Additionally, when QUIC_CRYPTO is used, the server
+    // MUST send an idle timeout no greater than the idle timeout it received
+    // from the client.
+    QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
+    error = max_idle_timeout_seconds.ProcessPeerHello(peer_hello, hello_type,
+                                                      error_details);
+    if (error == QUIC_NO_ERROR) {
+      if (max_idle_timeout_seconds.GetReceivedValue() >
+          max_idle_timeout_to_send_.ToSeconds()) {
+        // The received value is higher than ours, ignore it if from the client
+        // and raise an error if from the server.
+        if (hello_type == SERVER) {
+          error = QUIC_INVALID_NEGOTIATED_VALUE;
+          *error_details =
+              "Invalid value received for " + QuicTagToString(kICSL);
+        }
+      } else {
+        received_max_idle_timeout_ = QuicTime::Delta::FromSeconds(
+            max_idle_timeout_seconds.GetReceivedValue());
+      }
+    }
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = max_bidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
+                                                        error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = max_unidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
+                                                         error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
+                                                      error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
+                                                         error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
+        peer_hello, hello_type, error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = initial_session_flow_control_window_bytes_.ProcessPeerHello(
+        peer_hello, hello_type, error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = connection_migration_disabled_.ProcessPeerHello(
+        peer_hello, hello_type, error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
+                                                 error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    QuicFixedSocketAddress alternate_server_address(kASAD, PRESENCE_OPTIONAL);
+    error = alternate_server_address.ProcessPeerHello(peer_hello, hello_type,
+                                                      error_details);
+    if (error == QUIC_NO_ERROR && alternate_server_address.HasReceivedValue()) {
+      const QuicSocketAddress& received_address =
+          alternate_server_address.GetReceivedValue();
+      if (received_address.host().IsIPv6()) {
+        alternate_server_address_ipv6_.SetReceivedValue(received_address);
+      } else if (received_address.host().IsIPv4()) {
+        alternate_server_address_ipv4_.SetReceivedValue(received_address);
+      }
+    }
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = stateless_reset_token_.ProcessPeerHello(peer_hello, hello_type,
+                                                    error_details);
+  }
+
+  if (error == QUIC_NO_ERROR) {
+    error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
+                                               error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = ack_delay_exponent_.ProcessPeerHello(peer_hello, hello_type,
+                                                 error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    negotiated_ = true;
+  }
+  return error;
+}
+
+bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
+  if (original_destination_connection_id_to_send_.has_value()) {
+    params->original_destination_connection_id =
+        original_destination_connection_id_to_send_.value();
+  }
+
+  params->max_idle_timeout_ms.set_value(
+      max_idle_timeout_to_send_.ToMilliseconds());
+
+  if (stateless_reset_token_.HasSendValue()) {
+    StatelessResetToken stateless_reset_token =
+        stateless_reset_token_.GetSendValue();
+    params->stateless_reset_token.assign(
+        reinterpret_cast<const char*>(&stateless_reset_token),
+        reinterpret_cast<const char*>(&stateless_reset_token) +
+            sizeof(stateless_reset_token));
+  }
+
+  params->max_udp_payload_size.set_value(GetMaxPacketSizeToSend());
+  params->max_datagram_frame_size.set_value(GetMaxDatagramFrameSizeToSend());
+  params->initial_max_data.set_value(
+      GetInitialSessionFlowControlWindowToSend());
+  // The max stream data bidirectional transport parameters can be either local
+  // or remote. A stream is local iff it is initiated by the endpoint that sent
+  // the transport parameter (see the Transport Parameter Definitions section of
+  // draft-ietf-quic-transport). In this function we are sending transport
+  // parameters, so a local stream is one we initiated, which means an outgoing
+  // stream.
+  params->initial_max_stream_data_bidi_local.set_value(
+      GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  params->initial_max_stream_data_bidi_remote.set_value(
+      GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  params->initial_max_stream_data_uni.set_value(
+      GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  params->initial_max_streams_bidi.set_value(
+      GetMaxBidirectionalStreamsToSend());
+  params->initial_max_streams_uni.set_value(
+      GetMaxUnidirectionalStreamsToSend());
+  params->max_ack_delay.set_value(GetMaxAckDelayToSendMs());
+  if (min_ack_delay_ms_.HasSendValue()) {
+    params->min_ack_delay_us.set_value(min_ack_delay_ms_.GetSendValue() *
+                                       kNumMicrosPerMilli);
+  }
+  params->ack_delay_exponent.set_value(GetAckDelayExponentToSend());
+  params->disable_active_migration =
+      connection_migration_disabled_.HasSendValue() &&
+      connection_migration_disabled_.GetSendValue() != 0;
+
+  if (alternate_server_address_ipv6_.HasSendValue() ||
+      alternate_server_address_ipv4_.HasSendValue()) {
+    TransportParameters::PreferredAddress preferred_address;
+    if (alternate_server_address_ipv6_.HasSendValue()) {
+      preferred_address.ipv6_socket_address =
+          alternate_server_address_ipv6_.GetSendValue();
+    }
+    if (alternate_server_address_ipv4_.HasSendValue()) {
+      preferred_address.ipv4_socket_address =
+          alternate_server_address_ipv4_.GetSendValue();
+    }
+    if (preferred_address_connection_id_and_token_) {
+      preferred_address.connection_id =
+          preferred_address_connection_id_and_token_->first;
+      auto* begin = reinterpret_cast<const char*>(
+          &preferred_address_connection_id_and_token_->second);
+      auto* end =
+          begin + sizeof(preferred_address_connection_id_and_token_->second);
+      preferred_address.stateless_reset_token.assign(begin, end);
+    }
+    params->preferred_address =
+        std::make_unique<TransportParameters::PreferredAddress>(
+            preferred_address);
+  }
+
+  if (active_connection_id_limit_.HasSendValue()) {
+    params->active_connection_id_limit.set_value(
+        active_connection_id_limit_.GetSendValue());
+  }
+
+  if (initial_source_connection_id_to_send_.has_value()) {
+    params->initial_source_connection_id =
+        initial_source_connection_id_to_send_.value();
+  }
+
+  if (retry_source_connection_id_to_send_.has_value()) {
+    params->retry_source_connection_id =
+        retry_source_connection_id_to_send_.value();
+  }
+
+  if (initial_round_trip_time_us_.HasSendValue()) {
+    params->initial_round_trip_time_us.set_value(
+        initial_round_trip_time_us_.GetSendValue());
+  }
+  if (connection_options_.HasSendValues() &&
+      !connection_options_.GetSendValues().empty()) {
+    params->google_connection_options = connection_options_.GetSendValues();
+  }
+
+  params->custom_parameters = custom_transport_parameters_to_send_;
+
+  return true;
+}
+
+QuicErrorCode QuicConfig::ProcessTransportParameters(
+    const TransportParameters& params,
+    bool is_resumption,
+    std::string* error_details) {
+  if (!is_resumption && params.original_destination_connection_id.has_value()) {
+    received_original_destination_connection_id_ =
+        params.original_destination_connection_id.value();
+  }
+
+  if (params.max_idle_timeout_ms.value() > 0 &&
+      params.max_idle_timeout_ms.value() <
+          static_cast<uint64_t>(max_idle_timeout_to_send_.ToMilliseconds())) {
+    // An idle timeout of zero indicates it is disabled.
+    // We also ignore values higher than ours which will cause us to use the
+    // smallest value between ours and our peer's.
+    received_max_idle_timeout_ =
+        QuicTime::Delta::FromMilliseconds(params.max_idle_timeout_ms.value());
+  }
+
+  if (!is_resumption && !params.stateless_reset_token.empty()) {
+    StatelessResetToken stateless_reset_token;
+    if (params.stateless_reset_token.size() != sizeof(stateless_reset_token)) {
+      QUIC_BUG(quic_bug_10575_16) << "Bad stateless reset token length "
+                                  << params.stateless_reset_token.size();
+      *error_details = "Bad stateless reset token length";
+      return QUIC_INTERNAL_ERROR;
+    }
+    memcpy(&stateless_reset_token, params.stateless_reset_token.data(),
+           params.stateless_reset_token.size());
+    stateless_reset_token_.SetReceivedValue(stateless_reset_token);
+  }
+
+  if (params.max_udp_payload_size.IsValid()) {
+    max_udp_payload_size_.SetReceivedValue(params.max_udp_payload_size.value());
+  }
+
+  if (params.max_datagram_frame_size.IsValid()) {
+    max_datagram_frame_size_.SetReceivedValue(
+        params.max_datagram_frame_size.value());
+  }
+
+  initial_session_flow_control_window_bytes_.SetReceivedValue(
+      params.initial_max_data.value());
+
+  // IETF QUIC specifies stream IDs and stream counts as 62-bit integers but
+  // our implementation uses uint32_t to represent them to save memory.
+  max_bidirectional_streams_.SetReceivedValue(
+      std::min<uint64_t>(params.initial_max_streams_bidi.value(),
+                         std::numeric_limits<uint32_t>::max()));
+  max_unidirectional_streams_.SetReceivedValue(
+      std::min<uint64_t>(params.initial_max_streams_uni.value(),
+                         std::numeric_limits<uint32_t>::max()));
+
+  // The max stream data bidirectional transport parameters can be either local
+  // or remote. A stream is local iff it is initiated by the endpoint that sent
+  // the transport parameter (see the Transport Parameter Definitions section of
+  // draft-ietf-quic-transport). However in this function we are processing
+  // received transport parameters, so a local stream is one initiated by our
+  // peer, which means an incoming stream.
+  initial_max_stream_data_bytes_incoming_bidirectional_.SetReceivedValue(
+      params.initial_max_stream_data_bidi_local.value());
+  initial_max_stream_data_bytes_outgoing_bidirectional_.SetReceivedValue(
+      params.initial_max_stream_data_bidi_remote.value());
+  initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
+      params.initial_max_stream_data_uni.value());
+
+  if (!is_resumption) {
+    max_ack_delay_ms_.SetReceivedValue(params.max_ack_delay.value());
+    if (params.ack_delay_exponent.IsValid()) {
+      ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
+    }
+    if (params.preferred_address != nullptr) {
+      if (params.preferred_address->ipv6_socket_address.port() != 0) {
+        alternate_server_address_ipv6_.SetReceivedValue(
+            params.preferred_address->ipv6_socket_address);
+      }
+      if (params.preferred_address->ipv4_socket_address.port() != 0) {
+        alternate_server_address_ipv4_.SetReceivedValue(
+            params.preferred_address->ipv4_socket_address);
+      }
+      // TODO(haoyuewang) Treat 0 length connection ID sent in preferred_address
+      // as a connection error of type TRANSPORT_PARAMETER_ERROR when server
+      // fully supports it.
+      if (!params.preferred_address->connection_id.IsEmpty()) {
+        preferred_address_connection_id_and_token_ = std::make_pair(
+            params.preferred_address->connection_id,
+            *reinterpret_cast<const StatelessResetToken*>(
+                &params.preferred_address->stateless_reset_token.front()));
+      }
+    }
+    if (params.min_ack_delay_us.value() != 0) {
+      if (params.min_ack_delay_us.value() >
+          params.max_ack_delay.value() * kNumMicrosPerMilli) {
+        *error_details = "MinAckDelay is greater than MaxAckDelay.";
+        return IETF_QUIC_PROTOCOL_VIOLATION;
+      }
+      min_ack_delay_ms_.SetReceivedValue(params.min_ack_delay_us.value() /
+                                         kNumMicrosPerMilli);
+    }
+  }
+
+  if (params.disable_active_migration) {
+    connection_migration_disabled_.SetReceivedValue(1u);
+  }
+
+  active_connection_id_limit_.SetReceivedValue(
+      params.active_connection_id_limit.value());
+
+  if (!is_resumption) {
+    if (params.initial_source_connection_id.has_value()) {
+      received_initial_source_connection_id_ =
+          params.initial_source_connection_id.value();
+    }
+    if (params.retry_source_connection_id.has_value()) {
+      received_retry_source_connection_id_ =
+          params.retry_source_connection_id.value();
+    }
+  }
+
+  if (params.initial_round_trip_time_us.value() > 0) {
+    initial_round_trip_time_us_.SetReceivedValue(
+        params.initial_round_trip_time_us.value());
+  }
+  if (params.google_connection_options.has_value()) {
+    connection_options_.SetReceivedValues(
+        params.google_connection_options.value());
+  }
+
+  received_custom_transport_parameters_ = params.custom_parameters;
+
+  if (!is_resumption) {
+    negotiated_ = true;
+  }
+  *error_details = "";
+  return QUIC_NO_ERROR;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_config.h b/quiche/quic/core/quic_config.h
new file mode 100644
index 0000000..71257d7
--- /dev/null
+++ b/quiche/quic/core/quic_config.h
@@ -0,0 +1,665 @@
+// Copyright (c) 2013 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_CONFIG_H_
+#define QUICHE_QUIC_CORE_QUIC_CONFIG_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicConfigPeer;
+}  // namespace test
+
+class CryptoHandshakeMessage;
+
+// Describes whether or not a given QuicTag is required or optional in the
+// handshake message.
+enum QuicConfigPresence : uint8_t {
+  // This negotiable value can be absent from the handshake message. Default
+  // value is selected as the negotiated value in such a case.
+  PRESENCE_OPTIONAL,
+  // This negotiable value is required in the handshake message otherwise the
+  // Process*Hello function returns an error.
+  PRESENCE_REQUIRED,
+};
+
+// Whether the CryptoHandshakeMessage is from the client or server.
+enum HelloType {
+  CLIENT,
+  SERVER,
+};
+
+// An abstract base class that stores a value that can be sent in CHLO/SHLO
+// message. These values can be OPTIONAL or REQUIRED, depending on |presence_|.
+class QUIC_EXPORT_PRIVATE QuicConfigValue {
+ public:
+  QuicConfigValue(QuicTag tag, QuicConfigPresence presence);
+  virtual ~QuicConfigValue();
+
+  // Serialises tag name and value(s) to |out|.
+  virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const = 0;
+
+  // Selects a mutually acceptable value from those offered in |peer_hello|
+  // and those defined in the subclass.
+  virtual QuicErrorCode ProcessPeerHello(
+      const CryptoHandshakeMessage& peer_hello,
+      HelloType hello_type,
+      std::string* error_details) = 0;
+
+ protected:
+  const QuicTag tag_;
+  const QuicConfigPresence presence_;
+};
+
+// Stores uint32_t from CHLO or SHLO messages that are not negotiated.
+class QUIC_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
+ public:
+  QuicFixedUint32(QuicTag tag, QuicConfigPresence presence);
+  ~QuicFixedUint32() override;
+
+  bool HasSendValue() const;
+
+  uint32_t GetSendValue() const;
+
+  void SetSendValue(uint32_t value);
+
+  bool HasReceivedValue() const;
+
+  uint32_t GetReceivedValue() const;
+
+  void SetReceivedValue(uint32_t value);
+
+  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_value_;
+  bool has_receive_value_;
+  uint32_t send_value_;
+  uint32_t receive_value_;
+};
+
+// Stores 62bit numbers from handshake messages that unilaterally shared by each
+// endpoint. IMPORTANT: these are serialized as 32-bit unsigned integers when
+// using QUIC_CRYPTO versions and CryptoHandshakeMessage.
+class QUIC_EXPORT_PRIVATE QuicFixedUint62 : public QuicConfigValue {
+ public:
+  QuicFixedUint62(QuicTag name, QuicConfigPresence presence);
+  ~QuicFixedUint62() override;
+
+  bool HasSendValue() const;
+
+  uint64_t GetSendValue() const;
+
+  void SetSendValue(uint64_t value);
+
+  bool HasReceivedValue() const;
+
+  uint64_t GetReceivedValue() const;
+
+  void SetReceivedValue(uint64_t value);
+
+  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
+  // IMPORTANT: this method serializes |send_value_| as an unsigned 32bit
+  // integer.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_value_;
+  bool has_receive_value_;
+  uint64_t send_value_;
+  uint64_t receive_value_;
+};
+
+// Stores StatelessResetToken from CHLO or SHLO messages that are not
+// negotiated.
+class QUIC_EXPORT_PRIVATE QuicFixedStatelessResetToken
+    : public QuicConfigValue {
+ public:
+  QuicFixedStatelessResetToken(QuicTag tag, QuicConfigPresence presence);
+  ~QuicFixedStatelessResetToken() override;
+
+  bool HasSendValue() const;
+
+  const StatelessResetToken& GetSendValue() const;
+
+  void SetSendValue(const StatelessResetToken& value);
+
+  bool HasReceivedValue() const;
+
+  const StatelessResetToken& GetReceivedValue() const;
+
+  void SetReceivedValue(const StatelessResetToken& value);
+
+  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_value_;
+  bool has_receive_value_;
+  StatelessResetToken send_value_;
+  StatelessResetToken receive_value_;
+};
+
+// Stores tag from CHLO or SHLO messages that are not negotiated.
+class QUIC_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue {
+ public:
+  QuicFixedTagVector(QuicTag name, QuicConfigPresence presence);
+  QuicFixedTagVector(const QuicFixedTagVector& other);
+  ~QuicFixedTagVector() override;
+
+  bool HasSendValues() const;
+
+  const QuicTagVector& GetSendValues() const;
+
+  void SetSendValues(const QuicTagVector& values);
+
+  bool HasReceivedValues() const;
+
+  const QuicTagVector& GetReceivedValues() const;
+
+  void SetReceivedValues(const QuicTagVector& values);
+
+  // If has_send_value is true, serialises |tag_vector_| and |send_value_| to
+  // |out|.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  // Sets |receive_values_| to the corresponding value from |client_hello_| if
+  // it exists.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_values_;
+  bool has_receive_values_;
+  QuicTagVector send_values_;
+  QuicTagVector receive_values_;
+};
+
+// Stores QuicSocketAddress from CHLO or SHLO messages that are not negotiated.
+class QUIC_EXPORT_PRIVATE QuicFixedSocketAddress : public QuicConfigValue {
+ public:
+  QuicFixedSocketAddress(QuicTag tag, QuicConfigPresence presence);
+  ~QuicFixedSocketAddress() override;
+
+  bool HasSendValue() const;
+
+  const QuicSocketAddress& GetSendValue() const;
+
+  void SetSendValue(const QuicSocketAddress& value);
+
+  bool HasReceivedValue() const;
+
+  const QuicSocketAddress& GetReceivedValue() const;
+
+  void SetReceivedValue(const QuicSocketAddress& value);
+
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_value_;
+  bool has_receive_value_;
+  QuicSocketAddress send_value_;
+  QuicSocketAddress receive_value_;
+};
+
+// QuicConfig contains non-crypto configuration options that are negotiated in
+// the crypto handshake.
+class QUIC_EXPORT_PRIVATE QuicConfig {
+ public:
+  QuicConfig();
+  QuicConfig(const QuicConfig& other);
+  ~QuicConfig();
+
+  void SetConnectionOptionsToSend(const QuicTagVector& connection_options);
+
+  bool HasReceivedConnectionOptions() const;
+
+  // Sets initial received connection options.  All received connection options
+  // will be initialized with these fields. Initial received options may only be
+  // set once per config, prior to the setting of any other options.  If options
+  // have already been set (either by previous calls or via handshake), this
+  // function does nothing and returns false.
+  bool SetInitialReceivedConnectionOptions(const QuicTagVector& tags);
+
+  const QuicTagVector& ReceivedConnectionOptions() const;
+
+  bool HasSendConnectionOptions() const;
+
+  const QuicTagVector& SendConnectionOptions() const;
+
+  // Returns true if the client is sending or the server has received a
+  // connection option.
+  // TODO(ianswett): Rename to HasClientRequestedSharedOption
+  bool HasClientSentConnectionOption(QuicTag tag,
+                                     Perspective perspective) const;
+
+  void SetClientConnectionOptions(
+      const QuicTagVector& client_connection_options);
+
+  // Returns true if the client has requested the specified connection option.
+  // Checks the client connection options if the |perspective| is client and
+  // connection options if the |perspective| is the server.
+  bool HasClientRequestedIndependentOption(QuicTag tag,
+                                           Perspective perspective) const;
+
+  const QuicTagVector& ClientRequestedIndependentOptions(
+      Perspective perspective) const;
+
+  void SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout);
+
+  QuicTime::Delta IdleNetworkTimeout() const;
+
+  // Sets the max bidirectional stream count that this endpoint supports.
+  void SetMaxBidirectionalStreamsToSend(uint32_t max_streams);
+  uint32_t GetMaxBidirectionalStreamsToSend() const;
+
+  bool HasReceivedMaxBidirectionalStreams() const;
+  // Gets the max bidirectional stream limit imposed by the peer.
+  uint32_t ReceivedMaxBidirectionalStreams() const;
+
+  // Sets the max unidirectional stream count that this endpoint supports.
+  void SetMaxUnidirectionalStreamsToSend(uint32_t max_streams);
+  uint32_t GetMaxUnidirectionalStreamsToSend() const;
+
+  bool HasReceivedMaxUnidirectionalStreams() const;
+  // Gets the max unidirectional stream limit imposed by the peer.
+  uint32_t ReceivedMaxUnidirectionalStreams() const;
+
+  void set_max_time_before_crypto_handshake(
+      QuicTime::Delta max_time_before_crypto_handshake) {
+    max_time_before_crypto_handshake_ = max_time_before_crypto_handshake;
+  }
+
+  QuicTime::Delta max_time_before_crypto_handshake() const {
+    return max_time_before_crypto_handshake_;
+  }
+
+  void set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta max_idle_time_before_crypto_handshake) {
+    max_idle_time_before_crypto_handshake_ =
+        max_idle_time_before_crypto_handshake;
+  }
+
+  QuicTime::Delta max_idle_time_before_crypto_handshake() const {
+    return max_idle_time_before_crypto_handshake_;
+  }
+
+  void set_max_undecryptable_packets(size_t max_undecryptable_packets) {
+    max_undecryptable_packets_ = max_undecryptable_packets;
+  }
+
+  size_t max_undecryptable_packets() const {
+    return max_undecryptable_packets_;
+  }
+
+  // Peer's connection id length, in bytes. Only used in Q043 and Q046.
+  bool HasSetBytesForConnectionIdToSend() const;
+  void SetBytesForConnectionIdToSend(uint32_t bytes);
+  bool HasReceivedBytesForConnectionId() const;
+  uint32_t ReceivedBytesForConnectionId() const;
+
+  // Estimated initial round trip time in us.
+  void SetInitialRoundTripTimeUsToSend(uint64_t rtt_us);
+  bool HasReceivedInitialRoundTripTimeUs() const;
+  uint64_t ReceivedInitialRoundTripTimeUs() const;
+  bool HasInitialRoundTripTimeUsToSend() const;
+  uint64_t GetInitialRoundTripTimeUsToSend() const;
+
+  // Sets an initial stream flow control window size to transmit to the peer.
+  void SetInitialStreamFlowControlWindowToSend(uint64_t window_bytes);
+  uint64_t GetInitialStreamFlowControlWindowToSend() const;
+  bool HasReceivedInitialStreamFlowControlWindowBytes() const;
+  uint64_t ReceivedInitialStreamFlowControlWindowBytes() const;
+
+  // Specifies the initial flow control window (max stream data) for
+  // incoming bidirectional streams. Incoming means streams initiated by our
+  // peer. If not set, GetInitialMaxStreamDataBytesIncomingBidirectionalToSend
+  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
+  void SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+      uint64_t window_bytes);
+  uint64_t GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() const;
+  bool HasReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;
+  uint64_t ReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;
+
+  // Specifies the initial flow control window (max stream data) for
+  // outgoing bidirectional streams. Outgoing means streams initiated by us.
+  // If not set, GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend
+  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
+  void SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+      uint64_t window_bytes);
+  uint64_t GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() const;
+  bool HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
+  uint64_t ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
+
+  // Specifies the initial flow control window (max stream data) for
+  // unidirectional streams. If not set,
+  // GetInitialMaxStreamDataBytesUnidirectionalToSend returns the value passed
+  // to SetInitialStreamFlowControlWindowToSend.
+  void SetInitialMaxStreamDataBytesUnidirectionalToSend(uint64_t window_bytes);
+  uint64_t GetInitialMaxStreamDataBytesUnidirectionalToSend() const;
+  bool HasReceivedInitialMaxStreamDataBytesUnidirectional() const;
+  uint64_t ReceivedInitialMaxStreamDataBytesUnidirectional() const;
+
+  // Sets an initial session flow control window size to transmit to the peer.
+  void SetInitialSessionFlowControlWindowToSend(uint64_t window_bytes);
+  uint64_t GetInitialSessionFlowControlWindowToSend() const;
+  bool HasReceivedInitialSessionFlowControlWindowBytes() const;
+  uint64_t ReceivedInitialSessionFlowControlWindowBytes() const;
+
+  // Disable connection migration.
+  void SetDisableConnectionMigration();
+  bool DisableConnectionMigration() const;
+
+  // IPv6 alternate server address.
+  void SetIPv6AlternateServerAddressToSend(
+      const QuicSocketAddress& alternate_server_address_ipv6);
+  void SetIPv6AlternateServerAddressToSend(
+      const QuicSocketAddress& alternate_server_address_ipv6,
+      const QuicConnectionId& connection_id,
+      const StatelessResetToken& stateless_reset_token);
+  bool HasReceivedIPv6AlternateServerAddress() const;
+  const QuicSocketAddress& ReceivedIPv6AlternateServerAddress() const;
+
+  // IPv4 alternate server address.
+  void SetIPv4AlternateServerAddressToSend(
+      const QuicSocketAddress& alternate_server_address_ipv4);
+  void SetIPv4AlternateServerAddressToSend(
+      const QuicSocketAddress& alternate_server_address_ipv4,
+      const QuicConnectionId& connection_id,
+      const StatelessResetToken& stateless_reset_token);
+  bool HasReceivedIPv4AlternateServerAddress() const;
+  const QuicSocketAddress& ReceivedIPv4AlternateServerAddress() const;
+
+  // Preferred Address Connection ID and Token.
+  bool HasReceivedPreferredAddressConnectionIdAndToken() const;
+  const std::pair<QuicConnectionId, StatelessResetToken>&
+  ReceivedPreferredAddressConnectionIdAndToken() const;
+
+  // Original destination connection ID.
+  void SetOriginalConnectionIdToSend(
+      const QuicConnectionId& original_destination_connection_id);
+  bool HasReceivedOriginalConnectionId() const;
+  QuicConnectionId ReceivedOriginalConnectionId() const;
+
+  // Stateless reset token.
+  void SetStatelessResetTokenToSend(
+      const StatelessResetToken& stateless_reset_token);
+  bool HasReceivedStatelessResetToken() const;
+  const StatelessResetToken& ReceivedStatelessResetToken() const;
+
+  // Manage the IETF QUIC Max ACK Delay transport parameter.
+  // The sent value is the delay that this node uses
+  // (QuicSentPacketManager::local_max_ack_delay_).
+  // The received delay is the value received from
+  // the peer (QuicSentPacketManager::peer_max_ack_delay_).
+  void SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms);
+  uint32_t GetMaxAckDelayToSendMs() const;
+  bool HasReceivedMaxAckDelayMs() const;
+  uint32_t ReceivedMaxAckDelayMs() const;
+
+  // Manage the IETF QUIC extension Min Ack Delay transport parameter.
+  // An endpoint uses min_ack_delay to advsertise its support for
+  // AckFrequencyFrame sent by peer.
+  void SetMinAckDelayMs(uint32_t min_ack_delay_ms);
+  uint32_t GetMinAckDelayToSendMs() const;
+  bool HasReceivedMinAckDelayMs() const;
+  uint32_t ReceivedMinAckDelayMs() const;
+
+  void SetAckDelayExponentToSend(uint32_t exponent);
+  uint32_t GetAckDelayExponentToSend() const;
+  bool HasReceivedAckDelayExponent() const;
+  uint32_t ReceivedAckDelayExponent() const;
+
+  // IETF QUIC max_udp_payload_size transport parameter.
+  void SetMaxPacketSizeToSend(uint64_t max_udp_payload_size);
+  uint64_t GetMaxPacketSizeToSend() const;
+  bool HasReceivedMaxPacketSize() const;
+  uint64_t ReceivedMaxPacketSize() const;
+
+  // IETF QUIC max_datagram_frame_size transport parameter.
+  void SetMaxDatagramFrameSizeToSend(uint64_t max_datagram_frame_size);
+  uint64_t GetMaxDatagramFrameSizeToSend() const;
+  bool HasReceivedMaxDatagramFrameSize() const;
+  uint64_t ReceivedMaxDatagramFrameSize() const;
+
+  // IETF QUIC active_connection_id_limit transport parameter.
+  void SetActiveConnectionIdLimitToSend(uint64_t active_connection_id_limit);
+  uint64_t GetActiveConnectionIdLimitToSend() const;
+  bool HasReceivedActiveConnectionIdLimit() const;
+  uint64_t ReceivedActiveConnectionIdLimit() const;
+
+  // Initial source connection ID.
+  void SetInitialSourceConnectionIdToSend(
+      const QuicConnectionId& initial_source_connection_id);
+  bool HasReceivedInitialSourceConnectionId() const;
+  QuicConnectionId ReceivedInitialSourceConnectionId() const;
+
+  // Retry source connection ID.
+  void SetRetrySourceConnectionIdToSend(
+      const QuicConnectionId& retry_source_connection_id);
+  bool HasReceivedRetrySourceConnectionId() const;
+  QuicConnectionId ReceivedRetrySourceConnectionId() const;
+
+  bool negotiated() const;
+
+  void SetCreateSessionTagIndicators(QuicTagVector tags);
+
+  const QuicTagVector& create_session_tag_indicators() const;
+
+  // ToHandshakeMessage serialises the settings in this object as a series of
+  // tags /value pairs and adds them to |out|.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out,
+                          QuicTransportVersion transport_version) const;
+
+  // Calls ProcessPeerHello on each negotiable parameter. On failure returns
+  // the corresponding QuicErrorCode and sets detailed error in |error_details|.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details);
+
+  // FillTransportParameters writes the values to send for ICSL, MIDS, CFCW, and
+  // SFCW to |*params|, returning true if the values could be written and false
+  // if something prevents them from being written (e.g. a value is too large).
+  bool FillTransportParameters(TransportParameters* params) const;
+
+  // ProcessTransportParameters reads from |params| which were received from a
+  // peer. If |is_resumption|, some configs will not be processed.
+  // On failure, it returns a QuicErrorCode and puts a detailed error in
+  // |*error_details|.
+  QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
+                                           bool is_resumption,
+                                           std::string* error_details);
+
+  TransportParameters::ParameterMap& custom_transport_parameters_to_send() {
+    return custom_transport_parameters_to_send_;
+  }
+  const TransportParameters::ParameterMap&
+  received_custom_transport_parameters() const {
+    return received_custom_transport_parameters_;
+  }
+
+ private:
+  friend class test::QuicConfigPeer;
+
+  // SetDefaults sets the members to sensible, default values.
+  void SetDefaults();
+
+  // Whether we've received the peer's config.
+  bool negotiated_;
+
+  // Configurations options that are not negotiated.
+  // Maximum time the session can be alive before crypto handshake is finished.
+  QuicTime::Delta max_time_before_crypto_handshake_;
+  // Maximum idle time before the crypto handshake has completed.
+  QuicTime::Delta max_idle_time_before_crypto_handshake_;
+  // Maximum number of undecryptable packets stored before CHLO/SHLO.
+  size_t max_undecryptable_packets_;
+
+  // Connection options which affect the server side.  May also affect the
+  // client side in cases when identical behavior is desirable.
+  QuicFixedTagVector connection_options_;
+  // Connection options which only affect the client side.
+  QuicFixedTagVector client_connection_options_;
+  // Maximum idle network timeout.
+  // Uses the max_idle_timeout transport parameter in IETF QUIC.
+  // Note that received_max_idle_timeout_ is only populated if we receive the
+  // peer's value, which isn't guaranteed in IETF QUIC as sending is optional.
+  QuicTime::Delta max_idle_timeout_to_send_;
+  absl::optional<QuicTime::Delta> received_max_idle_timeout_;
+  // Maximum number of dynamic streams that a Google QUIC connection
+  // can support or the maximum number of bidirectional streams that
+  // an IETF QUIC connection can support.
+  // The SendValue is the limit on peer-created streams that this endpoint is
+  // advertising.
+  // The ReceivedValue is the limit on locally-created streams that
+  // the peer advertised.
+  // Uses the initial_max_streams_bidi transport parameter in IETF QUIC.
+  QuicFixedUint32 max_bidirectional_streams_;
+  // Maximum number of unidirectional streams that the connection can
+  // support.
+  // The SendValue is the limit on peer-created streams that this endpoint is
+  // advertising.
+  // The ReceivedValue is the limit on locally-created streams that the peer
+  // advertised.
+  // Uses the initial_max_streams_uni transport parameter in IETF QUIC.
+  QuicFixedUint32 max_unidirectional_streams_;
+  // The number of bytes required for the connection ID. This is only used in
+  // the legacy header format used only by Q043 at this point.
+  QuicFixedUint32 bytes_for_connection_id_;
+  // Initial round trip time estimate in microseconds.
+  QuicFixedUint62 initial_round_trip_time_us_;
+
+  // Initial IETF QUIC stream flow control receive windows in bytes.
+  // Incoming bidirectional streams.
+  // Uses the initial_max_stream_data_bidi_{local,remote} transport parameter
+  // in IETF QUIC, depending on whether we're sending or receiving.
+  QuicFixedUint62 initial_max_stream_data_bytes_incoming_bidirectional_;
+  // Outgoing bidirectional streams.
+  // Uses the initial_max_stream_data_bidi_{local,remote} transport parameter
+  // in IETF QUIC, depending on whether we're sending or receiving.
+  QuicFixedUint62 initial_max_stream_data_bytes_outgoing_bidirectional_;
+  // Unidirectional streams.
+  // Uses the initial_max_stream_data_uni transport parameter in IETF QUIC.
+  QuicFixedUint62 initial_max_stream_data_bytes_unidirectional_;
+
+  // Initial Google QUIC stream flow control receive window in bytes.
+  QuicFixedUint62 initial_stream_flow_control_window_bytes_;
+
+  // Initial session flow control receive window in bytes.
+  // Uses the initial_max_data transport parameter in IETF QUIC.
+  QuicFixedUint62 initial_session_flow_control_window_bytes_;
+
+  // Whether active connection migration is allowed.
+  // Uses the disable_active_migration transport parameter in IETF QUIC.
+  QuicFixedUint32 connection_migration_disabled_;
+
+  // Alternate server addresses the client could connect to.
+  // Uses the preferred_address transport parameter in IETF QUIC.
+  // Note that when QUIC_CRYPTO is in use, only one of the addresses is sent.
+  QuicFixedSocketAddress alternate_server_address_ipv6_;
+  QuicFixedSocketAddress alternate_server_address_ipv4_;
+  // Connection Id data to send from the server or receive at the client as part
+  // of the preferred address transport parameter.
+  absl::optional<std::pair<QuicConnectionId, StatelessResetToken>>
+      preferred_address_connection_id_and_token_;
+
+  // Stateless reset token used in IETF public reset packet.
+  // Uses the stateless_reset_token transport parameter in IETF QUIC.
+  QuicFixedStatelessResetToken stateless_reset_token_;
+
+  // List of QuicTags whose presence immediately causes the session to
+  // be created. This allows for CHLOs that are larger than a single
+  // packet to be processed.
+  QuicTagVector create_session_tag_indicators_;
+
+  // Maximum ack delay. The sent value is the value used on this node.
+  // The received value is the value received from the peer and used by
+  // the peer.
+  // Uses the max_ack_delay transport parameter in IETF QUIC.
+  QuicFixedUint32 max_ack_delay_ms_;
+
+  // Minimum ack delay. Used to enable sender control of max_ack_delay.
+  // Uses the min_ack_delay transport parameter in IETF QUIC extension.
+  QuicFixedUint32 min_ack_delay_ms_;
+
+  // The sent exponent is the exponent that this node uses when serializing an
+  // ACK frame (and the peer should use when deserializing the frame);
+  // the received exponent is the value the peer uses to serialize frames and
+  // this node uses to deserialize them.
+  // Uses the ack_delay_exponent transport parameter in IETF QUIC.
+  QuicFixedUint32 ack_delay_exponent_;
+
+  // Maximum packet size in bytes.
+  // Uses the max_udp_payload_size transport parameter in IETF QUIC.
+  QuicFixedUint62 max_udp_payload_size_;
+
+  // Maximum DATAGRAM/MESSAGE frame size in bytes.
+  // Uses the max_datagram_frame_size transport parameter in IETF QUIC.
+  QuicFixedUint62 max_datagram_frame_size_;
+
+  // Maximum number of connection IDs from the peer.
+  // Uses the active_connection_id_limit transport parameter in IETF QUIC.
+  QuicFixedUint62 active_connection_id_limit_;
+
+  // The value of the Destination Connection ID field from the first
+  // Initial packet sent by the client.
+  // Uses the original_destination_connection_id transport parameter in
+  // IETF QUIC.
+  absl::optional<QuicConnectionId> original_destination_connection_id_to_send_;
+  absl::optional<QuicConnectionId> received_original_destination_connection_id_;
+
+  // The value that the endpoint included in the Source Connection ID field of
+  // the first Initial packet it sent.
+  // Uses the initial_source_connection_id transport parameter in IETF QUIC.
+  absl::optional<QuicConnectionId> initial_source_connection_id_to_send_;
+  absl::optional<QuicConnectionId> received_initial_source_connection_id_;
+
+  // The value that the server included in the Source Connection ID field of a
+  // Retry packet it sent.
+  // Uses the retry_source_connection_id transport parameter in IETF QUIC.
+  absl::optional<QuicConnectionId> retry_source_connection_id_to_send_;
+  absl::optional<QuicConnectionId> received_retry_source_connection_id_;
+
+  // Custom transport parameters that can be sent and received in the TLS
+  // handshake.
+  TransportParameters::ParameterMap custom_transport_parameters_to_send_;
+  TransportParameters::ParameterMap received_custom_transport_parameters_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONFIG_H_
diff --git a/quiche/quic/core/quic_config_test.cc b/quiche/quic/core/quic_config_test.cc
new file mode 100644
index 0000000..9c42158
--- /dev/null
+++ b/quiche/quic/core/quic_config_test.cc
@@ -0,0 +1,727 @@
+// Copyright (c) 2013 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 "quiche/quic/core/quic_config.h"
+
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicConfigTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicConfigTest() : version_(GetParam()) {}
+
+ protected:
+  ParsedQuicVersion version_;
+  QuicConfig config_;
+};
+
+// Run all tests with all versions of QUIC.
+INSTANTIATE_TEST_SUITE_P(QuicConfigTests,
+                         QuicConfigTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicConfigTest, SetDefaults) {
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  EXPECT_FALSE(config_.HasReceivedInitialStreamFlowControlWindowBytes());
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+  EXPECT_EQ(kMaxIncomingPacketSize, config_.GetMaxPacketSizeToSend());
+  EXPECT_FALSE(config_.HasReceivedMaxPacketSize());
+}
+
+TEST_P(QuicConfigTest, AutoSetIetfFlowControl) {
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  static const uint32_t kTestWindowSize = 1234567;
+  config_.SetInitialStreamFlowControlWindowToSend(kTestWindowSize);
+  EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  static const uint32_t kTestWindowSizeTwo = 2345678;
+  config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+      kTestWindowSizeTwo);
+  EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kTestWindowSizeTwo,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+}
+
+TEST_P(QuicConfigTest, ToHandshakeMessage) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  config_.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  config_.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  config_.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(5));
+  CryptoHandshakeMessage msg;
+  config_.ToHandshakeMessage(&msg, version_.transport_version);
+
+  uint32_t value;
+  QuicErrorCode error = msg.GetUint32(kICSL, &value);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_EQ(5u, value);
+
+  error = msg.GetUint32(kSFCW, &value);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);
+
+  error = msg.GetUint32(kCFCW, &value);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
+}
+
+TEST_P(QuicConfigTest, ProcessClientHello) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  const uint32_t kTestMaxAckDelayMs =
+      static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
+  QuicConfig client_config;
+  QuicTagVector cgst;
+  cgst.push_back(kQBIC);
+  client_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
+  client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      2 * kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      2 * kInitialSessionFlowControlWindowForTest);
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetConnectionOptionsToSend(copt);
+  client_config.SetMaxAckDelayToSendMs(kTestMaxAckDelayMs);
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg, version_.transport_version);
+
+  std::string error_details;
+  QuicTagVector initial_received_options;
+  initial_received_options.push_back(kIW50);
+  EXPECT_TRUE(
+      config_.SetInitialReceivedConnectionOptions(initial_received_options));
+  EXPECT_FALSE(
+      config_.SetInitialReceivedConnectionOptions(initial_received_options))
+      << "You can only set initial options once.";
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_FALSE(
+      config_.SetInitialReceivedConnectionOptions(initial_received_options))
+      << "You cannot set initial options after the hello.";
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
+            config_.IdleNetworkTimeout());
+  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
+  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+  EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
+  EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
+  EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kTBBR);
+  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
+            2 * kInitialStreamFlowControlWindowForTest);
+  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
+            2 * kInitialSessionFlowControlWindowForTest);
+  EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
+  EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
+
+  // IETF QUIC stream limits should not be received in QUIC crypto messages.
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+}
+
+TEST_P(QuicConfigTest, ProcessServerHello) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicIpAddress host;
+  host.FromString("127.0.3.1");
+  const QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
+  const StatelessResetToken kTestStatelessResetToken{
+      0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+      0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
+  const uint32_t kTestMaxAckDelayMs =
+      static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
+  QuicConfig server_config;
+  QuicTagVector cgst;
+  cgst.push_back(kQBIC);
+  server_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
+  server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
+  server_config.SetInitialStreamFlowControlWindowToSend(
+      2 * kInitialStreamFlowControlWindowForTest);
+  server_config.SetInitialSessionFlowControlWindowToSend(
+      2 * kInitialSessionFlowControlWindowForTest);
+  server_config.SetIPv4AlternateServerAddressToSend(kTestServerAddress);
+  server_config.SetStatelessResetTokenToSend(kTestStatelessResetToken);
+  server_config.SetMaxAckDelayToSendMs(kTestMaxAckDelayMs);
+  CryptoHandshakeMessage msg;
+  server_config.ToHandshakeMessage(&msg, version_.transport_version);
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
+            config_.IdleNetworkTimeout());
+  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
+  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
+            2 * kInitialStreamFlowControlWindowForTest);
+  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
+            2 * kInitialSessionFlowControlWindowForTest);
+  EXPECT_TRUE(config_.HasReceivedIPv4AlternateServerAddress());
+  EXPECT_EQ(kTestServerAddress, config_.ReceivedIPv4AlternateServerAddress());
+  EXPECT_FALSE(config_.HasReceivedIPv6AlternateServerAddress());
+  EXPECT_TRUE(config_.HasReceivedStatelessResetToken());
+  EXPECT_EQ(kTestStatelessResetToken, config_.ReceivedStatelessResetToken());
+  EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
+  EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
+
+  // IETF QUIC stream limits should not be received in QUIC crypto messages.
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+}
+
+TEST_P(QuicConfigTest, MissingOptionalValuesInCHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  CryptoHandshakeMessage msg;
+  msg.SetValue(kICSL, 1);
+
+  // Set all REQUIRED tags.
+  msg.SetValue(kICSL, 1);
+  msg.SetValue(kMIBS, 1);
+
+  // No error, as rest are optional.
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+}
+
+TEST_P(QuicConfigTest, MissingOptionalValuesInSHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  CryptoHandshakeMessage msg;
+
+  // Set all REQUIRED tags.
+  msg.SetValue(kICSL, 1);
+  msg.SetValue(kMIBS, 1);
+
+  // No error, as rest are optional.
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+}
+
+TEST_P(QuicConfigTest, MissingValueInCHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  // Server receives CHLO with missing kICSL.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsError(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND));
+}
+
+TEST_P(QuicConfigTest, MissingValueInSHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  // Client receives SHLO with missing kICSL.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_THAT(error, IsError(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND));
+}
+
+TEST_P(QuicConfigTest, OutOfBoundSHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicConfig server_config;
+  server_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
+
+  CryptoHandshakeMessage msg;
+  server_config.ToHandshakeMessage(&msg, version_.transport_version);
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_THAT(error, IsError(QUIC_INVALID_NEGOTIATED_VALUE));
+}
+
+TEST_P(QuicConfigTest, InvalidFlowControlWindow) {
+  // QuicConfig should not accept an invalid flow control window to send to the
+  // peer: the receive window must be at least the default of 16 Kb.
+  QuicConfig config;
+  const uint64_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  EXPECT_QUIC_BUG(
+      config.SetInitialStreamFlowControlWindowToSend(kInvalidWindow),
+      "Initial stream flow control receive window");
+
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config.GetInitialStreamFlowControlWindowToSend());
+}
+
+TEST_P(QuicConfigTest, HasClientSentConnectionOption) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetConnectionOptionsToSend(copt);
+  EXPECT_TRUE(client_config.HasClientSentConnectionOption(
+      kTBBR, Perspective::IS_CLIENT));
+
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg, version_.transport_version);
+
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+
+  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+  EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
+  EXPECT_TRUE(
+      config_.HasClientSentConnectionOption(kTBBR, Perspective::IS_SERVER));
+}
+
+TEST_P(QuicConfigTest, DontSendClientConnectionOptions) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetClientConnectionOptions(copt);
+
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg, version_.transport_version);
+
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+
+  EXPECT_FALSE(config_.HasReceivedConnectionOptions());
+}
+
+TEST_P(QuicConfigTest, HasClientRequestedIndependentOption) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector client_opt;
+  client_opt.push_back(kRENO);
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetClientConnectionOptions(client_opt);
+  client_config.SetConnectionOptionsToSend(copt);
+  EXPECT_TRUE(client_config.HasClientSentConnectionOption(
+      kTBBR, Perspective::IS_CLIENT));
+  EXPECT_TRUE(client_config.HasClientRequestedIndependentOption(
+      kRENO, Perspective::IS_CLIENT));
+  EXPECT_FALSE(client_config.HasClientRequestedIndependentOption(
+      kTBBR, Perspective::IS_CLIENT));
+
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg, version_.transport_version);
+
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+
+  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+  EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
+  EXPECT_FALSE(config_.HasClientRequestedIndependentOption(
+      kRENO, Perspective::IS_SERVER));
+  EXPECT_TRUE(config_.HasClientRequestedIndependentOption(
+      kTBBR, Perspective::IS_SERVER));
+}
+
+TEST_P(QuicConfigTest, IncomingLargeIdleTimeoutTransportParameter) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  // Configure our idle timeout to 60s, then receive 120s from peer.
+  // Since the received value is above ours, we should then use ours.
+  config_.SetIdleNetworkTimeout(quic::QuicTime::Delta::FromSeconds(60));
+  TransportParameters params;
+  params.max_idle_timeout_ms.set_value(120000);
+
+  std::string error_details = "foobar";
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  EXPECT_EQ("", error_details);
+  EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(60),
+            config_.IdleNetworkTimeout());
+}
+
+TEST_P(QuicConfigTest, ReceivedInvalidMinAckDelayInTransportParameter) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  TransportParameters params;
+
+  params.max_ack_delay.set_value(25 /*ms*/);
+  params.min_ack_delay_us.set_value(25 * kNumMicrosPerMilli + 1);
+  std::string error_details = "foobar";
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ("MinAckDelay is greater than MaxAckDelay.", error_details);
+
+  params.max_ack_delay.set_value(25 /*ms*/);
+  params.min_ack_delay_us.set_value(25 * kNumMicrosPerMilli);
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  EXPECT_TRUE(error_details.empty());
+}
+
+TEST_P(QuicConfigTest, FillTransportParams) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+      2 * kMinimumFlowControlSendWindow);
+  config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+      3 * kMinimumFlowControlSendWindow);
+  config_.SetInitialMaxStreamDataBytesUnidirectionalToSend(
+      4 * kMinimumFlowControlSendWindow);
+  config_.SetMaxPacketSizeToSend(kMaxPacketSizeForTest);
+  config_.SetMaxDatagramFrameSizeToSend(kMaxDatagramFrameSizeForTest);
+  config_.SetActiveConnectionIdLimitToSend(kActiveConnectionIdLimitForTest);
+
+  config_.SetOriginalConnectionIdToSend(TestConnectionId(0x1111));
+  config_.SetInitialSourceConnectionIdToSend(TestConnectionId(0x2222));
+  config_.SetRetrySourceConnectionIdToSend(TestConnectionId(0x3333));
+  config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
+
+  QuicIpAddress host;
+  host.FromString("127.0.3.1");
+  QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
+  QuicConnectionId new_connection_id = TestConnectionId(5);
+  StatelessResetToken new_stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(new_connection_id);
+  config_.SetIPv4AlternateServerAddressToSend(
+      kTestServerAddress, new_connection_id, new_stateless_reset_token);
+
+  TransportParameters params;
+  config_.FillTransportParameters(&params);
+
+  EXPECT_EQ(2 * kMinimumFlowControlSendWindow,
+            params.initial_max_stream_data_bidi_remote.value());
+  EXPECT_EQ(3 * kMinimumFlowControlSendWindow,
+            params.initial_max_stream_data_bidi_local.value());
+  EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
+            params.initial_max_stream_data_uni.value());
+
+  EXPECT_EQ(static_cast<uint64_t>(kMaximumIdleTimeoutSecs * 1000),
+            params.max_idle_timeout_ms.value());
+
+  EXPECT_EQ(kMaxPacketSizeForTest, params.max_udp_payload_size.value());
+  EXPECT_EQ(kMaxDatagramFrameSizeForTest,
+            params.max_datagram_frame_size.value());
+  EXPECT_EQ(kActiveConnectionIdLimitForTest,
+            params.active_connection_id_limit.value());
+
+  ASSERT_TRUE(params.original_destination_connection_id.has_value());
+  EXPECT_EQ(TestConnectionId(0x1111),
+            params.original_destination_connection_id.value());
+  ASSERT_TRUE(params.initial_source_connection_id.has_value());
+  EXPECT_EQ(TestConnectionId(0x2222),
+            params.initial_source_connection_id.value());
+  ASSERT_TRUE(params.retry_source_connection_id.has_value());
+  EXPECT_EQ(TestConnectionId(0x3333),
+            params.retry_source_connection_id.value());
+
+  EXPECT_EQ(
+      static_cast<uint64_t>(kDefaultMinAckDelayTimeMs) * kNumMicrosPerMilli,
+      params.min_ack_delay_us.value());
+
+  EXPECT_EQ(params.preferred_address->ipv4_socket_address, kTestServerAddress);
+  EXPECT_EQ(*reinterpret_cast<StatelessResetToken*>(
+                &params.preferred_address->stateless_reset_token.front()),
+            new_stateless_reset_token);
+}
+
+TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  TransportParameters params;
+
+  params.initial_max_stream_data_bidi_local.set_value(
+      2 * kMinimumFlowControlSendWindow);
+  params.initial_max_stream_data_bidi_remote.set_value(
+      3 * kMinimumFlowControlSendWindow);
+  params.initial_max_stream_data_uni.set_value(4 *
+                                               kMinimumFlowControlSendWindow);
+  params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  params.max_datagram_frame_size.set_value(kMaxDatagramFrameSizeForTest);
+  params.initial_max_streams_bidi.set_value(kDefaultMaxStreamsPerConnection);
+  params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  params.active_connection_id_limit.set_value(kActiveConnectionIdLimitForTest);
+  params.original_destination_connection_id = TestConnectionId(0x1111);
+  params.initial_source_connection_id = TestConnectionId(0x2222);
+  params.retry_source_connection_id = TestConnectionId(0x3333);
+
+  std::string error_details;
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ true, &error_details),
+              IsQuicNoError())
+      << error_details;
+
+  EXPECT_FALSE(config_.negotiated());
+
+  ASSERT_TRUE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_EQ(2 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+
+  ASSERT_TRUE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_EQ(3 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+
+  ASSERT_TRUE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+  EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
+
+  ASSERT_TRUE(config_.HasReceivedMaxPacketSize());
+  EXPECT_EQ(kMaxPacketSizeForTest, config_.ReceivedMaxPacketSize());
+
+  ASSERT_TRUE(config_.HasReceivedMaxDatagramFrameSize());
+  EXPECT_EQ(kMaxDatagramFrameSizeForTest,
+            config_.ReceivedMaxDatagramFrameSize());
+
+  ASSERT_TRUE(config_.HasReceivedMaxBidirectionalStreams());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            config_.ReceivedMaxBidirectionalStreams());
+
+  EXPECT_FALSE(config_.DisableConnectionMigration());
+
+  // The following config shouldn't be processed because of resumption.
+  EXPECT_FALSE(config_.HasReceivedStatelessResetToken());
+  EXPECT_FALSE(config_.HasReceivedMaxAckDelayMs());
+  EXPECT_FALSE(config_.HasReceivedAckDelayExponent());
+  EXPECT_FALSE(config_.HasReceivedMinAckDelayMs());
+  EXPECT_FALSE(config_.HasReceivedOriginalConnectionId());
+  EXPECT_FALSE(config_.HasReceivedInitialSourceConnectionId());
+  EXPECT_FALSE(config_.HasReceivedRetrySourceConnectionId());
+
+  // Let the config process another slightly tweaked transport paramters.
+  // Note that the values for flow control and stream limit cannot be smaller
+  // than before. This rule is enforced in QuicSession::OnConfigNegotiated().
+  params.initial_max_stream_data_bidi_local.set_value(
+      2 * kMinimumFlowControlSendWindow + 1);
+  params.initial_max_stream_data_bidi_remote.set_value(
+      4 * kMinimumFlowControlSendWindow);
+  params.initial_max_stream_data_uni.set_value(5 *
+                                               kMinimumFlowControlSendWindow);
+  params.max_udp_payload_size.set_value(2 * kMaxPacketSizeForTest);
+  params.max_datagram_frame_size.set_value(2 * kMaxDatagramFrameSizeForTest);
+  params.initial_max_streams_bidi.set_value(2 *
+                                            kDefaultMaxStreamsPerConnection);
+  params.disable_active_migration = true;
+
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError())
+      << error_details;
+
+  EXPECT_TRUE(config_.negotiated());
+
+  ASSERT_TRUE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_EQ(2 * kMinimumFlowControlSendWindow + 1,
+            config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+
+  ASSERT_TRUE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+
+  ASSERT_TRUE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+  EXPECT_EQ(5 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
+
+  ASSERT_TRUE(config_.HasReceivedMaxPacketSize());
+  EXPECT_EQ(2 * kMaxPacketSizeForTest, config_.ReceivedMaxPacketSize());
+
+  ASSERT_TRUE(config_.HasReceivedMaxDatagramFrameSize());
+  EXPECT_EQ(2 * kMaxDatagramFrameSizeForTest,
+            config_.ReceivedMaxDatagramFrameSize());
+
+  ASSERT_TRUE(config_.HasReceivedMaxBidirectionalStreams());
+  EXPECT_EQ(2 * kDefaultMaxStreamsPerConnection,
+            config_.ReceivedMaxBidirectionalStreams());
+
+  EXPECT_TRUE(config_.DisableConnectionMigration());
+
+  ASSERT_TRUE(config_.HasReceivedStatelessResetToken());
+
+  ASSERT_TRUE(config_.HasReceivedMaxAckDelayMs());
+  EXPECT_EQ(config_.ReceivedMaxAckDelayMs(), kMaxAckDelayForTest);
+
+  ASSERT_TRUE(config_.HasReceivedMinAckDelayMs());
+  EXPECT_EQ(config_.ReceivedMinAckDelayMs(),
+            kMinAckDelayUsForTest / kNumMicrosPerMilli);
+
+  ASSERT_TRUE(config_.HasReceivedAckDelayExponent());
+  EXPECT_EQ(config_.ReceivedAckDelayExponent(), kAckDelayExponentForTest);
+
+  ASSERT_TRUE(config_.HasReceivedActiveConnectionIdLimit());
+  EXPECT_EQ(config_.ReceivedActiveConnectionIdLimit(),
+            kActiveConnectionIdLimitForTest);
+
+  ASSERT_TRUE(config_.HasReceivedOriginalConnectionId());
+  EXPECT_EQ(config_.ReceivedOriginalConnectionId(), TestConnectionId(0x1111));
+  ASSERT_TRUE(config_.HasReceivedInitialSourceConnectionId());
+  EXPECT_EQ(config_.ReceivedInitialSourceConnectionId(),
+            TestConnectionId(0x2222));
+  ASSERT_TRUE(config_.HasReceivedRetrySourceConnectionId());
+  EXPECT_EQ(config_.ReceivedRetrySourceConnectionId(),
+            TestConnectionId(0x3333));
+}
+
+TEST_P(QuicConfigTest, DisableMigrationTransportParameter) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  TransportParameters params;
+  params.disable_active_migration = true;
+  std::string error_details;
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  EXPECT_TRUE(config_.DisableConnectionMigration());
+}
+
+TEST_P(QuicConfigTest, SendPreferredIPv4Address) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+
+  EXPECT_FALSE(config_.HasReceivedPreferredAddressConnectionIdAndToken());
+
+  TransportParameters params;
+  QuicIpAddress host;
+  host.FromString("::ffff:192.0.2.128");
+  QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
+  QuicConnectionId new_connection_id = TestConnectionId(5);
+  StatelessResetToken new_stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(new_connection_id);
+  auto preferred_address =
+      std::make_unique<TransportParameters::PreferredAddress>();
+  preferred_address->ipv6_socket_address = kTestServerAddress;
+  preferred_address->connection_id = new_connection_id;
+  preferred_address->stateless_reset_token.assign(
+      reinterpret_cast<const char*>(&new_stateless_reset_token),
+      reinterpret_cast<const char*>(&new_stateless_reset_token) +
+          sizeof(new_stateless_reset_token));
+  params.preferred_address = std::move(preferred_address);
+
+  std::string error_details;
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+
+  EXPECT_TRUE(config_.HasReceivedIPv6AlternateServerAddress());
+  EXPECT_EQ(config_.ReceivedIPv6AlternateServerAddress(), kTestServerAddress);
+  EXPECT_TRUE(config_.HasReceivedPreferredAddressConnectionIdAndToken());
+  const std::pair<QuicConnectionId, StatelessResetToken>&
+      preferred_address_connection_id_and_token =
+          config_.ReceivedPreferredAddressConnectionIdAndToken();
+  EXPECT_EQ(preferred_address_connection_id_and_token.first, new_connection_id);
+  EXPECT_EQ(preferred_address_connection_id_and_token.second,
+            new_stateless_reset_token);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
new file mode 100644
index 0000000..9865f61
--- /dev/null
+++ b/quiche/quic/core/quic_connection.cc
@@ -0,0 +1,7118 @@
+// 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 "quiche/quic/core/quic_connection.h"
+
+#include <string.h>
+#include <sys/types.h>
+
+#include <algorithm>
+#include <iterator>
+#include <limits>
+#include <memory>
+#include <optional>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_legacy_version_encapsulator.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_client_stats.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_flag_utils.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+class QuicDecrypter;
+class QuicEncrypter;
+
+namespace {
+
+// Maximum number of consecutive sent nonretransmittable packets.
+const QuicPacketCount kMaxConsecutiveNonRetransmittablePackets = 19;
+
+// The minimum release time into future in ms.
+const int kMinReleaseTimeIntoFutureMs = 1;
+
+// Base class of all alarms owned by a QuicConnection.
+class QuicConnectionAlarmDelegate : public QuicAlarm::Delegate {
+ public:
+  explicit QuicConnectionAlarmDelegate(QuicConnection* connection)
+      : connection_(connection) {}
+  QuicConnectionAlarmDelegate(const QuicConnectionAlarmDelegate&) = delete;
+  QuicConnectionAlarmDelegate& operator=(const QuicConnectionAlarmDelegate&) =
+      delete;
+
+  QuicConnectionContext* GetConnectionContext() override {
+    return (connection_ == nullptr) ? nullptr : connection_->context();
+  }
+
+ protected:
+  QuicConnection* connection_;
+};
+
+// An alarm that is scheduled to send an ack if a timeout occurs.
+class AckAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->ack_frame_updated());
+    QUICHE_DCHECK(connection_->connected());
+    QuicConnection::ScopedPacketFlusher flusher(connection_);
+    if (connection_->SupportsMultiplePacketNumberSpaces()) {
+      connection_->SendAllPendingAcks();
+    } else {
+      connection_->SendAck();
+    }
+  }
+};
+
+// This alarm will be scheduled any time a data-bearing packet is sent out.
+// When the alarm goes off, the connection checks to see if the oldest packets
+// have been acked, and retransmit them if they have not.
+class RetransmissionAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->OnRetransmissionTimeout();
+  }
+};
+
+// An alarm that is scheduled when the SentPacketManager requires a delay
+// before sending packets and fires when the packet may be sent.
+class SendAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->WriteIfNotBlocked();
+  }
+};
+
+class PingAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->OnPingTimeout();
+  }
+};
+
+class MtuDiscoveryAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->DiscoverMtu();
+  }
+};
+
+class ProcessUndecryptablePacketsAlarmDelegate
+    : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    QuicConnection::ScopedPacketFlusher flusher(connection_);
+    connection_->MaybeProcessUndecryptablePackets();
+  }
+};
+
+class DiscardPreviousOneRttKeysAlarmDelegate
+    : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->DiscardPreviousOneRttKeys();
+  }
+};
+
+class DiscardZeroRttDecryptionKeysAlarmDelegate
+    : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    QUIC_DLOG(INFO) << "0-RTT discard alarm fired";
+    connection_->RemoveDecrypter(ENCRYPTION_ZERO_RTT);
+  }
+};
+
+// When the clearer goes out of scope, the coalesced packet gets cleared.
+class ScopedCoalescedPacketClearer {
+ public:
+  explicit ScopedCoalescedPacketClearer(QuicCoalescedPacket* coalesced)
+      : coalesced_(coalesced) {}
+  ~ScopedCoalescedPacketClearer() { coalesced_->Clear(); }
+
+ private:
+  QuicCoalescedPacket* coalesced_;  // Unowned.
+};
+
+// Whether this incoming packet is allowed to replace our connection ID.
+bool PacketCanReplaceServerConnectionId(const QuicPacketHeader& header,
+                                        Perspective perspective) {
+  return perspective == Perspective::IS_CLIENT &&
+         header.form == IETF_QUIC_LONG_HEADER_PACKET &&
+         header.version.IsKnown() &&
+         header.version.AllowsVariableLengthConnectionIds() &&
+         (header.long_packet_type == INITIAL ||
+          header.long_packet_type == RETRY);
+}
+
+CongestionControlType GetDefaultCongestionControlType() {
+  if (GetQuicReloadableFlag(quic_default_to_bbr_v2)) {
+    return kBBRv2;
+  }
+
+  if (GetQuicReloadableFlag(quic_default_to_bbr)) {
+    return kBBR;
+  }
+
+  return kCubicBytes;
+}
+
+}  // namespace
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+QuicConnection::QuicConnection(
+    QuicConnectionId server_connection_id,
+    QuicSocketAddress initial_self_address,
+    QuicSocketAddress initial_peer_address,
+    QuicConnectionHelperInterface* helper, QuicAlarmFactory* alarm_factory,
+    QuicPacketWriter* writer, bool owns_writer, Perspective perspective,
+    const ParsedQuicVersionVector& supported_versions)
+    : framer_(supported_versions, helper->GetClock()->ApproximateNow(),
+              perspective, server_connection_id.length()),
+      current_packet_content_(NO_FRAMES_RECEIVED),
+      is_current_packet_connectivity_probing_(false),
+      has_path_challenge_in_current_packet_(false),
+      current_effective_peer_migration_type_(NO_CHANGE),
+      helper_(helper),
+      alarm_factory_(alarm_factory),
+      per_packet_options_(nullptr),
+      writer_(writer),
+      owns_writer_(owns_writer),
+      encryption_level_(ENCRYPTION_INITIAL),
+      clock_(helper->GetClock()),
+      random_generator_(helper->GetRandomGenerator()),
+      client_connection_id_is_set_(false),
+      direct_peer_address_(initial_peer_address),
+      default_path_(initial_self_address, QuicSocketAddress(),
+                    /*client_connection_id=*/EmptyQuicConnectionId(),
+                    server_connection_id,
+                    /*stateless_reset_token=*/absl::nullopt),
+      active_effective_peer_migration_type_(NO_CHANGE),
+      support_key_update_for_connection_(false),
+      last_packet_decrypted_(false),
+      last_size_(0),
+      current_packet_data_(nullptr),
+      last_decrypted_packet_level_(ENCRYPTION_INITIAL),
+      should_last_packet_instigate_acks_(false),
+      max_undecryptable_packets_(0),
+      max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
+      idle_timeout_connection_close_behavior_(
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET),
+      num_rtos_for_blackhole_detection_(0),
+      uber_received_packet_manager_(&stats_),
+      stop_waiting_count_(0),
+      pending_retransmission_alarm_(false),
+      defer_send_in_response_to_packets_(false),
+      ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)),
+      initial_retransmittable_on_wire_timeout_(QuicTime::Delta::Infinite()),
+      consecutive_retransmittable_on_wire_ping_count_(0),
+      retransmittable_on_wire_ping_count_(0),
+      arena_(),
+      ack_alarm_(alarm_factory_->CreateAlarm(arena_.New<AckAlarmDelegate>(this),
+                                             &arena_)),
+      retransmission_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<RetransmissionAlarmDelegate>(this), &arena_)),
+      send_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<SendAlarmDelegate>(this), &arena_)),
+      ping_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<PingAlarmDelegate>(this), &arena_)),
+      mtu_discovery_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<MtuDiscoveryAlarmDelegate>(this), &arena_)),
+      process_undecryptable_packets_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<ProcessUndecryptablePacketsAlarmDelegate>(this), &arena_)),
+      discard_previous_one_rtt_keys_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<DiscardPreviousOneRttKeysAlarmDelegate>(this), &arena_)),
+      discard_zero_rtt_decryption_keys_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<DiscardZeroRttDecryptionKeysAlarmDelegate>(this),
+          &arena_)),
+      visitor_(nullptr),
+      debug_visitor_(nullptr),
+      packet_creator_(server_connection_id, &framer_, random_generator_, this),
+      last_received_packet_info_(clock_->ApproximateNow()),
+      sent_packet_manager_(perspective, clock_, random_generator_, &stats_,
+                           GetDefaultCongestionControlType()),
+      version_negotiated_(false),
+      perspective_(perspective),
+      connected_(true),
+      can_truncate_connection_ids_(perspective == Perspective::IS_SERVER),
+      mtu_probe_count_(0),
+      previous_validated_mtu_(0),
+      peer_max_packet_size_(kDefaultMaxPacketSizeTransportParam),
+      largest_received_packet_size_(0),
+      write_error_occurred_(false),
+      no_stop_waiting_frames_(version().HasIetfInvariantHeader()),
+      consecutive_num_packets_with_no_retransmittable_frames_(0),
+      max_consecutive_num_packets_with_no_retransmittable_frames_(
+          kMaxConsecutiveNonRetransmittablePackets),
+      bundle_retransmittable_with_pto_ack_(false),
+      fill_up_link_during_probing_(false),
+      probing_retransmission_pending_(false),
+      last_control_frame_id_(kInvalidControlFrameId),
+      is_path_degrading_(false),
+      processing_ack_frame_(false),
+      supports_release_time_(false),
+      release_time_into_future_(QuicTime::Delta::Zero()),
+      blackhole_detector_(this, &arena_, alarm_factory_, &context_),
+      idle_network_detector_(this, clock_->ApproximateNow(), &arena_,
+                             alarm_factory_, &context_),
+      path_validator_(alarm_factory_, &arena_, this, random_generator_,
+                      &context_),
+      most_recent_frame_type_(NUM_FRAME_TYPES) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT ||
+                default_path_.self_address.IsInitialized());
+
+  QUIC_DLOG(INFO) << ENDPOINT << "Created connection with server connection ID "
+                  << server_connection_id
+                  << " and version: " << ParsedQuicVersionToString(version());
+
+  QUIC_BUG_IF(quic_bug_12714_2, !QuicUtils::IsConnectionIdValidForVersion(
+                                    server_connection_id, transport_version()))
+      << "QuicConnection: attempted to use server connection ID "
+      << server_connection_id << " which is invalid with version " << version();
+  framer_.set_visitor(this);
+  stats_.connection_creation_time = clock_->ApproximateNow();
+  // TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument
+  // and make it required non-null, because it's always used.
+  sent_packet_manager_.SetNetworkChangeVisitor(this);
+  if (GetQuicRestartFlag(quic_offload_pacing_to_usps2)) {
+    sent_packet_manager_.SetPacingAlarmGranularity(QuicTime::Delta::Zero());
+    release_time_into_future_ =
+        QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs);
+  }
+  // Allow the packet writer to potentially reduce the packet size to a value
+  // even smaller than kDefaultMaxPacketSize.
+  SetMaxPacketLength(perspective_ == Perspective::IS_SERVER
+                         ? kDefaultServerMaxPacketSize
+                         : kDefaultMaxPacketSize);
+  uber_received_packet_manager_.set_max_ack_ranges(255);
+  MaybeEnableMultiplePacketNumberSpacesSupport();
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT ||
+                supported_versions.size() == 1);
+  InstallInitialCrypters(default_path_.server_connection_id);
+
+  // On the server side, version negotiation has been done by the dispatcher,
+  // and the server connection is created with the right version.
+  if (perspective_ == Perspective::IS_SERVER) {
+    SetVersionNegotiated();
+  }
+  if (default_enable_5rto_blackhole_detection_) {
+    num_rtos_for_blackhole_detection_ = 5;
+    if (GetQuicReloadableFlag(quic_disable_server_blackhole_detection) &&
+        perspective_ == Perspective::IS_SERVER) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_disable_server_blackhole_detection);
+      blackhole_detection_disabled_ = true;
+    }
+  }
+  packet_creator_.SetDefaultPeerAddress(initial_peer_address);
+}
+
+void QuicConnection::InstallInitialCrypters(QuicConnectionId connection_id) {
+  CrypterPair crypters;
+  CryptoUtils::CreateInitialObfuscators(perspective_, version(), connection_id,
+                                        &crypters);
+  SetEncrypter(ENCRYPTION_INITIAL, std::move(crypters.encrypter));
+  if (version().KnowsWhichDecrypterToUse()) {
+    InstallDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
+  } else {
+    SetDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
+  }
+}
+
+QuicConnection::~QuicConnection() {
+  QUICHE_DCHECK_GE(stats_.max_egress_mtu, long_term_mtu_);
+  if (owns_writer_) {
+    delete writer_;
+  }
+  ClearQueuedPackets();
+  if (stats_
+          .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter >
+      0) {
+    QUIC_CODE_COUNT_N(
+        quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 2,
+        3);
+  } else {
+    QUIC_CODE_COUNT_N(
+        quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 3,
+        3);
+  }
+}
+
+void QuicConnection::ClearQueuedPackets() {
+  buffered_packets_.clear();
+}
+
+bool QuicConnection::ValidateConfigConnectionIds(const QuicConfig& config) {
+  QUICHE_DCHECK(config.negotiated());
+  if (!version().UsesTls()) {
+    // QUIC+TLS is required to transmit connection ID transport parameters.
+    return true;
+  }
+  // This function validates connection IDs as defined in IETF draft-28 and
+  // later.
+
+  // Validate initial_source_connection_id.
+  QuicConnectionId expected_initial_source_connection_id;
+  if (perspective_ == Perspective::IS_CLIENT) {
+    expected_initial_source_connection_id = default_path_.server_connection_id;
+  } else {
+    expected_initial_source_connection_id = default_path_.client_connection_id;
+  }
+  if (!config.HasReceivedInitialSourceConnectionId() ||
+      config.ReceivedInitialSourceConnectionId() !=
+          expected_initial_source_connection_id) {
+    std::string received_value;
+    if (config.HasReceivedInitialSourceConnectionId()) {
+      received_value = config.ReceivedInitialSourceConnectionId().ToString();
+    } else {
+      received_value = "none";
+    }
+    std::string error_details =
+        absl::StrCat("Bad initial_source_connection_id: expected ",
+                     expected_initial_source_connection_id.ToString(),
+                     ", received ", received_value);
+    CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    // Validate original_destination_connection_id.
+    if (!config.HasReceivedOriginalConnectionId() ||
+        config.ReceivedOriginalConnectionId() !=
+            GetOriginalDestinationConnectionId()) {
+      std::string received_value;
+      if (config.HasReceivedOriginalConnectionId()) {
+        received_value = config.ReceivedOriginalConnectionId().ToString();
+      } else {
+        received_value = "none";
+      }
+      std::string error_details =
+          absl::StrCat("Bad original_destination_connection_id: expected ",
+                       GetOriginalDestinationConnectionId().ToString(),
+                       ", received ", received_value);
+      CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return false;
+    }
+    // Validate retry_source_connection_id.
+    if (retry_source_connection_id_.has_value()) {
+      // We received a RETRY packet, validate that the retry source
+      // connection ID from the config matches the one from the RETRY.
+      if (!config.HasReceivedRetrySourceConnectionId() ||
+          config.ReceivedRetrySourceConnectionId() !=
+              retry_source_connection_id_.value()) {
+        std::string received_value;
+        if (config.HasReceivedRetrySourceConnectionId()) {
+          received_value = config.ReceivedRetrySourceConnectionId().ToString();
+        } else {
+          received_value = "none";
+        }
+        std::string error_details =
+            absl::StrCat("Bad retry_source_connection_id: expected ",
+                         retry_source_connection_id_.value().ToString(),
+                         ", received ", received_value);
+        CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return false;
+      }
+    } else {
+      // We did not receive a RETRY packet, make sure we did not receive the
+      // retry_source_connection_id transport parameter.
+      if (config.HasReceivedRetrySourceConnectionId()) {
+        std::string error_details = absl::StrCat(
+            "Bad retry_source_connection_id: did not receive RETRY but "
+            "received ",
+            config.ReceivedRetrySourceConnectionId().ToString());
+        CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+void QuicConnection::SetFromConfig(const QuicConfig& config) {
+  if (config.negotiated()) {
+    // Handshake complete, set handshake timeout to Infinite.
+    SetNetworkTimeouts(QuicTime::Delta::Infinite(),
+                       config.IdleNetworkTimeout());
+    idle_timeout_connection_close_behavior_ =
+        ConnectionCloseBehavior::SILENT_CLOSE;
+    if (perspective_ == Perspective::IS_SERVER) {
+      idle_timeout_connection_close_behavior_ = ConnectionCloseBehavior::
+          SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED;
+    }
+    if (config.HasClientRequestedIndependentOption(kNSLC, perspective_)) {
+      idle_timeout_connection_close_behavior_ =
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET;
+    }
+    if (!ValidateConfigConnectionIds(config)) {
+      return;
+    }
+    support_key_update_for_connection_ = version().UsesTls();
+    framer_.SetKeyUpdateSupportForConnection(
+        support_key_update_for_connection_);
+  } else {
+    SetNetworkTimeouts(config.max_time_before_crypto_handshake(),
+                       config.max_idle_time_before_crypto_handshake());
+    if (config.HasClientRequestedIndependentOption(kNCHP, perspective_)) {
+      packet_creator_.set_chaos_protection_enabled(false);
+    }
+  }
+
+  if (version().HasIetfQuicFrames() &&
+      config.HasReceivedPreferredAddressConnectionIdAndToken()) {
+    QuicNewConnectionIdFrame frame;
+    std::tie(frame.connection_id, frame.stateless_reset_token) =
+        config.ReceivedPreferredAddressConnectionIdAndToken();
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    OnNewConnectionIdFrameInner(frame);
+  }
+
+  sent_packet_manager_.SetFromConfig(config);
+  if (perspective_ == Perspective::IS_SERVER &&
+      config.HasClientSentConnectionOption(kAFF2, perspective_)) {
+    send_ack_frequency_on_handshake_completion_ = true;
+  }
+  if (config.HasReceivedBytesForConnectionId() &&
+      can_truncate_connection_ids_) {
+    packet_creator_.SetServerConnectionIdLength(
+        config.ReceivedBytesForConnectionId());
+  }
+  max_undecryptable_packets_ = config.max_undecryptable_packets();
+
+  if (!GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server)) {
+    if (config.HasClientRequestedIndependentOption(kMTUH, perspective_)) {
+      SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
+    }
+  }
+  if (config.HasClientRequestedIndependentOption(kMTUL, perspective_)) {
+    SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow);
+  }
+  if (default_enable_5rto_blackhole_detection_) {
+    if (config.HasClientRequestedIndependentOption(kCBHD, perspective_)) {
+      QUIC_CODE_COUNT(quic_client_only_blackhole_detection);
+      blackhole_detection_disabled_ = true;
+    }
+    if (config.HasClientSentConnectionOption(kNBHD, perspective_)) {
+      blackhole_detection_disabled_ = true;
+    }
+    if (config.HasClientSentConnectionOption(k2RTO, perspective_)) {
+      QUIC_CODE_COUNT(quic_2rto_blackhole_detection);
+      num_rtos_for_blackhole_detection_ = 2;
+    }
+    if (config.HasClientSentConnectionOption(k3RTO, perspective_)) {
+      QUIC_CODE_COUNT(quic_3rto_blackhole_detection);
+      num_rtos_for_blackhole_detection_ = 3;
+    }
+    if (config.HasClientSentConnectionOption(k4RTO, perspective_)) {
+      QUIC_CODE_COUNT(quic_4rto_blackhole_detection);
+      num_rtos_for_blackhole_detection_ = 4;
+    }
+    if (config.HasClientSentConnectionOption(k6RTO, perspective_)) {
+      QUIC_CODE_COUNT(quic_6rto_blackhole_detection);
+      num_rtos_for_blackhole_detection_ = 6;
+    }
+  }
+
+  if (config.HasClientRequestedIndependentOption(kFIDT, perspective_)) {
+    idle_network_detector_.enable_shorter_idle_timeout_on_sent_packet();
+  }
+  if (config.HasClientRequestedIndependentOption(k3AFF, perspective_)) {
+    anti_amplification_factor_ = 3;
+  }
+  if (config.HasClientRequestedIndependentOption(k10AF, perspective_)) {
+    anti_amplification_factor_ = 10;
+  }
+
+  if (GetQuicReloadableFlag(quic_enable_server_on_wire_ping) &&
+      perspective_ == Perspective::IS_SERVER &&
+      config.HasClientSentConnectionOption(kSRWP, perspective_)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_enable_server_on_wire_ping);
+    set_initial_retransmittable_on_wire_timeout(
+        QuicTime::Delta::FromMilliseconds(200));
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSetFromConfig(config);
+  }
+  uber_received_packet_manager_.SetFromConfig(config, perspective_);
+  if (config.HasClientSentConnectionOption(k5RTO, perspective_)) {
+    num_rtos_for_blackhole_detection_ = 5;
+  }
+  if (sent_packet_manager_.pto_enabled()) {
+    if (config.HasClientSentConnectionOption(k6PTO, perspective_) ||
+        config.HasClientSentConnectionOption(k7PTO, perspective_) ||
+        config.HasClientSentConnectionOption(k8PTO, perspective_)) {
+      num_rtos_for_blackhole_detection_ = 5;
+    }
+  }
+  if (config.HasClientSentConnectionOption(kNSTP, perspective_)) {
+    no_stop_waiting_frames_ = true;
+  }
+  if (config.HasReceivedStatelessResetToken()) {
+    default_path_.stateless_reset_token = config.ReceivedStatelessResetToken();
+  }
+  if (config.HasReceivedAckDelayExponent()) {
+    framer_.set_peer_ack_delay_exponent(config.ReceivedAckDelayExponent());
+  }
+  if (config.HasClientSentConnectionOption(kEACK, perspective_)) {
+    bundle_retransmittable_with_pto_ack_ = true;
+  }
+  if (config.HasClientSentConnectionOption(kDFER, perspective_)) {
+    defer_send_in_response_to_packets_ = false;
+  }
+
+  if (config.HasClientRequestedIndependentOption(kINVC, perspective_)) {
+    send_connection_close_for_invalid_version_ = true;
+  }
+  const bool remove_connection_migration_connection_option =
+      GetQuicReloadableFlag(quic_remove_connection_migration_connection_option);
+  if (remove_connection_migration_connection_option) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_remove_connection_migration_connection_option);
+  }
+  if (framer_.version().HasIetfQuicFrames() && use_path_validator_ &&
+      count_bytes_on_alternative_path_separately_ &&
+      GetQuicReloadableFlag(quic_server_reverse_validate_new_path3) &&
+      (remove_connection_migration_connection_option ||
+       config.HasClientSentConnectionOption(kRVCM, perspective_))) {
+    QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 6, 6);
+    validate_client_addresses_ = true;
+  }
+  // Having connection_migration_use_new_cid_ depends on the same set of flags
+  // and connection option on both client and server sides has the advantage of:
+  // 1) Less chance of skew in using new connection ID or not between client
+  //    and server in unit tests with random flag combinations.
+  // 2) Client side's rollout can be protected by the same connection option.
+  connection_migration_use_new_cid_ =
+      validate_client_addresses_ &&
+      GetQuicReloadableFlag(quic_connection_migration_use_new_cid_v2);
+  if (config.HasReceivedMaxPacketSize()) {
+    peer_max_packet_size_ = config.ReceivedMaxPacketSize();
+    MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+  }
+  if (config.HasReceivedMaxDatagramFrameSize()) {
+    packet_creator_.SetMaxDatagramFrameSize(
+        config.ReceivedMaxDatagramFrameSize());
+  }
+
+  supports_release_time_ =
+      writer_ != nullptr && writer_->SupportsReleaseTime() &&
+      !config.HasClientSentConnectionOption(kNPCO, perspective_);
+
+  if (supports_release_time_) {
+    UpdateReleaseTimeIntoFuture();
+  }
+}
+
+void QuicConnection::EnableLegacyVersionEncapsulation(
+    const std::string& server_name) {
+  if (perspective_ != Perspective::IS_CLIENT) {
+    QUIC_BUG(quic_bug_10511_1)
+        << "Cannot enable Legacy Version Encapsulation on the server";
+    return;
+  }
+  if (legacy_version_encapsulation_enabled_) {
+    QUIC_BUG(quic_bug_10511_2)
+        << "Do not call EnableLegacyVersionEncapsulation twice";
+    return;
+  }
+  if (!QuicHostnameUtils::IsValidSNI(server_name)) {
+    // Legacy Version Encapsulation is only used when SNI is transmitted.
+    QUIC_DLOG(INFO)
+        << "Refusing to use Legacy Version Encapsulation with invalid SNI \""
+        << server_name << "\"";
+    return;
+  }
+  QUIC_DLOG(INFO) << "Enabling Legacy Version Encapsulation with SNI \""
+                  << server_name << "\"";
+  legacy_version_encapsulation_enabled_ = true;
+  legacy_version_encapsulation_sni_ = server_name;
+}
+
+bool QuicConnection::MaybeTestLiveness() {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
+    return false;
+  }
+  const QuicTime idle_network_deadline =
+      idle_network_detector_.GetIdleNetworkDeadline();
+  if (!idle_network_deadline.IsInitialized()) {
+    return false;
+  }
+  const QuicTime now = clock_->ApproximateNow();
+  if (now > idle_network_deadline) {
+    QUIC_DLOG(WARNING) << "Idle network deadline has passed";
+    return false;
+  }
+  const QuicTime::Delta timeout = idle_network_deadline - now;
+  if (2 * timeout > idle_network_detector_.idle_network_timeout()) {
+    // Do not test liveness if timeout is > half timeout. This is used to
+    // prevent an infinite loop for short idle timeout.
+    return false;
+  }
+  if (!sent_packet_manager_.IsLessThanThreePTOs(timeout)) {
+    return false;
+  }
+  SendConnectivityProbingPacket(writer_, peer_address());
+  return true;
+}
+
+void QuicConnection::ApplyConnectionOptions(
+    const QuicTagVector& connection_options) {
+  sent_packet_manager_.ApplyConnectionOptions(connection_options);
+}
+
+void QuicConnection::OnSendConnectionState(
+    const CachedNetworkParameters& cached_network_params) {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSendConnectionState(cached_network_params);
+  }
+}
+
+void QuicConnection::OnReceiveConnectionState(
+    const CachedNetworkParameters& cached_network_params) {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnReceiveConnectionState(cached_network_params);
+  }
+}
+
+void QuicConnection::ResumeConnectionState(
+    const CachedNetworkParameters& cached_network_params,
+    bool max_bandwidth_resumption) {
+  sent_packet_manager_.ResumeConnectionState(cached_network_params,
+                                             max_bandwidth_resumption);
+}
+
+void QuicConnection::SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
+  sent_packet_manager_.SetMaxPacingRate(max_pacing_rate);
+}
+
+void QuicConnection::AdjustNetworkParameters(
+    const SendAlgorithmInterface::NetworkParams& params) {
+  sent_packet_manager_.AdjustNetworkParameters(params);
+}
+
+void QuicConnection::SetLossDetectionTuner(
+    std::unique_ptr<LossDetectionTunerInterface> tuner) {
+  sent_packet_manager_.SetLossDetectionTuner(std::move(tuner));
+}
+
+void QuicConnection::OnConfigNegotiated() {
+  sent_packet_manager_.OnConfigNegotiated();
+
+  if (GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server) &&
+      perspective_ == Perspective::IS_SERVER) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_enable_mtu_discovery_at_server);
+    SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
+  }
+}
+
+QuicBandwidth QuicConnection::MaxPacingRate() const {
+  return sent_packet_manager_.MaxPacingRate();
+}
+
+bool QuicConnection::SelectMutualVersion(
+    const ParsedQuicVersionVector& available_versions) {
+  // Try to find the highest mutual version by iterating over supported
+  // versions, starting with the highest, and breaking out of the loop once we
+  // find a matching version in the provided available_versions vector.
+  const ParsedQuicVersionVector& supported_versions =
+      framer_.supported_versions();
+  for (size_t i = 0; i < supported_versions.size(); ++i) {
+    const ParsedQuicVersion& version = supported_versions[i];
+    if (std::find(available_versions.begin(), available_versions.end(),
+                  version) != available_versions.end()) {
+      framer_.set_version(version);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void QuicConnection::OnError(QuicFramer* framer) {
+  // Packets that we can not or have not decrypted are dropped.
+  // TODO(rch): add stats to measure this.
+  if (!connected_ || last_packet_decrypted_ == false) {
+    return;
+  }
+  CloseConnection(framer->error(), framer->detailed_error(),
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicConnection::OnPacket() {
+  last_packet_decrypted_ = false;
+}
+
+void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
+  // Check that any public reset packet with a different connection ID that was
+  // routed to this QuicConnection has been redirected before control reaches
+  // here.  (Check for a bug regression.)
+  QUICHE_DCHECK_EQ(default_path_.server_connection_id, packet.connection_id);
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  QUICHE_DCHECK(!version().HasIetfInvariantHeader());
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPublicResetPacket(packet);
+  }
+  std::string error_details = "Received public reset.";
+  if (perspective_ == Perspective::IS_CLIENT && !packet.endpoint_id.empty()) {
+    absl::StrAppend(&error_details, " From ", packet.endpoint_id, ".");
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << error_details;
+  QUIC_CODE_COUNT(quic_tear_down_local_connection_on_public_reset);
+  TearDownLocalConnectionState(QUIC_PUBLIC_RESET, NO_IETF_QUIC_ERROR,
+                               error_details, ConnectionCloseSource::FROM_PEER);
+}
+
+bool QuicConnection::OnProtocolVersionMismatch(
+    ParsedQuicVersion received_version) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Received packet with mismatched version "
+                  << ParsedQuicVersionToString(received_version);
+  if (perspective_ == Perspective::IS_CLIENT) {
+    const std::string error_details = "Protocol version mismatch.";
+    QUIC_BUG(quic_bug_10511_3) << ENDPOINT << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+  }
+
+  // Server drops old packets that were sent by the client before the version
+  // was negotiated.
+  return false;
+}
+
+// Handles version negotiation for client connection.
+void QuicConnection::OnVersionNegotiationPacket(
+    const QuicVersionNegotiationPacket& packet) {
+  // Check that any public reset packet with a different connection ID that was
+  // routed to this QuicConnection has been redirected before control reaches
+  // here.  (Check for a bug regression.)
+  QUICHE_DCHECK_EQ(default_path_.server_connection_id, packet.connection_id);
+  if (perspective_ == Perspective::IS_SERVER) {
+    const std::string error_details =
+        "Server received version negotiation packet.";
+    QUIC_BUG(quic_bug_10511_4) << error_details;
+    QUIC_CODE_COUNT(quic_tear_down_local_connection_on_version_negotiation);
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+    return;
+  }
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnVersionNegotiationPacket(packet);
+  }
+
+  if (version_negotiated_) {
+    // Possibly a duplicate version negotiation packet.
+    return;
+  }
+
+  if (std::find(packet.versions.begin(), packet.versions.end(), version()) !=
+      packet.versions.end()) {
+    const std::string error_details = absl::StrCat(
+        "Server already supports client's version ",
+        ParsedQuicVersionToString(version()),
+        " and should have accepted the connection instead of sending {",
+        ParsedQuicVersionVectorToString(packet.versions), "}.");
+    QUIC_DLOG(WARNING) << error_details;
+    CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, error_details,
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+    return;
+  }
+
+  server_supported_versions_ = packet.versions;
+  CloseConnection(
+      QUIC_INVALID_VERSION,
+      absl::StrCat(
+          "Client may support one of the versions in the server's list, but "
+          "it's going to close the connection anyway. Supported versions: {",
+          ParsedQuicVersionVectorToString(framer_.supported_versions()),
+          "}, peer supported versions: {",
+          ParsedQuicVersionVectorToString(packet.versions), "}"),
+      send_connection_close_for_invalid_version_
+          ? ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET
+          : ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+// Handles retry for client connection.
+void QuicConnection::OnRetryPacket(QuicConnectionId original_connection_id,
+                                   QuicConnectionId new_connection_id,
+                                   absl::string_view retry_token,
+                                   absl::string_view retry_integrity_tag,
+                                   absl::string_view retry_without_tag) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+  if (version().UsesTls()) {
+    if (!CryptoUtils::ValidateRetryIntegrityTag(
+            version(), default_path_.server_connection_id, retry_without_tag,
+            retry_integrity_tag)) {
+      QUIC_DLOG(ERROR) << "Ignoring RETRY with invalid integrity tag";
+      return;
+    }
+  } else {
+    if (original_connection_id != default_path_.server_connection_id) {
+      QUIC_DLOG(ERROR) << "Ignoring RETRY with original connection ID "
+                       << original_connection_id << " not matching expected "
+                       << default_path_.server_connection_id << " token "
+                       << absl::BytesToHexString(retry_token);
+      return;
+    }
+  }
+  framer_.set_drop_incoming_retry_packets(true);
+  stats_.retry_packet_processed = true;
+  QUIC_DLOG(INFO) << "Received RETRY, replacing connection ID "
+                  << default_path_.server_connection_id << " with "
+                  << new_connection_id << ", received token "
+                  << absl::BytesToHexString(retry_token);
+  if (!original_destination_connection_id_.has_value()) {
+    original_destination_connection_id_ = default_path_.server_connection_id;
+  }
+  QUICHE_DCHECK(!retry_source_connection_id_.has_value())
+      << retry_source_connection_id_.value();
+  retry_source_connection_id_ = new_connection_id;
+  ReplaceInitialServerConnectionId(new_connection_id);
+  packet_creator_.SetRetryToken(retry_token);
+
+  // Reinstall initial crypters because the connection ID changed.
+  InstallInitialCrypters(default_path_.server_connection_id);
+
+  sent_packet_manager_.MarkInitialPacketsForRetransmission();
+}
+
+void QuicConnection::SetOriginalDestinationConnectionId(
+    const QuicConnectionId& original_destination_connection_id) {
+  QUIC_DLOG(INFO) << "Setting original_destination_connection_id to "
+                  << original_destination_connection_id
+                  << " on connection with server_connection_id "
+                  << default_path_.server_connection_id;
+  QUICHE_DCHECK_NE(original_destination_connection_id,
+                   default_path_.server_connection_id);
+  InstallInitialCrypters(original_destination_connection_id);
+  QUICHE_DCHECK(!original_destination_connection_id_.has_value())
+      << original_destination_connection_id_.value();
+  original_destination_connection_id_ = original_destination_connection_id;
+  original_destination_connection_id_replacement_ =
+      default_path_.server_connection_id;
+}
+
+QuicConnectionId QuicConnection::GetOriginalDestinationConnectionId() {
+  if (original_destination_connection_id_.has_value()) {
+    return original_destination_connection_id_.value();
+  }
+  return default_path_.server_connection_id;
+}
+
+bool QuicConnection::ValidateServerConnectionId(
+    const QuicPacketHeader& header) const {
+  if (perspective_ == Perspective::IS_CLIENT &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+    return true;
+  }
+
+  QuicConnectionId server_connection_id =
+      GetServerConnectionIdAsRecipient(header, perspective_);
+
+  if (server_connection_id == default_path_.server_connection_id ||
+      server_connection_id == original_destination_connection_id_) {
+    return true;
+  }
+
+  if (PacketCanReplaceServerConnectionId(header, perspective_)) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
+                    << server_connection_id << " instead of "
+                    << default_path_.server_connection_id;
+    return true;
+  }
+
+  if (connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_SERVER &&
+      self_issued_cid_manager_ != nullptr &&
+      self_issued_cid_manager_->IsConnectionIdInUse(server_connection_id)) {
+    return true;
+  }
+
+  return false;
+}
+
+bool QuicConnection::OnUnauthenticatedPublicHeader(
+    const QuicPacketHeader& header) {
+  last_packet_destination_connection_id_ = header.destination_connection_id;
+  // If last packet destination connection ID is the original server
+  // connection ID chosen by client, replaces it with the connection ID chosen
+  // by server.
+  if (perspective_ == Perspective::IS_SERVER &&
+      original_destination_connection_id_.has_value() &&
+      last_packet_destination_connection_id_ ==
+          *original_destination_connection_id_) {
+    last_packet_destination_connection_id_ =
+        original_destination_connection_id_replacement_;
+  }
+
+  // As soon as we receive an initial we start ignoring subsequent retries.
+  if (header.version_flag && header.long_packet_type == INITIAL) {
+    framer_.set_drop_incoming_retry_packets(true);
+  }
+
+  if (!ValidateServerConnectionId(header)) {
+    ++stats_.packets_dropped;
+    QuicConnectionId server_connection_id =
+        GetServerConnectionIdAsRecipient(header, perspective_);
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Ignoring packet from unexpected server connection ID "
+                    << server_connection_id << " instead of "
+                    << default_path_.server_connection_id;
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnIncorrectConnectionId(server_connection_id);
+    }
+    // If this is a server, the dispatcher routes each packet to the
+    // QuicConnection responsible for the packet's connection ID.  So if control
+    // arrives here and this is a server, the dispatcher must be malfunctioning.
+    QUICHE_DCHECK_NE(Perspective::IS_SERVER, perspective_);
+    return false;
+  }
+
+  if (!version().SupportsClientConnectionIds()) {
+    return true;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+    return true;
+  }
+
+  QuicConnectionId client_connection_id =
+      GetClientConnectionIdAsRecipient(header, perspective_);
+
+  if (client_connection_id == default_path_.client_connection_id) {
+    return true;
+  }
+
+  if (!client_connection_id_is_set_ && perspective_ == Perspective::IS_SERVER) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Setting client connection ID from first packet to "
+                    << client_connection_id;
+    set_client_connection_id(client_connection_id);
+    return true;
+  }
+
+  if (connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_CLIENT &&
+      self_issued_cid_manager_ != nullptr &&
+      self_issued_cid_manager_->IsConnectionIdInUse(client_connection_id)) {
+    return true;
+  }
+
+  ++stats_.packets_dropped;
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "Ignoring packet from unexpected client connection ID "
+                  << client_connection_id << " instead of "
+                  << default_path_.client_connection_id;
+  return false;
+}
+
+bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnUnauthenticatedHeader(header);
+  }
+
+  // Sanity check on the server connection ID in header.
+  QUICHE_DCHECK(ValidateServerConnectionId(header));
+
+  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 "
+        "processed.";
+    QUIC_BUG(quic_pending_frames_not_serialized)
+        << error_details << ", received header: " << header;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  return true;
+}
+
+void QuicConnection::OnSuccessfulVersionNegotiation() {
+  visitor_->OnSuccessfulVersionNegotiation(version());
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSuccessfulVersionNegotiation(version());
+  }
+}
+
+void QuicConnection::OnSuccessfulMigration(bool is_port_change) {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  if (IsPathDegrading()) {
+    // If path was previously degrading, and migration is successful after
+    // probing, restart the path degrading and blackhole detection.
+    OnForwardProgressMade();
+  }
+  if (IsAlternativePath(default_path_.self_address,
+                        default_path_.peer_address)) {
+    // Reset alternative path state even if it is still under validation.
+    alternative_path_.Clear();
+  }
+  // TODO(b/159074035): notify SentPacketManger with RTT sample from probing.
+  if (version().HasIetfQuicFrames() && !is_port_change) {
+    sent_packet_manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
+  }
+}
+
+void QuicConnection::OnTransportParametersSent(
+    const TransportParameters& transport_parameters) const {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnTransportParametersSent(transport_parameters);
+  }
+}
+
+void QuicConnection::OnTransportParametersReceived(
+    const TransportParameters& transport_parameters) const {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnTransportParametersReceived(transport_parameters);
+  }
+}
+
+void QuicConnection::OnTransportParametersResumed(
+    const TransportParameters& transport_parameters) const {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnTransportParametersResumed(transport_parameters);
+  }
+}
+
+bool QuicConnection::HasPendingAcks() const {
+  return ack_alarm_->IsSet();
+}
+
+void QuicConnection::OnUserAgentIdKnown(const std::string& /*user_agent_id*/) {
+  sent_packet_manager_.OnUserAgentIdKnown();
+}
+
+void QuicConnection::OnDecryptedPacket(size_t /*length*/,
+                                       EncryptionLevel level) {
+  last_decrypted_packet_level_ = level;
+  last_packet_decrypted_ = true;
+  if (level == ENCRYPTION_FORWARD_SECURE &&
+      !have_decrypted_first_one_rtt_packet_) {
+    have_decrypted_first_one_rtt_packet_ = true;
+    if (version().UsesTls() && perspective_ == Perspective::IS_SERVER) {
+      // Servers MAY temporarily retain 0-RTT keys to allow decrypting reordered
+      // packets without requiring their contents to be retransmitted with 1-RTT
+      // keys. After receiving a 1-RTT packet, servers MUST discard 0-RTT keys
+      // within a short time; the RECOMMENDED time period is three times the
+      // Probe Timeout.
+      // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-discarding-0-rtt-keys
+      discard_zero_rtt_decryption_keys_alarm_->Set(
+          clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay() * 3);
+    }
+  }
+  if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
+      (last_decrypted_packet_level_ == ENCRYPTION_HANDSHAKE ||
+       last_decrypted_packet_level_ == ENCRYPTION_FORWARD_SECURE)) {
+    // Address is validated by successfully processing a HANDSHAKE or 1-RTT
+    // packet.
+    default_path_.validated = true;
+    stats_.address_validated_via_decrypting_packet = true;
+  }
+  idle_network_detector_.OnPacketReceived(
+      last_received_packet_info_.receipt_time);
+
+  visitor_->OnPacketDecrypted(level);
+}
+
+QuicSocketAddress QuicConnection::GetEffectivePeerAddressFromCurrentPacket()
+    const {
+  // By default, the connection is not proxied, and the effective peer address
+  // is the packet's source address, i.e. the direct peer address.
+  return last_received_packet_info_.source_address;
+}
+
+bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPacketHeader(header, clock_->ApproximateNow(),
+                                   last_decrypted_packet_level_);
+  }
+
+  // Will be decremented below if we fall through to return true.
+  ++stats_.packets_dropped;
+
+  if (!ProcessValidatedPacket(header)) {
+    return false;
+  }
+
+  // Initialize the current packet content state.
+  most_recent_frame_type_ = NUM_FRAME_TYPES;
+  current_packet_content_ = NO_FRAMES_RECEIVED;
+  is_current_packet_connectivity_probing_ = false;
+  has_path_challenge_in_current_packet_ = false;
+  current_effective_peer_migration_type_ = NO_CHANGE;
+
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (!GetLargestReceivedPacket().IsInitialized() ||
+        header.packet_number > GetLargestReceivedPacket()) {
+      // Update direct_peer_address_ and default path peer_address immediately
+      // for client connections.
+      // TODO(fayang): only change peer addresses in application data packet
+      // number space.
+      UpdatePeerAddress(last_received_packet_info_.source_address);
+      default_path_.peer_address = GetEffectivePeerAddressFromCurrentPacket();
+    }
+  } else {
+    // At server, remember the address change type of effective_peer_address
+    // in current_effective_peer_migration_type_. But this variable alone
+    // doesn't necessarily starts a migration. A migration will be started
+    // later, once the current packet is confirmed to meet the following
+    // conditions:
+    // 1) current_effective_peer_migration_type_ is not NO_CHANGE.
+    // 2) The current packet is not a connectivity probing.
+    // 3) The current packet is not reordered, i.e. its packet number is the
+    //    largest of this connection so far.
+    // Once the above conditions are confirmed, a new migration will start
+    // even if there is an active migration underway.
+    current_effective_peer_migration_type_ =
+        QuicUtils::DetermineAddressChangeType(
+            default_path_.peer_address,
+            GetEffectivePeerAddressFromCurrentPacket());
+
+    if (connection_migration_use_new_cid_) {
+      auto effective_peer_address = GetEffectivePeerAddressFromCurrentPacket();
+      // Since server does not send new connection ID to client before handshake
+      // completion and source connection ID is omitted in short header packet,
+      // the server_connection_id on PathState on the server side does not
+      // affect the packets server writes after handshake completion. On the
+      // other hand, it is still desirable to have the "correct" server
+      // connection ID set on path.
+      // 1) If client uses 1 unique server connection ID per path and the packet
+      // is received from an existing path, then
+      // last_packet_destination_connection_id_ will always be the same as the
+      // server connection ID on path. Server side will maintain the 1-to-1
+      // mapping from server connection ID to path.
+      // 2) If client uses multiple server connection IDs on the same path,
+      // compared to the server_connection_id on path,
+      // last_packet_destination_connection_id_ has the advantage that it is
+      // still present in the session map since the packet can be routed here
+      // regardless of packet reordering.
+      if (IsDefaultPath(last_received_packet_info_.destination_address,
+                        effective_peer_address)) {
+        default_path_.server_connection_id =
+            last_packet_destination_connection_id_;
+      } else if (IsAlternativePath(
+                     last_received_packet_info_.destination_address,
+                     effective_peer_address)) {
+        alternative_path_.server_connection_id =
+            last_packet_destination_connection_id_;
+      }
+    }
+
+    if (last_packet_destination_connection_id_ !=
+            default_path_.server_connection_id &&
+        (!original_destination_connection_id_.has_value() ||
+         last_packet_destination_connection_id_ !=
+             *original_destination_connection_id_)) {
+      QUIC_CODE_COUNT(quic_connection_id_change);
+    }
+
+    QUIC_DLOG_IF(INFO, current_effective_peer_migration_type_ != NO_CHANGE)
+        << ENDPOINT << "Effective peer's ip:port changed from "
+        << default_path_.peer_address.ToString() << " to "
+        << GetEffectivePeerAddressFromCurrentPacket().ToString()
+        << ", active_effective_peer_migration_type is "
+        << active_effective_peer_migration_type_;
+  }
+
+  --stats_.packets_dropped;
+  QUIC_DVLOG(1) << ENDPOINT << "Received packet header: " << header;
+  last_header_ = header;
+  if (!stats_.first_decrypted_packet.IsInitialized()) {
+    stats_.first_decrypted_packet = last_header_.packet_number;
+  }
+
+  // Record packet receipt to populate ack info before processing stream
+  // frames, since the processing may result in sending a bundled ack.
+  QuicTime receipt_time = idle_network_detector_.time_of_last_received_packet();
+  if (SupportsMultiplePacketNumberSpaces()) {
+    receipt_time = last_received_packet_info_.receipt_time;
+  }
+  uber_received_packet_manager_.RecordPacketReceived(
+      last_decrypted_packet_level_, last_header_, receipt_time);
+  if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
+      !header.retry_token.empty() &&
+      visitor_->ValidateToken(header.retry_token)) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Address validated via token.";
+    QUIC_CODE_COUNT(quic_address_validated_via_token);
+    default_path_.validated = true;
+    stats_.address_validated_via_token = true;
+  }
+  QUICHE_DCHECK(connected_);
+  return true;
+}
+
+bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_3, !connected_)
+      << "Processing STREAM frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a stream frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(STREAM_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnStreamFrame(frame);
+  }
+  if (!QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) &&
+      last_decrypted_packet_level_ == ENCRYPTION_INITIAL) {
+    if (MaybeConsiderAsMemoryCorruption(frame)) {
+      CloseConnection(QUIC_MAYBE_CORRUPTED_MEMORY,
+                      "Received crypto frame on non crypto stream.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return false;
+    }
+
+    QUIC_PEER_BUG(quic_peer_bug_10511_6)
+        << ENDPOINT << "Received an unencrypted data frame: closing connection"
+        << " packet_number:" << last_header_.packet_number
+        << " stream_id:" << frame.stream_id
+        << " received_packets:" << ack_frame();
+    CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA,
+                    "Unencrypted stream data seen.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  // TODO(fayang): Consider moving UpdatePacketContent and
+  // MaybeUpdateAckTimeout to a stand-alone function instead of calling them for
+  // all frames.
+  MaybeUpdateAckTimeout();
+  visitor_->OnStreamFrame(frame);
+  stats_.stream_bytes_received += frame.data_length;
+  consecutive_retransmittable_on_wire_ping_count_ = 0;
+  return connected_;
+}
+
+bool QuicConnection::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_4, !connected_)
+      << "Processing CRYPTO frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a CRYPTO frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(CRYPTO_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnCryptoFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  visitor_->OnCryptoFrame(frame);
+  return connected_;
+}
+
+bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
+                                     QuicTime::Delta ack_delay_time) {
+  QUIC_BUG_IF(quic_bug_12714_5, !connected_)
+      << "Processing ACK frame start when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  if (processing_ack_frame_) {
+    CloseConnection(QUIC_INVALID_ACK_DATA,
+                    "Received a new ack while processing an ack frame.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  // Since an ack frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(ACK_FRAME)) {
+    return false;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT
+                << "OnAckFrameStart, largest_acked: " << largest_acked;
+
+  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
+      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
+    return true;
+  }
+
+  if (!sent_packet_manager_.GetLargestSentPacket().IsInitialized() ||
+      largest_acked > sent_packet_manager_.GetLargestSentPacket()) {
+    QUIC_DLOG(WARNING) << ENDPOINT
+                       << "Peer's observed unsent packet:" << largest_acked
+                       << " vs " << sent_packet_manager_.GetLargestSentPacket()
+                       << ". SupportsMultiplePacketNumberSpaces():"
+                       << SupportsMultiplePacketNumberSpaces()
+                       << ", last_decrypted_packet_level_:"
+                       << last_decrypted_packet_level_;
+    // We got an ack for data we have not sent.
+    CloseConnection(QUIC_INVALID_ACK_DATA, "Largest observed too high.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  processing_ack_frame_ = true;
+  sent_packet_manager_.OnAckFrameStart(
+      largest_acked, ack_delay_time,
+      idle_network_detector_.time_of_last_received_packet());
+  return true;
+}
+
+bool QuicConnection::OnAckRange(QuicPacketNumber start, QuicPacketNumber end) {
+  QUIC_BUG_IF(quic_bug_12714_6, !connected_)
+      << "Processing ACK frame range when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  QUIC_DVLOG(1) << ENDPOINT << "OnAckRange: [" << start << ", " << end << ")";
+
+  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
+      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
+    return true;
+  }
+
+  sent_packet_manager_.OnAckRange(start, end);
+  return true;
+}
+
+bool QuicConnection::OnAckTimestamp(QuicPacketNumber packet_number,
+                                    QuicTime timestamp) {
+  QUIC_BUG_IF(quic_bug_10511_7, !connected_)
+      << "Processing ACK frame time stamp when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  QUIC_DVLOG(1) << ENDPOINT << "OnAckTimestamp: [" << packet_number << ", "
+                << timestamp.ToDebuggingValue() << ")";
+
+  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
+      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
+    return true;
+  }
+
+  sent_packet_manager_.OnAckTimestamp(packet_number, timestamp);
+  return true;
+}
+
+bool QuicConnection::OnAckFrameEnd(QuicPacketNumber start) {
+  QUIC_BUG_IF(quic_bug_12714_7, !connected_)
+      << "Processing ACK frame end when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  QUIC_DVLOG(1) << ENDPOINT << "OnAckFrameEnd, start: " << start;
+
+  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
+      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
+    return true;
+  }
+  const bool one_rtt_packet_was_acked =
+      sent_packet_manager_.one_rtt_packet_acked();
+  const bool zero_rtt_packet_was_acked =
+      sent_packet_manager_.zero_rtt_packet_acked();
+  const AckResult ack_result = sent_packet_manager_.OnAckFrameEnd(
+      idle_network_detector_.time_of_last_received_packet(),
+      last_header_.packet_number, last_decrypted_packet_level_);
+  if (ack_result != PACKETS_NEWLY_ACKED &&
+      ack_result != NO_PACKETS_NEWLY_ACKED) {
+    // Error occurred (e.g., this ACK tries to ack packets in wrong packet
+    // number space), and this would cause the connection to be closed.
+    QUIC_DLOG(ERROR) << ENDPOINT
+                     << "Error occurred when processing an ACK frame: "
+                     << QuicUtils::AckResultToString(ack_result);
+    return false;
+  }
+  if (SupportsMultiplePacketNumberSpaces() && !one_rtt_packet_was_acked &&
+      sent_packet_manager_.one_rtt_packet_acked()) {
+    visitor_->OnOneRttPacketAcknowledged();
+  }
+  if (debug_visitor_ != nullptr && version().UsesTls() &&
+      !zero_rtt_packet_was_acked &&
+      sent_packet_manager_.zero_rtt_packet_acked()) {
+    debug_visitor_->OnZeroRttPacketAcked();
+  }
+  // Cancel the send alarm because new packets likely have been acked, which
+  // may change the congestion window and/or pacing rate.  Canceling the alarm
+  // causes CanWrite to recalculate the next send time.
+  if (send_alarm_->IsSet()) {
+    send_alarm_->Cancel();
+  }
+  if (supports_release_time_) {
+    // Update pace time into future because smoothed RTT is likely updated.
+    UpdateReleaseTimeIntoFuture();
+  }
+  SetLargestReceivedPacketWithAck(last_header_.packet_number);
+  // If the incoming ack's packets set expresses missing packets: peer is still
+  // waiting for a packet lower than a packet that we are no longer planning to
+  // send.
+  // If the incoming ack's packets set expresses received packets: peer is still
+  // acking packets which we never care about.
+  // Send an ack to raise the high water mark.
+  const bool send_stop_waiting =
+      no_stop_waiting_frames_ ? false : GetLeastUnacked() > start;
+  PostProcessAfterAckFrame(send_stop_waiting,
+                           ack_result == PACKETS_NEWLY_ACKED);
+  processing_ack_frame_ = false;
+  return connected_;
+}
+
+bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_8, !connected_)
+      << "Processing STOP_WAITING frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a stop waiting frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(STOP_WAITING_FRAME)) {
+    return false;
+  }
+
+  if (no_stop_waiting_frames_) {
+    return true;
+  }
+  if (largest_seen_packet_with_stop_waiting_.IsInitialized() &&
+      last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Received an old stop waiting frame: ignoring";
+    return true;
+  }
+
+  const char* error = ValidateStopWaitingFrame(frame);
+  if (error != nullptr) {
+    CloseConnection(QUIC_INVALID_STOP_WAITING_DATA, error,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnStopWaitingFrame(frame);
+  }
+
+  largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
+  uber_received_packet_manager_.DontWaitForPacketsBefore(
+      last_decrypted_packet_level_, frame.least_unacked);
+  return connected_;
+}
+
+bool QuicConnection::OnPaddingFrame(const QuicPaddingFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_9, !connected_)
+      << "Processing PADDING frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(PADDING_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPaddingFrame(frame);
+  }
+  return true;
+}
+
+bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_10, !connected_)
+      << "Processing PING frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(PING_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    QuicTime::Delta ping_received_delay = QuicTime::Delta::Zero();
+    const QuicTime now = clock_->ApproximateNow();
+    if (now > stats_.connection_creation_time) {
+      ping_received_delay = now - stats_.connection_creation_time;
+    }
+    debug_visitor_->OnPingFrame(frame, ping_received_delay);
+  }
+  MaybeUpdateAckTimeout();
+  return true;
+}
+
+const char* QuicConnection::ValidateStopWaitingFrame(
+    const QuicStopWaitingFrame& stop_waiting) {
+  const QuicPacketNumber peer_least_packet_awaiting_ack =
+      uber_received_packet_manager_.peer_least_packet_awaiting_ack();
+  if (peer_least_packet_awaiting_ack.IsInitialized() &&
+      stop_waiting.least_unacked < peer_least_packet_awaiting_ack) {
+    QUIC_DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: "
+                     << stop_waiting.least_unacked << " vs "
+                     << peer_least_packet_awaiting_ack;
+    // We never process old ack frames, so this number should only increase.
+    return "Least unacked too small.";
+  }
+
+  if (stop_waiting.least_unacked > last_header_.packet_number) {
+    QUIC_DLOG(ERROR) << ENDPOINT
+                     << "Peer sent least_unacked:" << stop_waiting.least_unacked
+                     << " greater than the enclosing packet number:"
+                     << last_header_.packet_number;
+    return "Least unacked too large.";
+  }
+
+  return nullptr;
+}
+
+bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_11, !connected_)
+      << "Processing RST_STREAM frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a reset stream frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(RST_STREAM_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnRstStreamFrame(frame);
+  }
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "RST_STREAM_FRAME received for stream: " << frame.stream_id
+                  << " with error: "
+                  << QuicRstStreamErrorCodeToString(frame.error_code);
+  MaybeUpdateAckTimeout();
+  visitor_->OnRstStream(frame);
+  return connected_;
+}
+
+bool QuicConnection::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_12, !connected_)
+      << "Processing STOP_SENDING frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a reset stream frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(STOP_SENDING_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnStopSendingFrame(frame);
+  }
+
+  QUIC_DLOG(INFO) << ENDPOINT << "STOP_SENDING frame received for stream: "
+                  << frame.stream_id
+                  << " with error: " << frame.ietf_error_code;
+  MaybeUpdateAckTimeout();
+  visitor_->OnStopSendingFrame(frame);
+  return connected_;
+}
+
+class ReversePathValidationContext : public QuicPathValidationContext {
+ public:
+  ReversePathValidationContext(const QuicSocketAddress& self_address,
+                               const QuicSocketAddress& peer_address,
+                               const QuicSocketAddress& effective_peer_address,
+                               QuicConnection* connection)
+      : QuicPathValidationContext(self_address,
+                                  peer_address,
+                                  effective_peer_address),
+        connection_(connection) {}
+
+  QuicPacketWriter* WriterToUse() override { return connection_->writer(); }
+
+ private:
+  QuicConnection* connection_;
+};
+
+bool QuicConnection::OnPathChallengeFrame(const QuicPathChallengeFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_8, !connected_)
+      << "Processing PATH_CHALLENGE frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (has_path_challenge_in_current_packet_) {
+    // Only respond to the 1st PATH_CHALLENGE in the packet.
+    return true;
+  }
+  if (!validate_client_addresses_) {
+    return OnPathChallengeFrameInternal(frame);
+  }
+  QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 1, 6);
+  {
+    // TODO(danzh) inline OnPathChallengeFrameInternal() once
+    // validate_client_addresses_ is deprecated.
+    if (!OnPathChallengeFrameInternal(frame)) {
+      return false;
+    }
+  }
+  return connected_;
+}
+
+bool QuicConnection::OnPathChallengeFrameInternal(
+    const QuicPathChallengeFrame& frame) {
+  should_proactively_validate_peer_address_on_path_challenge_ = false;
+  // UpdatePacketContent() may start reverse path validation.
+  if (!UpdatePacketContent(PATH_CHALLENGE_FRAME)) {
+    return false;
+  }
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPathChallengeFrame(frame);
+  }
+
+  const QuicSocketAddress current_effective_peer_address =
+      GetEffectivePeerAddressFromCurrentPacket();
+  QuicConnectionId client_cid, server_cid;
+  FindOnPathConnectionIds(last_received_packet_info_.destination_address,
+                          current_effective_peer_address, &client_cid,
+                          &server_cid);
+  QuicPacketCreator::ScopedPeerAddressContext context(
+      &packet_creator_, last_received_packet_info_.source_address, client_cid,
+      server_cid, connection_migration_use_new_cid_);
+  if (should_proactively_validate_peer_address_on_path_challenge_) {
+    // Conditions to proactively validate peer address:
+    // The perspective is server
+    // The PATH_CHALLENGE is received on an unvalidated alternative path.
+    // The connection isn't validating migrated peer address, which is of
+    // higher prority.
+    QUIC_DVLOG(1) << "Proactively validate the effective peer address "
+                  << current_effective_peer_address;
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 2, 6);
+    ValidatePath(std::make_unique<ReversePathValidationContext>(
+                     default_path_.self_address,
+                     last_received_packet_info_.source_address,
+                     current_effective_peer_address, this),
+                 std::make_unique<ReversePathValidationResultDelegate>(
+                     this, peer_address()));
+  }
+  has_path_challenge_in_current_packet_ = true;
+  MaybeUpdateAckTimeout();
+  // Queue or send PATH_RESPONSE. Send PATH_RESPONSE to the source address of
+  // the current incoming packet, even if it's not the default path or the
+  // alternative path.
+  if (!SendPathResponse(frame.data_buffer,
+                        last_received_packet_info_.source_address,
+                        current_effective_peer_address)) {
+    QUIC_CODE_COUNT(quic_failed_to_send_path_response);
+  }
+  // TODO(b/150095588): change the stats to
+  // num_valid_path_challenge_received.
+  ++stats_.num_connectivity_probing_received;
+
+  // SendPathResponse() might cause connection to be closed.
+  return connected_;
+}
+
+bool QuicConnection::OnPathResponseFrame(const QuicPathResponseFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_9, !connected_)
+      << "Processing PATH_RESPONSE frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(PATH_RESPONSE_FRAME)) {
+    return false;
+  }
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPathResponseFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  if (use_path_validator_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 1, 4);
+    path_validator_.OnPathResponse(
+        frame.data_buffer, last_received_packet_info_.destination_address);
+  } else {
+    if (!transmitted_connectivity_probe_payload_ ||
+        *transmitted_connectivity_probe_payload_ != frame.data_buffer) {
+      // Is not for the probe we sent, ignore it.
+      return true;
+    }
+    // Have received the matching PATH RESPONSE, saved payload no longer valid.
+    transmitted_connectivity_probe_payload_ = nullptr;
+  }
+  return connected_;
+}
+
+bool QuicConnection::OnConnectionCloseFrame(
+    const QuicConnectionCloseFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_10, !connected_)
+      << "Processing CONNECTION_CLOSE frame when "
+         "connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a connection close frame was received, this is not a connectivity
+  // probe. A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(CONNECTION_CLOSE_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnConnectionCloseFrame(frame);
+  }
+  switch (frame.close_type) {
+    case GOOGLE_QUIC_CONNECTION_CLOSE:
+      QUIC_DLOG(INFO) << ENDPOINT << "Received ConnectionClose for connection: "
+                      << connection_id() << ", with error: "
+                      << QuicErrorCodeToString(frame.quic_error_code) << " ("
+                      << frame.error_details << ")";
+      break;
+    case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "Received Transport ConnectionClose for connection: "
+                      << connection_id() << ", with error: "
+                      << QuicErrorCodeToString(frame.quic_error_code) << " ("
+                      << frame.error_details << ")"
+                      << ", transport error code: "
+                      << QuicIetfTransportErrorCodeString(
+                             static_cast<QuicIetfTransportErrorCodes>(
+                                 frame.wire_error_code))
+                      << ", error frame type: "
+                      << frame.transport_close_frame_type;
+      break;
+    case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "Received Application ConnectionClose for connection: "
+                      << connection_id() << ", with error: "
+                      << QuicErrorCodeToString(frame.quic_error_code) << " ("
+                      << frame.error_details << ")"
+                      << ", application error code: " << frame.wire_error_code;
+      break;
+  }
+
+  if (frame.quic_error_code == QUIC_BAD_MULTIPATH_FLAG) {
+    QUIC_LOG_FIRST_N(ERROR, 10) << "Unexpected QUIC_BAD_MULTIPATH_FLAG error."
+                                << " last_received_header: " << last_header_
+                                << " encryption_level: " << encryption_level_;
+  }
+  TearDownLocalConnectionState(frame, ConnectionCloseSource::FROM_PEER);
+  return connected_;
+}
+
+bool QuicConnection::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_13, !connected_)
+      << "Processing MAX_STREAMS frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(MAX_STREAMS_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnMaxStreamsFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  return visitor_->OnMaxStreamsFrame(frame) && connected_;
+}
+
+bool QuicConnection::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_11, !connected_)
+      << "Processing STREAMS_BLOCKED frame when "
+         "connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(STREAMS_BLOCKED_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnStreamsBlockedFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  return visitor_->OnStreamsBlockedFrame(frame) && connected_;
+}
+
+bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_14, !connected_)
+      << "Processing GOAWAY frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a go away frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(GOAWAY_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnGoAwayFrame(frame);
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "GOAWAY_FRAME received with last good stream: "
+                  << frame.last_good_stream_id
+                  << " and error: " << QuicErrorCodeToString(frame.error_code)
+                  << " and reason: " << frame.reason_phrase;
+  MaybeUpdateAckTimeout();
+  visitor_->OnGoAway(frame);
+  return connected_;
+}
+
+bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_12, !connected_)
+      << "Processing WINDOW_UPDATE frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a window update frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(WINDOW_UPDATE_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnWindowUpdateFrame(
+        frame, idle_network_detector_.time_of_last_received_packet());
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "WINDOW_UPDATE_FRAME received " << frame;
+  MaybeUpdateAckTimeout();
+  visitor_->OnWindowUpdateFrame(frame);
+  return connected_;
+}
+
+void QuicConnection::OnClientConnectionIdAvailable() {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER);
+  if (!peer_issued_cid_manager_->HasUnusedConnectionId()) {
+    return;
+  }
+  if (default_path_.client_connection_id.IsEmpty()) {
+    // Count client connection ID patched onto the default path.
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 3,
+                                 6);
+    const QuicConnectionIdData* unused_cid_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    QUIC_DVLOG(1) << ENDPOINT << "Patch connection ID "
+                  << unused_cid_data->connection_id << " to default path";
+    default_path_.client_connection_id = unused_cid_data->connection_id;
+    default_path_.stateless_reset_token =
+        unused_cid_data->stateless_reset_token;
+    QUICHE_DCHECK(!packet_creator_.HasPendingFrames());
+    QUICHE_DCHECK(packet_creator_.GetDestinationConnectionId().IsEmpty());
+    packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
+    return;
+  }
+  if (alternative_path_.peer_address.IsInitialized() &&
+      alternative_path_.client_connection_id.IsEmpty()) {
+    // Count client connection ID patched onto the alternative path.
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 4,
+                                 6);
+    const QuicConnectionIdData* unused_cid_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    QUIC_DVLOG(1) << ENDPOINT << "Patch connection ID "
+                  << unused_cid_data->connection_id << " to alternative path";
+    alternative_path_.client_connection_id = unused_cid_data->connection_id;
+    alternative_path_.stateless_reset_token =
+        unused_cid_data->stateless_reset_token;
+  }
+}
+
+bool QuicConnection::ShouldSetRetransmissionAlarmOnPacketSent(
+    bool in_flight, EncryptionLevel level) const {
+  QUICHE_DCHECK(!sent_packet_manager_.simplify_set_retransmission_alarm());
+  if (!retransmission_alarm_->IsSet()) {
+    return true;
+  }
+  if (!in_flight) {
+    return false;
+  }
+
+  if (!SupportsMultiplePacketNumberSpaces()) {
+    return true;
+  }
+  // Before handshake gets confirmed, do not re-arm PTO timer on application
+  // data. Think about this scenario: on the client side, the CHLO gets
+  // acknowledged and the SHLO is not received yet. The PTO alarm is set when
+  // the CHLO acknowledge is received (and there is no in flight INITIAL
+  // packet). Re-arming PTO alarm on 0-RTT packet would keep postponing the PTO
+  // alarm.
+  return IsHandshakeConfirmed() || level == ENCRYPTION_INITIAL ||
+         level == ENCRYPTION_HANDSHAKE;
+}
+
+bool QuicConnection::OnNewConnectionIdFrameInner(
+    const QuicNewConnectionIdFrame& frame) {
+  if (peer_issued_cid_manager_ == nullptr) {
+    CloseConnection(
+        IETF_QUIC_PROTOCOL_VIOLATION,
+        "Receives NEW_CONNECTION_ID while peer uses zero length connection ID",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  std::string error_detail;
+  QuicErrorCode error =
+      peer_issued_cid_manager_->OnNewConnectionIdFrame(frame, &error_detail);
+  if (error != QUIC_NO_ERROR) {
+    CloseConnection(error, error_detail,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  if (perspective_ == Perspective::IS_SERVER) {
+    OnClientConnectionIdAvailable();
+  }
+  MaybeUpdateAckTimeout();
+  return true;
+}
+
+bool QuicConnection::OnNewConnectionIdFrame(
+    const QuicNewConnectionIdFrame& frame) {
+  QUICHE_DCHECK(version().HasIetfQuicFrames());
+  QUIC_BUG_IF(quic_bug_10511_13, !connected_)
+      << "Processing NEW_CONNECTION_ID frame when "
+         "connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(NEW_CONNECTION_ID_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnNewConnectionIdFrame(frame);
+  }
+  return OnNewConnectionIdFrameInner(frame);
+}
+
+bool QuicConnection::OnRetireConnectionIdFrame(
+    const QuicRetireConnectionIdFrame& frame) {
+  QUICHE_DCHECK(version().HasIetfQuicFrames());
+  QUIC_BUG_IF(quic_bug_10511_14, !connected_)
+      << "Processing RETIRE_CONNECTION_ID frame when "
+         "connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(RETIRE_CONNECTION_ID_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnRetireConnectionIdFrame(frame);
+  }
+  if (!connection_migration_use_new_cid_) {
+    // Do not respond to RetireConnectionId frame.
+    return true;
+  }
+  if (self_issued_cid_manager_ == nullptr) {
+    CloseConnection(
+        IETF_QUIC_PROTOCOL_VIOLATION,
+        "Receives RETIRE_CONNECTION_ID while new connection ID is never issued",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  std::string error_detail;
+  QuicErrorCode error = self_issued_cid_manager_->OnRetireConnectionIdFrame(
+      frame, sent_packet_manager_.GetPtoDelay(), &error_detail);
+  if (error != QUIC_NO_ERROR) {
+    CloseConnection(error, error_detail,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  // Count successfully received RETIRE_CONNECTION_ID frames.
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 5, 6);
+  MaybeUpdateAckTimeout();
+  return true;
+}
+
+bool QuicConnection::OnNewTokenFrame(const QuicNewTokenFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_15, !connected_)
+      << "Processing NEW_TOKEN frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(NEW_TOKEN_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnNewTokenFrame(frame);
+  }
+  if (perspective_ == Perspective::IS_SERVER) {
+    CloseConnection(QUIC_INVALID_NEW_TOKEN, "Server received new token frame.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  // NEW_TOKEN frame should insitgate ACKs.
+  MaybeUpdateAckTimeout();
+  visitor_->OnNewTokenReceived(frame.token);
+  return true;
+}
+
+bool QuicConnection::OnMessageFrame(const QuicMessageFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_16, !connected_)
+      << "Processing MESSAGE frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a message frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(MESSAGE_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnMessageFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  visitor_->OnMessageReceived(
+      absl::string_view(frame.data, frame.message_length));
+  return connected_;
+}
+
+bool QuicConnection::OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_15, !connected_)
+      << "Processing HANDSHAKE_DONE frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!version().UsesTls()) {
+    CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
+                    "Handshake done frame is unsupported",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER) {
+    CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
+                    "Server received handshake done frame.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  // Since a handshake done frame was received, this is not a connectivity
+  // probe. A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(HANDSHAKE_DONE_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnHandshakeDoneFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  visitor_->OnHandshakeDoneReceived();
+  return connected_;
+}
+
+bool QuicConnection::OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_16, !connected_)
+      << "Processing ACK_FREQUENCY frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnAckFrequencyFrame(frame);
+  }
+  if (!UpdatePacketContent(ACK_FREQUENCY_FRAME)) {
+    return false;
+  }
+
+  if (!can_receive_ack_frequency_frame_) {
+    QUIC_LOG_EVERY_N_SEC(ERROR, 120) << "Get unexpected AckFrequencyFrame.";
+    return false;
+  }
+  if (auto packet_number_space =
+          QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_) ==
+          APPLICATION_DATA) {
+    uber_received_packet_manager_.OnAckFrequencyFrame(frame);
+  } else {
+    QUIC_LOG_EVERY_N_SEC(ERROR, 120)
+        << "Get AckFrequencyFrame in packet number space "
+        << packet_number_space;
+  }
+  MaybeUpdateAckTimeout();
+  return true;
+}
+
+bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_17, !connected_)
+      << "Processing BLOCKED frame when connection is closed. Last frame was "
+      << most_recent_frame_type_;
+
+  // Since a blocked frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(BLOCKED_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnBlockedFrame(frame);
+  }
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "BLOCKED_FRAME received for stream: " << frame.stream_id;
+  MaybeUpdateAckTimeout();
+  visitor_->OnBlockedFrame(frame);
+  stats_.blocked_frames_received++;
+  return connected_;
+}
+
+void QuicConnection::OnPacketComplete() {
+  // Don't do anything if this packet closed the connection.
+  if (!connected_) {
+    ClearLastFrames();
+    return;
+  }
+
+  if (IsCurrentPacketConnectivityProbing()) {
+    QUICHE_DCHECK(!version().HasIetfQuicFrames());
+    ++stats_.num_connectivity_probing_received;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Got"
+                << (SupportsMultiplePacketNumberSpaces()
+                        ? (" " + EncryptionLevelToString(
+                                     last_decrypted_packet_level_))
+                        : "")
+                << " packet " << last_header_.packet_number << " for "
+                << GetServerConnectionIdAsRecipient(last_header_, perspective_);
+
+  QUIC_DLOG_IF(INFO, current_packet_content_ == SECOND_FRAME_IS_PADDING)
+      << ENDPOINT << "Received a padded PING packet. is_probing: "
+      << IsCurrentPacketConnectivityProbing();
+
+  if (!version().HasIetfQuicFrames()) {
+    MaybeRespondToConnectivityProbingOrMigration();
+  }
+
+  current_effective_peer_migration_type_ = NO_CHANGE;
+
+  // For IETF QUIC, it is guaranteed that TLS will give connection the
+  // corresponding write key before read key. In other words, connection should
+  // never process a packet while an ACK for it cannot be encrypted.
+  if (!should_last_packet_instigate_acks_) {
+    uber_received_packet_manager_.MaybeUpdateAckTimeout(
+        should_last_packet_instigate_acks_, last_decrypted_packet_level_,
+        last_header_.packet_number, last_received_packet_info_.receipt_time,
+        clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
+  }
+
+  ClearLastFrames();
+  CloseIfTooManyOutstandingSentPackets();
+}
+
+void QuicConnection::MaybeRespondToConnectivityProbingOrMigration() {
+  QUICHE_DCHECK(!version().HasIetfQuicFrames());
+  if (IsCurrentPacketConnectivityProbing()) {
+    visitor_->OnPacketReceived(last_received_packet_info_.destination_address,
+                               last_received_packet_info_.source_address,
+                               /*is_connectivity_probe=*/true);
+    return;
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    // This node is a client, notify that a speculative connectivity probing
+    // packet has been received anyway.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received a speculative connectivity probing packet for "
+                  << GetServerConnectionIdAsRecipient(last_header_,
+                                                      perspective_)
+                  << " from ip:port: "
+                  << last_received_packet_info_.source_address.ToString()
+                  << " to ip:port: "
+                  << last_received_packet_info_.destination_address.ToString();
+    visitor_->OnPacketReceived(last_received_packet_info_.destination_address,
+                               last_received_packet_info_.source_address,
+                               /*is_connectivity_probe=*/false);
+    return;
+  }
+}
+
+bool QuicConnection::IsValidStatelessResetToken(
+    const StatelessResetToken& token) const {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  return default_path_.stateless_reset_token.has_value() &&
+         QuicUtils::AreStatelessResetTokensEqual(
+             token, *default_path_.stateless_reset_token);
+}
+
+void QuicConnection::OnAuthenticatedIetfStatelessResetPacket(
+    const QuicIetfStatelessResetPacket& /*packet*/) {
+  // TODO(fayang): Add OnAuthenticatedIetfStatelessResetPacket to
+  // debug_visitor_.
+  QUICHE_DCHECK(version().HasIetfInvariantHeader());
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+
+  if (use_path_validator_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 4, 4);
+    if (!IsDefaultPath(last_received_packet_info_.destination_address,
+                       last_received_packet_info_.source_address)) {
+      // This packet is received on a probing path. Do not close connection.
+      if (IsAlternativePath(last_received_packet_info_.destination_address,
+                            GetEffectivePeerAddressFromCurrentPacket())) {
+        QUIC_BUG_IF(quic_bug_12714_18, alternative_path_.validated)
+            << "STATELESS_RESET received on alternate path after it's "
+               "validated.";
+        path_validator_.CancelPathValidation();
+      } else {
+        QUIC_BUG(quic_bug_10511_17)
+            << "Received Stateless Reset on unknown socket.";
+      }
+      return;
+    }
+  } else if (!visitor_->ValidateStatelessReset(
+                 last_received_packet_info_.destination_address,
+                 last_received_packet_info_.source_address)) {
+    // This packet is received on a probing path. Do not close connection.
+    return;
+  }
+
+  const std::string error_details = "Received stateless reset.";
+  QUIC_CODE_COUNT(quic_tear_down_local_connection_on_stateless_reset);
+  TearDownLocalConnectionState(QUIC_PUBLIC_RESET, NO_IETF_QUIC_ERROR,
+                               error_details, ConnectionCloseSource::FROM_PEER);
+}
+
+void QuicConnection::OnKeyUpdate(KeyUpdateReason reason) {
+  QUICHE_DCHECK(support_key_update_for_connection_);
+  QUIC_DLOG(INFO) << ENDPOINT << "Key phase updated for " << reason;
+
+  lowest_packet_sent_in_current_key_phase_.Clear();
+  stats_.key_update_count++;
+
+  // If another key update triggers while the previous
+  // discard_previous_one_rtt_keys_alarm_ hasn't fired yet, cancel it since the
+  // old keys would already be discarded.
+  discard_previous_one_rtt_keys_alarm_->Cancel();
+
+  visitor_->OnKeyUpdate(reason);
+}
+
+void QuicConnection::OnDecryptedFirstPacketInKeyPhase() {
+  QUIC_DLOG(INFO) << ENDPOINT << "OnDecryptedFirstPacketInKeyPhase";
+  // An endpoint SHOULD retain old read keys for no more than three times the
+  // PTO after having received a packet protected using the new keys. After this
+  // period, old read keys and their corresponding secrets SHOULD be discarded.
+  //
+  // Note that this will cause an unnecessary
+  // discard_previous_one_rtt_keys_alarm_ on the first packet in the 1RTT
+  // encryption level, but this is harmless.
+  discard_previous_one_rtt_keys_alarm_->Set(
+      clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay() * 3);
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicConnection::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  QUIC_DLOG(INFO) << ENDPOINT << "AdvanceKeysAndCreateCurrentOneRttDecrypter";
+  return visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter> QuicConnection::CreateCurrentOneRttEncrypter() {
+  QUIC_DLOG(INFO) << ENDPOINT << "CreateCurrentOneRttEncrypter";
+  return visitor_->CreateCurrentOneRttEncrypter();
+}
+
+void QuicConnection::ClearLastFrames() {
+  should_last_packet_instigate_acks_ = false;
+}
+
+void QuicConnection::CloseIfTooManyOutstandingSentPackets() {
+  // This occurs if we don't discard old packets we've seen fast enough. It's
+  // possible largest observed is less than leaset unacked.
+  const bool should_close =
+      sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
+      sent_packet_manager_.GetLargestSentPacket() >
+          sent_packet_manager_.GetLeastUnacked() + max_tracked_packets_;
+
+  if (should_close) {
+    CloseConnection(
+        QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS,
+        absl::StrCat("More than ", max_tracked_packets_,
+                     " outstanding, least_unacked: ",
+                     sent_packet_manager_.GetLeastUnacked().ToUint64(),
+                     ", packets_processed: ", stats_.packets_processed,
+                     ", last_decrypted_packet_level: ",
+                     EncryptionLevelToString(last_decrypted_packet_level_)),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }
+}
+
+const QuicFrame QuicConnection::GetUpdatedAckFrame() {
+  QUICHE_DCHECK(!uber_received_packet_manager_.IsAckFrameEmpty(
+      QuicUtils::GetPacketNumberSpace(encryption_level_)))
+      << "Try to retrieve an empty ACK frame";
+  return uber_received_packet_manager_.GetUpdatedAckFrame(
+      QuicUtils::GetPacketNumberSpace(encryption_level_),
+      clock_->ApproximateNow());
+}
+
+void QuicConnection::PopulateStopWaitingFrame(
+    QuicStopWaitingFrame* stop_waiting) {
+  stop_waiting->least_unacked = GetLeastUnacked();
+}
+
+QuicPacketNumber QuicConnection::GetLeastUnacked() const {
+  return sent_packet_manager_.GetLeastUnacked();
+}
+
+bool QuicConnection::HandleWriteBlocked() {
+  if (!writer_->IsWriteBlocked()) {
+    return false;
+  }
+
+  visitor_->OnWriteBlocked();
+  return true;
+}
+
+void QuicConnection::MaybeSendInResponseToPacket() {
+  if (!connected_) {
+    return;
+  }
+
+  // If the writer is blocked, don't attempt to send packets now or in the send
+  // alarm. When the writer unblocks, OnCanWrite() will be called for this
+  // connection to send.
+  if (HandleWriteBlocked()) {
+    return;
+  }
+
+  // Now that we have received an ack, we might be able to send packets which
+  // are queued locally, or drain streams which are blocked.
+  if (defer_send_in_response_to_packets_) {
+    send_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
+  } else {
+    WriteIfNotBlocked();
+  }
+}
+
+void QuicConnection::MaybeActivateLegacyVersionEncapsulation() {
+  if (!legacy_version_encapsulation_enabled_) {
+    return;
+  }
+  QUICHE_DCHECK(!legacy_version_encapsulation_in_progress_);
+  QUIC_BUG_IF(quic_bug_12714_19, !packet_creator_.CanSetMaxPacketLength())
+      << "Cannot activate Legacy Version Encapsulation mid-packet";
+  QUIC_BUG_IF(quic_bug_12714_20, coalesced_packet_.length() != 0u)
+      << "Cannot activate Legacy Version Encapsulation mid-coalesced-packet";
+  legacy_version_encapsulation_in_progress_ = true;
+  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+}
+void QuicConnection::MaybeDisactivateLegacyVersionEncapsulation() {
+  if (!legacy_version_encapsulation_in_progress_) {
+    return;
+  }
+  // Flush any remaining packet before disactivating encapsulation.
+  packet_creator_.FlushCurrentPacket();
+  QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
+  legacy_version_encapsulation_in_progress_ = false;
+  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+}
+
+size_t QuicConnection::SendCryptoData(EncryptionLevel level,
+                                      size_t write_length,
+                                      QuicStreamOffset offset) {
+  if (write_length == 0) {
+    QUIC_BUG(quic_bug_10511_18) << "Attempt to send empty crypto frame";
+    return 0;
+  }
+  if (level == ENCRYPTION_INITIAL) {
+    MaybeActivateLegacyVersionEncapsulation();
+  }
+  size_t consumed_length;
+  {
+    ScopedPacketFlusher flusher(this);
+    consumed_length =
+        packet_creator_.ConsumeCryptoData(level, write_length, offset);
+  }  // Added scope ensures packets are flushed before continuing.
+  MaybeDisactivateLegacyVersionEncapsulation();
+  return consumed_length;
+}
+
+QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
+                                                size_t write_length,
+                                                QuicStreamOffset offset,
+                                                StreamSendingState state) {
+  if (state == NO_FIN && write_length == 0) {
+    QUIC_BUG(quic_bug_10511_19) << "Attempt to send empty stream frame";
+    return QuicConsumedData(0, false);
+  }
+
+  if (packet_creator_.encryption_level() == ENCRYPTION_INITIAL &&
+      QuicUtils::IsCryptoStreamId(transport_version(), id)) {
+    MaybeActivateLegacyVersionEncapsulation();
+  }
+  if (perspective_ == Perspective::IS_SERVER &&
+      version().CanSendCoalescedPackets() && !IsHandshakeConfirmed()) {
+    if (in_on_retransmission_time_out_ &&
+        coalesced_packet_.NumberOfPackets() == 0u) {
+      // PTO fires while handshake is not confirmed. Do not preempt handshake
+      // data with stream data.
+      QUIC_CODE_COUNT(quic_try_to_send_half_rtt_data_when_pto_fires);
+      return QuicConsumedData(0, false);
+    }
+    if (coalesced_packet_.ContainsPacketOfEncryptionLevel(ENCRYPTION_INITIAL) &&
+        coalesced_packet_.NumberOfPackets() == 1u) {
+      // Handshake is not confirmed yet, if there is only an initial packet in
+      // the coalescer, try to bundle an ENCRYPTION_HANDSHAKE packet before
+      // sending stream data.
+      sent_packet_manager_.RetransmitDataOfSpaceIfAny(HANDSHAKE_DATA);
+    }
+  }
+  QuicConsumedData consumed_data(0, false);
+  {
+    // Opportunistically bundle an ack with every outgoing packet.
+    // Particularly, we want to bundle with handshake packets since we don't
+    // know which decrypter will be used on an ack packet following a handshake
+    // 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);
+    consumed_data =
+        packet_creator_.ConsumeData(id, write_length, offset, state);
+  }  // Added scope ensures packets are flushed before continuing.
+  MaybeDisactivateLegacyVersionEncapsulation();
+  return consumed_data;
+}
+
+bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
+  if (SupportsMultiplePacketNumberSpaces() &&
+      (encryption_level_ == ENCRYPTION_INITIAL ||
+       encryption_level_ == ENCRYPTION_HANDSHAKE) &&
+      frame.type != PING_FRAME) {
+    // Allow PING frame to be sent without APPLICATION key. For example, when
+    // anti-amplification limit is used, client needs to send something to avoid
+    // handshake deadlock.
+    QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame
+                  << " at encryption level: " << encryption_level_;
+    return false;
+  }
+  ScopedPacketFlusher flusher(this);
+  const bool consumed =
+      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_creator_.FlushCurrentPacket();
+    stats_.ping_frames_sent++;
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnPingSent();
+    }
+  }
+  if (frame.type == BLOCKED_FRAME) {
+    stats_.blocked_frames_sent++;
+  }
+  return true;
+}
+
+void QuicConnection::OnStreamReset(QuicStreamId id,
+                                   QuicRstStreamErrorCode error) {
+  if (error == QUIC_STREAM_NO_ERROR) {
+    // All data for streams which are reset with QUIC_STREAM_NO_ERROR must
+    // be received by the peer.
+    return;
+  }
+  // Flush stream frames of reset stream.
+  if (packet_creator_.HasPendingStreamFramesOfStream(id)) {
+    ScopedPacketFlusher flusher(this);
+    packet_creator_.FlushCurrentPacket();
+  }
+  // TODO(ianswett): Consider checking for 3 RTOs when the last stream is
+  // cancelled as well.
+}
+
+const QuicConnectionStats& QuicConnection::GetStats() {
+  const RttStats* rtt_stats = sent_packet_manager_.GetRttStats();
+
+  // Update rtt and estimated bandwidth.
+  QuicTime::Delta min_rtt = rtt_stats->min_rtt();
+  if (min_rtt.IsZero()) {
+    // If min RTT has not been set, use initial RTT instead.
+    min_rtt = rtt_stats->initial_rtt();
+  }
+  stats_.min_rtt_us = min_rtt.ToMicroseconds();
+
+  QuicTime::Delta srtt = rtt_stats->SmoothedOrInitialRtt();
+  stats_.srtt_us = srtt.ToMicroseconds();
+
+  stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate();
+  sent_packet_manager_.GetSendAlgorithm()->PopulateConnectionStats(&stats_);
+  stats_.egress_mtu = long_term_mtu_;
+  stats_.ingress_mtu = largest_received_packet_size_;
+  return stats_;
+}
+
+void QuicConnection::OnCoalescedPacket(const QuicEncryptedPacket& packet) {
+  QueueCoalescedPacket(packet);
+}
+
+void QuicConnection::OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                                           EncryptionLevel decryption_level,
+                                           bool has_decryption_key) {
+  QUIC_DVLOG(1) << ENDPOINT << "Received undecryptable packet of length "
+                << packet.length() << " with"
+                << (has_decryption_key ? "" : "out") << " key at level "
+                << decryption_level
+                << " while connection is at encryption level "
+                << encryption_level_;
+  QUICHE_DCHECK(EncryptionLevelIsValid(decryption_level));
+  if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
+    ++stats_.undecryptable_packets_received_before_handshake_complete;
+  }
+
+  const bool should_enqueue =
+      ShouldEnqueueUnDecryptablePacket(decryption_level, has_decryption_key);
+  if (should_enqueue) {
+    QueueUndecryptablePacket(packet, decryption_level);
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnUndecryptablePacket(decryption_level,
+                                          /*dropped=*/!should_enqueue);
+  }
+
+  if (has_decryption_key) {
+    stats_.num_failed_authentication_packets_received++;
+    if (version().UsesTls()) {
+      // Should always be non-null if has_decryption_key is true.
+      QUICHE_DCHECK(framer_.GetDecrypter(decryption_level));
+      const QuicPacketCount integrity_limit =
+          framer_.GetDecrypter(decryption_level)->GetIntegrityLimit();
+      QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD integrity limits:"
+                    << " num_failed_authentication_packets_received="
+                    << stats_.num_failed_authentication_packets_received
+                    << " integrity_limit=" << integrity_limit;
+      if (stats_.num_failed_authentication_packets_received >=
+          integrity_limit) {
+        const std::string error_details = absl::StrCat(
+            "decrypter integrity limit reached:"
+            " num_failed_authentication_packets_received=",
+            stats_.num_failed_authentication_packets_received,
+            " integrity_limit=", integrity_limit);
+        CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      }
+    }
+  }
+
+  if (version().UsesTls() && perspective_ == Perspective::IS_SERVER &&
+      decryption_level == ENCRYPTION_ZERO_RTT && !has_decryption_key &&
+      had_zero_rtt_decrypter_) {
+    QUIC_CODE_COUNT_N(
+        quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 1,
+        3);
+    stats_
+        .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter++;
+  }
+}
+
+bool QuicConnection::ShouldEnqueueUnDecryptablePacket(
+    EncryptionLevel decryption_level, bool has_decryption_key) const {
+  if (has_decryption_key) {
+    // We already have the key for this decryption level, therefore no
+    // future keys will allow it be decrypted.
+    return false;
+  }
+  if (IsHandshakeComplete()) {
+    // We do not expect to install any further keys.
+    return false;
+  }
+  if (undecryptable_packets_.size() >= max_undecryptable_packets_) {
+    // We do not queue more than max_undecryptable_packets_ packets.
+    return false;
+  }
+  if (version().KnowsWhichDecrypterToUse() &&
+      decryption_level == ENCRYPTION_INITIAL) {
+    // When the corresponding decryption key is not available, all
+    // non-Initial packets should be buffered until the handshake is complete.
+    return false;
+  }
+  if (perspective_ == Perspective::IS_CLIENT && version().UsesTls() &&
+      decryption_level == ENCRYPTION_ZERO_RTT) {
+    // Only clients send Zero RTT packets in IETF QUIC.
+    QUIC_PEER_BUG(quic_peer_bug_client_received_zero_rtt)
+        << "Client received a Zero RTT packet, not buffering.";
+    return false;
+  }
+  return true;
+}
+
+std::string QuicConnection::UndecryptablePacketsInfo() const {
+  std::string info = absl::StrCat(
+      "num_undecryptable_packets: ", undecryptable_packets_.size(), " {");
+  for (const auto& packet : undecryptable_packets_) {
+    absl::StrAppend(&info, "[",
+                    EncryptionLevelToString(packet.encryption_level), ", ",
+                    packet.packet->length(), "]");
+  }
+  absl::StrAppend(&info, "}");
+  return info;
+}
+
+void QuicConnection::MaybeUpdatePacketCreatorMaxPacketLengthAndPadding() {
+  QuicByteCount max_packet_length = GetLimitedMaxPacketSize(long_term_mtu_);
+  if (legacy_version_encapsulation_in_progress_) {
+    QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
+    const QuicByteCount minimum_overhead =
+        QuicLegacyVersionEncapsulator::GetMinimumOverhead(
+            legacy_version_encapsulation_sni_);
+    if (max_packet_length < minimum_overhead) {
+      QUIC_BUG(quic_bug_10511_20)
+          << "Cannot apply Legacy Version Encapsulation overhead because "
+          << "max_packet_length " << max_packet_length << " < minimum_overhead "
+          << minimum_overhead;
+      legacy_version_encapsulation_in_progress_ = false;
+      legacy_version_encapsulation_enabled_ = false;
+      MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+      return;
+    }
+    max_packet_length -= minimum_overhead;
+  }
+  packet_creator_.SetMaxPacketLength(max_packet_length);
+}
+
+void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
+                                      const QuicSocketAddress& peer_address,
+                                      const QuicReceivedPacket& packet) {
+  if (!connected_) {
+    return;
+  }
+  QUIC_DVLOG(2) << ENDPOINT << "Received encrypted " << packet.length()
+                << " bytes:" << std::endl
+                << quiche::QuicheTextUtils::HexDump(
+                       absl::string_view(packet.data(), packet.length()));
+  QUIC_BUG_IF(quic_bug_12714_21, current_packet_data_ != nullptr)
+      << "ProcessUdpPacket must not be called while processing a packet.";
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
+  }
+  last_received_packet_info_ =
+      ReceivedPacketInfo(self_address, peer_address, packet.receipt_time());
+  last_size_ = packet.length();
+  current_packet_data_ = packet.data();
+
+  if (!default_path_.self_address.IsInitialized()) {
+    default_path_.self_address = last_received_packet_info_.destination_address;
+  }
+
+  if (!direct_peer_address_.IsInitialized()) {
+    UpdatePeerAddress(last_received_packet_info_.source_address);
+  }
+
+  if (!default_path_.peer_address.IsInitialized()) {
+    const QuicSocketAddress effective_peer_addr =
+        GetEffectivePeerAddressFromCurrentPacket();
+
+    // The default path peer_address must be initialized at the beginning of the
+    // first packet processed(here). If effective_peer_addr is uninitialized,
+    // just set effective_peer_address_ to the direct peer address.
+    default_path_.peer_address = effective_peer_addr.IsInitialized()
+                                     ? effective_peer_addr
+                                     : direct_peer_address_;
+  }
+
+  stats_.bytes_received += packet.length();
+  ++stats_.packets_received;
+  if (!count_bytes_on_alternative_path_separately_) {
+    if (EnforceAntiAmplificationLimit()) {
+      default_path_.bytes_received_before_address_validation += last_size_;
+    }
+  } else if (IsDefaultPath(last_received_packet_info_.destination_address,
+                           last_received_packet_info_.source_address) &&
+             EnforceAntiAmplificationLimit()) {
+    QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 1, 5);
+    last_received_packet_info_.received_bytes_counted = true;
+    default_path_.bytes_received_before_address_validation += last_size_;
+  }
+
+  // Ensure the time coming from the packet reader is within 2 minutes of now.
+  if (std::abs((packet.receipt_time() - clock_->ApproximateNow()).ToSeconds()) >
+      2 * 60) {
+    QUIC_BUG(quic_bug_10511_21)
+        << "Packet receipt time:" << packet.receipt_time().ToDebuggingValue()
+        << " too far from current time:"
+        << clock_->ApproximateNow().ToDebuggingValue();
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "time of last received packet: "
+                << packet.receipt_time().ToDebuggingValue() << " from peer "
+                << last_received_packet_info_.source_address;
+
+  ScopedPacketFlusher flusher(this);
+  if (!framer_.ProcessPacket(packet)) {
+    // If we are unable to decrypt this packet, it might be
+    // because the CHLO or SHLO packet was lost.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Unable to process packet.  Last packet processed: "
+                  << last_header_.packet_number;
+    current_packet_data_ = nullptr;
+    is_current_packet_connectivity_probing_ = false;
+
+    MaybeProcessCoalescedPackets();
+    return;
+  }
+
+  ++stats_.packets_processed;
+
+  QUIC_DLOG_IF(INFO, active_effective_peer_migration_type_ != NO_CHANGE)
+      << "sent_packet_manager_.GetLargestObserved() = "
+      << sent_packet_manager_.GetLargestObserved()
+      << ", highest_packet_sent_before_effective_peer_migration_ = "
+      << highest_packet_sent_before_effective_peer_migration_;
+  if (!validate_client_addresses_ &&
+      active_effective_peer_migration_type_ != NO_CHANGE &&
+      sent_packet_manager_.GetLargestObserved().IsInitialized() &&
+      (!highest_packet_sent_before_effective_peer_migration_.IsInitialized() ||
+       sent_packet_manager_.GetLargestObserved() >
+           highest_packet_sent_before_effective_peer_migration_)) {
+    if (perspective_ == Perspective::IS_SERVER) {
+      OnEffectivePeerMigrationValidated();
+    }
+  }
+
+  if (!MaybeProcessCoalescedPackets()) {
+    MaybeProcessUndecryptablePackets();
+    MaybeSendInResponseToPacket();
+  }
+  SetPingAlarm();
+  RetirePeerIssuedConnectionIdsNoLongerOnPath();
+  current_packet_data_ = nullptr;
+  is_current_packet_connectivity_probing_ = false;
+}
+
+void QuicConnection::OnBlockedWriterCanWrite() {
+  writer_->SetWritable();
+  OnCanWrite();
+}
+
+void QuicConnection::OnCanWrite() {
+  if (!connected_) {
+    return;
+  }
+  if (writer_->IsWriteBlocked()) {
+    const std::string error_details =
+        "Writer is blocked while calling OnCanWrite.";
+    QUIC_BUG(quic_bug_10511_22) << ENDPOINT << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  ScopedPacketFlusher flusher(this);
+
+  WriteQueuedPackets();
+  const QuicTime ack_timeout =
+      uber_received_packet_manager_.GetEarliestAckTimeout();
+  if (ack_timeout.IsInitialized() && ack_timeout <= clock_->ApproximateNow()) {
+    // Send an ACK now because either 1) we were write blocked when we last
+    // tried to send an ACK, or 2) both ack alarm and send alarm were set to
+    // go off together.
+    if (SupportsMultiplePacketNumberSpaces()) {
+      SendAllPendingAcks();
+    } else {
+      SendAck();
+    }
+  }
+
+  // Sending queued packets may have caused the socket to become write blocked,
+  // or the congestion manager to prohibit sending.
+  if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+    return;
+  }
+
+  // Tell the session it can write.
+  visitor_->OnCanWrite();
+
+  // After the visitor writes, it may have caused the socket to become write
+  // blocked or the congestion manager to prohibit sending, so check again.
+  if (visitor_->WillingAndAbleToWrite() && !send_alarm_->IsSet() &&
+      CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+    // We're not write blocked, but some data wasn't written. Register for
+    // 'immediate' resumption so we'll keep writing after other connections.
+    send_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicConnection::WriteIfNotBlocked() {
+  if (framer().is_processing_packet()) {
+    QUIC_BUG(connection_write_mid_packet_processing)
+        << ENDPOINT << "Tried to write in mid of packet processing";
+    return;
+  }
+  if (!HandleWriteBlocked()) {
+    OnCanWrite();
+  }
+}
+
+void QuicConnection::MaybeClearQueuedPacketsOnPathChange() {
+  if (connection_migration_use_new_cid_ &&
+      peer_issued_cid_manager_ != nullptr && HasQueuedPackets()) {
+    // Discard packets serialized with the connection ID on the old code path.
+    // It is possible to clear queued packets only if connection ID changes.
+    // However, the case where connection ID is unchanged and queued packets are
+    // non-empty is quite rare.
+    ClearQueuedPackets();
+  }
+}
+
+void QuicConnection::ReplaceInitialServerConnectionId(
+    const QuicConnectionId& new_server_connection_id) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
+  if (version().HasIetfQuicFrames()) {
+    if (new_server_connection_id.IsEmpty()) {
+      peer_issued_cid_manager_ = nullptr;
+    } else {
+      if (peer_issued_cid_manager_ != nullptr) {
+        QUIC_BUG_IF(quic_bug_12714_22,
+                    !peer_issued_cid_manager_->IsConnectionIdActive(
+                        default_path_.server_connection_id))
+            << "Connection ID replaced header is no longer active. old id: "
+            << default_path_.server_connection_id
+            << " new_id: " << new_server_connection_id;
+        peer_issued_cid_manager_->ReplaceConnectionId(
+            default_path_.server_connection_id, new_server_connection_id);
+      } else {
+        peer_issued_cid_manager_ =
+            std::make_unique<QuicPeerIssuedConnectionIdManager>(
+                kMinNumOfActiveConnectionIds, new_server_connection_id, clock_,
+                alarm_factory_, this, context());
+      }
+    }
+  }
+  default_path_.server_connection_id = new_server_connection_id;
+  packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
+}
+
+void QuicConnection::FindMatchingOrNewClientConnectionIdOrToken(
+    const PathState& default_path, const PathState& alternative_path,
+    const QuicConnectionId& server_connection_id,
+    QuicConnectionId* client_connection_id,
+    absl::optional<StatelessResetToken>* stateless_reset_token) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER);
+  if (peer_issued_cid_manager_ == nullptr ||
+      server_connection_id == default_path.server_connection_id) {
+    *client_connection_id = default_path.client_connection_id;
+    *stateless_reset_token = default_path.stateless_reset_token;
+    return;
+  }
+  if (server_connection_id == alternative_path_.server_connection_id) {
+    *client_connection_id = alternative_path.client_connection_id;
+    *stateless_reset_token = alternative_path.stateless_reset_token;
+    return;
+  }
+  if (!connection_migration_use_new_cid_) {
+    QUIC_BUG(quic_bug_46004) << "Cannot find matching connection ID.";
+    return;
+  }
+  auto* connection_id_data =
+      peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+  if (connection_id_data == nullptr) {
+    return;
+  }
+  *client_connection_id = connection_id_data->connection_id;
+  *stateless_reset_token = connection_id_data->stateless_reset_token;
+}
+
+bool QuicConnection::FindOnPathConnectionIds(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    QuicConnectionId* client_connection_id,
+    QuicConnectionId* server_connection_id) const {
+  if (IsDefaultPath(self_address, peer_address)) {
+    *client_connection_id = default_path_.client_connection_id,
+    *server_connection_id = default_path_.server_connection_id;
+    return true;
+  }
+  if (IsAlternativePath(self_address, peer_address)) {
+    *client_connection_id = alternative_path_.client_connection_id,
+    *server_connection_id = alternative_path_.server_connection_id;
+    return true;
+  }
+  return false;
+}
+
+void QuicConnection::SetDefaultPathState(PathState new_path_state) {
+  default_path_ = std::move(new_path_state);
+  if (connection_migration_use_new_cid_) {
+    packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
+    packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
+  }
+}
+
+bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
+  if (perspective_ == Perspective::IS_CLIENT && version().HasIetfQuicFrames() &&
+      direct_peer_address_.IsInitialized() &&
+      last_received_packet_info_.source_address.IsInitialized() &&
+      direct_peer_address_ != last_received_packet_info_.source_address &&
+      !visitor_->IsKnownServerAddress(
+          last_received_packet_info_.source_address)) {
+    // TODO(haoyuewang) Revisit this when preferred_address transport parameter
+    // is used on the client side.
+    // Discard packets received from unseen server addresses.
+    return false;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER &&
+      default_path_.self_address.IsInitialized() &&
+      last_received_packet_info_.destination_address.IsInitialized() &&
+      default_path_.self_address !=
+          last_received_packet_info_.destination_address) {
+    // Allow change between pure IPv4 and equivalent mapped IPv4 address.
+    if (default_path_.self_address.port() !=
+            last_received_packet_info_.destination_address.port() ||
+        default_path_.self_address.host().Normalized() !=
+            last_received_packet_info_.destination_address.host()
+                .Normalized()) {
+      if (!visitor_->AllowSelfAddressChange()) {
+        const std::string error_details = absl::StrCat(
+            "Self address migration is not supported at the server, current "
+            "address: ",
+            default_path_.self_address.ToString(),
+            ", received packet address: ",
+            last_received_packet_info_.destination_address.ToString(),
+            ", size: ", last_size_,
+            ", packet number: ", header.packet_number.ToString(),
+            ", encryption level: ",
+            EncryptionLevelToString(last_decrypted_packet_level_));
+        if (GetQuicReloadableFlag(
+                quic_drop_packets_with_changed_server_address)) {
+          QUIC_LOG_EVERY_N_SEC(INFO, 100) << error_details;
+          QUIC_CODE_COUNT(quic_dropped_packets_with_changed_server_address);
+          return false;
+        }
+        QUIC_PEER_BUG(Server self address change) << error_details;
+        CloseConnection(QUIC_ERROR_MIGRATING_ADDRESS, error_details,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return false;
+      }
+    }
+    default_path_.self_address = last_received_packet_info_.destination_address;
+  }
+
+  if (PacketCanReplaceServerConnectionId(header, perspective_) &&
+      default_path_.server_connection_id != header.source_connection_id) {
+    QUICHE_DCHECK_EQ(header.long_packet_type, INITIAL);
+    if (server_connection_id_replaced_by_initial_) {
+      QUIC_DLOG(ERROR) << ENDPOINT << "Refusing to replace connection ID "
+                       << default_path_.server_connection_id << " with "
+                       << header.source_connection_id;
+      return false;
+    }
+    server_connection_id_replaced_by_initial_ = true;
+    QUIC_DLOG(INFO) << ENDPOINT << "Replacing connection ID "
+                    << default_path_.server_connection_id << " with "
+                    << header.source_connection_id;
+    if (!original_destination_connection_id_.has_value()) {
+      original_destination_connection_id_ = default_path_.server_connection_id;
+    }
+    ReplaceInitialServerConnectionId(header.source_connection_id);
+  }
+
+  if (!ValidateReceivedPacketNumber(header.packet_number)) {
+    return false;
+  }
+
+  if (!version_negotiated_) {
+    if (perspective_ == Perspective::IS_CLIENT) {
+      QUICHE_DCHECK(!header.version_flag || header.form != GOOGLE_QUIC_PACKET);
+      if (!version().HasIetfInvariantHeader()) {
+        // If the client gets a packet without the version flag from the server
+        // it should stop sending version since the version negotiation is done.
+        // IETF QUIC stops sending version once encryption level switches to
+        // forward secure.
+        packet_creator_.StopSendingVersion();
+      }
+      version_negotiated_ = true;
+      OnSuccessfulVersionNegotiation();
+    }
+  }
+
+  if (last_size_ > largest_received_packet_size_) {
+    largest_received_packet_size_ = last_size_;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER &&
+      encryption_level_ == ENCRYPTION_INITIAL &&
+      last_size_ > packet_creator_.max_packet_length()) {
+    if (GetQuicFlag(FLAGS_quic_use_lower_server_response_mtu_for_test)) {
+      SetMaxPacketLength(std::min(last_size_, QuicByteCount(1250)));
+    } else {
+      SetMaxPacketLength(last_size_);
+    }
+  }
+  return true;
+}
+
+bool QuicConnection::ValidateReceivedPacketNumber(
+    QuicPacketNumber packet_number) {
+  // If this packet has already been seen, or the sender has told us that it
+  // will not be retransmitted, then stop processing the packet.
+  if (!uber_received_packet_manager_.IsAwaitingPacket(
+          last_decrypted_packet_level_, packet_number)) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Packet " << packet_number
+                    << " no longer being waited for at level "
+                    << static_cast<int>(last_decrypted_packet_level_)
+                    << ".  Discarding.";
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnDuplicatePacket(packet_number);
+    }
+    return false;
+  }
+
+  return true;
+}
+
+void QuicConnection::WriteQueuedPackets() {
+  QUICHE_DCHECK(!writer_->IsWriteBlocked());
+
+  QUIC_CLIENT_HISTOGRAM_COUNTS("QuicSession.NumQueuedPacketsBeforeWrite",
+                               buffered_packets_.size(), 1, 1000, 50, "");
+
+  while (!buffered_packets_.empty()) {
+    if (HandleWriteBlocked()) {
+      break;
+    }
+    const BufferedPacket& packet = buffered_packets_.front();
+    WriteResult result = writer_->WritePacket(
+        packet.encrypted_buffer.data(), packet.encrypted_buffer.length(),
+        packet.self_address.host(), packet.peer_address, per_packet_options_);
+    QUIC_DVLOG(1) << ENDPOINT << "Sending buffered packet, result: " << result;
+    if (IsMsgTooBig(writer_, result) &&
+        packet.encrypted_buffer.length() > long_term_mtu_) {
+      // When MSG_TOO_BIG is returned, the system typically knows what the
+      // actual MTU is, so there is no need to probe further.
+      // TODO(wub): Reduce max packet size to a safe default, or the actual MTU.
+      mtu_discoverer_.Disable();
+      mtu_discovery_alarm_->Cancel();
+      buffered_packets_.pop_front();
+      continue;
+    }
+    if (IsWriteError(result.status)) {
+      OnWriteError(result.error_code);
+      break;
+    }
+    if (result.status == WRITE_STATUS_OK ||
+        result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
+      buffered_packets_.pop_front();
+    }
+    if (IsWriteBlockedStatus(result.status)) {
+      visitor_->OnWriteBlocked();
+      break;
+    }
+  }
+}
+
+void QuicConnection::SendProbingRetransmissions() {
+  while (sent_packet_manager_.GetSendAlgorithm()->ShouldSendProbingPacket() &&
+         CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+    if (!visitor_->SendProbingData()) {
+      QUIC_DVLOG(1)
+          << "Cannot send probing retransmissions: nothing to retransmit.";
+      break;
+    }
+  }
+}
+
+void QuicConnection::MarkZeroRttPacketsForRetransmission(int reject_reason) {
+  sent_packet_manager_.MarkZeroRttPacketsForRetransmission();
+  if (debug_visitor_ != nullptr && version().UsesTls()) {
+    debug_visitor_->OnZeroRttRejected(reject_reason);
+  }
+}
+
+void QuicConnection::NeuterUnencryptedPackets() {
+  sent_packet_manager_.NeuterUnencryptedPackets();
+  // This may have changed the retransmission timer, so re-arm it.
+  SetRetransmissionAlarm();
+  if (default_enable_5rto_blackhole_detection_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
+                                 1, 3);
+    // Consider this as forward progress since this is called when initial key
+    // gets discarded (or previous unencrypted data is not needed anymore).
+    OnForwardProgressMade();
+  }
+  if (SupportsMultiplePacketNumberSpaces()) {
+    // Stop sending ack of initial packet number space.
+    uber_received_packet_manager_.ResetAckStates(ENCRYPTION_INITIAL);
+    // Re-arm ack alarm.
+    ack_alarm_->Update(uber_received_packet_manager_.GetEarliestAckTimeout(),
+                       kAlarmGranularity);
+  }
+}
+
+bool QuicConnection::ShouldGeneratePacket(
+    HasRetransmittableData retransmittable,
+    IsHandshake handshake) {
+  QUICHE_DCHECK(handshake != IS_HANDSHAKE ||
+                QuicVersionUsesCryptoFrames(transport_version()))
+      << ENDPOINT
+      << "Handshake in STREAM frames should not check ShouldGeneratePacket";
+  if (peer_issued_cid_manager_ != nullptr &&
+      packet_creator_.GetDestinationConnectionId().IsEmpty()) {
+    QUICHE_DCHECK(version().HasIetfQuicFrames());
+    QUIC_CODE_COUNT(quic_generate_packet_blocked_by_no_connection_id);
+    QUIC_BUG_IF(quic_bug_90265_1, perspective_ == Perspective::IS_CLIENT);
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "There is no destination connection ID available to "
+                       "generate packet.";
+    return false;
+  }
+  if (!count_bytes_on_alternative_path_separately_) {
+    return CanWrite(retransmittable);
+  }
+  QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 4, 5);
+  if (IsDefaultPath(default_path_.self_address,
+                    packet_creator_.peer_address())) {
+    return CanWrite(retransmittable);
+  }
+  // This is checking on the alternative path with a different peer address. The
+  // self address and the writer used are the same as the default path. In the
+  // case of different self address and writer, writing packet would use a
+  // differnt code path without checking the states of the default writer.
+  return connected_ && !HandleWriteBlocked();
+}
+
+const QuicFrames QuicConnection::MaybeBundleAckOpportunistically() {
+  if (!ack_frequency_sent_ && sent_packet_manager_.CanSendAckFrequency()) {
+    if (packet_creator_.NextSendingPacketNumber() >=
+        FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 3, 3);
+      ack_frequency_sent_ = true;
+      auto frame = sent_packet_manager_.GetUpdatedAckFrequencyFrame();
+      visitor_->SendAckFrequency(frame);
+    }
+  }
+
+  QuicFrames frames;
+  const bool has_pending_ack =
+      uber_received_packet_manager_
+          .GetAckTimeout(QuicUtils::GetPacketNumberSpace(encryption_level_))
+          .IsInitialized();
+  if (!has_pending_ack && stop_waiting_count_ <= 1) {
+    // No need to send an ACK.
+    return frames;
+  }
+  ResetAckStates();
+
+  QUIC_DVLOG(1) << ENDPOINT << "Bundle an ACK opportunistically";
+  QuicFrame updated_ack_frame = GetUpdatedAckFrame();
+  QUIC_BUG_IF(quic_bug_12714_23, updated_ack_frame.ack_frame->packets.Empty())
+      << ENDPOINT << "Attempted to opportunistically bundle an empty "
+      << encryption_level_ << " ACK, " << (has_pending_ack ? "" : "!")
+      << "has_pending_ack, stop_waiting_count_ " << stop_waiting_count_;
+  frames.push_back(updated_ack_frame);
+
+  if (!no_stop_waiting_frames_) {
+    QuicStopWaitingFrame stop_waiting;
+    PopulateStopWaitingFrame(&stop_waiting);
+    frames.push_back(QuicFrame(stop_waiting));
+  }
+  return frames;
+}
+
+bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
+  if (!connected_) {
+    return false;
+  }
+
+  if (version().CanSendCoalescedPackets() &&
+      framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL) &&
+      framer_.is_processing_packet()) {
+    // While we still have initial keys, suppress sending in mid of packet
+    // processing.
+    // TODO(fayang): always suppress sending while in the mid of packet
+    // processing.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Suppress sending in the mid of packet processing";
+    return false;
+  }
+
+  if (fill_coalesced_packet_) {
+    // Try to coalesce packet, only allow to write when creator is on soft max
+    // packet length. Given the next created packet is going to fill current
+    // coalesced packet, do not check amplification factor.
+    return packet_creator_.HasSoftMaxPacketLength();
+  }
+
+  if (sent_packet_manager_.pending_timer_transmission_count() > 0) {
+    // Allow sending if there are pending tokens, which occurs when:
+    // 1) firing PTO,
+    // 2) bundling CRYPTO data with ACKs,
+    // 3) coalescing CRYPTO data of higher space.
+    return true;
+  }
+
+  if (LimitedByAmplificationFactor()) {
+    // Server is constrained by the amplification restriction.
+    QUIC_CODE_COUNT(quic_throttled_by_amplification_limit);
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Constrained by amplification restriction to peer address "
+                  << default_path_.peer_address << " bytes received "
+                  << default_path_.bytes_received_before_address_validation
+                  << ", bytes sent"
+                  << default_path_.bytes_sent_before_address_validation;
+    ++stats_.num_amplification_throttling;
+    return false;
+  }
+
+  if (HandleWriteBlocked()) {
+    return false;
+  }
+
+  // Allow acks and probing frames to be sent immediately.
+  if (retransmittable == NO_RETRANSMITTABLE_DATA) {
+    return true;
+  }
+  // If the send alarm is set, wait for it to fire.
+  if (send_alarm_->IsSet()) {
+    return false;
+  }
+
+  QuicTime now = clock_->Now();
+  QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend(now);
+  if (delay.IsInfinite()) {
+    send_alarm_->Cancel();
+    return false;
+  }
+
+  // Scheduler requires a delay.
+  if (!delay.IsZero()) {
+    if (delay <= release_time_into_future_) {
+      // Required delay is within pace time into future, send now.
+      return true;
+    }
+    // Cannot send packet now because delay is too far in the future.
+    send_alarm_->Update(now + delay, kAlarmGranularity);
+    QUIC_DVLOG(1) << ENDPOINT << "Delaying sending " << delay.ToMilliseconds()
+                  << "ms";
+    return false;
+  }
+  return true;
+}
+
+QuicTime QuicConnection::CalculatePacketSentTime() {
+  const QuicTime now = clock_->Now();
+  if (!supports_release_time_ || per_packet_options_ == nullptr) {
+    // Don't change the release delay.
+    return now;
+  }
+
+  auto next_release_time_result = sent_packet_manager_.GetNextReleaseTime();
+
+  // Release before |now| is impossible.
+  QuicTime next_release_time =
+      std::max(now, next_release_time_result.release_time);
+  per_packet_options_->release_time_delay = next_release_time - now;
+  per_packet_options_->allow_burst = next_release_time_result.allow_burst;
+  return next_release_time;
+}
+
+bool QuicConnection::WritePacket(SerializedPacket* packet) {
+  if (sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
+      packet->packet_number < sent_packet_manager_.GetLargestSentPacket()) {
+    QUIC_BUG(quic_bug_10511_23)
+        << "Attempt to write packet:" << packet->packet_number
+        << " after:" << sent_packet_manager_.GetLargestSentPacket();
+    CloseConnection(QUIC_INTERNAL_ERROR, "Packet written out of order.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return true;
+  }
+  const bool is_mtu_discovery = QuicUtils::ContainsFrameType(
+      packet->nonretransmittable_frames, MTU_DISCOVERY_FRAME);
+  const SerializedPacketFate fate = packet->fate;
+  // Termination packets are encrypted and saved, so don't exit early.
+  QuicErrorCode error_code = QUIC_NO_ERROR;
+  const bool is_termination_packet = IsTerminationPacket(*packet, &error_code);
+  QuicPacketNumber packet_number = packet->packet_number;
+  QuicPacketLength encrypted_length = packet->encrypted_length;
+  // Termination packets are eventually owned by TimeWaitListManager.
+  // Others are deleted at the end of this call.
+  if (is_termination_packet) {
+    if (termination_packets_ == nullptr) {
+      termination_packets_.reset(
+          new std::vector<std::unique_ptr<QuicEncryptedPacket>>);
+    }
+    // Copy the buffer so it's owned in the future.
+    char* buffer_copy = CopyBuffer(*packet);
+    termination_packets_->emplace_back(
+        new QuicEncryptedPacket(buffer_copy, encrypted_length, true));
+    if (error_code == QUIC_SILENT_IDLE_TIMEOUT) {
+      QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+      // TODO(fayang): populate histogram indicating the time elapsed from this
+      // connection gets closed to following client packets get received.
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Added silent connection close to termination packets, "
+                       "num of termination packets: "
+                    << termination_packets_->size();
+      return true;
+    }
+  }
+
+  QUICHE_DCHECK_LE(encrypted_length, kMaxOutgoingPacketSize);
+  QUICHE_DCHECK(is_mtu_discovery ||
+                encrypted_length <= packet_creator_.max_packet_length())
+      << " encrypted_length=" << encrypted_length
+      << " > packet_creator max_packet_length="
+      << packet_creator_.max_packet_length();
+  QUIC_DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
+                << (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
+                        ? "data bearing "
+                        : " ack or probing only ")
+                << ", encryption level: " << packet->encryption_level
+                << ", encrypted length:" << encrypted_length
+                << ", fate: " << fate << " to peer " << packet->peer_address;
+  QUIC_DVLOG(2) << ENDPOINT << packet->encryption_level << " packet number "
+                << packet_number << " of length " << encrypted_length << ": "
+                << std::endl
+                << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                       packet->encrypted_buffer, encrypted_length));
+
+  // Measure the RTT from before the write begins to avoid underestimating the
+  // min_rtt_, especially in cases where the thread blocks or gets swapped out
+  // during the WritePacket below.
+  QuicTime packet_send_time = CalculatePacketSentTime();
+  WriteResult result(WRITE_STATUS_OK, encrypted_length);
+  QuicSocketAddress send_to_address = packet->peer_address;
+  // Self address is always the default self address on this code path.
+  bool send_on_current_path = send_to_address == peer_address();
+  switch (fate) {
+    case DISCARD:
+      ++stats_.packets_discarded;
+      if (debug_visitor_ != nullptr) {
+        debug_visitor_->OnPacketDiscarded(*packet);
+      }
+      return true;
+    case COALESCE:
+      QUIC_BUG_IF(quic_bug_12714_24,
+                  !version().CanSendCoalescedPackets() || coalescing_done_);
+      if (!coalesced_packet_.MaybeCoalescePacket(
+              *packet, self_address(), send_to_address,
+              helper_->GetStreamSendBufferAllocator(),
+              packet_creator_.max_packet_length())) {
+        // Failed to coalesce packet, flush current coalesced packet.
+        if (!FlushCoalescedPacket()) {
+          QUIC_BUG_IF(quic_connection_connected_after_flush_coalesced_failure,
+                      connected_)
+              << "QUIC connection is still connected after failing to flush "
+                 "coalesced packet.";
+          // Failed to flush coalesced packet, write error has been handled.
+          return false;
+        }
+        if (!coalesced_packet_.MaybeCoalescePacket(
+                *packet, self_address(), send_to_address,
+                helper_->GetStreamSendBufferAllocator(),
+                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";
+          result.error_code = WRITE_STATUS_FAILED_TO_COALESCE_PACKET;
+          break;
+        }
+      }
+      if (coalesced_packet_.length() < coalesced_packet_.max_packet_length()) {
+        QUIC_DVLOG(1) << ENDPOINT << "Trying to set soft max packet length to "
+                      << coalesced_packet_.max_packet_length() -
+                             coalesced_packet_.length();
+        packet_creator_.SetSoftMaxPacketLength(
+            coalesced_packet_.max_packet_length() - coalesced_packet_.length());
+      }
+      break;
+    case BUFFER:
+      QUIC_DVLOG(1) << ENDPOINT << "Adding packet: " << packet->packet_number
+                    << " to buffered packets";
+      buffered_packets_.emplace_back(*packet, self_address(), send_to_address);
+      break;
+    case SEND_TO_WRITER:
+      // Stop using coalescer from now on.
+      coalescing_done_ = true;
+      // At this point, packet->release_encrypted_buffer is either nullptr,
+      // meaning |packet->encrypted_buffer| is a stack buffer, or not-nullptr,
+      /// meaning it's a writer-allocated buffer. Note that connectivity probing
+      // packets do not use this function, so setting release_encrypted_buffer
+      // to nullptr will not cause probing packets to be leaked.
+      //
+      // writer_->WritePacket transfers buffer ownership back to the writer.
+      packet->release_encrypted_buffer = nullptr;
+      result = writer_->WritePacket(packet->encrypted_buffer, encrypted_length,
+                                    self_address().host(), send_to_address,
+                                    per_packet_options_);
+      // This is a work around for an issue with linux UDP GSO batch writers.
+      // When sending a GSO packet with 2 segments, if the first segment is
+      // larger than the path MTU, instead of EMSGSIZE, the linux kernel returns
+      // EINVAL, which translates to WRITE_STATUS_ERROR and causes conneciton to
+      // be closed. By manually flush the writer here, the MTU probe is sent in
+      // a normal(non-GSO) packet, so the kernel can return EMSGSIZE and we will
+      // not close the connection.
+      if (is_mtu_discovery && writer_->IsBatchMode()) {
+        result = writer_->Flush();
+      }
+      break;
+    case LEGACY_VERSION_ENCAPSULATE: {
+      QUICHE_DCHECK(!is_mtu_discovery);
+      QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+      QUICHE_DCHECK_EQ(packet->encryption_level, ENCRYPTION_INITIAL);
+      QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
+      QUICHE_DCHECK(legacy_version_encapsulation_in_progress_);
+      QuicPacketLength encapsulated_length =
+          QuicLegacyVersionEncapsulator::Encapsulate(
+              legacy_version_encapsulation_sni_,
+              absl::string_view(packet->encrypted_buffer,
+                                packet->encrypted_length),
+              default_path_.server_connection_id, framer_.creation_time(),
+              GetLimitedMaxPacketSize(long_term_mtu_),
+              const_cast<char*>(packet->encrypted_buffer));
+      if (encapsulated_length != 0) {
+        stats_.sent_legacy_version_encapsulated_packets++;
+        packet->encrypted_length = encapsulated_length;
+        encrypted_length = encapsulated_length;
+        QUIC_DVLOG(2)
+            << ENDPOINT
+            << "Successfully performed Legacy Version Encapsulation on "
+            << packet->encryption_level << " packet number " << packet_number
+            << " of length " << encrypted_length << ": " << std::endl
+            << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                   packet->encrypted_buffer, encrypted_length));
+      } else {
+        QUIC_BUG(quic_bug_10511_24)
+            << ENDPOINT << "Failed to perform Legacy Version Encapsulation on "
+            << packet->encryption_level << " packet number " << packet_number
+            << " of length " << encrypted_length;
+      }
+      if (!buffered_packets_.empty() || HandleWriteBlocked()) {
+        // Buffer the packet.
+        buffered_packets_.emplace_back(*packet, self_address(),
+                                       send_to_address);
+      } else {  // Send the packet to the writer.
+        // writer_->WritePacket transfers buffer ownership back to the writer.
+        packet->release_encrypted_buffer = nullptr;
+        result = writer_->WritePacket(packet->encrypted_buffer,
+                                      encrypted_length, self_address().host(),
+                                      send_to_address, per_packet_options_);
+      }
+    } break;
+    default:
+      QUICHE_DCHECK(false);
+      break;
+  }
+
+  QUIC_HISTOGRAM_ENUM(
+      "QuicConnection.WritePacketStatus", result.status,
+      WRITE_STATUS_NUM_VALUES,
+      "Status code returned by writer_->WritePacket() in QuicConnection.");
+
+  if (IsWriteBlockedStatus(result.status)) {
+    // Ensure the writer is still write blocked, otherwise QUIC may continue
+    // trying to write when it will not be able to.
+    QUICHE_DCHECK(writer_->IsWriteBlocked());
+    visitor_->OnWriteBlocked();
+    // If the socket buffers the data, then the packet should not
+    // be queued and sent again, which would result in an unnecessary
+    // duplicate packet being sent.  The helper must call OnCanWrite
+    // when the write completes, and OnWriteError if an error occurs.
+    if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
+      QUIC_DVLOG(1) << ENDPOINT << "Adding packet: " << packet->packet_number
+                    << " to buffered packets";
+      buffered_packets_.emplace_back(*packet, self_address(), send_to_address);
+    }
+  }
+
+  // In some cases, an MTU probe can cause EMSGSIZE. This indicates that the
+  // MTU discovery is permanently unsuccessful.
+  if (IsMsgTooBig(writer_, result)) {
+    if (is_mtu_discovery) {
+      // When MSG_TOO_BIG is returned, the system typically knows what the
+      // actual MTU is, so there is no need to probe further.
+      // TODO(wub): Reduce max packet size to a safe default, or the actual MTU.
+      QUIC_DVLOG(1) << ENDPOINT
+                    << " MTU probe packet too big, size:" << encrypted_length
+                    << ", long_term_mtu_:" << long_term_mtu_;
+      mtu_discoverer_.Disable();
+      mtu_discovery_alarm_->Cancel();
+      // The write failed, but the writer is not blocked, so return true.
+      return true;
+    }
+    if (use_path_validator_ && !send_on_current_path) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 2, 4);
+      // Only handle MSG_TOO_BIG as error on current path.
+      return true;
+    }
+  }
+
+  if (IsWriteError(result.status)) {
+    QUIC_LOG_FIRST_N(ERROR, 10)
+        << ENDPOINT << "Failed writing packet " << packet_number << " of "
+        << encrypted_length << " bytes from " << self_address().host() << " to "
+        << send_to_address << ", with error code " << result.error_code
+        << ". long_term_mtu_:" << long_term_mtu_
+        << ", previous_validated_mtu_:" << previous_validated_mtu_
+        << ", max_packet_length():" << max_packet_length()
+        << ", is_mtu_discovery:" << is_mtu_discovery;
+    if (MaybeRevertToPreviousMtu()) {
+      return true;
+    }
+
+    OnWriteError(result.error_code);
+    return false;
+  }
+
+  if (result.status == WRITE_STATUS_OK) {
+    // packet_send_time is the ideal send time, if allow_burst is true, writer
+    // may have sent it earlier than that.
+    packet_send_time = packet_send_time + result.send_time_offset;
+  }
+
+  if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA &&
+      !is_termination_packet) {
+    // Start blackhole/path degrading detections if the sent packet is not
+    // termination packet and contains retransmittable data.
+    // Do not restart detection if detection is in progress indicating no
+    // forward progress has been made since last event (i.e., packet was sent
+    // or new packets were acknowledged).
+    if (!blackhole_detector_.IsDetectionInProgress()) {
+      // Try to start detections if no detection in progress. This could
+      // because either both detections are inactive when sending last packet
+      // or this connection just gets out of quiescence.
+      blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
+                                           GetNetworkBlackholeDeadline(),
+                                           GetPathMtuReductionDeadline());
+    }
+    idle_network_detector_.OnPacketSent(packet_send_time,
+                                        sent_packet_manager_.GetPtoDelay());
+  }
+
+  MaybeSetMtuAlarm(packet_number);
+  QUIC_DVLOG(1) << ENDPOINT << "time we began writing last sent packet: "
+                << packet_send_time.ToDebuggingValue();
+
+  if (!count_bytes_on_alternative_path_separately_) {
+    if (EnforceAntiAmplificationLimit()) {
+      // Include bytes sent even if they are not in flight.
+      default_path_.bytes_sent_before_address_validation += encrypted_length;
+    }
+  } else {
+    QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 2, 5);
+    if (IsDefaultPath(default_path_.self_address, send_to_address)) {
+      if (EnforceAntiAmplificationLimit()) {
+        // Include bytes sent even if they are not in flight.
+        default_path_.bytes_sent_before_address_validation += encrypted_length;
+      }
+    } else {
+      MaybeUpdateBytesSentToAlternativeAddress(send_to_address,
+                                               encrypted_length);
+    }
+  }
+
+  // Do not measure rtt of this packet if it's not sent on current path.
+  QUIC_DLOG_IF(INFO, !send_on_current_path)
+      << ENDPOINT << " Sent packet " << packet->packet_number
+      << " on a different path with remote address " << send_to_address
+      << " while current path has peer address " << peer_address();
+  const bool in_flight = sent_packet_manager_.OnPacketSent(
+      packet, packet_send_time, packet->transmission_type,
+      IsRetransmittable(*packet), /*measure_rtt=*/send_on_current_path);
+  QUIC_BUG_IF(quic_bug_12714_25,
+              perspective_ == Perspective::IS_SERVER &&
+                  default_enable_5rto_blackhole_detection_ &&
+                  blackhole_detector_.IsDetectionInProgress() &&
+                  !sent_packet_manager_.HasInFlightPackets())
+      << ENDPOINT
+      << "Trying to start blackhole detection without no bytes in flight";
+
+  if (debug_visitor_ != nullptr) {
+    if (sent_packet_manager_.unacked_packets().empty()) {
+      QUIC_BUG(quic_bug_10511_25)
+          << "Unacked map is empty right after packet is sent";
+    } else {
+      debug_visitor_->OnPacketSent(
+          packet->packet_number, packet->encrypted_length,
+          packet->has_crypto_handshake, packet->transmission_type,
+          packet->encryption_level,
+          sent_packet_manager_.unacked_packets()
+              .rbegin()
+              ->retransmittable_frames,
+          packet->nonretransmittable_frames, packet_send_time);
+    }
+  }
+  if (packet->encryption_level == ENCRYPTION_HANDSHAKE) {
+    handshake_packet_sent_ = true;
+  }
+
+  if (packet->encryption_level == ENCRYPTION_FORWARD_SECURE) {
+    if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) {
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "lowest_packet_sent_in_current_key_phase_ = "
+                      << packet_number;
+      lowest_packet_sent_in_current_key_phase_ = packet_number;
+    }
+    if (!is_termination_packet &&
+        MaybeHandleAeadConfidentialityLimits(*packet)) {
+      return true;
+    }
+  }
+  if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_simplify_set_retransmission_alarm, 1, 2);
+    if (in_flight || !retransmission_alarm_->IsSet()) {
+      SetRetransmissionAlarm();
+    }
+  } else if (ShouldSetRetransmissionAlarmOnPacketSent(
+                 in_flight, packet->encryption_level)) {
+    SetRetransmissionAlarm();
+  }
+  SetPingAlarm();
+  RetirePeerIssuedConnectionIdsNoLongerOnPath();
+
+  // The packet number length must be updated after OnPacketSent, because it
+  // may change the packet number length in packet.
+  packet_creator_.UpdatePacketNumberLength(
+      sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
+      sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
+
+  stats_.bytes_sent += result.bytes_written;
+  ++stats_.packets_sent;
+  if (packet->transmission_type != NOT_RETRANSMISSION) {
+    stats_.bytes_retransmitted += result.bytes_written;
+    ++stats_.packets_retransmitted;
+  }
+
+  return true;
+}
+
+bool QuicConnection::MaybeHandleAeadConfidentialityLimits(
+    const SerializedPacket& packet) {
+  if (!version().UsesTls()) {
+    return false;
+  }
+
+  if (packet.encryption_level != ENCRYPTION_FORWARD_SECURE) {
+    QUIC_BUG(quic_bug_12714_26)
+        << "MaybeHandleAeadConfidentialityLimits called on non 1-RTT packet";
+    return false;
+  }
+  if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) {
+    QUIC_BUG(quic_bug_10511_26)
+        << "lowest_packet_sent_in_current_key_phase_ must be initialized "
+           "before calling MaybeHandleAeadConfidentialityLimits";
+    return false;
+  }
+
+  // Calculate the number of packets encrypted from the packet number, which is
+  // simpler than keeping another counter. The packet number space may be
+  // sparse, so this might overcount, but doing a key update earlier than
+  // necessary would only improve security and has negligible cost.
+  if (packet.packet_number < lowest_packet_sent_in_current_key_phase_) {
+    const std::string error_details =
+        absl::StrCat("packet_number(", packet.packet_number.ToString(),
+                     ") < lowest_packet_sent_in_current_key_phase_ (",
+                     lowest_packet_sent_in_current_key_phase_.ToString(), ")");
+    QUIC_BUG(quic_bug_10511_27) << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return true;
+  }
+  const QuicPacketCount num_packets_encrypted_in_current_key_phase =
+      packet.packet_number - lowest_packet_sent_in_current_key_phase_ + 1;
+
+  const QuicPacketCount confidentiality_limit =
+      framer_.GetOneRttEncrypterConfidentialityLimit();
+
+  // Attempt to initiate a key update before reaching the AEAD
+  // confidentiality limit when the number of packets sent in the current
+  // key phase gets within |kKeyUpdateConfidentialityLimitOffset| packets of
+  // the limit, unless overridden by
+  // FLAGS_quic_key_update_confidentiality_limit.
+  constexpr QuicPacketCount kKeyUpdateConfidentialityLimitOffset = 1000;
+  QuicPacketCount key_update_limit = 0;
+  if (confidentiality_limit > kKeyUpdateConfidentialityLimitOffset) {
+    key_update_limit =
+        confidentiality_limit - kKeyUpdateConfidentialityLimitOffset;
+  }
+  const QuicPacketCount key_update_limit_override =
+      GetQuicFlag(FLAGS_quic_key_update_confidentiality_limit);
+  if (key_update_limit_override) {
+    key_update_limit = key_update_limit_override;
+  }
+
+  QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD confidentiality limits: "
+                << "num_packets_encrypted_in_current_key_phase="
+                << num_packets_encrypted_in_current_key_phase
+                << " key_update_limit=" << key_update_limit
+                << " confidentiality_limit=" << confidentiality_limit
+                << " IsKeyUpdateAllowed()=" << IsKeyUpdateAllowed();
+
+  if (num_packets_encrypted_in_current_key_phase >= confidentiality_limit) {
+    // Reached the confidentiality limit without initiating a key update,
+    // must close the connection.
+    const std::string error_details = absl::StrCat(
+        "encrypter confidentiality limit reached: "
+        "num_packets_encrypted_in_current_key_phase=",
+        num_packets_encrypted_in_current_key_phase,
+        " key_update_limit=", key_update_limit,
+        " confidentiality_limit=", confidentiality_limit,
+        " IsKeyUpdateAllowed()=", IsKeyUpdateAllowed());
+    CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return true;
+  }
+
+  if (IsKeyUpdateAllowed() &&
+      num_packets_encrypted_in_current_key_phase >= key_update_limit) {
+    // Approaching the confidentiality limit, initiate key update so that
+    // the next set of keys will be ready for the next packet before the
+    // limit is reached.
+    KeyUpdateReason reason = KeyUpdateReason::kLocalAeadConfidentialityLimit;
+    if (key_update_limit_override) {
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "reached FLAGS_quic_key_update_confidentiality_limit, "
+                         "initiating key update: "
+                      << "num_packets_encrypted_in_current_key_phase="
+                      << num_packets_encrypted_in_current_key_phase
+                      << " key_update_limit=" << key_update_limit
+                      << " confidentiality_limit=" << confidentiality_limit;
+      reason = KeyUpdateReason::kLocalKeyUpdateLimitOverride;
+    } else {
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "approaching AEAD confidentiality limit, "
+                         "initiating key update: "
+                      << "num_packets_encrypted_in_current_key_phase="
+                      << num_packets_encrypted_in_current_key_phase
+                      << " key_update_limit=" << key_update_limit
+                      << " confidentiality_limit=" << confidentiality_limit;
+    }
+    InitiateKeyUpdate(reason);
+  }
+
+  return false;
+}
+
+void QuicConnection::FlushPackets() {
+  if (!connected_) {
+    return;
+  }
+
+  if (!writer_->IsBatchMode()) {
+    return;
+  }
+
+  if (HandleWriteBlocked()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "FlushPackets called while blocked.";
+    return;
+  }
+
+  WriteResult result = writer_->Flush();
+
+  QUIC_HISTOGRAM_ENUM("QuicConnection.FlushPacketStatus", result.status,
+                      WRITE_STATUS_NUM_VALUES,
+                      "Status code returned by writer_->Flush() in "
+                      "QuicConnection::FlushPackets.");
+
+  if (HandleWriteBlocked()) {
+    QUICHE_DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status)
+        << "Unexpected flush result:" << result;
+    QUIC_DLOG(INFO) << ENDPOINT << "Write blocked in FlushPackets.";
+    return;
+  }
+
+  if (IsWriteError(result.status) && !MaybeRevertToPreviousMtu()) {
+    OnWriteError(result.error_code);
+  }
+}
+
+bool QuicConnection::IsMsgTooBig(const QuicPacketWriter* writer,
+                                 const WriteResult& result) {
+  absl::optional<int> writer_error_code = writer->MessageTooBigErrorCode();
+  return (result.status == WRITE_STATUS_MSG_TOO_BIG) ||
+         (writer_error_code.has_value() && IsWriteError(result.status) &&
+          result.error_code == *writer_error_code);
+}
+
+bool QuicConnection::ShouldDiscardPacket(EncryptionLevel encryption_level) {
+  if (!connected_) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Not sending packet as connection is disconnected.";
+    return true;
+  }
+
+  if (encryption_level_ == ENCRYPTION_FORWARD_SECURE &&
+      encryption_level == ENCRYPTION_INITIAL) {
+    // Drop packets that are NULL encrypted since the peer won't accept them
+    // anymore.
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Dropping NULL encrypted packet since the connection is "
+                       "forward secure.";
+    return true;
+  }
+
+  return false;
+}
+
+QuicTime QuicConnection::GetPathMtuReductionDeadline() const {
+  if (previous_validated_mtu_ == 0) {
+    return QuicTime::Zero();
+  }
+  QuicTime::Delta delay = sent_packet_manager_.GetMtuReductionDelay(
+      num_rtos_for_blackhole_detection_);
+  if (delay.IsZero()) {
+    return QuicTime::Zero();
+  }
+  return clock_->ApproximateNow() + delay;
+}
+
+bool QuicConnection::MaybeRevertToPreviousMtu() {
+  if (previous_validated_mtu_ == 0) {
+    return false;
+  }
+
+  SetMaxPacketLength(previous_validated_mtu_);
+  mtu_discoverer_.Disable();
+  mtu_discovery_alarm_->Cancel();
+  previous_validated_mtu_ = 0;
+  return true;
+}
+
+void QuicConnection::OnWriteError(int error_code) {
+  if (write_error_occurred_) {
+    // A write error already occurred. The connection is being closed.
+    return;
+  }
+  write_error_occurred_ = true;
+
+  const std::string error_details = absl::StrCat(
+      "Write failed with error: ", error_code, " (", strerror(error_code), ")");
+  QUIC_LOG_FIRST_N(ERROR, 2) << ENDPOINT << error_details;
+  absl::optional<int> writer_error_code = writer_->MessageTooBigErrorCode();
+  if (writer_error_code.has_value() && error_code == *writer_error_code) {
+    CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  // We can't send an error as the socket is presumably borked.
+  if (version().HasIetfInvariantHeader()) {
+    QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_ietf);
+  } else {
+    QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_non_ietf);
+  }
+  CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
+                  ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+QuicPacketBuffer QuicConnection::GetPacketBuffer() {
+  if (version().CanSendCoalescedPackets() && !coalescing_done_) {
+    // Do not use writer's packet buffer for coalesced packets which may
+    // contain multiple QUIC packets.
+    return {nullptr, nullptr};
+  }
+  return writer_->GetNextWriteLocation(self_address().host(), peer_address());
+}
+
+void QuicConnection::OnSerializedPacket(SerializedPacket serialized_packet) {
+  if (serialized_packet.encrypted_buffer == nullptr) {
+    // We failed to serialize the packet, so close the connection.
+    // Specify that the close is silent, that no packet be sent, so no infinite
+    // loop here.
+    // TODO(ianswett): This is actually an internal error, not an
+    // encryption failure.
+    if (version().HasIetfInvariantHeader()) {
+      QUIC_CODE_COUNT(
+          quic_tear_down_local_connection_on_serialized_packet_ietf);
+    } else {
+      QUIC_CODE_COUNT(
+          quic_tear_down_local_connection_on_serialized_packet_non_ietf);
+    }
+    CloseConnection(QUIC_ENCRYPTION_FAILURE,
+                    "Serialized packet does not have an encrypted buffer.",
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+    return;
+  }
+
+  if (serialized_packet.retransmittable_frames.empty()) {
+    // Increment consecutive_num_packets_with_no_retransmittable_frames_ if
+    // this packet is a new transmission with no retransmittable frames.
+    ++consecutive_num_packets_with_no_retransmittable_frames_;
+  } else {
+    consecutive_num_packets_with_no_retransmittable_frames_ = 0;
+  }
+  SendOrQueuePacket(std::move(serialized_packet));
+}
+
+void QuicConnection::OnUnrecoverableError(QuicErrorCode error,
+                                          const std::string& error_details) {
+  // The packet creator or generator encountered an unrecoverable error: tear
+  // down local connection state immediately.
+  if (version().HasIetfInvariantHeader()) {
+    QUIC_CODE_COUNT(
+        quic_tear_down_local_connection_on_unrecoverable_error_ietf);
+  } else {
+    QUIC_CODE_COUNT(
+        quic_tear_down_local_connection_on_unrecoverable_error_non_ietf);
+  }
+  CloseConnection(error, error_details, ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+void QuicConnection::OnCongestionChange() {
+  visitor_->OnCongestionWindowChange(clock_->ApproximateNow());
+
+  // Uses the connection's smoothed RTT. If zero, uses initial_rtt.
+  QuicTime::Delta rtt = sent_packet_manager_.GetRttStats()->smoothed_rtt();
+  if (rtt.IsZero()) {
+    rtt = sent_packet_manager_.GetRttStats()->initial_rtt();
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnRttChanged(rtt);
+  }
+}
+
+void QuicConnection::OnPathMtuIncreased(QuicPacketLength packet_size) {
+  if (packet_size > max_packet_length()) {
+    previous_validated_mtu_ = max_packet_length();
+    SetMaxPacketLength(packet_size);
+    mtu_discoverer_.OnMaxPacketLengthUpdated(previous_validated_mtu_,
+                                             max_packet_length());
+  }
+}
+
+std::unique_ptr<QuicSelfIssuedConnectionIdManager>
+QuicConnection::MakeSelfIssuedConnectionIdManager() {
+  QUICHE_DCHECK((perspective_ == Perspective::IS_CLIENT &&
+                 !default_path_.client_connection_id.IsEmpty()) ||
+                (perspective_ == Perspective::IS_SERVER &&
+                 !default_path_.server_connection_id.IsEmpty()));
+  return std::make_unique<QuicSelfIssuedConnectionIdManager>(
+      kMinNumOfActiveConnectionIds,
+      perspective_ == Perspective::IS_CLIENT
+          ? default_path_.client_connection_id
+          : default_path_.server_connection_id,
+      clock_, alarm_factory_, this, context());
+}
+
+void QuicConnection::MaybeSendConnectionIdToClient() {
+  if (perspective_ == Perspective::IS_CLIENT) {
+    return;
+  }
+  QUICHE_DCHECK(self_issued_cid_manager_ != nullptr);
+  self_issued_cid_manager_->MaybeSendNewConnectionIds();
+}
+
+void QuicConnection::OnHandshakeComplete() {
+  sent_packet_manager_.SetHandshakeConfirmed();
+  if (connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_SERVER &&
+      self_issued_cid_manager_ != nullptr) {
+    self_issued_cid_manager_->MaybeSendNewConnectionIds();
+  }
+  if (send_ack_frequency_on_handshake_completion_ &&
+      sent_packet_manager_.CanSendAckFrequency()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 2, 3);
+    auto ack_frequency_frame =
+        sent_packet_manager_.GetUpdatedAckFrequencyFrame();
+    // This AckFrequencyFrame is meant to only update the max_ack_delay. Set
+    // packet tolerance to the default value for now.
+    ack_frequency_frame.packet_tolerance =
+        kDefaultRetransmittablePacketsBeforeAck;
+    visitor_->SendAckFrequency(ack_frequency_frame);
+    if (!connected_) {
+      return;
+    }
+  }
+  // This may have changed the retransmission timer, so re-arm it.
+  SetRetransmissionAlarm();
+  if (default_enable_5rto_blackhole_detection_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
+                                 2, 3);
+    OnForwardProgressMade();
+  }
+  if (!SupportsMultiplePacketNumberSpaces()) {
+    // The client should immediately ack the SHLO to confirm the handshake is
+    // complete with the server.
+    if (perspective_ == Perspective::IS_CLIENT && ack_frame_updated()) {
+      ack_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
+    }
+    return;
+  }
+  // Stop sending ack of handshake packet number space.
+  uber_received_packet_manager_.ResetAckStates(ENCRYPTION_HANDSHAKE);
+  // Re-arm ack alarm.
+  ack_alarm_->Update(uber_received_packet_manager_.GetEarliestAckTimeout(),
+                     kAlarmGranularity);
+}
+
+void QuicConnection::SendOrQueuePacket(SerializedPacket packet) {
+  // The caller of this function is responsible for checking CanWrite().
+  WritePacket(&packet);
+}
+
+void QuicConnection::OnPingTimeout() {
+  if (retransmission_alarm_->IsSet() ||
+      !visitor_->ShouldKeepConnectionAlive()) {
+    return;
+  }
+  SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
+}
+
+void QuicConnection::SendAck() {
+  QUICHE_DCHECK(!SupportsMultiplePacketNumberSpaces());
+  QUIC_DVLOG(1) << ENDPOINT << "Sending an ACK proactively";
+  QuicFrames frames;
+  frames.push_back(GetUpdatedAckFrame());
+  if (!no_stop_waiting_frames_) {
+    QuicStopWaitingFrame stop_waiting;
+    PopulateStopWaitingFrame(&stop_waiting);
+    frames.push_back(QuicFrame(stop_waiting));
+  }
+  if (!packet_creator_.FlushAckFrame(frames)) {
+    return;
+  }
+  ResetAckStates();
+  if (!ShouldBundleRetransmittableFrameWithAck()) {
+    return;
+  }
+  consecutive_num_packets_with_no_retransmittable_frames_ = 0;
+  if (packet_creator_.HasPendingRetransmittableFrames() ||
+      visitor_->WillingAndAbleToWrite()) {
+    // There are pending retransmittable frames.
+    return;
+  }
+
+  visitor_->OnAckNeedsRetransmittableFrame();
+}
+
+void QuicConnection::OnRetransmissionTimeout() {
+  ScopedRetransmissionTimeoutIndicator indicator(this);
+#ifndef NDEBUG
+  if (sent_packet_manager_.unacked_packets().empty()) {
+    QUICHE_DCHECK(sent_packet_manager_.handshake_mode_disabled());
+    QUICHE_DCHECK(!IsHandshakeComplete());
+  }
+#endif
+  if (!connected_) {
+    return;
+  }
+
+  QuicPacketNumber previous_created_packet_number =
+      packet_creator_.packet_number();
+  const auto retransmission_mode =
+      sent_packet_manager_.OnRetransmissionTimeout();
+  if (sent_packet_manager_.skip_packet_number_for_pto() &&
+      retransmission_mode == QuicSentPacketManager::PTO_MODE &&
+      sent_packet_manager_.pending_timer_transmission_count() == 1) {
+    // Skip a packet number when a single PTO packet is sent to elicit an
+    // immediate ACK.
+    const QuicPacketCount num_packet_numbers_to_skip = 1;
+    packet_creator_.SkipNPacketNumbers(
+        num_packet_numbers_to_skip,
+        sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
+        sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
+    previous_created_packet_number += num_packet_numbers_to_skip;
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnNPacketNumbersSkipped(num_packet_numbers_to_skip,
+                                              clock_->Now());
+    }
+  }
+  if (default_enable_5rto_blackhole_detection_ &&
+      !sent_packet_manager_.HasInFlightPackets() &&
+      blackhole_detector_.IsDetectionInProgress()) {
+    // Stop detection in quiescence.
+    QUICHE_DCHECK_EQ(QuicSentPacketManager::LOSS_MODE, retransmission_mode);
+    blackhole_detector_.StopDetection(/*permanent=*/false);
+  }
+  WriteIfNotBlocked();
+
+  // A write failure can result in the connection being closed, don't attempt to
+  // write further packets, or to set alarms.
+  if (!connected_) {
+    return;
+  }
+
+  // In the PTO and TLP cases, the SentPacketManager gives the connection the
+  // opportunity to send new data before retransmitting.
+  if (sent_packet_manager_.pto_enabled()) {
+    sent_packet_manager_.MaybeSendProbePackets();
+  } else if (sent_packet_manager_.MaybeRetransmitTailLossProbe()) {
+    // Send the pending retransmission now that it's been queued.
+    WriteIfNotBlocked();
+  }
+
+  if (packet_creator_.packet_number() == previous_created_packet_number &&
+      (retransmission_mode == QuicSentPacketManager::TLP_MODE ||
+       retransmission_mode == QuicSentPacketManager::RTO_MODE ||
+       retransmission_mode == QuicSentPacketManager::PTO_MODE) &&
+      !visitor_->WillingAndAbleToWrite()) {
+    // Send PING if timer fires in TLP/RTO/PTO mode but there is no data to
+    // send.
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "No packet gets sent when timer fires in mode "
+                    << retransmission_mode << ", send PING";
+    QUICHE_DCHECK_LT(0u,
+                     sent_packet_manager_.pending_timer_transmission_count());
+    if (SupportsMultiplePacketNumberSpaces()) {
+      // Based on https://datatracker.ietf.org/doc/html/rfc9002#appendix-A.9
+      PacketNumberSpace packet_number_space;
+      if (sent_packet_manager_
+              .GetEarliestPacketSentTimeForPto(&packet_number_space)
+              .IsInitialized()) {
+        SendPingAtLevel(QuicUtils::GetEncryptionLevel(packet_number_space));
+      } else {
+        // The client must PTO when there is nothing in flight if the server
+        // could be blocked from sending by the amplification limit
+        QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+        if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE)) {
+          SendPingAtLevel(ENCRYPTION_HANDSHAKE);
+        } else if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
+          SendPingAtLevel(ENCRYPTION_INITIAL);
+        } else {
+          QUIC_BUG(quic_bug_no_pto) << "PTO fired but nothing was sent.";
+        }
+      }
+    } else {
+      SendPingAtLevel(encryption_level_);
+    }
+  }
+  if (retransmission_mode == QuicSentPacketManager::PTO_MODE) {
+    sent_packet_manager_.AdjustPendingTimerTransmissions();
+  }
+  if (retransmission_mode != QuicSentPacketManager::LOSS_MODE &&
+      retransmission_mode != QuicSentPacketManager::HANDSHAKE_MODE) {
+    // When timer fires in TLP/RTO/PTO 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(
+        quic_bug_12714_27,
+        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_creator_.packet_number()
+        << ", session has data to write: " << visitor_->WillingAndAbleToWrite()
+        << ", writer is blocked: " << writer_->IsWriteBlocked()
+        << ", pending_timer_transmission_count: "
+        << sent_packet_manager_.pending_timer_transmission_count();
+  }
+
+  // Ensure the retransmission alarm is always set if there are unacked packets
+  // and nothing waiting to be sent.
+  // This happens if the loss algorithm invokes a timer based loss, but the
+  // packet doesn't need to be retransmitted.
+  if (!HasQueuedData() && !retransmission_alarm_->IsSet()) {
+    SetRetransmissionAlarm();
+  }
+}
+
+void QuicConnection::SetEncrypter(EncryptionLevel level,
+                                  std::unique_ptr<QuicEncrypter> encrypter) {
+  packet_creator_.SetEncrypter(level, std::move(encrypter));
+}
+
+void QuicConnection::RemoveEncrypter(EncryptionLevel level) {
+  framer_.RemoveEncrypter(level);
+}
+
+void QuicConnection::SetDiversificationNonce(
+    const DiversificationNonce& nonce) {
+  QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+  packet_creator_.SetDiversificationNonce(nonce);
+}
+
+void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
+  QUIC_DVLOG(1) << ENDPOINT << "Setting default encryption level from "
+                << encryption_level_ << " to " << level;
+  const bool changing_level = level != encryption_level_;
+  if (changing_level && packet_creator_.HasPendingFrames()) {
+    // Flush all queued frames when encryption level changes.
+    ScopedPacketFlusher flusher(this);
+    packet_creator_.FlushCurrentPacket();
+  }
+  encryption_level_ = level;
+  packet_creator_.set_encryption_level(level);
+  QUIC_BUG_IF(quic_bug_12714_28, !framer_.HasEncrypterOfEncryptionLevel(level))
+      << ENDPOINT << "Trying to set encryption level to "
+      << EncryptionLevelToString(level) << " while the key is missing";
+
+  if (!changing_level) {
+    return;
+  }
+  // The least packet awaited by the peer depends on the encryption level so
+  // we recalculate it here.
+  packet_creator_.UpdatePacketNumberLength(
+      sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
+      sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
+}
+
+void QuicConnection::SetDecrypter(EncryptionLevel level,
+                                  std::unique_ptr<QuicDecrypter> decrypter) {
+  framer_.SetDecrypter(level, std::move(decrypter));
+
+  if (!undecryptable_packets_.empty() &&
+      !process_undecryptable_packets_alarm_->IsSet()) {
+    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicConnection::SetAlternativeDecrypter(
+    EncryptionLevel level,
+    std::unique_ptr<QuicDecrypter> decrypter,
+    bool latch_once_used) {
+  framer_.SetAlternativeDecrypter(level, std::move(decrypter), latch_once_used);
+
+  if (!undecryptable_packets_.empty() &&
+      !process_undecryptable_packets_alarm_->IsSet()) {
+    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicConnection::InstallDecrypter(
+    EncryptionLevel level,
+    std::unique_ptr<QuicDecrypter> decrypter) {
+  if (level == ENCRYPTION_ZERO_RTT) {
+    had_zero_rtt_decrypter_ = true;
+  }
+  framer_.InstallDecrypter(level, std::move(decrypter));
+  if (!undecryptable_packets_.empty() &&
+      !process_undecryptable_packets_alarm_->IsSet()) {
+    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicConnection::RemoveDecrypter(EncryptionLevel level) {
+  framer_.RemoveDecrypter(level);
+}
+
+void QuicConnection::DiscardPreviousOneRttKeys() {
+  framer_.DiscardPreviousOneRttKeys();
+}
+
+bool QuicConnection::IsKeyUpdateAllowed() const {
+  return support_key_update_for_connection_ &&
+         GetLargestAckedPacket().IsInitialized() &&
+         lowest_packet_sent_in_current_key_phase_.IsInitialized() &&
+         GetLargestAckedPacket() >= lowest_packet_sent_in_current_key_phase_;
+}
+
+bool QuicConnection::HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const {
+  return lowest_packet_sent_in_current_key_phase_.IsInitialized() &&
+         (!GetLargestAckedPacket().IsInitialized() ||
+          GetLargestAckedPacket() < lowest_packet_sent_in_current_key_phase_);
+}
+
+QuicPacketCount QuicConnection::PotentialPeerKeyUpdateAttemptCount() const {
+  return framer_.PotentialPeerKeyUpdateAttemptCount();
+}
+
+bool QuicConnection::InitiateKeyUpdate(KeyUpdateReason reason) {
+  QUIC_DLOG(INFO) << ENDPOINT << "InitiateKeyUpdate";
+  if (!IsKeyUpdateAllowed()) {
+    QUIC_BUG(quic_bug_10511_28) << "key update not allowed";
+    return false;
+  }
+  return framer_.DoKeyUpdate(reason);
+}
+
+const QuicDecrypter* QuicConnection::decrypter() const {
+  return framer_.decrypter();
+}
+
+const QuicDecrypter* QuicConnection::alternative_decrypter() const {
+  return framer_.alternative_decrypter();
+}
+
+void QuicConnection::QueueUndecryptablePacket(
+    const QuicEncryptedPacket& packet,
+    EncryptionLevel decryption_level) {
+  for (const auto& saved_packet : undecryptable_packets_) {
+    if (packet.data() == saved_packet.packet->data() &&
+        packet.length() == saved_packet.packet->length()) {
+      QUIC_DVLOG(1) << ENDPOINT << "Not queueing known undecryptable packet";
+      return;
+    }
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Queueing undecryptable packet.";
+  undecryptable_packets_.emplace_back(packet, decryption_level,
+                                      last_received_packet_info_);
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
+      SetRetransmissionAlarm();
+    } else if (!retransmission_alarm_->IsSet() ||
+               GetRetransmissionDeadline() <
+                   retransmission_alarm_->deadline()) {
+      // Re-arm PTO only if we can make it sooner to speed up recovery.
+      SetRetransmissionAlarm();
+    }
+  }
+}
+
+void QuicConnection::MaybeProcessUndecryptablePackets() {
+  process_undecryptable_packets_alarm_->Cancel();
+
+  if (undecryptable_packets_.empty() ||
+      encryption_level_ == ENCRYPTION_INITIAL) {
+    return;
+  }
+
+  auto iter = undecryptable_packets_.begin();
+  while (connected_ && iter != undecryptable_packets_.end()) {
+    // Making sure there is no pending frames when processing next undecrypted
+    // packet because the queued ack frame may change.
+    packet_creator_.FlushCurrentPacket();
+    if (!connected_) {
+      return;
+    }
+    UndecryptablePacket* undecryptable_packet = &*iter;
+    QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet";
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnAttemptingToProcessUndecryptablePacket(
+          undecryptable_packet->encryption_level);
+    }
+    last_received_packet_info_ = undecryptable_packet->packet_info;
+    last_size_ = undecryptable_packet->packet->length();
+    current_packet_data_ = undecryptable_packet->packet->data();
+    const bool processed = framer_.ProcessPacket(*undecryptable_packet->packet);
+    current_packet_data_ = nullptr;
+
+    if (processed) {
+      QUIC_DVLOG(1) << ENDPOINT << "Processed undecryptable packet!";
+      iter = undecryptable_packets_.erase(iter);
+      ++stats_.packets_processed;
+      continue;
+    }
+    const bool has_decryption_key = version().KnowsWhichDecrypterToUse() &&
+                                    framer_.HasDecrypterOfEncryptionLevel(
+                                        undecryptable_packet->encryption_level);
+    if (framer_.error() == QUIC_DECRYPTION_FAILURE &&
+        ShouldEnqueueUnDecryptablePacket(undecryptable_packet->encryption_level,
+                                         has_decryption_key)) {
+      QUIC_DVLOG(1)
+          << ENDPOINT
+          << "Need to attempt to process this undecryptable packet later";
+      ++iter;
+      continue;
+    }
+    iter = undecryptable_packets_.erase(iter);
+  }
+
+  // Once handshake is complete, there will be no new keys installed and hence
+  // any undecryptable packets will never be able to be decrypted.
+  if (IsHandshakeComplete()) {
+    if (debug_visitor_ != nullptr) {
+      for (const auto& undecryptable_packet : undecryptable_packets_) {
+        debug_visitor_->OnUndecryptablePacket(
+            undecryptable_packet.encryption_level, /*dropped=*/true);
+      }
+    }
+    undecryptable_packets_.clear();
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
+      SetRetransmissionAlarm();
+    } else if (!retransmission_alarm_->IsSet() ||
+               undecryptable_packets_.empty() ||
+               GetRetransmissionDeadline() <
+                   retransmission_alarm_->deadline()) {
+      // 1) If there is still undecryptable packet, only re-arm PTO to make it
+      // sooner to speed up recovery.
+      // 2) If all undecryptable packets get processed, re-arm (which may
+      // postpone) PTO since no immediate recovery is needed.
+      SetRetransmissionAlarm();
+    }
+  }
+}
+
+void QuicConnection::QueueCoalescedPacket(const QuicEncryptedPacket& packet) {
+  QUIC_DVLOG(1) << ENDPOINT << "Queueing coalesced packet.";
+  received_coalesced_packets_.push_back(packet.Clone());
+  ++stats_.num_coalesced_packets_received;
+}
+
+bool QuicConnection::MaybeProcessCoalescedPackets() {
+  bool processed = false;
+  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_creator_.FlushCurrentPacket();
+    if (!connected_) {
+      return processed;
+    }
+
+    std::unique_ptr<QuicEncryptedPacket> packet =
+        std::move(received_coalesced_packets_.front());
+    received_coalesced_packets_.pop_front();
+
+    QUIC_DVLOG(1) << ENDPOINT << "Processing coalesced packet";
+    if (framer_.ProcessPacket(*packet)) {
+      processed = true;
+      ++stats_.num_coalesced_packets_processed;
+    } else {
+      // If we are unable to decrypt this packet, it might be
+      // because the CHLO or SHLO packet was lost.
+    }
+  }
+  if (processed) {
+    MaybeProcessUndecryptablePackets();
+    MaybeSendInResponseToPacket();
+  }
+  return processed;
+}
+
+void QuicConnection::CloseConnection(
+    QuicErrorCode error,
+    const std::string& details,
+    ConnectionCloseBehavior connection_close_behavior) {
+  CloseConnection(error, NO_IETF_QUIC_ERROR, details,
+                  connection_close_behavior);
+}
+
+void QuicConnection::CloseConnection(
+    QuicErrorCode error,
+    QuicIetfTransportErrorCodes ietf_error,
+    const std::string& error_details,
+    ConnectionCloseBehavior connection_close_behavior) {
+  QUICHE_DCHECK(!error_details.empty());
+  if (!connected_) {
+    QUIC_DLOG(INFO) << "Connection is already closed.";
+    return;
+  }
+
+  if (ietf_error != NO_IETF_QUIC_ERROR) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
+                    << ", with wire error: " << ietf_error
+                    << ", error: " << QuicErrorCodeToString(error)
+                    << ", and details:  " << error_details;
+  } else {
+    QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
+                    << ", with error: " << QuicErrorCodeToString(error) << " ("
+                    << error << "), and details:  " << error_details;
+  }
+
+  if (connection_close_behavior != ConnectionCloseBehavior::SILENT_CLOSE) {
+    SendConnectionClosePacket(error, ietf_error, error_details);
+  }
+
+  TearDownLocalConnectionState(error, ietf_error, error_details,
+                               ConnectionCloseSource::FROM_SELF);
+}
+
+void QuicConnection::SendConnectionClosePacket(
+    QuicErrorCode error,
+    QuicIetfTransportErrorCodes ietf_error,
+    const std::string& details) {
+  // Always use the current path to send CONNECTION_CLOSE.
+  QuicPacketCreator::ScopedPeerAddressContext context(
+      &packet_creator_, peer_address(), default_path_.client_connection_id,
+      default_path_.server_connection_id, connection_migration_use_new_cid_);
+  if (!SupportsMultiplePacketNumberSpaces()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet.";
+    ScopedEncryptionLevelContext context(this,
+                                         GetConnectionCloseEncryptionLevel());
+    if (version().CanSendCoalescedPackets()) {
+      coalesced_packet_.Clear();
+    }
+    ClearQueuedPackets();
+    // If there was a packet write error, write the smallest close possible.
+    ScopedPacketFlusher flusher(this);
+    // Always bundle an ACK with connection close for debugging purpose.
+    if (error != QUIC_PACKET_WRITE_ERROR &&
+        !uber_received_packet_manager_.IsAckFrameEmpty(
+            QuicUtils::GetPacketNumberSpace(encryption_level_)) &&
+        !packet_creator_.has_ack()) {
+      SendAck();
+    }
+    QuicConnectionCloseFrame* frame;
+
+    frame = new QuicConnectionCloseFrame(transport_version(), error, ietf_error,
+                                         details,
+                                         framer_.current_received_frame_type());
+    packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
+    packet_creator_.FlushCurrentPacket();
+    if (version().CanSendCoalescedPackets()) {
+      FlushCoalescedPacket();
+    }
+    ClearQueuedPackets();
+    return;
+  }
+  ScopedPacketFlusher flusher(this);
+
+  // Now that the connection is being closed, discard any unsent packets
+  // so the only packets to be sent will be connection close packets.
+  if (version().CanSendCoalescedPackets()) {
+    coalesced_packet_.Clear();
+  }
+  ClearQueuedPackets();
+
+  for (EncryptionLevel level :
+       {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
+        ENCRYPTION_FORWARD_SECURE}) {
+    if (!framer_.HasEncrypterOfEncryptionLevel(level)) {
+      continue;
+    }
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Sending connection close packet at level: " << level;
+    ScopedEncryptionLevelContext context(this, level);
+    // Bundle an ACK of the corresponding packet number space for debugging
+    // purpose.
+    if (error != QUIC_PACKET_WRITE_ERROR &&
+        !uber_received_packet_manager_.IsAckFrameEmpty(
+            QuicUtils::GetPacketNumberSpace(encryption_level_)) &&
+        !packet_creator_.has_ack()) {
+      QuicFrames frames;
+      frames.push_back(GetUpdatedAckFrame());
+      packet_creator_.FlushAckFrame(frames);
+    }
+
+    if (level == ENCRYPTION_FORWARD_SECURE &&
+        perspective_ == Perspective::IS_SERVER) {
+      visitor_->BeforeConnectionCloseSent();
+    }
+
+    auto* frame = new QuicConnectionCloseFrame(
+        transport_version(), error, ietf_error, details,
+        framer_.current_received_frame_type());
+    if (level == ENCRYPTION_FORWARD_SECURE) {
+      if (connection_close_frame_sent_.has_value()) {
+        QUIC_BUG(quic_send_multiple_connection_closes)
+            << ENDPOINT << "Already sent connection close: "
+            << connection_close_frame_sent_.value()
+            << ", going to send connection close: " << *frame;
+      } else {
+        connection_close_frame_sent_ = *frame;
+      }
+    }
+    packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
+    packet_creator_.FlushCurrentPacket();
+  }
+  if (version().CanSendCoalescedPackets()) {
+    FlushCoalescedPacket();
+  }
+  // Since the connection is closing, if the connection close packets were not
+  // sent, then they should be discarded.
+  ClearQueuedPackets();
+}
+
+void QuicConnection::TearDownLocalConnectionState(
+    QuicErrorCode error,
+    QuicIetfTransportErrorCodes ietf_error,
+    const std::string& error_details,
+    ConnectionCloseSource source) {
+  QuicConnectionCloseFrame frame(transport_version(), error, ietf_error,
+                                 error_details,
+                                 framer_.current_received_frame_type());
+  return TearDownLocalConnectionState(frame, source);
+}
+
+void QuicConnection::TearDownLocalConnectionState(
+    const QuicConnectionCloseFrame& frame,
+    ConnectionCloseSource source) {
+  if (!connected_) {
+    QUIC_DLOG(INFO) << "Connection is already closed.";
+    return;
+  }
+
+  // If we are using a batch writer, flush packets queued in it, if any.
+  FlushPackets();
+  connected_ = false;
+  QUICHE_DCHECK(visitor_ != nullptr);
+  visitor_->OnConnectionClosed(frame, source);
+  // LossDetectionTunerInterface::Finish() may be called from
+  // sent_packet_manager_.OnConnectionClosed. Which may require the session to
+  // finish its business first.
+  sent_packet_manager_.OnConnectionClosed();
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnConnectionClosed(frame, source);
+  }
+  // Cancel the alarms so they don't trigger any action now that the
+  // connection is closed.
+  CancelAllAlarms();
+  if (use_path_validator_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 3, 4);
+    CancelPathValidation();
+  }
+  peer_issued_cid_manager_.reset();
+  self_issued_cid_manager_.reset();
+}
+
+void QuicConnection::CancelAllAlarms() {
+  QUIC_DVLOG(1) << "Cancelling all QuicConnection alarms.";
+
+  ack_alarm_->PermanentCancel();
+  ping_alarm_->PermanentCancel();
+  retransmission_alarm_->PermanentCancel();
+  send_alarm_->PermanentCancel();
+  mtu_discovery_alarm_->PermanentCancel();
+  process_undecryptable_packets_alarm_->PermanentCancel();
+  discard_previous_one_rtt_keys_alarm_->PermanentCancel();
+  discard_zero_rtt_decryption_keys_alarm_->PermanentCancel();
+  blackhole_detector_.StopDetection(/*permanent=*/true);
+  idle_network_detector_.StopDetection();
+}
+
+QuicByteCount QuicConnection::max_packet_length() const {
+  return packet_creator_.max_packet_length();
+}
+
+void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
+  long_term_mtu_ = length;
+  stats_.max_egress_mtu = std::max(stats_.max_egress_mtu, long_term_mtu_);
+  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+}
+
+bool QuicConnection::HasQueuedData() const {
+  return packet_creator_.HasPendingFrames() || !buffered_packets_.empty();
+}
+
+void QuicConnection::SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
+                                        QuicTime::Delta idle_timeout) {
+  QUIC_BUG_IF(quic_bug_12714_29, idle_timeout > handshake_timeout)
+      << "idle_timeout:" << idle_timeout.ToMilliseconds()
+      << " handshake_timeout:" << handshake_timeout.ToMilliseconds();
+  // Adjust the idle timeout on client and server to prevent clients from
+  // sending requests to servers which have already closed the connection.
+  if (perspective_ == Perspective::IS_SERVER) {
+    idle_timeout = idle_timeout + QuicTime::Delta::FromSeconds(3);
+  } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) {
+    idle_timeout = idle_timeout - QuicTime::Delta::FromSeconds(1);
+  }
+  idle_network_detector_.SetTimeouts(handshake_timeout, idle_timeout);
+}
+
+void QuicConnection::SetPingAlarm() {
+  if (!connected_) {
+    return;
+  }
+  if (perspective_ == Perspective::IS_SERVER &&
+      initial_retransmittable_on_wire_timeout_.IsInfinite()) {
+    // The PING alarm exists to support two features:
+    // 1) clients send PINGs every 15s to prevent NAT timeouts,
+    // 2) both clients and servers can send retransmittable on the wire PINGs
+    // (ROWP) while ShouldKeepConnectionAlive is true and there is no packets in
+    // flight.
+    return;
+  }
+  if (!visitor_->ShouldKeepConnectionAlive()) {
+    ping_alarm_->Cancel();
+    // Don't send a ping unless the application (ie: HTTP/3) says to, usually
+    // because it is expecting a response from the server.
+    return;
+  }
+  if (initial_retransmittable_on_wire_timeout_.IsInfinite() ||
+      sent_packet_manager_.HasInFlightPackets() ||
+      retransmittable_on_wire_ping_count_ >
+          GetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count)) {
+    if (perspective_ == Perspective::IS_CLIENT) {
+      // Clients send 15s PINGs to avoid NATs from timing out.
+      ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
+                          QuicTime::Delta::FromSeconds(1));
+    } else {
+      // Servers do not send 15s PINGs.
+      ping_alarm_->Cancel();
+    }
+    return;
+  }
+  QUICHE_DCHECK_LT(initial_retransmittable_on_wire_timeout_, ping_timeout_);
+  QuicTime::Delta retransmittable_on_wire_timeout =
+      initial_retransmittable_on_wire_timeout_;
+  int max_aggressive_retransmittable_on_wire_ping_count =
+      GetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count);
+  QUICHE_DCHECK_LE(0, max_aggressive_retransmittable_on_wire_ping_count);
+  if (consecutive_retransmittable_on_wire_ping_count_ >
+      max_aggressive_retransmittable_on_wire_ping_count) {
+    // Exponentially back off the timeout if the number of consecutive
+    // retransmittable on wire pings has exceeds the allowance.
+    int shift = consecutive_retransmittable_on_wire_ping_count_ -
+                max_aggressive_retransmittable_on_wire_ping_count;
+    retransmittable_on_wire_timeout =
+        initial_retransmittable_on_wire_timeout_ * (1 << shift);
+  }
+  // If it's already set to an earlier time, then don't update it.
+  if (ping_alarm_->IsSet() &&
+      ping_alarm_->deadline() <
+          clock_->ApproximateNow() + retransmittable_on_wire_timeout) {
+    return;
+  }
+
+  if (retransmittable_on_wire_timeout < ping_timeout_) {
+    // Use a shorter timeout if there are open streams, but nothing on the wire.
+    ping_alarm_->Update(
+        clock_->ApproximateNow() + retransmittable_on_wire_timeout,
+        kAlarmGranularity);
+    if (max_aggressive_retransmittable_on_wire_ping_count != 0) {
+      consecutive_retransmittable_on_wire_ping_count_++;
+    }
+    retransmittable_on_wire_ping_count_++;
+    return;
+  }
+
+  ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
+                      kAlarmGranularity);
+}
+
+void QuicConnection::SetRetransmissionAlarm() {
+  if (!connected_) {
+    if (retransmission_alarm_->IsSet()) {
+      QUIC_BUG(quic_bug_10511_29)
+          << ENDPOINT << "Retransmission alarm is set while disconnected";
+      retransmission_alarm_->Cancel();
+    }
+    return;
+  }
+  if (packet_creator_.PacketFlusherAttached()) {
+    pending_retransmission_alarm_ = true;
+    return;
+  }
+  if (LimitedByAmplificationFactor()) {
+    // Do not set retransmission timer if connection is anti-amplification limit
+    // throttled. Otherwise, nothing can be sent when timer fires.
+    retransmission_alarm_->Cancel();
+    return;
+  }
+  PacketNumberSpace packet_number_space;
+  if (sent_packet_manager_.simplify_set_retransmission_alarm() &&
+      SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() &&
+      !sent_packet_manager_
+           .GetEarliestPacketSentTimeForPto(&packet_number_space)
+           .IsInitialized()) {
+    // Before handshake gets confirmed, GetEarliestPacketSentTimeForPto
+    // returning 0 indicates no packets are in flight or only application data
+    // is in flight.
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_simplify_set_retransmission_alarm, 2, 2);
+    if (perspective_ == Perspective::IS_SERVER) {
+      // No need to arm PTO on server side.
+      retransmission_alarm_->Cancel();
+      return;
+    }
+    if (retransmission_alarm_->IsSet() &&
+        GetRetransmissionDeadline() > retransmission_alarm_->deadline()) {
+      // Do not postpone armed PTO on the client side.
+      return;
+    }
+  }
+
+  retransmission_alarm_->Update(GetRetransmissionDeadline(), kAlarmGranularity);
+}
+
+void QuicConnection::MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number) {
+  if (mtu_discovery_alarm_->IsSet() ||
+      !mtu_discoverer_.ShouldProbeMtu(sent_packet_number)) {
+    return;
+  }
+  mtu_discovery_alarm_->Set(clock_->ApproximateNow());
+}
+
+QuicConnection::ScopedPacketFlusher::ScopedPacketFlusher(
+    QuicConnection* connection)
+    : connection_(connection),
+      flush_and_set_pending_retransmission_alarm_on_delete_(false),
+      handshake_packet_sent_(connection != nullptr &&
+                             connection->handshake_packet_sent_) {
+  if (connection_ == nullptr) {
+    return;
+  }
+
+  if (!connection_->packet_creator_.PacketFlusherAttached()) {
+    flush_and_set_pending_retransmission_alarm_on_delete_ = true;
+    connection->packet_creator_.AttachPacketFlusher();
+  }
+}
+
+QuicConnection::ScopedPacketFlusher::~ScopedPacketFlusher() {
+  if (connection_ == nullptr || !connection_->connected()) {
+    return;
+  }
+
+  if (flush_and_set_pending_retransmission_alarm_on_delete_) {
+    const QuicTime ack_timeout =
+        connection_->uber_received_packet_manager_.GetEarliestAckTimeout();
+    if (ack_timeout.IsInitialized()) {
+      if (ack_timeout <= connection_->clock_->ApproximateNow() &&
+          !connection_->CanWrite(NO_RETRANSMITTABLE_DATA)) {
+        // Cancel ACK alarm if connection is write blocked, and ACK will be
+        // sent when connection gets unblocked.
+        connection_->ack_alarm_->Cancel();
+      } else if (!connection_->ack_alarm_->IsSet() ||
+                 connection_->ack_alarm_->deadline() > ack_timeout) {
+        connection_->ack_alarm_->Update(ack_timeout, QuicTime::Delta::Zero());
+      }
+    }
+    if (connection_->ack_alarm_->IsSet() &&
+        connection_->ack_alarm_->deadline() <=
+            connection_->clock_->ApproximateNow()) {
+      // An ACK needs to be sent right now. This ACK did not get bundled
+      // because either there was no data to write or packets were marked as
+      // received after frames were queued in the generator.
+      if (connection_->send_alarm_->IsSet() &&
+          connection_->send_alarm_->deadline() <=
+              connection_->clock_->ApproximateNow()) {
+        // If send alarm will go off soon, let send alarm send the ACK.
+        connection_->ack_alarm_->Cancel();
+      } else if (connection_->SupportsMultiplePacketNumberSpaces()) {
+        connection_->SendAllPendingAcks();
+      } else {
+        connection_->SendAck();
+      }
+    }
+
+    if (connection_->flush_after_coalesce_higher_space_packets_) {
+      // INITIAL or HANDSHAKE retransmission could cause peer to derive new
+      // keys, such that the buffered undecryptable packets may be processed.
+      // This endpoint would derive an inflated RTT sample when receiving ACKs
+      // of those undecryptable packets. To mitigate this, tries to coalesce as
+      // many higher space packets as possible (via for loop inside
+      // MaybeCoalescePacketOfHigherSpace) to fill the remaining space in the
+      // coalescer.
+      QUIC_RELOADABLE_FLAG_COUNT(
+          quic_flush_after_coalesce_higher_space_packets);
+      if (connection_->version().CanSendCoalescedPackets()) {
+        connection_->MaybeCoalescePacketOfHigherSpace();
+      }
+      connection_->packet_creator_.Flush();
+      if (connection_->version().CanSendCoalescedPackets()) {
+        connection_->FlushCoalescedPacket();
+      }
+    } else {
+      connection_->packet_creator_.Flush();
+      if (connection_->version().CanSendCoalescedPackets()) {
+        connection_->MaybeCoalescePacketOfHigherSpace();
+        connection_->FlushCoalescedPacket();
+      }
+    }
+    connection_->FlushPackets();
+    if (!handshake_packet_sent_ && connection_->handshake_packet_sent_) {
+      // This would cause INITIAL key to be dropped. Drop keys here to avoid
+      // missing the write keys in the middle of writing.
+      connection_->visitor_->OnHandshakePacketSent();
+    }
+    // Reset transmission type.
+    connection_->SetTransmissionType(NOT_RETRANSMISSION);
+
+    // Once all transmissions are done, check if there is any outstanding data
+    // to send and notify the congestion controller if not.
+    //
+    // Note that this means that the application limited check will happen as
+    // soon as the last flusher gets destroyed, which is typically after a
+    // single stream write is finished.  This means that if all the data from a
+    // single write goes through the connection, the application-limited signal
+    // will fire even if the caller does a write operation immediately after.
+    // There are two important approaches to remedy this situation:
+    // (1) Instantiate ScopedPacketFlusher before performing multiple subsequent
+    //     writes, thus deferring this check until all writes are done.
+    // (2) Write data in chunks sufficiently large so that they cause the
+    //     connection to be limited by the congestion control.  Typically, this
+    //     would mean writing chunks larger than the product of the current
+    //     pacing rate and the pacer granularity.  So, for instance, if the
+    //     pacing rate of the connection is 1 Gbps, and the pacer granularity is
+    //     1 ms, the caller should send at least 125k bytes in order to not
+    //     be marked as application-limited.
+    connection_->CheckIfApplicationLimited();
+
+    if (connection_->pending_retransmission_alarm_) {
+      connection_->SetRetransmissionAlarm();
+      connection_->pending_retransmission_alarm_ = false;
+    }
+  }
+  QUICHE_DCHECK_EQ(flush_and_set_pending_retransmission_alarm_on_delete_,
+                   !connection_->packet_creator_.PacketFlusherAttached());
+}
+
+QuicConnection::ScopedEncryptionLevelContext::ScopedEncryptionLevelContext(
+    QuicConnection* connection,
+    EncryptionLevel encryption_level)
+    : connection_(connection), latched_encryption_level_(ENCRYPTION_INITIAL) {
+  if (connection_ == nullptr) {
+    return;
+  }
+  latched_encryption_level_ = connection_->encryption_level_;
+  connection_->SetDefaultEncryptionLevel(encryption_level);
+}
+
+QuicConnection::ScopedEncryptionLevelContext::~ScopedEncryptionLevelContext() {
+  if (connection_ == nullptr || !connection_->connected_) {
+    return;
+  }
+  connection_->SetDefaultEncryptionLevel(latched_encryption_level_);
+}
+
+QuicConnection::BufferedPacket::BufferedPacket(
+    const SerializedPacket& packet,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address)
+    : encrypted_buffer(CopyBuffer(packet), packet.encrypted_length),
+      self_address(self_address),
+      peer_address(peer_address) {}
+
+QuicConnection::BufferedPacket::BufferedPacket(
+    char* encrypted_buffer,
+    QuicPacketLength encrypted_length,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address)
+    : encrypted_buffer(CopyBuffer(encrypted_buffer, encrypted_length),
+                       encrypted_length),
+      self_address(self_address),
+      peer_address(peer_address) {}
+
+QuicConnection::BufferedPacket::~BufferedPacket() {
+  delete[] encrypted_buffer.data();
+}
+
+HasRetransmittableData QuicConnection::IsRetransmittable(
+    const SerializedPacket& packet) {
+  // Retransmitted packets retransmittable frames are owned by the unacked
+  // packet map, but are not present in the serialized packet.
+  if (packet.transmission_type != NOT_RETRANSMISSION ||
+      !packet.retransmittable_frames.empty()) {
+    return HAS_RETRANSMITTABLE_DATA;
+  } else {
+    return NO_RETRANSMITTABLE_DATA;
+  }
+}
+
+bool QuicConnection::IsTerminationPacket(const SerializedPacket& packet,
+                                         QuicErrorCode* error_code) {
+  if (packet.retransmittable_frames.empty()) {
+    return false;
+  }
+  for (const QuicFrame& frame : packet.retransmittable_frames) {
+    if (frame.type == CONNECTION_CLOSE_FRAME) {
+      *error_code = frame.connection_close_frame->quic_error_code;
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) {
+  QUIC_DVLOG(2) << ENDPOINT << "SetMtuDiscoveryTarget: " << target;
+  mtu_discoverer_.Disable();
+  mtu_discoverer_.Enable(max_packet_length(), GetLimitedMaxPacketSize(target));
+}
+
+QuicByteCount QuicConnection::GetLimitedMaxPacketSize(
+    QuicByteCount suggested_max_packet_size) {
+  if (!peer_address().IsInitialized()) {
+    QUIC_BUG(quic_bug_10511_30)
+        << "Attempted to use a connection without a valid peer address";
+    return suggested_max_packet_size;
+  }
+
+  const QuicByteCount writer_limit = writer_->GetMaxPacketSize(peer_address());
+
+  QuicByteCount max_packet_size = suggested_max_packet_size;
+  if (max_packet_size > writer_limit) {
+    max_packet_size = writer_limit;
+  }
+  if (max_packet_size > peer_max_packet_size_) {
+    max_packet_size = peer_max_packet_size_;
+  }
+  if (max_packet_size > kMaxOutgoingPacketSize) {
+    max_packet_size = kMaxOutgoingPacketSize;
+  }
+  return max_packet_size;
+}
+
+void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) {
+  // Currently, this limit is ensured by the caller.
+  QUICHE_DCHECK_EQ(target_mtu, GetLimitedMaxPacketSize(target_mtu));
+
+  // Send the probe.
+  packet_creator_.GenerateMtuDiscoveryPacket(target_mtu);
+}
+
+// TODO(zhongyi): change this method to generate a connectivity probing packet
+// and let the caller to call writer to write the packet and handle write
+// status.
+bool QuicConnection::SendConnectivityProbingPacket(
+    QuicPacketWriter* probing_writer,
+    const QuicSocketAddress& peer_address) {
+  QUICHE_DCHECK(peer_address.IsInitialized());
+  if (!connected_) {
+    QUIC_BUG(quic_bug_10511_31)
+        << "Not sending connectivity probing packet as connection is "
+        << "disconnected.";
+    return false;
+  }
+  if (perspective_ == Perspective::IS_SERVER && probing_writer == nullptr) {
+    // Server can use default packet writer to write packet.
+    probing_writer = writer_;
+  }
+  QUICHE_DCHECK(probing_writer);
+
+  if (probing_writer->IsWriteBlocked()) {
+    QUIC_DLOG(INFO)
+        << ENDPOINT
+        << "Writer blocked when sending connectivity probing packet.";
+    if (probing_writer == writer_) {
+      // Visitor should not be write blocked if the probing writer is not the
+      // default packet writer.
+      visitor_->OnWriteBlocked();
+    }
+    return true;
+  }
+
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "Sending path probe packet for connection_id = "
+                  << default_path_.server_connection_id;
+
+  std::unique_ptr<SerializedPacket> probing_packet;
+  if (!version().HasIetfQuicFrames()) {
+    // Non-IETF QUIC, generate a padded ping regardless of whether this is a
+    // request or a response.
+    probing_packet = packet_creator_.SerializeConnectivityProbingPacket();
+  } else {
+    // IETF QUIC path challenge.
+    // Send a path probe request using IETF QUIC PATH_CHALLENGE frame.
+    transmitted_connectivity_probe_payload_ =
+        std::make_unique<QuicPathFrameBuffer>();
+    random_generator_->RandBytes(transmitted_connectivity_probe_payload_.get(),
+                                 sizeof(QuicPathFrameBuffer));
+    probing_packet =
+        packet_creator_.SerializePathChallengeConnectivityProbingPacket(
+            *transmitted_connectivity_probe_payload_);
+    if (!probing_packet) {
+      transmitted_connectivity_probe_payload_ = nullptr;
+    }
+  }
+  QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
+  return WritePacketUsingWriter(std::move(probing_packet), probing_writer,
+                                self_address(), peer_address,
+                                /*measure_rtt=*/true);
+}
+
+bool QuicConnection::WritePacketUsingWriter(
+    std::unique_ptr<SerializedPacket> packet,
+    QuicPacketWriter* writer,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    bool measure_rtt) {
+  const QuicTime packet_send_time = clock_->Now();
+  QUIC_DVLOG(2) << ENDPOINT
+                << "Sending path probe packet for server connection ID "
+                << default_path_.server_connection_id << std::endl
+                << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                       packet->encrypted_buffer, packet->encrypted_length));
+  WriteResult result = writer->WritePacket(
+      packet->encrypted_buffer, packet->encrypted_length, self_address.host(),
+      peer_address, per_packet_options_);
+
+  // If using a batch writer and the probing packet is buffered, flush it.
+  if (writer->IsBatchMode() && result.status == WRITE_STATUS_OK &&
+      result.bytes_written == 0) {
+    result = writer->Flush();
+  }
+
+  if (IsWriteError(result.status)) {
+    // Write error for any connectivity probe should not affect the connection
+    // as it is sent on a different path.
+    QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet failed with error = "
+                    << result.error_code;
+    return false;
+  }
+
+  // Send in currrent path. Call OnPacketSent regardless of the write result.
+  sent_packet_manager_.OnPacketSent(packet.get(), packet_send_time,
+                                    packet->transmission_type,
+                                    NO_RETRANSMITTABLE_DATA, measure_rtt);
+
+  if (debug_visitor_ != nullptr) {
+    if (sent_packet_manager_.unacked_packets().empty()) {
+      QUIC_BUG(quic_bug_10511_32)
+          << "Unacked map is empty right after packet is sent";
+    } else {
+      debug_visitor_->OnPacketSent(
+          packet->packet_number, packet->encrypted_length,
+          packet->has_crypto_handshake, packet->transmission_type,
+          packet->encryption_level,
+          sent_packet_manager_.unacked_packets()
+              .rbegin()
+              ->retransmittable_frames,
+          packet->nonretransmittable_frames, packet_send_time);
+    }
+  }
+
+  if (IsWriteBlockedStatus(result.status)) {
+    if (writer == writer_) {
+      // Visitor should not be write blocked if the probing writer is not the
+      // default packet writer.
+      visitor_->OnWriteBlocked();
+    }
+    if (result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
+      QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet blocked";
+    }
+  }
+
+  return true;
+}
+
+void QuicConnection::DisableMtuDiscovery() {
+  mtu_discoverer_.Disable();
+  mtu_discovery_alarm_->Cancel();
+}
+
+void QuicConnection::DiscoverMtu() {
+  QUICHE_DCHECK(!mtu_discovery_alarm_->IsSet());
+
+  const QuicPacketNumber largest_sent_packet =
+      sent_packet_manager_.GetLargestSentPacket();
+  if (mtu_discoverer_.ShouldProbeMtu(largest_sent_packet)) {
+    ++mtu_probe_count_;
+    SendMtuDiscoveryPacket(
+        mtu_discoverer_.GetUpdatedMtuProbeSize(largest_sent_packet));
+  }
+  QUICHE_DCHECK(!mtu_discovery_alarm_->IsSet());
+}
+
+void QuicConnection::OnEffectivePeerMigrationValidated() {
+  if (active_effective_peer_migration_type_ == NO_CHANGE) {
+    QUIC_BUG(quic_bug_10511_33) << "No migration underway.";
+    return;
+  }
+  highest_packet_sent_before_effective_peer_migration_.Clear();
+  const bool send_address_token =
+      active_effective_peer_migration_type_ != PORT_CHANGE;
+  active_effective_peer_migration_type_ = NO_CHANGE;
+  ++stats_.num_validated_peer_migration;
+  if (!validate_client_addresses_) {
+    return;
+  }
+  QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 2, 6);
+  if (debug_visitor_ != nullptr) {
+    const QuicTime now = clock_->ApproximateNow();
+    if (now >= stats_.handshake_completion_time) {
+      debug_visitor_->OnPeerMigrationValidated(
+          now - stats_.handshake_completion_time);
+    } else {
+      QUIC_BUG(quic_bug_10511_34)
+          << "Handshake completion time is larger than current time.";
+    }
+  }
+
+  // Lift anti-amplification limit.
+  default_path_.validated = true;
+  alternative_path_.Clear();
+  if (send_address_token) {
+    visitor_->MaybeSendAddressToken();
+  }
+}
+
+void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
+  // TODO(fayang): Currently, all peer address change type are allowed. Need to
+  // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
+  // determine whether |type| is allowed.
+  if (!validate_client_addresses_) {
+    if (type == NO_CHANGE) {
+      QUIC_BUG(quic_bug_10511_35)
+          << "EffectivePeerMigration started without address change.";
+      return;
+    }
+    QUIC_DLOG(INFO)
+        << ENDPOINT << "Effective peer's ip:port changed from "
+        << default_path_.peer_address.ToString() << " to "
+        << GetEffectivePeerAddressFromCurrentPacket().ToString()
+        << ", address change type is " << type
+        << ", migrating connection without validating new client address.";
+
+    highest_packet_sent_before_effective_peer_migration_ =
+        sent_packet_manager_.GetLargestSentPacket();
+    default_path_.peer_address = GetEffectivePeerAddressFromCurrentPacket();
+    active_effective_peer_migration_type_ = type;
+
+    OnConnectionMigration();
+    return;
+  }
+
+  QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 3, 6);
+  if (type == NO_CHANGE) {
+    UpdatePeerAddress(last_received_packet_info_.source_address);
+    QUIC_BUG(quic_bug_10511_36)
+        << "EffectivePeerMigration started without address change.";
+    return;
+  }
+  if (GetQuicReloadableFlag(
+          quic_flush_pending_frames_and_padding_bytes_on_migration)) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_flush_pending_frames_and_padding_bytes_on_migration);
+    // There could be pending NEW_TOKEN_FRAME triggered by non-probing
+    // PATH_RESPONSE_FRAME in the same packet or pending padding bytes in the
+    // packet creator.
+    packet_creator_.FlushCurrentPacket();
+    packet_creator_.SendRemainingPendingPadding();
+    if (!connected_) {
+      return;
+    }
+  } else {
+    if (packet_creator_.HasPendingFrames()) {
+      packet_creator_.FlushCurrentPacket();
+      if (!connected_) {
+        return;
+      }
+    }
+  }
+
+  // Action items:
+  //   1. Switch congestion controller;
+  //   2. Update default_path_ (addresses, validation and bytes accounting);
+  //   3. Save previous default path if needed;
+  //   4. Kick off reverse path validation if needed.
+  // Items 1 and 2 are must-to-do. Items 3 and 4 depends on if the new address
+  // is validated or not and which path the incoming packet is on.
+
+  const QuicSocketAddress current_effective_peer_address =
+      GetEffectivePeerAddressFromCurrentPacket();
+  QUIC_DLOG(INFO) << ENDPOINT << "Effective peer's ip:port changed from "
+                  << default_path_.peer_address.ToString() << " to "
+                  << current_effective_peer_address.ToString()
+                  << ", address change type is " << type
+                  << ", migrating connection.";
+
+  const QuicSocketAddress previous_direct_peer_address = direct_peer_address_;
+  PathState previous_default_path = std::move(default_path_);
+  active_effective_peer_migration_type_ = type;
+  MaybeClearQueuedPacketsOnPathChange();
+  OnConnectionMigration();
+
+  // Update congestion controller if the address change type is not PORT_CHANGE.
+  if (type == PORT_CHANGE) {
+    QUICHE_DCHECK(previous_default_path.validated ||
+                  (alternative_path_.validated &&
+                   alternative_path_.send_algorithm != nullptr));
+    // No need to store previous congestion controller because either the new
+    // default path is validated or the alternative path is validated and
+    // already has associated congestion controller.
+  } else {
+    previous_default_path.rtt_stats.emplace();
+    previous_default_path.rtt_stats->CloneFrom(
+        *sent_packet_manager_.GetRttStats());
+    // If the new peer address share the same IP with the alternative path, the
+    // connection should switch to the congestion controller of the alternative
+    // path. Otherwise, the connection should use a brand new one.
+    // In order to re-use existing code in sent_packet_manager_, reset
+    // congestion controller to initial state first and then change to the one
+    // on alternative path.
+    // TODO(danzh) combine these two steps into one after deprecating gQUIC.
+    previous_default_path.send_algorithm = OnPeerIpAddressChanged();
+
+    if (alternative_path_.peer_address.host() ==
+            current_effective_peer_address.host() &&
+        alternative_path_.send_algorithm != nullptr) {
+      // Update the default path with the congestion controller of the
+      // alternative path.
+      sent_packet_manager_.SetSendAlgorithm(
+          alternative_path_.send_algorithm.release());
+      sent_packet_manager_.SetRttStats(
+          std::move(alternative_path_.rtt_stats).value());
+    }
+  }
+  // Update to the new peer address.
+  UpdatePeerAddress(last_received_packet_info_.source_address);
+  // Update the default path.
+  if (IsAlternativePath(last_received_packet_info_.destination_address,
+                        current_effective_peer_address)) {
+    SetDefaultPathState(std::move(alternative_path_));
+  } else {
+    QuicConnectionId client_connection_id;
+    absl::optional<StatelessResetToken> stateless_reset_token;
+    FindMatchingOrNewClientConnectionIdOrToken(
+        previous_default_path, alternative_path_,
+        last_packet_destination_connection_id_, &client_connection_id,
+        &stateless_reset_token);
+    SetDefaultPathState(PathState(
+        last_received_packet_info_.destination_address,
+        current_effective_peer_address, client_connection_id,
+        last_packet_destination_connection_id_, stateless_reset_token));
+    // The path is considered validated if its peer IP address matches any
+    // validated path's peer IP address.
+    default_path_.validated =
+        (alternative_path_.peer_address.host() ==
+             current_effective_peer_address.host() &&
+         alternative_path_.validated) ||
+        (previous_default_path.validated && type == PORT_CHANGE);
+  }
+  if (!last_received_packet_info_.received_bytes_counted) {
+    // Increment bytes counting on the new default path.
+    default_path_.bytes_received_before_address_validation += last_size_;
+    last_received_packet_info_.received_bytes_counted = true;
+  }
+
+  if (!previous_default_path.validated) {
+    // If the old address is under validation, cancel and fail it. Failing to
+    // validate the old path shouldn't take any effect.
+    QUIC_DVLOG(1) << "Cancel validation of previous peer address change to "
+                  << previous_default_path.peer_address
+                  << " upon peer migration to " << default_path_.peer_address;
+    path_validator_.CancelPathValidation();
+    ++stats_.num_peer_migration_while_validating_default_path;
+  }
+
+  // Clear alternative path if the new default path shares the same IP as the
+  // alternative path.
+  if (alternative_path_.peer_address.host() ==
+      default_path_.peer_address.host()) {
+    alternative_path_.Clear();
+  }
+
+  if (default_path_.validated) {
+    QUIC_DVLOG(1) << "Peer migrated to a validated address.";
+    // No need to save previous default path, validate new peer address or
+    // update bytes sent/received.
+    if (!(previous_default_path.validated && type == PORT_CHANGE)) {
+      // The alternative path was validated because of proactive reverse path
+      // validation.
+      ++stats_.num_peer_migration_to_proactively_validated_address;
+    }
+    OnEffectivePeerMigrationValidated();
+    return;
+  }
+
+  // The new default address is not validated yet. Anti-amplification limit is
+  // enforced.
+  QUICHE_DCHECK(EnforceAntiAmplificationLimit());
+  QUIC_DVLOG(1) << "Apply anti-amplification limit to effective peer address "
+                << default_path_.peer_address << " with "
+                << default_path_.bytes_sent_before_address_validation
+                << " bytes sent and "
+                << default_path_.bytes_received_before_address_validation
+                << " bytes received.";
+
+  QUICHE_DCHECK(!alternative_path_.peer_address.IsInitialized() ||
+                alternative_path_.peer_address.host() !=
+                    default_path_.peer_address.host());
+
+  // Save previous default path to the altenative path.
+  if (previous_default_path.validated) {
+    // The old path is a validated path which the connection might revert back
+    // to later. Store it as the alternative path.
+    alternative_path_ = std::move(previous_default_path);
+    QUICHE_DCHECK(alternative_path_.send_algorithm != nullptr);
+  }
+
+  // If the new address is not validated and the connection is not already
+  // validating that address, a new reverse path validation is needed.
+  if (!path_validator_.IsValidatingPeerAddress(
+          current_effective_peer_address)) {
+    ++stats_.num_reverse_path_validtion_upon_migration;
+    ValidatePath(std::make_unique<ReversePathValidationContext>(
+                     default_path_.self_address, peer_address(),
+                     default_path_.peer_address, this),
+                 std::make_unique<ReversePathValidationResultDelegate>(
+                     this, previous_direct_peer_address));
+  } else {
+    QUIC_DVLOG(1) << "Peer address " << default_path_.peer_address
+                  << " is already under validation, wait for result.";
+    ++stats_.num_peer_migration_to_proactively_validated_address;
+  }
+}
+
+void QuicConnection::OnConnectionMigration() {
+  if (debug_visitor_ != nullptr) {
+    const QuicTime now = clock_->ApproximateNow();
+    if (now >= stats_.handshake_completion_time) {
+      debug_visitor_->OnPeerAddressChange(
+          active_effective_peer_migration_type_,
+          now - stats_.handshake_completion_time);
+    }
+  }
+  visitor_->OnConnectionMigration(active_effective_peer_migration_type_);
+  if (active_effective_peer_migration_type_ != PORT_CHANGE &&
+      active_effective_peer_migration_type_ != IPV4_SUBNET_CHANGE &&
+      !validate_client_addresses_) {
+    sent_packet_manager_.OnConnectionMigration(/*reset_send_algorithm=*/false);
+  }
+}
+
+bool QuicConnection::IsCurrentPacketConnectivityProbing() const {
+  return is_current_packet_connectivity_probing_;
+}
+
+bool QuicConnection::ack_frame_updated() const {
+  return uber_received_packet_manager_.IsAckFrameUpdated();
+}
+
+absl::string_view QuicConnection::GetCurrentPacket() {
+  if (current_packet_data_ == nullptr) {
+    return absl::string_view();
+  }
+  return absl::string_view(current_packet_data_, last_size_);
+}
+
+bool QuicConnection::MaybeConsiderAsMemoryCorruption(
+    const QuicStreamFrame& frame) {
+  if (QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) ||
+      last_decrypted_packet_level_ != ENCRYPTION_INITIAL) {
+    return false;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER &&
+      frame.data_length >= sizeof(kCHLO) &&
+      strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kCHLO),
+              sizeof(kCHLO)) == 0) {
+    return true;
+  }
+
+  if (perspective_ == Perspective::IS_CLIENT &&
+      frame.data_length >= sizeof(kREJ) &&
+      strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kREJ),
+              sizeof(kREJ)) == 0) {
+    return true;
+  }
+
+  return false;
+}
+
+void QuicConnection::MaybeSendProbingRetransmissions() {
+  QUICHE_DCHECK(fill_up_link_during_probing_);
+
+  // Don't send probing retransmissions until the handshake has completed.
+  if (!IsHandshakeComplete() ||
+      sent_packet_manager().HasUnackedCryptoPackets()) {
+    return;
+  }
+
+  if (probing_retransmission_pending_) {
+    QUIC_BUG(quic_bug_10511_37)
+        << "MaybeSendProbingRetransmissions is called while another call "
+           "to it is already in progress";
+    return;
+  }
+
+  probing_retransmission_pending_ = true;
+  SendProbingRetransmissions();
+  probing_retransmission_pending_ = false;
+}
+
+void QuicConnection::CheckIfApplicationLimited() {
+  if (!connected_ || probing_retransmission_pending_) {
+    return;
+  }
+
+  bool application_limited =
+      buffered_packets_.empty() && !visitor_->WillingAndAbleToWrite();
+
+  if (!application_limited) {
+    return;
+  }
+
+  if (fill_up_link_during_probing_) {
+    MaybeSendProbingRetransmissions();
+    if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+      return;
+    }
+  }
+
+  sent_packet_manager_.OnApplicationLimited();
+}
+
+bool QuicConnection::UpdatePacketContent(QuicFrameType type) {
+  most_recent_frame_type_ = type;
+  if (version().HasIetfQuicFrames()) {
+    if (!QuicUtils::IsProbingFrame(type)) {
+      MaybeStartIetfPeerMigration();
+      return connected_;
+    }
+    QuicSocketAddress current_effective_peer_address =
+        GetEffectivePeerAddressFromCurrentPacket();
+    if (!count_bytes_on_alternative_path_separately_ ||
+        IsDefaultPath(last_received_packet_info_.destination_address,
+                      last_received_packet_info_.source_address)) {
+      return connected_;
+    }
+    QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 3, 5);
+    if (perspective_ == Perspective::IS_SERVER &&
+        type == PATH_CHALLENGE_FRAME &&
+        !IsAlternativePath(last_received_packet_info_.destination_address,
+                           current_effective_peer_address)) {
+      QUIC_DVLOG(1)
+          << "The peer is probing a new path with effective peer address "
+          << current_effective_peer_address << ",  self address "
+          << last_received_packet_info_.destination_address;
+      if (!validate_client_addresses_) {
+        QuicConnectionId client_cid;
+        absl::optional<StatelessResetToken> stateless_reset_token;
+        FindMatchingOrNewClientConnectionIdOrToken(
+            default_path_, alternative_path_,
+            last_packet_destination_connection_id_, &client_cid,
+            &stateless_reset_token);
+        alternative_path_ = PathState(
+            last_received_packet_info_.destination_address,
+            current_effective_peer_address, client_cid,
+            last_packet_destination_connection_id_, stateless_reset_token);
+      } else if (!default_path_.validated) {
+        QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 4, 6);
+        // Skip reverse path validation because either handshake hasn't
+        // completed or the connection is validating the default path. Using
+        // PATH_CHALLENGE to validate alternative client address before
+        // handshake gets comfirmed is meaningless because anyone can respond to
+        // it. If the connection is validating the default path, this
+        // alternative path is currently the only validated path which shouldn't
+        // be overridden.
+        QUIC_DVLOG(1) << "The connection hasn't finished handshake or is "
+                         "validating a recent peer address change.";
+        QUIC_BUG_IF(quic_bug_12714_30,
+                    IsHandshakeConfirmed() && !alternative_path_.validated)
+            << "No validated peer address to send after handshake comfirmed.";
+      } else if (!IsReceivedPeerAddressValidated()) {
+        QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 5, 6);
+        QuicConnectionId client_connection_id;
+        absl::optional<StatelessResetToken> stateless_reset_token;
+        FindMatchingOrNewClientConnectionIdOrToken(
+            default_path_, alternative_path_,
+            last_packet_destination_connection_id_, &client_connection_id,
+            &stateless_reset_token);
+        // Only override alternative path state upon receiving a PATH_CHALLENGE
+        // from an unvalidated peer address, and the connection isn't validating
+        // a recent peer migration.
+        alternative_path_ = PathState(
+            last_received_packet_info_.destination_address,
+            current_effective_peer_address, client_connection_id,
+            last_packet_destination_connection_id_, stateless_reset_token);
+        should_proactively_validate_peer_address_on_path_challenge_ = true;
+      }
+    }
+    MaybeUpdateBytesReceivedFromAlternativeAddress(last_size_);
+    return connected_;
+  }
+  // Packet content is tracked to identify connectivity probe in non-IETF
+  // version, where a connectivity probe is defined as
+  // - a padded PING packet with peer address change received by server,
+  // - a padded PING packet on new path received by client.
+
+  if (current_packet_content_ == NOT_PADDED_PING) {
+    // We have already learned the current packet is not a connectivity
+    // probing packet. Peer migration should have already been started earlier
+    // if needed.
+    return connected_;
+  }
+
+  if (type == PING_FRAME) {
+    if (current_packet_content_ == NO_FRAMES_RECEIVED) {
+      current_packet_content_ = FIRST_FRAME_IS_PING;
+      return connected_;
+    }
+  }
+
+  // In Google QUIC, we look for a packet with just a PING and PADDING.
+  // If the condition is met, mark things as connectivity-probing, causing
+  // later processing to generate the correct response.
+  if (type == PADDING_FRAME && current_packet_content_ == FIRST_FRAME_IS_PING) {
+    current_packet_content_ = SECOND_FRAME_IS_PADDING;
+    if (perspective_ == Perspective::IS_SERVER) {
+      is_current_packet_connectivity_probing_ =
+          current_effective_peer_migration_type_ != NO_CHANGE;
+      QUIC_DLOG_IF(INFO, is_current_packet_connectivity_probing_)
+          << ENDPOINT
+          << "Detected connectivity probing packet. "
+             "current_effective_peer_migration_type_:"
+          << current_effective_peer_migration_type_;
+    } else {
+      is_current_packet_connectivity_probing_ =
+          (last_received_packet_info_.source_address != peer_address()) ||
+          (last_received_packet_info_.destination_address !=
+           default_path_.self_address);
+      QUIC_DLOG_IF(INFO, is_current_packet_connectivity_probing_)
+          << ENDPOINT
+          << "Detected connectivity probing packet. "
+             "last_packet_source_address:"
+          << last_received_packet_info_.source_address
+          << ", peer_address_:" << peer_address()
+          << ", last_packet_destination_address:"
+          << last_received_packet_info_.destination_address
+          << ", default path self_address :" << default_path_.self_address;
+    }
+    return connected_;
+  }
+
+  current_packet_content_ = NOT_PADDED_PING;
+  if (GetLargestReceivedPacket().IsInitialized() &&
+      last_header_.packet_number == GetLargestReceivedPacket()) {
+    UpdatePeerAddress(last_received_packet_info_.source_address);
+    if (current_effective_peer_migration_type_ != NO_CHANGE) {
+      // Start effective peer migration immediately when the current packet is
+      // confirmed not a connectivity probing packet.
+      StartEffectivePeerMigration(current_effective_peer_migration_type_);
+    }
+  }
+  current_effective_peer_migration_type_ = NO_CHANGE;
+  return connected_;
+}
+
+void QuicConnection::MaybeStartIetfPeerMigration() {
+  QUICHE_DCHECK(version().HasIetfQuicFrames());
+  if (current_effective_peer_migration_type_ != NO_CHANGE &&
+      !IsHandshakeConfirmed()) {
+    QUIC_LOG_EVERY_N_SEC(INFO, 60)
+        << ENDPOINT << "Effective peer's ip:port changed from "
+        << default_path_.peer_address.ToString() << " to "
+        << GetEffectivePeerAddressFromCurrentPacket().ToString()
+        << " before handshake confirmed, "
+           "current_effective_peer_migration_type_: "
+        << current_effective_peer_migration_type_;
+    // Peer migrated before handshake gets confirmed.
+    CloseConnection((current_effective_peer_migration_type_ == PORT_CHANGE
+                         ? QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED
+                         : QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED),
+                    "Peer address changed before handshake is confirmed.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (GetLargestReceivedPacket().IsInitialized() &&
+      last_header_.packet_number == GetLargestReceivedPacket()) {
+    if (current_effective_peer_migration_type_ != NO_CHANGE) {
+      // Start effective peer migration when the current packet contains a
+      // non-probing frame.
+      // TODO(fayang): When multiple packet number spaces is supported, only
+      // start peer migration for the application data.
+      if (!validate_client_addresses_) {
+        UpdatePeerAddress(last_received_packet_info_.source_address);
+      }
+      StartEffectivePeerMigration(current_effective_peer_migration_type_);
+    } else {
+      UpdatePeerAddress(last_received_packet_info_.source_address);
+    }
+  }
+  current_effective_peer_migration_type_ = NO_CHANGE;
+}
+
+void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting,
+                                              bool acked_new_packet) {
+  if (no_stop_waiting_frames_ && !packet_creator_.has_ack()) {
+    uber_received_packet_manager_.DontWaitForPacketsBefore(
+        last_decrypted_packet_level_,
+        SupportsMultiplePacketNumberSpaces()
+            ? sent_packet_manager_.GetLargestPacketPeerKnowsIsAcked(
+                  last_decrypted_packet_level_)
+            : sent_packet_manager_.largest_packet_peer_knows_is_acked());
+  }
+  // Always reset the retransmission alarm when an ack comes in, since we now
+  // have a better estimate of the current rtt than when it was set.
+  SetRetransmissionAlarm();
+  if (acked_new_packet) {
+    OnForwardProgressMade();
+  } else if (default_enable_5rto_blackhole_detection_ &&
+             !sent_packet_manager_.HasInFlightPackets() &&
+             blackhole_detector_.IsDetectionInProgress()) {
+    // In case no new packets get acknowledged, it is possible packets are
+    // detected lost because of time based loss detection. Cancel blackhole
+    // detection if there is no packets in flight.
+    blackhole_detector_.StopDetection(/*permanent=*/false);
+  }
+
+  if (send_stop_waiting) {
+    ++stop_waiting_count_;
+  } else {
+    stop_waiting_count_ = 0;
+  }
+}
+
+void QuicConnection::SetSessionNotifier(
+    SessionNotifierInterface* session_notifier) {
+  sent_packet_manager_.SetSessionNotifier(session_notifier);
+}
+
+void QuicConnection::SetDataProducer(
+    QuicStreamFrameDataProducer* data_producer) {
+  framer_.set_data_producer(data_producer);
+}
+
+void QuicConnection::SetTransmissionType(TransmissionType type) {
+  packet_creator_.SetTransmissionType(type);
+}
+
+void QuicConnection::UpdateReleaseTimeIntoFuture() {
+  QUICHE_DCHECK(supports_release_time_);
+
+  const QuicTime::Delta prior_max_release_time = release_time_into_future_;
+  release_time_into_future_ = std::max(
+      QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs),
+      std::min(
+          QuicTime::Delta::FromMilliseconds(
+              GetQuicFlag(FLAGS_quic_max_pace_time_into_future_ms)),
+          sent_packet_manager_.GetRttStats()->SmoothedOrInitialRtt() *
+              GetQuicFlag(FLAGS_quic_pace_time_into_future_srtt_fraction)));
+  QUIC_DVLOG(3) << "Updated max release time delay from "
+                << prior_max_release_time << " to "
+                << release_time_into_future_;
+}
+
+void QuicConnection::ResetAckStates() {
+  ack_alarm_->Cancel();
+  stop_waiting_count_ = 0;
+  uber_received_packet_manager_.ResetAckStates(encryption_level_);
+}
+
+MessageStatus QuicConnection::SendMessage(
+    QuicMessageId message_id, absl::Span<quiche::QuicheMemSlice> message,
+    bool flush) {
+  if (!VersionSupportsMessageFrames(transport_version())) {
+    QUIC_BUG(quic_bug_10511_38)
+        << "MESSAGE frame is not supported for version " << transport_version();
+    return MESSAGE_STATUS_UNSUPPORTED;
+  }
+  if (MemSliceSpanTotalSize(message) > GetCurrentLargestMessagePayload()) {
+    return MESSAGE_STATUS_TOO_LARGE;
+  }
+  if (!connected_ || (!flush && !CanWrite(HAS_RETRANSMITTABLE_DATA))) {
+    return MESSAGE_STATUS_BLOCKED;
+  }
+  ScopedPacketFlusher flusher(this);
+  return packet_creator_.AddMessageFrame(message_id, message);
+}
+
+QuicPacketLength QuicConnection::GetCurrentLargestMessagePayload() const {
+  return packet_creator_.GetCurrentLargestMessagePayload();
+}
+
+QuicPacketLength QuicConnection::GetGuaranteedLargestMessagePayload() const {
+  return packet_creator_.GetGuaranteedLargestMessagePayload();
+}
+
+uint32_t QuicConnection::cipher_id() const {
+  if (version().KnowsWhichDecrypterToUse()) {
+    return framer_.GetDecrypter(last_decrypted_packet_level_)->cipher_id();
+  }
+  return framer_.decrypter()->cipher_id();
+}
+
+EncryptionLevel QuicConnection::GetConnectionCloseEncryptionLevel() const {
+  if (perspective_ == Perspective::IS_CLIENT) {
+    return encryption_level_;
+  }
+  if (IsHandshakeComplete()) {
+    // A forward secure packet has been received.
+    QUIC_BUG_IF(quic_bug_12714_31,
+                encryption_level_ != ENCRYPTION_FORWARD_SECURE)
+        << ENDPOINT << "Unexpected connection close encryption level "
+        << encryption_level_;
+    return ENCRYPTION_FORWARD_SECURE;
+  }
+  if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT)) {
+    if (encryption_level_ != ENCRYPTION_ZERO_RTT) {
+      if (version().HasIetfInvariantHeader()) {
+        QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close_ietf);
+      } else {
+        QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close);
+      }
+    }
+    return ENCRYPTION_ZERO_RTT;
+  }
+  return ENCRYPTION_INITIAL;
+}
+
+void QuicConnection::MaybeBundleCryptoDataWithAcks() {
+  QUICHE_DCHECK(SupportsMultiplePacketNumberSpaces());
+  if (IsHandshakeConfirmed()) {
+    return;
+  }
+  PacketNumberSpace space = HANDSHAKE_DATA;
+  if (perspective() == Perspective::IS_SERVER &&
+      framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
+    // On the server side, sends INITIAL data with INITIAL ACK if initial key is
+    // available.
+    space = INITIAL_DATA;
+  }
+  const QuicTime ack_timeout =
+      uber_received_packet_manager_.GetAckTimeout(space);
+  if (!ack_timeout.IsInitialized() ||
+      (ack_timeout > clock_->ApproximateNow() &&
+       ack_timeout > uber_received_packet_manager_.GetEarliestAckTimeout())) {
+    // No pending ACK of space.
+    return;
+  }
+  if (coalesced_packet_.length() > 0) {
+    // Do not bundle CRYPTO data if the ACK could be coalesced with other
+    // packets.
+    return;
+  }
+
+  if (!framer_.HasAnEncrypterForSpace(space)) {
+    QUIC_BUG(quic_bug_10511_39)
+        << ENDPOINT
+        << "Try to bundle crypto with ACK with missing key of space "
+        << PacketNumberSpaceToString(space);
+    return;
+  }
+
+  sent_packet_manager_.RetransmitDataOfSpaceIfAny(space);
+}
+
+void QuicConnection::SendAllPendingAcks() {
+  QUICHE_DCHECK(SupportsMultiplePacketNumberSpaces());
+  QUIC_DVLOG(1) << ENDPOINT << "Trying to send all pending ACKs";
+  ack_alarm_->Cancel();
+  QuicTime earliest_ack_timeout =
+      uber_received_packet_manager_.GetEarliestAckTimeout();
+  QUIC_BUG_IF(quic_bug_12714_32, !earliest_ack_timeout.IsInitialized());
+  MaybeBundleCryptoDataWithAcks();
+  earliest_ack_timeout = uber_received_packet_manager_.GetEarliestAckTimeout();
+  if (!earliest_ack_timeout.IsInitialized()) {
+    return;
+  }
+  for (int8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
+    const QuicTime ack_timeout = uber_received_packet_manager_.GetAckTimeout(
+        static_cast<PacketNumberSpace>(i));
+    if (!ack_timeout.IsInitialized()) {
+      continue;
+    }
+    if (!framer_.HasAnEncrypterForSpace(static_cast<PacketNumberSpace>(i))) {
+      // The key has been dropped.
+      continue;
+    }
+    if (ack_timeout > clock_->ApproximateNow() &&
+        ack_timeout > earliest_ack_timeout) {
+      // Always send the earliest ACK to make forward progress in case alarm
+      // fires early.
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Sending ACK of packet number space "
+                  << PacketNumberSpaceToString(
+                         static_cast<PacketNumberSpace>(i));
+    ScopedEncryptionLevelContext context(
+        this, QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
+    QuicFrames frames;
+    frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame(
+        static_cast<PacketNumberSpace>(i), clock_->ApproximateNow()));
+    const bool flushed = packet_creator_.FlushAckFrame(frames);
+    if (!flushed) {
+      // Connection is write blocked.
+      QUIC_BUG_IF(quic_bug_12714_33,
+                  !writer_->IsWriteBlocked() && !LimitedByAmplificationFactor())
+          << "Writer not blocked and not throttled by amplification factor, "
+             "but ACK not flushed for packet space:"
+          << i;
+      break;
+    }
+    ResetAckStates();
+  }
+
+  const QuicTime timeout =
+      uber_received_packet_manager_.GetEarliestAckTimeout();
+  if (timeout.IsInitialized()) {
+    // If there are ACKs pending, re-arm ack alarm.
+    ack_alarm_->Update(timeout, kAlarmGranularity);
+  }
+  // Only try to bundle retransmittable data with ACK frame if default
+  // encryption level is forward secure.
+  if (encryption_level_ != ENCRYPTION_FORWARD_SECURE ||
+      !ShouldBundleRetransmittableFrameWithAck()) {
+    return;
+  }
+  consecutive_num_packets_with_no_retransmittable_frames_ = 0;
+  if (packet_creator_.HasPendingRetransmittableFrames() ||
+      visitor_->WillingAndAbleToWrite()) {
+    // There are pending retransmittable frames.
+    return;
+  }
+
+  visitor_->OnAckNeedsRetransmittableFrame();
+}
+
+bool QuicConnection::ShouldBundleRetransmittableFrameWithAck() const {
+  if (consecutive_num_packets_with_no_retransmittable_frames_ >=
+      max_consecutive_num_packets_with_no_retransmittable_frames_) {
+    return true;
+  }
+  if (bundle_retransmittable_with_pto_ack_ &&
+      (sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
+       sent_packet_manager_.GetConsecutivePtoCount() > 0)) {
+    // Bundle a retransmittable frame with an ACK if the PTO or RTO has fired
+    // in order to recover more quickly in cases of temporary network outage.
+    return true;
+  }
+  return false;
+}
+
+void QuicConnection::MaybeCoalescePacketOfHigherSpace() {
+  if (!connected() || !packet_creator_.HasSoftMaxPacketLength()) {
+    return;
+  }
+  if (fill_coalesced_packet_) {
+    // Make sure MaybeCoalescePacketOfHigherSpace is not re-entrant.
+    QUIC_BUG_IF(quic_coalesce_packet_reentrant,
+                flush_after_coalesce_higher_space_packets_);
+    return;
+  }
+  for (EncryptionLevel retransmission_level :
+       {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE}) {
+    // Coalesce HANDSHAKE with INITIAL retransmission, and coalesce 1-RTT with
+    // HANDSHAKE retransmission.
+    const EncryptionLevel coalesced_level =
+        retransmission_level == ENCRYPTION_INITIAL ? ENCRYPTION_HANDSHAKE
+                                                   : ENCRYPTION_FORWARD_SECURE;
+    if (coalesced_packet_.ContainsPacketOfEncryptionLevel(
+            retransmission_level) &&
+        coalesced_packet_.TransmissionTypeOfPacket(retransmission_level) !=
+            NOT_RETRANSMISSION &&
+        framer_.HasEncrypterOfEncryptionLevel(coalesced_level) &&
+        !coalesced_packet_.ContainsPacketOfEncryptionLevel(coalesced_level)) {
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Trying to coalesce packet of encryption level: "
+                    << EncryptionLevelToString(coalesced_level);
+      fill_coalesced_packet_ = true;
+      sent_packet_manager_.RetransmitDataOfSpaceIfAny(
+          QuicUtils::GetPacketNumberSpace(coalesced_level));
+      fill_coalesced_packet_ = false;
+    }
+  }
+}
+
+bool QuicConnection::FlushCoalescedPacket() {
+  ScopedCoalescedPacketClearer clearer(&coalesced_packet_);
+  if (!connected_) {
+    return false;
+  }
+  if (!version().CanSendCoalescedPackets()) {
+    QUIC_BUG_IF(quic_bug_12714_34, coalesced_packet_.length() > 0);
+    return true;
+  }
+  if (coalesced_packet_.ContainsPacketOfEncryptionLevel(ENCRYPTION_INITIAL) &&
+      !framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
+    // Initial packet will be re-serialized. Neuter it in case initial key has
+    // been dropped.
+    QUIC_BUG(quic_bug_10511_40)
+        << ENDPOINT
+        << "Coalescer contains initial packet while initial key has "
+           "been dropped.";
+    coalesced_packet_.NeuterInitialPacket();
+  }
+  if (coalesced_packet_.length() == 0) {
+    return true;
+  }
+
+  char buffer[kMaxOutgoingPacketSize];
+  const size_t length = packet_creator_.SerializeCoalescedPacket(
+      coalesced_packet_, buffer, coalesced_packet_.max_packet_length());
+  if (length == 0) {
+    if (packet_creator_
+            .close_connection_if_fail_to_serialzie_coalesced_packet() &&
+        connected_) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2, 2, 2);
+      CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET,
+                      "Failed to serialize coalesced packet.",
+                      ConnectionCloseBehavior::SILENT_CLOSE);
+    }
+    return false;
+  }
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnCoalescedPacketSent(coalesced_packet_, length);
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Sending coalesced packet "
+                << coalesced_packet_.ToString(length);
+
+  if (!buffered_packets_.empty() || HandleWriteBlocked()) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Buffering coalesced packet of len: " << length;
+    buffered_packets_.emplace_back(
+        buffer, static_cast<QuicPacketLength>(length),
+        coalesced_packet_.self_address(), coalesced_packet_.peer_address());
+    return true;
+  }
+
+  WriteResult result = writer_->WritePacket(
+      buffer, length, coalesced_packet_.self_address().host(),
+      coalesced_packet_.peer_address(), per_packet_options_);
+  if (IsWriteError(result.status)) {
+    OnWriteError(result.error_code);
+    return false;
+  }
+  if (IsWriteBlockedStatus(result.status)) {
+    visitor_->OnWriteBlocked();
+    if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Buffering coalesced packet of len: " << length;
+      buffered_packets_.emplace_back(
+          buffer, static_cast<QuicPacketLength>(length),
+          coalesced_packet_.self_address(), coalesced_packet_.peer_address());
+    }
+  }
+  // Account for added padding.
+  if (length > coalesced_packet_.length()) {
+    size_t padding_size = length - coalesced_packet_.length();
+    if (!count_bytes_on_alternative_path_separately_) {
+      if (EnforceAntiAmplificationLimit()) {
+        default_path_.bytes_sent_before_address_validation += padding_size;
+      }
+    } else {
+      QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 5, 5);
+      if (IsDefaultPath(coalesced_packet_.self_address(),
+                        coalesced_packet_.peer_address())) {
+        if (EnforceAntiAmplificationLimit()) {
+          // Include bytes sent even if they are not in flight.
+          default_path_.bytes_sent_before_address_validation += padding_size;
+        }
+      } else {
+        MaybeUpdateBytesSentToAlternativeAddress(
+            coalesced_packet_.peer_address(), padding_size);
+      }
+    }
+    stats_.bytes_sent += padding_size;
+    if (coalesced_packet_.initial_packet() != nullptr &&
+        coalesced_packet_.initial_packet()->transmission_type !=
+            NOT_RETRANSMISSION) {
+      stats_.bytes_retransmitted += padding_size;
+    }
+  }
+  return true;
+}
+
+void QuicConnection::MaybeEnableMultiplePacketNumberSpacesSupport() {
+  if (version().handshake_protocol != PROTOCOL_TLS1_3) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "connection " << connection_id()
+                << " supports multiple packet number spaces";
+  framer_.EnableMultiplePacketNumberSpacesSupport();
+  sent_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
+  uber_received_packet_manager_.EnableMultiplePacketNumberSpacesSupport(
+      perspective_);
+}
+
+bool QuicConnection::SupportsMultiplePacketNumberSpaces() const {
+  return sent_packet_manager_.supports_multiple_packet_number_spaces();
+}
+
+void QuicConnection::SetLargestReceivedPacketWithAck(
+    QuicPacketNumber new_value) {
+  if (SupportsMultiplePacketNumberSpaces()) {
+    largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
+        last_decrypted_packet_level_)] = new_value;
+  } else {
+    largest_seen_packet_with_ack_ = new_value;
+  }
+}
+
+void QuicConnection::OnForwardProgressMade() {
+  if (!connected_) {
+    return;
+  }
+  if (is_path_degrading_) {
+    visitor_->OnForwardProgressMadeAfterPathDegrading();
+    is_path_degrading_ = false;
+  }
+  if (sent_packet_manager_.HasInFlightPackets()) {
+    // Restart detections if forward progress has been made.
+    blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
+                                         GetNetworkBlackholeDeadline(),
+                                         GetPathMtuReductionDeadline());
+  } else {
+    // Stop detections in quiecense.
+    blackhole_detector_.StopDetection(/*permanent=*/false);
+  }
+  QUIC_BUG_IF(quic_bug_12714_35,
+              perspective_ == Perspective::IS_SERVER &&
+                  default_enable_5rto_blackhole_detection_ &&
+                  blackhole_detector_.IsDetectionInProgress() &&
+                  !sent_packet_manager_.HasInFlightPackets())
+      << ENDPOINT
+      << "Trying to start blackhole detection without no bytes in flight";
+}
+
+QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
+  if (SupportsMultiplePacketNumberSpaces()) {
+    return largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
+        last_decrypted_packet_level_)];
+  }
+  return largest_seen_packet_with_ack_;
+}
+
+QuicPacketNumber QuicConnection::GetLargestAckedPacket() const {
+  if (SupportsMultiplePacketNumberSpaces()) {
+    return sent_packet_manager_.GetLargestAckedPacket(
+        last_decrypted_packet_level_);
+  }
+  return sent_packet_manager_.GetLargestObserved();
+}
+
+QuicPacketNumber QuicConnection::GetLargestReceivedPacket() const {
+  return uber_received_packet_manager_.GetLargestObserved(
+      last_decrypted_packet_level_);
+}
+
+bool QuicConnection::EnforceAntiAmplificationLimit() const {
+  return version().SupportsAntiAmplificationLimit() &&
+         perspective_ == Perspective::IS_SERVER && !default_path_.validated;
+}
+
+// TODO(danzh) Pass in path object or its reference of some sort to use this
+// method to check anti-amplification limit on non-default path.
+bool QuicConnection::LimitedByAmplificationFactor() const {
+  return EnforceAntiAmplificationLimit() &&
+         default_path_.bytes_sent_before_address_validation >=
+             anti_amplification_factor_ *
+                 default_path_.bytes_received_before_address_validation;
+}
+
+SerializedPacketFate QuicConnection::GetSerializedPacketFate(
+    bool is_mtu_discovery,
+    EncryptionLevel encryption_level) {
+  if (ShouldDiscardPacket(encryption_level)) {
+    return DISCARD;
+  }
+  if (legacy_version_encapsulation_in_progress_) {
+    QUICHE_DCHECK(!is_mtu_discovery);
+    return LEGACY_VERSION_ENCAPSULATE;
+  }
+  if (version().CanSendCoalescedPackets() && !coalescing_done_ &&
+      !is_mtu_discovery) {
+    if (!IsHandshakeConfirmed()) {
+      // Before receiving ACK for any 1-RTT packets, always try to coalesce
+      // packet (except MTU discovery packet).
+      return COALESCE;
+    }
+    if (coalesced_packet_.length() > 0) {
+      // If the coalescer is not empty, let this packet go through coalescer
+      // to avoid potential out of order sending.
+      return COALESCE;
+    }
+  }
+  if (!buffered_packets_.empty() || HandleWriteBlocked()) {
+    return BUFFER;
+  }
+  return SEND_TO_WRITER;
+}
+
+bool QuicConnection::IsHandshakeComplete() const {
+  return visitor_->GetHandshakeState() >= HANDSHAKE_COMPLETE;
+}
+
+bool QuicConnection::IsHandshakeConfirmed() const {
+  QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3, version().handshake_protocol);
+  return visitor_->GetHandshakeState() == HANDSHAKE_CONFIRMED;
+}
+
+size_t QuicConnection::min_received_before_ack_decimation() const {
+  return uber_received_packet_manager_.min_received_before_ack_decimation();
+}
+
+void QuicConnection::set_min_received_before_ack_decimation(size_t new_value) {
+  uber_received_packet_manager_.set_min_received_before_ack_decimation(
+      new_value);
+}
+
+const QuicAckFrame& QuicConnection::ack_frame() const {
+  if (SupportsMultiplePacketNumberSpaces()) {
+    return uber_received_packet_manager_.GetAckFrame(
+        QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_));
+  }
+  return uber_received_packet_manager_.ack_frame();
+}
+
+void QuicConnection::set_client_connection_id(
+    QuicConnectionId client_connection_id) {
+  if (!version().SupportsClientConnectionIds()) {
+    QUIC_BUG_IF(quic_bug_12714_36, !client_connection_id.IsEmpty())
+        << ENDPOINT << "Attempted to use client connection ID "
+        << client_connection_id << " with unsupported version " << version();
+    return;
+  }
+  default_path_.client_connection_id = client_connection_id;
+
+  client_connection_id_is_set_ = true;
+  if (version().HasIetfQuicFrames() && !client_connection_id.IsEmpty()) {
+    if (perspective_ == Perspective::IS_SERVER) {
+      QUICHE_DCHECK(peer_issued_cid_manager_ == nullptr);
+      peer_issued_cid_manager_ =
+          std::make_unique<QuicPeerIssuedConnectionIdManager>(
+              kMinNumOfActiveConnectionIds, client_connection_id, clock_,
+              alarm_factory_, this, context());
+    } else {
+      // Note in Chromium client, set_client_connection_id is not called and
+      // thus self_issued_cid_manager_ should be null.
+      self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager();
+    }
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "setting client connection ID to "
+                  << default_path_.client_connection_id
+                  << " for connection with server connection ID "
+                  << default_path_.server_connection_id;
+  packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
+  framer_.SetExpectedClientConnectionIdLength(
+      default_path_.client_connection_id.length());
+}
+
+void QuicConnection::OnPathDegradingDetected() {
+  is_path_degrading_ = true;
+  visitor_->OnPathDegrading();
+}
+
+void QuicConnection::OnBlackholeDetected() {
+  if (default_enable_5rto_blackhole_detection_ &&
+      !sent_packet_manager_.HasInFlightPackets()) {
+    QUIC_BUG(quic_bug_10511_41)
+        << ENDPOINT
+        << "Blackhole detected, but there is no bytes in flight, version: "
+        << version();
+    // Do not close connection if there is no bytes in flight.
+    return;
+  }
+  CloseConnection(QUIC_TOO_MANY_RTOS, "Network blackhole detected",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicConnection::OnPathMtuReductionDetected() {
+  MaybeRevertToPreviousMtu();
+}
+
+void QuicConnection::OnHandshakeTimeout() {
+  const QuicTime::Delta duration =
+      clock_->ApproximateNow() - stats_.connection_creation_time;
+  std::string error_details = absl::StrCat(
+      "Handshake timeout expired after ", duration.ToDebuggingValue(),
+      ". Timeout:",
+      idle_network_detector_.handshake_timeout().ToDebuggingValue());
+  if (perspective() == Perspective::IS_CLIENT && version().UsesTls()) {
+    absl::StrAppend(&error_details, UndecryptablePacketsInfo());
+  }
+  QUIC_DVLOG(1) << ENDPOINT << error_details;
+  CloseConnection(QUIC_HANDSHAKE_TIMEOUT, error_details,
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicConnection::OnIdleNetworkDetected() {
+  const QuicTime::Delta duration =
+      clock_->ApproximateNow() -
+      idle_network_detector_.last_network_activity_time();
+  std::string error_details = absl::StrCat(
+      "No recent network activity after ", duration.ToDebuggingValue(),
+      ". Timeout:",
+      idle_network_detector_.idle_network_timeout().ToDebuggingValue());
+  if (perspective() == Perspective::IS_CLIENT && version().UsesTls() &&
+      !IsHandshakeComplete()) {
+    absl::StrAppend(&error_details, UndecryptablePacketsInfo());
+  }
+  QUIC_DVLOG(1) << ENDPOINT << error_details;
+  const bool has_consecutive_pto =
+      sent_packet_manager_.GetConsecutiveTlpCount() > 0 ||
+      sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
+      sent_packet_manager_.GetConsecutivePtoCount() > 0;
+  if (has_consecutive_pto || visitor_->ShouldKeepConnectionAlive()) {
+    if (GetQuicReloadableFlag(quic_add_stream_info_to_idle_close_detail) &&
+        !has_consecutive_pto) {
+      // Include stream information in error detail if there are open streams.
+      QUIC_RELOADABLE_FLAG_COUNT(quic_add_stream_info_to_idle_close_detail);
+      absl::StrAppend(&error_details, ", ",
+                      visitor_->GetStreamsInfoForLogging());
+    }
+    CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  QuicErrorCode error_code = QUIC_NETWORK_IDLE_TIMEOUT;
+  if (idle_timeout_connection_close_behavior_ ==
+      ConnectionCloseBehavior::
+          SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED) {
+    error_code = QUIC_SILENT_IDLE_TIMEOUT;
+  }
+  CloseConnection(error_code, error_details,
+                  idle_timeout_connection_close_behavior_);
+}
+
+void QuicConnection::OnPeerIssuedConnectionIdRetired() {
+  QUICHE_DCHECK(peer_issued_cid_manager_ != nullptr);
+  QuicConnectionId* default_path_cid =
+      perspective_ == Perspective::IS_CLIENT
+          ? &default_path_.server_connection_id
+          : &default_path_.client_connection_id;
+  QuicConnectionId* alternative_path_cid =
+      perspective_ == Perspective::IS_CLIENT
+          ? &alternative_path_.server_connection_id
+          : &alternative_path_.client_connection_id;
+  bool default_path_and_alternative_path_use_the_same_peer_connection_id =
+      *default_path_cid == *alternative_path_cid;
+  if (!default_path_cid->IsEmpty() &&
+      !peer_issued_cid_manager_->IsConnectionIdActive(*default_path_cid)) {
+    *default_path_cid = QuicConnectionId();
+  }
+  // TODO(haoyuewang) Handle the change for default_path_ & alternatvie_path_
+  // via the same helper function.
+  if (default_path_cid->IsEmpty()) {
+    // Try setting a new connection ID now such that subsequent
+    // RetireConnectionId frames can be sent on the default path.
+    const QuicConnectionIdData* unused_connection_id_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    if (unused_connection_id_data != nullptr) {
+      *default_path_cid = unused_connection_id_data->connection_id;
+      default_path_.stateless_reset_token =
+          unused_connection_id_data->stateless_reset_token;
+      if (perspective_ == Perspective::IS_CLIENT) {
+        packet_creator_.SetServerConnectionId(
+            unused_connection_id_data->connection_id);
+      } else {
+        packet_creator_.SetClientConnectionId(
+            unused_connection_id_data->connection_id);
+      }
+    }
+  }
+  if (default_path_and_alternative_path_use_the_same_peer_connection_id) {
+    *alternative_path_cid = *default_path_cid;
+    alternative_path_.stateless_reset_token =
+        default_path_.stateless_reset_token;
+  } else if (!alternative_path_cid->IsEmpty() &&
+             !peer_issued_cid_manager_->IsConnectionIdActive(
+                 *alternative_path_cid)) {
+    *alternative_path_cid = EmptyQuicConnectionId();
+    const QuicConnectionIdData* unused_connection_id_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    if (unused_connection_id_data != nullptr) {
+      *alternative_path_cid = unused_connection_id_data->connection_id;
+      alternative_path_.stateless_reset_token =
+          unused_connection_id_data->stateless_reset_token;
+    }
+  }
+
+  std::vector<uint64_t> retired_cid_sequence_numbers =
+      peer_issued_cid_manager_->ConsumeToBeRetiredConnectionIdSequenceNumbers();
+  QUICHE_DCHECK(!retired_cid_sequence_numbers.empty());
+  for (const auto& sequence_number : retired_cid_sequence_numbers) {
+    ++stats_.num_retire_connection_id_sent;
+    visitor_->SendRetireConnectionId(sequence_number);
+  }
+}
+
+bool QuicConnection::SendNewConnectionId(
+    const QuicNewConnectionIdFrame& frame) {
+  visitor_->SendNewConnectionId(frame);
+  ++stats_.num_new_connection_id_sent;
+  return connected_;
+}
+
+void QuicConnection::OnNewConnectionIdIssued(
+    const QuicConnectionId& connection_id) {
+  if (perspective_ == Perspective::IS_SERVER) {
+    visitor_->OnServerConnectionIdIssued(connection_id);
+  }
+}
+
+void QuicConnection::OnSelfIssuedConnectionIdRetired(
+    const QuicConnectionId& connection_id) {
+  if (perspective_ == Perspective::IS_SERVER) {
+    visitor_->OnServerConnectionIdRetired(connection_id);
+  }
+}
+
+void QuicConnection::MaybeUpdateAckTimeout() {
+  if (should_last_packet_instigate_acks_) {
+    return;
+  }
+  should_last_packet_instigate_acks_ = true;
+  uber_received_packet_manager_.MaybeUpdateAckTimeout(
+      /*should_last_packet_instigate_acks=*/true, last_decrypted_packet_level_,
+      last_header_.packet_number, last_received_packet_info_.receipt_time,
+      clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
+}
+
+QuicTime QuicConnection::GetPathDegradingDeadline() const {
+  if (!ShouldDetectPathDegrading()) {
+    return QuicTime::Zero();
+  }
+  return clock_->ApproximateNow() +
+         sent_packet_manager_.GetPathDegradingDelay();
+}
+
+bool QuicConnection::ShouldDetectPathDegrading() const {
+  if (!connected_) {
+    return false;
+  }
+  // No path degrading detection before handshake completes.
+  if (!idle_network_detector_.handshake_timeout().IsInfinite()) {
+    return false;
+  }
+  return perspective_ == Perspective::IS_CLIENT && !is_path_degrading_;
+}
+
+QuicTime QuicConnection::GetNetworkBlackholeDeadline() const {
+  if (!ShouldDetectBlackhole()) {
+    return QuicTime::Zero();
+  }
+  QUICHE_DCHECK_LT(0u, num_rtos_for_blackhole_detection_);
+  return clock_->ApproximateNow() +
+         sent_packet_manager_.GetNetworkBlackholeDelay(
+             num_rtos_for_blackhole_detection_);
+}
+
+bool QuicConnection::ShouldDetectBlackhole() const {
+  if (!connected_ || blackhole_detection_disabled_) {
+    return false;
+  }
+  // No blackhole detection before handshake completes.
+  if (default_enable_5rto_blackhole_detection_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
+                                 3, 3);
+    return IsHandshakeComplete();
+  }
+
+  if (!idle_network_detector_.handshake_timeout().IsInfinite()) {
+    return false;
+  }
+  return num_rtos_for_blackhole_detection_ > 0;
+}
+
+QuicTime QuicConnection::GetRetransmissionDeadline() const {
+  if (perspective_ == Perspective::IS_CLIENT &&
+      SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() &&
+      stats_.pto_count == 0 &&
+      !framer_.HasDecrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE) &&
+      !undecryptable_packets_.empty()) {
+    // Retransmits ClientHello quickly when a Handshake or 1-RTT packet is
+    // received prior to having Handshake keys. Adding kAlarmGranulary will
+    // avoid spurious retransmissions in the case of small-scale reordering.
+    return clock_->ApproximateNow() + kAlarmGranularity;
+  }
+  return sent_packet_manager_.GetRetransmissionTime();
+}
+
+bool QuicConnection::SendPathChallenge(
+    const QuicPathFrameBuffer& data_buffer,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    const QuicSocketAddress& effective_peer_address,
+    QuicPacketWriter* writer) {
+  if (!framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
+    return connected_;
+  }
+  if (connection_migration_use_new_cid_) {
+    {
+      QuicConnectionId client_cid, server_cid;
+      FindOnPathConnectionIds(self_address, effective_peer_address, &client_cid,
+                              &server_cid);
+      QuicPacketCreator::ScopedPeerAddressContext context(
+          &packet_creator_, peer_address, client_cid, server_cid,
+          connection_migration_use_new_cid_);
+      if (writer == writer_) {
+        ScopedPacketFlusher flusher(this);
+        // It's on current path, add the PATH_CHALLENGE the same way as other
+        // frames. This may cause connection to be closed.
+        packet_creator_.AddPathChallengeFrame(data_buffer);
+      } else {
+        std::unique_ptr<SerializedPacket> probing_packet =
+            packet_creator_.SerializePathChallengeConnectivityProbingPacket(
+                data_buffer);
+        QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet),
+                         NO_RETRANSMITTABLE_DATA);
+        QUICHE_DCHECK_EQ(self_address, alternative_path_.self_address);
+        WritePacketUsingWriter(std::move(probing_packet), writer, self_address,
+                               peer_address, /*measure_rtt=*/false);
+      }
+    }
+    return connected_;
+  }
+  if (writer == writer_) {
+    ScopedPacketFlusher flusher(this);
+    {
+      // It's on current path, add the PATH_CHALLENGE the same way as other
+      // frames.
+      QuicPacketCreator::ScopedPeerAddressContext context(
+          &packet_creator_, peer_address, /*update_connection_id=*/false);
+      // This may cause connection to be closed.
+      packet_creator_.AddPathChallengeFrame(data_buffer);
+    }
+    // Return outside of the scope so that the flush result can be reflected.
+    return connected_;
+  }
+  std::unique_ptr<SerializedPacket> probing_packet =
+      packet_creator_.SerializePathChallengeConnectivityProbingPacket(
+          data_buffer);
+  QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
+  QUICHE_DCHECK_EQ(self_address, alternative_path_.self_address);
+  WritePacketUsingWriter(std::move(probing_packet), writer, self_address,
+                         peer_address, /*measure_rtt=*/false);
+  return true;
+}
+
+QuicTime QuicConnection::GetRetryTimeout(
+    const QuicSocketAddress& peer_address_to_use,
+    QuicPacketWriter* writer_to_use) const {
+  if (writer_to_use == writer_ && peer_address_to_use == peer_address()) {
+    return clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay();
+  }
+  return clock_->ApproximateNow() +
+         QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
+}
+
+void QuicConnection::ValidatePath(
+    std::unique_ptr<QuicPathValidationContext> context,
+    std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
+  QUICHE_DCHECK(use_path_validator_);
+  if (!connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_CLIENT &&
+      !IsDefaultPath(context->self_address(), context->peer_address())) {
+    alternative_path_ = PathState(
+        context->self_address(), context->peer_address(),
+        default_path_.client_connection_id, default_path_.server_connection_id,
+        default_path_.stateless_reset_token);
+  }
+  if (path_validator_.HasPendingPathValidation()) {
+    // Cancel and fail any earlier validation.
+    path_validator_.CancelPathValidation();
+  }
+  if (connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_CLIENT &&
+      !IsDefaultPath(context->self_address(), context->peer_address())) {
+    if (self_issued_cid_manager_ != nullptr) {
+      self_issued_cid_manager_->MaybeSendNewConnectionIds();
+      if (!connected_) {
+        return;
+      }
+    }
+    if ((self_issued_cid_manager_ != nullptr &&
+         !self_issued_cid_manager_->HasConnectionIdToConsume()) ||
+        (peer_issued_cid_manager_ != nullptr &&
+         !peer_issued_cid_manager_->HasUnusedConnectionId())) {
+      QUIC_DVLOG(1) << "Client cannot start new path validation as there is no "
+                       "requried connection ID is available.";
+      result_delegate->OnPathValidationFailure(std::move(context));
+      return;
+    }
+    QuicConnectionId client_connection_id, server_connection_id;
+    absl::optional<StatelessResetToken> stateless_reset_token;
+    if (self_issued_cid_manager_ != nullptr) {
+      client_connection_id =
+          *self_issued_cid_manager_->ConsumeOneConnectionId();
+    }
+    if (peer_issued_cid_manager_ != nullptr) {
+      const auto* connection_id_data =
+          peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+      server_connection_id = connection_id_data->connection_id;
+      stateless_reset_token = connection_id_data->stateless_reset_token;
+    }
+    alternative_path_ = PathState(context->self_address(),
+                                  context->peer_address(), client_connection_id,
+                                  server_connection_id, stateless_reset_token);
+  }
+  path_validator_.StartPathValidation(std::move(context),
+                                      std::move(result_delegate));
+}
+
+bool QuicConnection::SendPathResponse(
+    const QuicPathFrameBuffer& data_buffer,
+    const QuicSocketAddress& peer_address_to_send,
+    const QuicSocketAddress& effective_peer_address) {
+  if (!framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
+    return false;
+  }
+  QuicConnectionId client_cid, server_cid;
+  if (connection_migration_use_new_cid_) {
+    FindOnPathConnectionIds(last_received_packet_info_.destination_address,
+                            effective_peer_address, &client_cid, &server_cid);
+  }
+  // Send PATH_RESPONSE using the provided peer address. If the creator has been
+  // using a different peer address, it will flush before and after serializing
+  // the current PATH_RESPONSE.
+  QuicPacketCreator::ScopedPeerAddressContext context(
+      &packet_creator_, peer_address_to_send, client_cid, server_cid,
+      connection_migration_use_new_cid_);
+  QUIC_DVLOG(1) << ENDPOINT << "Send PATH_RESPONSE to " << peer_address_to_send;
+  if (default_path_.self_address ==
+      last_received_packet_info_.destination_address) {
+    // The PATH_CHALLENGE is received on the default socket. Respond on the same
+    // socket.
+    return packet_creator_.AddPathResponseFrame(data_buffer);
+  }
+
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+  // This PATH_CHALLENGE is received on an alternative socket which should be
+  // used to send PATH_RESPONSE.
+  if (!path_validator_.HasPendingPathValidation() ||
+      path_validator_.GetContext()->self_address() !=
+          last_received_packet_info_.destination_address) {
+    // Ignore this PATH_CHALLENGE if it's received from an uninteresting
+    // socket.
+    return true;
+  }
+  QuicPacketWriter* writer = path_validator_.GetContext()->WriterToUse();
+
+  std::unique_ptr<SerializedPacket> probing_packet =
+      packet_creator_.SerializePathResponseConnectivityProbingPacket(
+          {data_buffer}, /*is_padded=*/true);
+  QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
+  QUIC_DVLOG(1) << ENDPOINT
+                << "Send PATH_RESPONSE from alternative socket with address "
+                << last_received_packet_info_.destination_address;
+  // Ignore the return value to treat write error on the alternative writer as
+  // part of network error. If the writer becomes blocked, wait for the peer to
+  // send another PATH_CHALLENGE.
+  WritePacketUsingWriter(std::move(probing_packet), writer,
+                         last_received_packet_info_.destination_address,
+                         peer_address_to_send,
+                         /*measure_rtt=*/false);
+  return true;
+}
+
+void QuicConnection::UpdatePeerAddress(QuicSocketAddress peer_address) {
+  direct_peer_address_ = peer_address;
+  packet_creator_.SetDefaultPeerAddress(peer_address);
+}
+
+void QuicConnection::SendPingAtLevel(EncryptionLevel level) {
+  ScopedEncryptionLevelContext context(this, level);
+  SendControlFrame(QuicFrame(QuicPingFrame()));
+}
+
+bool QuicConnection::HasPendingPathValidation() const {
+  QUICHE_DCHECK(use_path_validator_);
+  return path_validator_.HasPendingPathValidation();
+}
+
+QuicPathValidationContext* QuicConnection::GetPathValidationContext() const {
+  QUICHE_DCHECK(use_path_validator_);
+  return path_validator_.GetContext();
+}
+
+void QuicConnection::CancelPathValidation() {
+  QUICHE_DCHECK(use_path_validator_);
+  path_validator_.CancelPathValidation();
+}
+
+bool QuicConnection::UpdateConnectionIdsOnClientMigration(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
+  if (IsAlternativePath(self_address, peer_address)) {
+    // Client migration is after path validation.
+    default_path_.client_connection_id = alternative_path_.client_connection_id;
+    default_path_.server_connection_id = alternative_path_.server_connection_id;
+    default_path_.stateless_reset_token =
+        alternative_path_.stateless_reset_token;
+    return true;
+  }
+  // Client migration is without path validation.
+  if (self_issued_cid_manager_ != nullptr) {
+    self_issued_cid_manager_->MaybeSendNewConnectionIds();
+    if (!connected_) {
+      return false;
+    }
+  }
+  if ((self_issued_cid_manager_ != nullptr &&
+       !self_issued_cid_manager_->HasConnectionIdToConsume()) ||
+      (peer_issued_cid_manager_ != nullptr &&
+       !peer_issued_cid_manager_->HasUnusedConnectionId())) {
+    return false;
+  }
+  if (self_issued_cid_manager_ != nullptr) {
+    default_path_.client_connection_id =
+        *self_issued_cid_manager_->ConsumeOneConnectionId();
+  }
+  if (peer_issued_cid_manager_ != nullptr) {
+    const auto* connection_id_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    default_path_.server_connection_id = connection_id_data->connection_id;
+    default_path_.stateless_reset_token =
+        connection_id_data->stateless_reset_token;
+  }
+  return true;
+}
+
+void QuicConnection::RetirePeerIssuedConnectionIdsNoLongerOnPath() {
+  if (!connection_migration_use_new_cid_ ||
+      peer_issued_cid_manager_ == nullptr) {
+    return;
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    peer_issued_cid_manager_->MaybeRetireUnusedConnectionIds(
+        {default_path_.server_connection_id,
+         alternative_path_.server_connection_id});
+  } else {
+    peer_issued_cid_manager_->MaybeRetireUnusedConnectionIds(
+        {default_path_.client_connection_id,
+         alternative_path_.client_connection_id});
+  }
+}
+
+void QuicConnection::RetirePeerIssuedConnectionIdsOnPathValidationFailure() {
+  // The alarm to retire connection IDs no longer on paths is scheduled at the
+  // end of writing and reading packet. On path validation failure, there could
+  // be no packet to write or read. Hence the retirement alarm for the
+  // connection ID associated with the failed path needs to be proactively
+  // scheduled here.
+  if (GetQuicReloadableFlag(
+          quic_retire_cid_on_reverse_path_validation_failure) ||
+      perspective_ == Perspective::IS_CLIENT) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_retire_cid_on_reverse_path_validation_failure);
+    RetirePeerIssuedConnectionIdsNoLongerOnPath();
+  }
+}
+
+bool QuicConnection::MigratePath(const QuicSocketAddress& self_address,
+                                 const QuicSocketAddress& peer_address,
+                                 QuicPacketWriter* writer,
+                                 bool owns_writer) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
+  if (!connected_) {
+    if (owns_writer) {
+      delete writer;
+    }
+    return false;
+  }
+  QUICHE_DCHECK(!version().UsesHttp3() || IsHandshakeConfirmed());
+
+  if (connection_migration_use_new_cid_) {
+    if (!UpdateConnectionIdsOnClientMigration(self_address, peer_address)) {
+      if (owns_writer) {
+        delete writer;
+      }
+      return false;
+    }
+    if (packet_creator_.GetServerConnectionId().length() !=
+        default_path_.server_connection_id.length()) {
+      packet_creator_.FlushCurrentPacket();
+    }
+    packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
+    packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
+  }
+
+  const auto self_address_change_type = QuicUtils::DetermineAddressChangeType(
+      default_path_.self_address, self_address);
+  const auto peer_address_change_type = QuicUtils::DetermineAddressChangeType(
+      default_path_.peer_address, peer_address);
+  QUICHE_DCHECK(self_address_change_type != NO_CHANGE ||
+                peer_address_change_type != NO_CHANGE);
+  const bool is_port_change = (self_address_change_type == PORT_CHANGE ||
+                               self_address_change_type == NO_CHANGE) &&
+                              (peer_address_change_type == PORT_CHANGE ||
+                               peer_address_change_type == NO_CHANGE);
+  SetSelfAddress(self_address);
+  UpdatePeerAddress(peer_address);
+  SetQuicPacketWriter(writer, owns_writer);
+  MaybeClearQueuedPacketsOnPathChange();
+  OnSuccessfulMigration(is_port_change);
+  return true;
+}
+
+void QuicConnection::OnPathValidationFailureAtClient() {
+  if (connection_migration_use_new_cid_) {
+    QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
+    alternative_path_.Clear();
+  }
+  RetirePeerIssuedConnectionIdsOnPathValidationFailure();
+}
+
+QuicConnectionId QuicConnection::GetOneActiveServerConnectionId() const {
+  if (perspective_ == Perspective::IS_CLIENT ||
+      self_issued_cid_manager_ == nullptr) {
+    return connection_id();
+  }
+  auto active_connection_ids = GetActiveServerConnectionIds();
+  QUIC_BUG_IF(quic_bug_6944, active_connection_ids.empty());
+  if (active_connection_ids.empty() ||
+      std::find(active_connection_ids.begin(), active_connection_ids.end(),
+                connection_id()) != active_connection_ids.end()) {
+    return connection_id();
+  }
+  QUICHE_CODE_COUNT(connection_id_on_default_path_has_been_retired);
+  auto active_connection_id =
+      self_issued_cid_manager_->GetOneActiveConnectionId();
+  return active_connection_id;
+}
+
+std::vector<QuicConnectionId> QuicConnection::GetActiveServerConnectionIds()
+    const {
+  if (self_issued_cid_manager_ == nullptr) {
+    return {default_path_.server_connection_id};
+  }
+  QUICHE_DCHECK(version().HasIetfQuicFrames());
+  return self_issued_cid_manager_->GetUnretiredConnectionIds();
+}
+
+void QuicConnection::CreateConnectionIdManager() {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (!default_path_.server_connection_id.IsEmpty()) {
+      peer_issued_cid_manager_ =
+          std::make_unique<QuicPeerIssuedConnectionIdManager>(
+              kMinNumOfActiveConnectionIds, default_path_.server_connection_id,
+              clock_, alarm_factory_, this, context());
+    }
+  } else {
+    if (!default_path_.server_connection_id.IsEmpty()) {
+      self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager();
+    }
+  }
+}
+
+void QuicConnection::SetUnackedMapInitialCapacity() {
+  sent_packet_manager_.ReserveUnackedPacketsInitialCapacity(
+      GetUnackedMapInitialCapacity());
+}
+
+void QuicConnection::SetSourceAddressTokenToSend(absl::string_view token) {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  if (!packet_creator_.HasRetryToken()) {
+    // Ignore received tokens (via NEW_TOKEN frame) from previous connections
+    // when a RETRY token has been received.
+    packet_creator_.SetRetryToken(std::string(token.data(), token.length()));
+  }
+}
+
+void QuicConnection::MaybeUpdateBytesSentToAlternativeAddress(
+    const QuicSocketAddress& peer_address,
+    QuicByteCount sent_packet_size) {
+  if (!version().SupportsAntiAmplificationLimit() ||
+      perspective_ != Perspective::IS_SERVER) {
+    return;
+  }
+  QUICHE_DCHECK(!IsDefaultPath(default_path_.self_address, peer_address));
+  if (!IsAlternativePath(default_path_.self_address, peer_address)) {
+    QUIC_DLOG(INFO) << "Wrote to uninteresting peer address: " << peer_address
+                    << " default direct_peer_address_ " << direct_peer_address_
+                    << " alternative path peer address "
+                    << alternative_path_.peer_address;
+    return;
+  }
+  if (alternative_path_.validated) {
+    return;
+  }
+  if (alternative_path_.bytes_sent_before_address_validation >=
+      anti_amplification_factor_ *
+          alternative_path_.bytes_received_before_address_validation) {
+    QUIC_LOG_FIRST_N(WARNING, 100)
+        << "Server sent more data than allowed to unverified alternative "
+           "peer address "
+        << peer_address << " bytes sent "
+        << alternative_path_.bytes_sent_before_address_validation
+        << ", bytes received "
+        << alternative_path_.bytes_received_before_address_validation;
+  }
+  alternative_path_.bytes_sent_before_address_validation += sent_packet_size;
+}
+
+void QuicConnection::MaybeUpdateBytesReceivedFromAlternativeAddress(
+    QuicByteCount received_packet_size) {
+  if (!version().SupportsAntiAmplificationLimit() ||
+      perspective_ != Perspective::IS_SERVER ||
+      !IsAlternativePath(last_received_packet_info_.destination_address,
+                         GetEffectivePeerAddressFromCurrentPacket()) ||
+      last_received_packet_info_.received_bytes_counted) {
+    return;
+  }
+  // Only update bytes received if this probing frame is received on the most
+  // recent alternative path.
+  QUICHE_DCHECK(!IsDefaultPath(last_received_packet_info_.destination_address,
+                               GetEffectivePeerAddressFromCurrentPacket()));
+  if (!alternative_path_.validated) {
+    alternative_path_.bytes_received_before_address_validation +=
+        received_packet_size;
+  }
+  last_received_packet_info_.received_bytes_counted = true;
+}
+
+bool QuicConnection::IsDefaultPath(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address) const {
+  return direct_peer_address_ == peer_address &&
+         default_path_.self_address == self_address;
+}
+
+bool QuicConnection::IsAlternativePath(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address) const {
+  return alternative_path_.peer_address == peer_address &&
+         alternative_path_.self_address == self_address;
+}
+
+void QuicConnection::PathState::Clear() {
+  self_address = QuicSocketAddress();
+  peer_address = QuicSocketAddress();
+  client_connection_id = {};
+  server_connection_id = {};
+  validated = false;
+  bytes_received_before_address_validation = 0;
+  bytes_sent_before_address_validation = 0;
+  send_algorithm = nullptr;
+  rtt_stats = absl::nullopt;
+  stateless_reset_token.reset();
+}
+
+QuicConnection::PathState::PathState(PathState&& other) {
+  *this = std::move(other);
+}
+
+QuicConnection::PathState& QuicConnection::PathState::operator=(
+    QuicConnection::PathState&& other) {
+  if (this != &other) {
+    self_address = other.self_address;
+    peer_address = other.peer_address;
+    client_connection_id = other.client_connection_id;
+    server_connection_id = other.server_connection_id;
+    stateless_reset_token = other.stateless_reset_token;
+    validated = other.validated;
+    bytes_received_before_address_validation =
+        other.bytes_received_before_address_validation;
+    bytes_sent_before_address_validation =
+        other.bytes_sent_before_address_validation;
+    send_algorithm = std::move(other.send_algorithm);
+    if (other.rtt_stats.has_value()) {
+      rtt_stats.emplace();
+      rtt_stats->CloneFrom(other.rtt_stats.value());
+    } else {
+      rtt_stats.reset();
+    }
+    other.Clear();
+  }
+  return *this;
+}
+
+bool QuicConnection::IsReceivedPeerAddressValidated() const {
+  QuicSocketAddress current_effective_peer_address =
+      GetEffectivePeerAddressFromCurrentPacket();
+  QUICHE_DCHECK(current_effective_peer_address.IsInitialized());
+  return (alternative_path_.peer_address.host() ==
+              current_effective_peer_address.host() &&
+          alternative_path_.validated) ||
+         (default_path_.validated && default_path_.peer_address.host() ==
+                                         current_effective_peer_address.host());
+}
+
+QuicConnection::ReversePathValidationResultDelegate::
+    ReversePathValidationResultDelegate(
+        QuicConnection* connection,
+        const QuicSocketAddress& direct_peer_address)
+    : QuicPathValidator::ResultDelegate(),
+      connection_(connection),
+      original_direct_peer_address_(direct_peer_address),
+      peer_address_default_path_(connection->direct_peer_address_),
+      peer_address_alternative_path_(
+          connection_->alternative_path_.peer_address),
+      active_effective_peer_migration_type_(
+          connection_->active_effective_peer_migration_type_) {}
+
+void QuicConnection::ReversePathValidationResultDelegate::
+    OnPathValidationSuccess(
+        std::unique_ptr<QuicPathValidationContext> context) {
+  QUIC_DLOG(INFO) << "Successfully validated new path " << *context;
+  if (connection_->IsDefaultPath(context->self_address(),
+                                 context->peer_address())) {
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 3, 6);
+    if (connection_->active_effective_peer_migration_type_ == NO_CHANGE) {
+      connection_->quic_bug_10511_43_timestamp_ =
+          connection_->clock_->WallNow();
+      connection_->quic_bug_10511_43_error_detail_ = absl::StrCat(
+          "Reverse path validation on default path from ",
+          context->self_address().ToString(), " to ",
+          context->peer_address().ToString(),
+          " completed without active peer address change: current "
+          "peer address on default path ",
+          connection_->direct_peer_address_.ToString(),
+          ", peer address on default path when the reverse path "
+          "validation was kicked off ",
+          peer_address_default_path_.ToString(),
+          ", peer address on alternative path when the reverse "
+          "path validation was kicked off ",
+          peer_address_alternative_path_.ToString(),
+          ", with active_effective_peer_migration_type_ = ",
+          AddressChangeTypeToString(active_effective_peer_migration_type_),
+          ". The last received packet number ",
+          connection_->last_header_.packet_number.ToString(),
+          " Connection is connected: ", connection_->connected_);
+      QUIC_BUG(quic_bug_10511_43)
+          << connection_->quic_bug_10511_43_error_detail_;
+    }
+    connection_->OnEffectivePeerMigrationValidated();
+  } else {
+    QUICHE_DCHECK(connection_->IsAlternativePath(
+        context->self_address(), context->effective_peer_address()));
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 4, 6);
+    QUIC_DVLOG(1) << "Mark alternative peer address "
+                  << context->effective_peer_address() << " validated.";
+    connection_->alternative_path_.validated = true;
+  }
+}
+
+void QuicConnection::ReversePathValidationResultDelegate::
+    OnPathValidationFailure(
+        std::unique_ptr<QuicPathValidationContext> context) {
+  if (!connection_->connected()) {
+    return;
+  }
+  QUIC_DLOG(INFO) << "Fail to validate new path " << *context;
+  if (connection_->IsDefaultPath(context->self_address(),
+                                 context->peer_address())) {
+    // Only act upon validation failure on the default path.
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 5, 6);
+    connection_->RestoreToLastValidatedPath(original_direct_peer_address_);
+  } else if (connection_->IsAlternativePath(
+                 context->self_address(), context->effective_peer_address())) {
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 6, 6);
+    connection_->alternative_path_.Clear();
+  }
+  connection_->RetirePeerIssuedConnectionIdsOnPathValidationFailure();
+}
+
+QuicConnection::ScopedRetransmissionTimeoutIndicator::
+    ScopedRetransmissionTimeoutIndicator(QuicConnection* connection)
+    : connection_(connection) {
+  QUICHE_DCHECK(!connection_->in_on_retransmission_time_out_)
+      << "ScopedRetransmissionTimeoutIndicator is not supposed to be nested";
+  connection_->in_on_retransmission_time_out_ = true;
+}
+
+QuicConnection::ScopedRetransmissionTimeoutIndicator::
+    ~ScopedRetransmissionTimeoutIndicator() {
+  QUICHE_DCHECK(connection_->in_on_retransmission_time_out_);
+  connection_->in_on_retransmission_time_out_ = false;
+}
+
+void QuicConnection::RestoreToLastValidatedPath(
+    QuicSocketAddress original_direct_peer_address) {
+  QUIC_DLOG(INFO) << "Switch back to use the old peer address "
+                  << alternative_path_.peer_address;
+  if (!alternative_path_.validated) {
+    // If not validated by now, close connection silently so that the following
+    // packets received will be rejected.
+    CloseConnection(QUIC_INTERNAL_ERROR,
+                    "No validated peer address to use after reverse path "
+                    "validation failure.",
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+    return;
+  }
+  MaybeClearQueuedPacketsOnPathChange();
+
+  // Revert congestion control context to old state.
+  OnPeerIpAddressChanged();
+
+  if (alternative_path_.send_algorithm != nullptr) {
+    sent_packet_manager_.SetSendAlgorithm(
+        alternative_path_.send_algorithm.release());
+    sent_packet_manager_.SetRttStats(alternative_path_.rtt_stats.value());
+  } else {
+    QUIC_BUG(quic_bug_10511_42)
+        << "Fail to store congestion controller before migration.";
+  }
+
+  UpdatePeerAddress(original_direct_peer_address);
+  SetDefaultPathState(std::move(alternative_path_));
+
+  active_effective_peer_migration_type_ = NO_CHANGE;
+  ++stats_.num_invalid_peer_migration;
+  // The reverse path validation failed because of alarm firing, flush all the
+  // pending writes previously throttled by anti-amplification limit.
+  WriteIfNotBlocked();
+}
+
+std::unique_ptr<SendAlgorithmInterface>
+QuicConnection::OnPeerIpAddressChanged() {
+  QUICHE_DCHECK(validate_client_addresses_);
+  std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
+      sent_packet_manager_.OnConnectionMigration(
+          /*reset_send_algorithm=*/true);
+  // OnConnectionMigration() should have marked in-flight packets to be
+  // retransmitted if there is any.
+  QUICHE_DCHECK(!sent_packet_manager_.HasInFlightPackets());
+  // OnConnectionMigration() may have changed the retransmission timer, so
+  // re-arm it.
+  SetRetransmissionAlarm();
+  // Stop detections in quiecense.
+  blackhole_detector_.StopDetection(/*permanent=*/false);
+  return old_send_algorithm;
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
new file mode 100644
index 0000000..23b78be
--- /dev/null
+++ b/quiche/quic/core/quic_connection.h
@@ -0,0 +1,2290 @@
+// 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 entity that handles framing writes for a Quic client or server.
+// Each QuicSession will have a connection associated with it.
+//
+// On the server side, the Dispatcher handles the raw reads, and hands off
+// packets via ProcessUdpPacket for framing and processing.
+//
+// On the client side, the Connection handles the raw reads, as well as the
+// processing.
+//
+// Note: this class is not thread-safe.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_max_streams_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_blocked_writer_interface.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_connection_id_manager.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_idle_network_detector.h"
+#include "quiche/quic/core/quic_mtu_discovery.h"
+#include "quiche/quic/core/quic_network_blackhole_detector.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_sent_packet_manager.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/uber_received_packet_manager.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+class QuicClock;
+class QuicConfig;
+class QuicConnection;
+class QuicRandom;
+
+namespace test {
+class QuicConnectionPeer;
+}  // namespace test
+
+// Class that receives callbacks from the connection when frames are received
+// and when other interesting events happen.
+class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
+ public:
+  virtual ~QuicConnectionVisitorInterface() {}
+
+  // A simple visitor interface for dealing with a data frame.
+  virtual void OnStreamFrame(const QuicStreamFrame& frame) = 0;
+
+  // Called when a CRYPTO frame containing handshake data is received.
+  virtual void OnCryptoFrame(const QuicCryptoFrame& frame) = 0;
+
+  // The session should process the WINDOW_UPDATE frame, adjusting both stream
+  // and connection level flow control windows.
+  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) = 0;
+
+  // A BLOCKED frame indicates the peer is flow control blocked
+  // on a specified stream.
+  virtual void OnBlockedFrame(const QuicBlockedFrame& frame) = 0;
+
+  // Called when the stream is reset by the peer.
+  virtual void OnRstStream(const QuicRstStreamFrame& frame) = 0;
+
+  // Called when the connection is going away according to the peer.
+  virtual void OnGoAway(const QuicGoAwayFrame& frame) = 0;
+
+  // Called when |message| has been received.
+  virtual void OnMessageReceived(absl::string_view message) = 0;
+
+  // Called when a HANDSHAKE_DONE frame has been received.
+  virtual void OnHandshakeDoneReceived() = 0;
+
+  // Called when a NEW_TOKEN frame has been received.
+  virtual void OnNewTokenReceived(absl::string_view token) = 0;
+
+  // Called when a MAX_STREAMS frame has been received from the peer.
+  virtual bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) = 0;
+
+  // Called when a STREAMS_BLOCKED frame has been received from the peer.
+  virtual bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) = 0;
+
+  // Called when the connection is closed either locally by the framer, or
+  // remotely by the peer.
+  virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                                  ConnectionCloseSource source) = 0;
+
+  // Called when the connection failed to write because the socket was blocked.
+  virtual void OnWriteBlocked() = 0;
+
+  // Called once a specific QUIC version is agreed by both endpoints.
+  virtual void OnSuccessfulVersionNegotiation(
+      const ParsedQuicVersion& version) = 0;
+
+  // Called when a packet has been received by the connection, after being
+  // validated and parsed. Only called when the client receives a valid packet
+  // or the server receives a connectivity probing packet.
+  // |is_connectivity_probe| is true if the received packet is a connectivity
+  // probe.
+  virtual void OnPacketReceived(const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address,
+                                bool is_connectivity_probe) = 0;
+
+  // Called when a blocked socket becomes writable.
+  virtual void OnCanWrite() = 0;
+
+  // Called when the connection needs more data to probe for additional
+  // bandwidth.  Returns true if data was sent, false otherwise.
+  virtual bool SendProbingData() = 0;
+
+  // Called when stateless reset packet is received. Returns true if the
+  // connection needs to be closed.
+  virtual bool ValidateStatelessReset(
+      const quic::QuicSocketAddress& self_address,
+      const quic::QuicSocketAddress& peer_address) = 0;
+
+  // Called when the connection experiences a change in congestion window.
+  virtual void OnCongestionWindowChange(QuicTime now) = 0;
+
+  // Called when the connection receives a packet from a migrated client.
+  virtual void OnConnectionMigration(AddressChangeType type) = 0;
+
+  // Called when the peer seems unreachable over the current path.
+  virtual void OnPathDegrading() = 0;
+
+  // Called when forward progress made after path degrading.
+  virtual void OnForwardProgressMadeAfterPathDegrading() = 0;
+
+  // Called when the connection sends ack after
+  // max_consecutive_num_packets_with_no_retransmittable_frames_ consecutive not
+  // retransmittable packets sent. To instigate an ack from peer, a
+  // retransmittable frame needs to be added.
+  virtual void OnAckNeedsRetransmittableFrame() = 0;
+
+  // Called when an AckFrequency frame need to be sent.
+  virtual void SendAckFrequency(const QuicAckFrequencyFrame& frame) = 0;
+
+  // Called to send a NEW_CONNECTION_ID frame.
+  virtual void SendNewConnectionId(const QuicNewConnectionIdFrame& frame) = 0;
+
+  // Called to send a RETIRE_CONNECTION_ID frame.
+  virtual void SendRetireConnectionId(uint64_t sequence_number) = 0;
+
+  // Called when server starts to use a server issued connection ID.
+  virtual void OnServerConnectionIdIssued(
+      const QuicConnectionId& server_connection_id) = 0;
+
+  // Called when server stops to use a server issued connection ID.
+  virtual void OnServerConnectionIdRetired(
+      const QuicConnectionId& server_connection_id) = 0;
+
+  // Called to ask if the visitor wants to schedule write resumption as it both
+  // has pending data to write, and is able to write (e.g. based on flow control
+  // limits).
+  // Writes may be pending because they were write-blocked, congestion-throttled
+  // or yielded to other connections.
+  virtual bool WillingAndAbleToWrite() const = 0;
+
+  // Called to ask if the connection should be kept alive and prevented
+  // from timing out, for example if there are outstanding application
+  // transactions expecting a response.
+  virtual bool ShouldKeepConnectionAlive() const = 0;
+
+  // Called to retrieve streams information for logging purpose.
+  virtual std::string GetStreamsInfoForLogging() const = 0;
+
+  // Called when a self address change is observed. Returns true if self address
+  // change is allowed.
+  virtual bool AllowSelfAddressChange() const = 0;
+
+  // Called to get current handshake state.
+  virtual HandshakeState GetHandshakeState() const = 0;
+
+  // Called when a STOP_SENDING frame has been received.
+  virtual void OnStopSendingFrame(const QuicStopSendingFrame& frame) = 0;
+
+  // Called when a packet of encryption |level| has been successfully decrypted.
+  virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
+
+  // Called when a 1RTT packet has been acknowledged.
+  virtual void OnOneRttPacketAcknowledged() = 0;
+
+  // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
+  virtual void OnHandshakePacketSent() = 0;
+
+  // Called when a key update has occurred.
+  virtual void OnKeyUpdate(KeyUpdateReason reason) = 0;
+
+  // Called to generate a decrypter for the next key phase. Each call should
+  // generate the key for phase n+1.
+  virtual std::unique_ptr<QuicDecrypter>
+  AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
+
+  // Called to generate an encrypter for the same key phase of the last
+  // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
+  virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
+
+  // Called when connection is being closed right before a CONNECTION_CLOSE
+  // frame is serialized, but only on the server and only if forward secure
+  // encryption has already been established.
+  virtual void BeforeConnectionCloseSent() = 0;
+
+  // Called by the server to validate |token| in received INITIAL packets.
+  // Consider the client address gets validated (and therefore remove
+  // amplification factor) once the |token| gets successfully validated.
+  virtual bool ValidateToken(absl::string_view token) = 0;
+
+  // Called by the server to send another token.
+  // Return false if the crypto stream fail to generate one.
+  virtual bool MaybeSendAddressToken() = 0;
+
+  // Whether the server address is known to the connection.
+  virtual bool IsKnownServerAddress(const QuicSocketAddress& address) const = 0;
+};
+
+// Interface which gets callbacks from the QuicConnection at interesting
+// points.  Implementations must not mutate the state of the connection
+// as a result of these callbacks.
+class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor
+    : public QuicSentPacketManager::DebugDelegate {
+ public:
+  ~QuicConnectionDebugVisitor() override {}
+
+  // Called when a packet has been sent.
+  virtual void OnPacketSent(QuicPacketNumber /*packet_number*/,
+                            QuicPacketLength /*packet_length*/,
+                            bool /*has_crypto_handshake*/,
+                            TransmissionType /*transmission_type*/,
+                            EncryptionLevel /*encryption_level*/,
+                            const QuicFrames& /*retransmittable_frames*/,
+                            const QuicFrames& /*nonretransmittable_frames*/,
+                            QuicTime /*sent_time*/) {}
+
+  // Called when a coalesced packet is successfully serialized.
+  virtual void OnCoalescedPacketSent(
+      const QuicCoalescedPacket& /*coalesced_packet*/, size_t /*length*/) {}
+
+  // Called when a PING frame has been sent.
+  virtual void OnPingSent() {}
+
+  // Called when a packet has been received, but before it is
+  // validated or parsed.
+  virtual void OnPacketReceived(const QuicSocketAddress& /*self_address*/,
+                                const QuicSocketAddress& /*peer_address*/,
+                                const QuicEncryptedPacket& /*packet*/) {}
+
+  // Called when the unauthenticated portion of the header has been parsed.
+  virtual void OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) {}
+
+  // Called when a packet is received with a connection id that does not
+  // match the ID of this connection.
+  virtual void OnIncorrectConnectionId(QuicConnectionId /*connection_id*/) {}
+
+  // Called when an undecryptable packet has been received. If |dropped| is
+  // true, the packet has been dropped. Otherwise, the packet will be queued and
+  // connection will attempt to process it later.
+  virtual void OnUndecryptablePacket(EncryptionLevel /*decryption_level*/,
+                                     bool /*dropped*/) {}
+
+  // Called when attempting to process a previously undecryptable packet.
+  virtual void OnAttemptingToProcessUndecryptablePacket(
+      EncryptionLevel /*decryption_level*/) {}
+
+  // Called when a duplicate packet has been received.
+  virtual void OnDuplicatePacket(QuicPacketNumber /*packet_number*/) {}
+
+  // Called when the protocol version on the received packet doensn't match
+  // current protocol version of the connection.
+  virtual void OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) {}
+
+  // Called when the complete header of a packet has been parsed.
+  virtual void OnPacketHeader(const QuicPacketHeader& /*header*/,
+                              QuicTime /*receive_time*/,
+                              EncryptionLevel /*level*/) {}
+
+  // Called when a StreamFrame has been parsed.
+  virtual void OnStreamFrame(const QuicStreamFrame& /*frame*/) {}
+
+  // Called when a CRYPTO frame containing handshake data is received.
+  virtual void OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {}
+
+  // Called when a StopWaitingFrame has been parsed.
+  virtual void OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) {}
+
+  // Called when a QuicPaddingFrame has been parsed.
+  virtual void OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {}
+
+  // Called when a Ping has been parsed.
+  virtual void OnPingFrame(const QuicPingFrame& /*frame*/,
+                           QuicTime::Delta /*ping_received_delay*/) {}
+
+  // Called when a GoAway has been parsed.
+  virtual void OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {}
+
+  // Called when a RstStreamFrame has been parsed.
+  virtual void OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {}
+
+  // Called when a ConnectionCloseFrame has been parsed. All forms
+  // of CONNECTION CLOSE are handled, Google QUIC, IETF QUIC
+  // CONNECTION CLOSE/Transport and IETF QUIC CONNECTION CLOSE/Application
+  virtual void OnConnectionCloseFrame(
+      const QuicConnectionCloseFrame& /*frame*/) {}
+
+  // Called when a WindowUpdate has been parsed.
+  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
+                                   const QuicTime& /*receive_time*/) {}
+
+  // Called when a BlockedFrame has been parsed.
+  virtual void OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {}
+
+  // Called when a NewConnectionIdFrame has been parsed.
+  virtual void OnNewConnectionIdFrame(
+      const QuicNewConnectionIdFrame& /*frame*/) {}
+
+  // Called when a RetireConnectionIdFrame has been parsed.
+  virtual void OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& /*frame*/) {}
+
+  // Called when a NewTokenFrame has been parsed.
+  virtual void OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {}
+
+  // Called when a MessageFrame has been parsed.
+  virtual void OnMessageFrame(const QuicMessageFrame& /*frame*/) {}
+
+  // Called when a HandshakeDoneFrame has been parsed.
+  virtual void OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) {}
+
+  // Called when a public reset packet has been received.
+  virtual void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) {}
+
+  // Called when a version negotiation packet has been received.
+  virtual void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& /*packet*/) {}
+
+  // Called when the connection is closed.
+  virtual void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/,
+                                  ConnectionCloseSource /*source*/) {}
+
+  // Called when the version negotiation is successful.
+  virtual void OnSuccessfulVersionNegotiation(
+      const ParsedQuicVersion& /*version*/) {}
+
+  // Called when a CachedNetworkParameters is sent to the client.
+  virtual void OnSendConnectionState(
+      const CachedNetworkParameters& /*cached_network_params*/) {}
+
+  // Called when a CachedNetworkParameters are received from the client.
+  virtual void OnReceiveConnectionState(
+      const CachedNetworkParameters& /*cached_network_params*/) {}
+
+  // Called when the connection parameters are set from the supplied
+  // |config|.
+  virtual void OnSetFromConfig(const QuicConfig& /*config*/) {}
+
+  // Called when RTT may have changed, including when an RTT is read from
+  // the config.
+  virtual void OnRttChanged(QuicTime::Delta /*rtt*/) const {}
+
+  // Called when a StopSendingFrame has been parsed.
+  virtual void OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) {}
+
+  // Called when a PathChallengeFrame has been parsed.
+  virtual void OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) {}
+
+  // Called when a PathResponseFrame has been parsed.
+  virtual void OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) {}
+
+  // Called when a StreamsBlockedFrame has been parsed.
+  virtual void OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& /*frame*/) {
+  }
+
+  // Called when a MaxStreamsFrame has been parsed.
+  virtual void OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) {}
+
+  // Called when an AckFrequencyFrame has been parsed.
+  virtual void OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) {}
+
+  // Called when |count| packet numbers have been skipped.
+  virtual void OnNPacketNumbersSkipped(QuicPacketCount /*count*/,
+                                       QuicTime /*now*/) {}
+
+  // Called when a packet is serialized but discarded (i.e. not sent).
+  virtual void OnPacketDiscarded(const SerializedPacket& /*packet*/) {}
+
+  // Called for QUIC+TLS versions when we send transport parameters.
+  virtual void OnTransportParametersSent(
+      const TransportParameters& /*transport_parameters*/) {}
+
+  // Called for QUIC+TLS versions when we receive transport parameters.
+  virtual void OnTransportParametersReceived(
+      const TransportParameters& /*transport_parameters*/) {}
+
+  // Called for QUIC+TLS versions when we resume cached transport parameters for
+  // 0-RTT.
+  virtual void OnTransportParametersResumed(
+      const TransportParameters& /*transport_parameters*/) {}
+
+  // Called for QUIC+TLS versions when 0-RTT is rejected.
+  virtual void OnZeroRttRejected(int /*reject_reason*/) {}
+
+  // Called for QUIC+TLS versions when 0-RTT packet gets acked.
+  virtual void OnZeroRttPacketAcked() {}
+
+  // Called on peer address change.
+  virtual void OnPeerAddressChange(AddressChangeType /*type*/,
+                                   QuicTime::Delta /*connection_time*/) {}
+
+  // Called after peer migration is validated.
+  virtual void OnPeerMigrationValidated(QuicTime::Delta /*connection_time*/) {}
+};
+
+class QUIC_EXPORT_PRIVATE QuicConnectionHelperInterface {
+ public:
+  virtual ~QuicConnectionHelperInterface() {}
+
+  // Returns a QuicClock to be used for all time related functions.
+  virtual const QuicClock* GetClock() const = 0;
+
+  // Returns a QuicRandom to be used for all random number related functions.
+  virtual QuicRandom* GetRandomGenerator() = 0;
+
+  // Returns a QuicheBufferAllocator to be used for stream send buffers.
+  virtual quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() = 0;
+};
+
+class QUIC_EXPORT_PRIVATE QuicConnection
+    : public QuicFramerVisitorInterface,
+      public QuicBlockedWriterInterface,
+      public QuicPacketCreator::DelegateInterface,
+      public QuicSentPacketManager::NetworkChangeVisitor,
+      public QuicNetworkBlackholeDetector::Delegate,
+      public QuicIdleNetworkDetector::Delegate,
+      public QuicPathValidator::SendDelegate,
+      public QuicConnectionIdManagerVisitorInterface {
+ public:
+  // Constructs a new QuicConnection for |connection_id| and
+  // |initial_peer_address| using |writer| to write packets. |owns_writer|
+  // specifies whether the connection takes ownership of |writer|. |helper| must
+  // outlive this connection.
+  QuicConnection(QuicConnectionId server_connection_id,
+                 QuicSocketAddress initial_self_address,
+                 QuicSocketAddress initial_peer_address,
+                 QuicConnectionHelperInterface* helper,
+                 QuicAlarmFactory* alarm_factory,
+                 QuicPacketWriter* writer,
+                 bool owns_writer,
+                 Perspective perspective,
+                 const ParsedQuicVersionVector& supported_versions);
+  QuicConnection(const QuicConnection&) = delete;
+  QuicConnection& operator=(const QuicConnection&) = delete;
+  ~QuicConnection() override;
+
+  // Sets connection parameters from the supplied |config|.
+  void SetFromConfig(const QuicConfig& config);
+
+  // Apply |connection_options| for this connection. Unlike SetFromConfig, this
+  // can happen at anytime in the life of a connection.
+  // Note there is no guarantee that all options can be applied. Components will
+  // only apply cherrypicked options that make sense at the time of the call.
+  void ApplyConnectionOptions(const QuicTagVector& connection_options);
+
+  // Called by the session when sending connection state to the client.
+  virtual void OnSendConnectionState(
+      const CachedNetworkParameters& cached_network_params);
+
+  // Called by the session when receiving connection state from the client.
+  virtual void OnReceiveConnectionState(
+      const CachedNetworkParameters& cached_network_params);
+
+  // Called by the Session when the client has provided CachedNetworkParameters.
+  virtual void ResumeConnectionState(
+      const CachedNetworkParameters& cached_network_params,
+      bool max_bandwidth_resumption);
+
+  // Called by the Session when a max pacing rate for the connection is needed.
+  virtual void SetMaxPacingRate(QuicBandwidth max_pacing_rate);
+
+  // Allows the client to adjust network parameters based on external
+  // information.
+  void AdjustNetworkParameters(
+      const SendAlgorithmInterface::NetworkParams& params);
+  void AdjustNetworkParameters(QuicBandwidth bandwidth,
+                               QuicTime::Delta rtt,
+                               bool allow_cwnd_to_decrease);
+
+  // Install a loss detection tuner. Must be called before OnConfigNegotiated.
+  void SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface> tuner);
+  // Called by the session when session->is_configured() becomes true.
+  void OnConfigNegotiated();
+
+  // Returns the max pacing rate for the connection.
+  virtual QuicBandwidth MaxPacingRate() const;
+
+  // Sends crypto handshake messages of length |write_length| to the peer in as
+  // few packets as possible. Returns the number of bytes consumed from the
+  // data.
+  virtual size_t SendCryptoData(EncryptionLevel level,
+                                size_t write_length,
+                                QuicStreamOffset offset);
+
+  // Send the data of length |write_length| to the peer in as few packets as
+  // possible. Returns the number of bytes consumed from data, and a boolean
+  // indicating if the fin bit was consumed.  This does not indicate the data
+  // has been sent on the wire: it may have been turned into a packet and queued
+  // if the socket was unexpectedly blocked.
+  virtual QuicConsumedData SendStreamData(QuicStreamId id,
+                                          size_t write_length,
+                                          QuicStreamOffset offset,
+                                          StreamSendingState state);
+
+  // Send |frame| to the peer. Returns true if frame is consumed, false
+  // otherwise.
+  virtual bool SendControlFrame(const QuicFrame& frame);
+
+  // Called when stream |id| is reset because of |error|.
+  virtual void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error);
+
+  // Closes the connection.
+  // |connection_close_behavior| determines whether or not a connection close
+  // packet is sent to the peer.
+  virtual void CloseConnection(
+      QuicErrorCode error,
+      const std::string& details,
+      ConnectionCloseBehavior connection_close_behavior);
+  // Closes the connection, specifying the wire error code |ietf_error|
+  // explicitly.
+  virtual void CloseConnection(
+      QuicErrorCode error,
+      QuicIetfTransportErrorCodes ietf_error,
+      const std::string& details,
+      ConnectionCloseBehavior connection_close_behavior);
+
+  QuicConnectionStats& mutable_stats() { return stats_; }
+
+  int retransmittable_on_wire_ping_count() const {
+    return retransmittable_on_wire_ping_count_;
+  }
+
+  // Returns statistics tracked for this connection.
+  const QuicConnectionStats& GetStats();
+
+  // Processes an incoming UDP packet (consisting of a QuicEncryptedPacket) from
+  // the peer.
+  // In a client, the packet may be "stray" and have a different connection ID
+  // than that of this connection.
+  virtual void ProcessUdpPacket(const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address,
+                                const QuicReceivedPacket& packet);
+
+  // QuicBlockedWriterInterface
+  // Called when the underlying connection becomes writable to allow queued
+  // writes to happen.
+  void OnBlockedWriterCanWrite() override;
+
+  bool IsWriterBlocked() const override {
+    return writer_ != nullptr && writer_->IsWriteBlocked();
+  }
+
+  // Called when the caller thinks it's worth a try to write.
+  // TODO(fayang): consider unifying this with QuicSession::OnCanWrite.
+  virtual void OnCanWrite();
+
+  // Called when an error occurs while attempting to write a packet to the
+  // network.
+  void OnWriteError(int error_code);
+
+  // Whether |result| represents a MSG TOO BIG write error.
+  bool IsMsgTooBig(const QuicPacketWriter* writer, const WriteResult& result);
+
+  // If the socket is not blocked, writes queued packets.
+  void WriteIfNotBlocked();
+
+  // Set the packet writer.
+  void SetQuicPacketWriter(QuicPacketWriter* writer, bool owns_writer) {
+    QUICHE_DCHECK(writer != nullptr);
+    if (writer_ != nullptr && owns_writer_) {
+      delete writer_;
+    }
+    writer_ = writer;
+    owns_writer_ = owns_writer;
+  }
+
+  // Set self address.
+  void SetSelfAddress(QuicSocketAddress address) {
+    default_path_.self_address = address;
+  }
+
+  // The version of the protocol this connection is using.
+  QuicTransportVersion transport_version() const {
+    return framer_.transport_version();
+  }
+
+  ParsedQuicVersion version() const { return framer_.version(); }
+
+  // The versions of the protocol that this connection supports.
+  const ParsedQuicVersionVector& supported_versions() const {
+    return framer_.supported_versions();
+  }
+
+  // Mark version negotiated for this connection. Once called, the connection
+  // will ignore received version negotiation packets.
+  void SetVersionNegotiated() {
+    version_negotiated_ = true;
+    if (perspective_ == Perspective::IS_SERVER) {
+      framer_.InferPacketHeaderTypeFromVersion();
+    }
+  }
+
+  // From QuicFramerVisitorInterface
+  void OnError(QuicFramer* framer) override;
+  bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override;
+  void OnPacket() override;
+  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override;
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& packet) override;
+  void OnRetryPacket(QuicConnectionId original_connection_id,
+                     QuicConnectionId new_connection_id,
+                     absl::string_view retry_token,
+                     absl::string_view retry_integrity_tag,
+                     absl::string_view retry_without_tag) override;
+  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
+  void OnDecryptedPacket(size_t length, EncryptionLevel level) override;
+  bool OnPacketHeader(const QuicPacketHeader& header) override;
+  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
+  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                             EncryptionLevel decryption_level,
+                             bool has_decryption_key) override;
+  bool OnStreamFrame(const QuicStreamFrame& frame) override;
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time) override;
+  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
+  bool OnAckTimestamp(QuicPacketNumber packet_number,
+                      QuicTime timestamp) override;
+  bool OnAckFrameEnd(QuicPacketNumber start) override;
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
+  bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
+  bool OnPingFrame(const QuicPingFrame& frame) override;
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
+  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
+  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
+  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) override;
+  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
+  bool OnMessageFrame(const QuicMessageFrame& frame) override;
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
+  void OnPacketComplete() override;
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const override;
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& packet) override;
+  void OnKeyUpdate(KeyUpdateReason reason) override;
+  void OnDecryptedFirstPacketInKeyPhase() override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+
+  // QuicPacketCreator::DelegateInterface
+  bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
+                            IsHandshake handshake) override;
+  const QuicFrames MaybeBundleAckOpportunistically() override;
+  QuicPacketBuffer GetPacketBuffer() override;
+  void OnSerializedPacket(SerializedPacket packet) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& error_details) override;
+  SerializedPacketFate GetSerializedPacketFate(
+      bool is_mtu_discovery,
+      EncryptionLevel encryption_level) override;
+
+  // QuicSentPacketManager::NetworkChangeVisitor
+  void OnCongestionChange() override;
+  void OnPathMtuIncreased(QuicPacketLength packet_size) override;
+
+  // QuicNetworkBlackholeDetector::Delegate
+  void OnPathDegradingDetected() override;
+  void OnBlackholeDetected() override;
+  void OnPathMtuReductionDetected() override;
+
+  // QuicIdleNetworkDetector::Delegate
+  void OnHandshakeTimeout() override;
+  void OnIdleNetworkDetected() override;
+
+  // QuicConnectionIdManagerVisitorInterface
+  void OnPeerIssuedConnectionIdRetired() override;
+  bool SendNewConnectionId(const QuicNewConnectionIdFrame& frame) override;
+  void OnNewConnectionIdIssued(const QuicConnectionId& connection_id) override;
+  void OnSelfIssuedConnectionIdRetired(
+      const QuicConnectionId& connection_id) override;
+
+  // Please note, this is not a const function. For logging purpose, please use
+  // ack_frame().
+  const QuicFrame GetUpdatedAckFrame();
+
+  // Called to send a new connection ID to client if the # of connection ID has
+  // not exceeded the active connection ID limits.
+  void MaybeSendConnectionIdToClient();
+
+  // Called when the handshake completes. On the client side, handshake
+  // completes on receipt of SHLO. On the server side, handshake completes when
+  // SHLO gets ACKed (or a forward secure packet gets decrypted successfully).
+  // TODO(fayang): Add a guard that this only gets called once.
+  void OnHandshakeComplete();
+
+  // Accessors
+  void set_visitor(QuicConnectionVisitorInterface* visitor) {
+    visitor_ = visitor;
+  }
+  void set_debug_visitor(QuicConnectionDebugVisitor* debug_visitor) {
+    debug_visitor_ = debug_visitor;
+    sent_packet_manager_.SetDebugDelegate(debug_visitor);
+  }
+  // Used in Chromium, but not internally.
+  // Must only be called before ping_alarm_ is set.
+  void set_ping_timeout(QuicTime::Delta ping_timeout) {
+    QUICHE_DCHECK(!ping_alarm_->IsSet());
+    ping_timeout_ = ping_timeout;
+  }
+  const QuicTime::Delta ping_timeout() const { return ping_timeout_; }
+  // Sets an initial timeout for the ping alarm when there is no retransmittable
+  // data in flight, allowing for a more aggressive ping alarm in that case.
+  void set_initial_retransmittable_on_wire_timeout(
+      QuicTime::Delta retransmittable_on_wire_timeout) {
+    QUICHE_DCHECK(!ping_alarm_->IsSet());
+    initial_retransmittable_on_wire_timeout_ = retransmittable_on_wire_timeout;
+  }
+  const QuicTime::Delta initial_retransmittable_on_wire_timeout() const {
+    return initial_retransmittable_on_wire_timeout_;
+  }
+  // Used in Chromium, but not internally.
+  void set_creator_debug_delegate(QuicPacketCreator::DebugDelegate* visitor) {
+    packet_creator_.set_debug_delegate(visitor);
+  }
+  const QuicSocketAddress& self_address() const {
+    return default_path_.self_address;
+  }
+  const QuicSocketAddress& peer_address() const { return direct_peer_address_; }
+  const QuicSocketAddress& effective_peer_address() const {
+    return default_path_.peer_address;
+  }
+
+  // Returns the server connection ID used on the default path.
+  const QuicConnectionId& connection_id() const {
+    return default_path_.server_connection_id;
+  }
+
+  const QuicConnectionId& client_connection_id() const {
+    return default_path_.client_connection_id;
+  }
+  void set_client_connection_id(QuicConnectionId client_connection_id);
+  const QuicClock* clock() const { return clock_; }
+  QuicRandom* random_generator() const { return random_generator_; }
+  QuicByteCount max_packet_length() const;
+  void SetMaxPacketLength(QuicByteCount length);
+
+  size_t mtu_probe_count() const { return mtu_probe_count_; }
+
+  bool connected() const { return connected_; }
+
+  // Must only be called on client connections.
+  const ParsedQuicVersionVector& server_supported_versions() const {
+    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+    return server_supported_versions_;
+  }
+
+  bool HasQueuedPackets() const { return !buffered_packets_.empty(); }
+  // Testing only. TODO(ianswett): Use a peer instead.
+  size_t NumQueuedPackets() const { return buffered_packets_.size(); }
+
+  // Returns true if the connection has queued packets or frames.
+  bool HasQueuedData() const;
+
+  // Sets the handshake and idle state connection timeouts.
+  void SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
+                          QuicTime::Delta idle_timeout);
+
+  // Called when the ping alarm fires. Causes a ping frame to be sent only
+  // if the retransmission alarm is not running.
+  void OnPingTimeout();
+
+  // Sets up a packet with an QuicAckFrame and sends it out.
+  void SendAck();
+
+  // Called when an RTO fires.  Resets the retransmission alarm if there are
+  // remaining unacked packets.
+  void OnRetransmissionTimeout();
+
+  // Mark all sent 0-RTT encrypted packets for retransmission. Called when new
+  // 0-RTT or 1-RTT key is available in gQUIC, or when 0-RTT is rejected in IETF
+  // QUIC. |reject_reason| is used in TLS-QUIC to log why 0-RTT was rejected.
+  void MarkZeroRttPacketsForRetransmission(int reject_reason);
+
+  // Calls |sent_packet_manager_|'s NeuterUnencryptedPackets. Used when the
+  // connection becomes forward secure and hasn't received acks for all packets.
+  void NeuterUnencryptedPackets();
+
+  // Changes the encrypter used for level |level| to |encrypter|.
+  void SetEncrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicEncrypter> encrypter);
+
+  // Called to remove encrypter of encryption |level|.
+  void RemoveEncrypter(EncryptionLevel level);
+
+  // SetNonceForPublicHeader sets the nonce that will be transmitted in the
+  // header of each packet encrypted at the initial encryption level decrypted.
+  // This should only be called on the server side.
+  void SetDiversificationNonce(const DiversificationNonce& nonce);
+
+  // SetDefaultEncryptionLevel sets the encryption level that will be applied
+  // to new packets.
+  void SetDefaultEncryptionLevel(EncryptionLevel level);
+
+  // SetDecrypter sets the primary decrypter, replacing any that already exists.
+  // If an alternative decrypter is in place then the function QUICHE_DCHECKs.
+  // This is intended for cases where one knows that future packets will be
+  // using the new decrypter and the previous decrypter is now obsolete. |level|
+  // indicates the encryption level of the new decrypter.
+  void SetDecrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicDecrypter> decrypter);
+
+  // SetAlternativeDecrypter sets a decrypter that may be used to decrypt
+  // future packets. |level| indicates the encryption level of the decrypter. If
+  // |latch_once_used| is true, then the first time that the decrypter is
+  // successful it will replace the primary decrypter.  Otherwise both
+  // decrypters will remain active and the primary decrypter will be the one
+  // last used.
+  void SetAlternativeDecrypter(EncryptionLevel level,
+                               std::unique_ptr<QuicDecrypter> decrypter,
+                               bool latch_once_used);
+
+  void InstallDecrypter(EncryptionLevel level,
+                        std::unique_ptr<QuicDecrypter> decrypter);
+  void RemoveDecrypter(EncryptionLevel level);
+
+  // Discard keys for the previous key phase.
+  void DiscardPreviousOneRttKeys();
+
+  // Returns true if it is currently allowed to initiate a key update.
+  bool IsKeyUpdateAllowed() const;
+
+  // Returns true if packets have been sent in the current 1-RTT key phase but
+  // none of these packets have been acked.
+  bool HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const;
+
+  // Returns the count of packets received that appeared to attempt a key
+  // update but failed decryption that have been received since the last
+  // successfully decrypted packet.
+  QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const;
+
+  // Increment the key phase. It is a bug to call this when IsKeyUpdateAllowed()
+  // is false. Returns false on error.
+  bool InitiateKeyUpdate(KeyUpdateReason reason);
+
+  const QuicDecrypter* decrypter() const;
+  const QuicDecrypter* alternative_decrypter() const;
+
+  Perspective perspective() const { return perspective_; }
+
+  // Allow easy overriding of truncated connection IDs.
+  void set_can_truncate_connection_ids(bool can) {
+    can_truncate_connection_ids_ = can;
+  }
+
+  // Returns the underlying sent packet manager.
+  const QuicSentPacketManager& sent_packet_manager() const {
+    return sent_packet_manager_;
+  }
+
+  // Returns the underlying sent packet manager.
+  QuicSentPacketManager& sent_packet_manager() { return sent_packet_manager_; }
+
+  UberReceivedPacketManager& received_packet_manager() {
+    return uber_received_packet_manager_;
+  }
+
+  bool CanWrite(HasRetransmittableData retransmittable);
+
+  // When the flusher is out of scope, only the outermost flusher will cause a
+  // flush of the connection and set the retransmission alarm if there is one
+  // pending.  In addition, this flusher can be configured to ensure that an ACK
+  // frame is included in the first packet created, if there's new ack
+  // information to be sent.
+  class QUIC_EXPORT_PRIVATE ScopedPacketFlusher {
+   public:
+    explicit ScopedPacketFlusher(QuicConnection* connection);
+    ~ScopedPacketFlusher();
+
+   private:
+    QuicConnection* connection_;
+    // If true, when this flusher goes out of scope, flush connection and set
+    // retransmission alarm if there is one pending.
+    bool flush_and_set_pending_retransmission_alarm_on_delete_;
+    // Latched connection's handshake_packet_sent_ on creation of this flusher.
+    const bool handshake_packet_sent_;
+  };
+
+  class QUIC_EXPORT_PRIVATE ScopedEncryptionLevelContext {
+   public:
+    ScopedEncryptionLevelContext(QuicConnection* connection,
+                                 EncryptionLevel level);
+    ~ScopedEncryptionLevelContext();
+
+   private:
+    QuicConnection* connection_;
+    // Latched current write encryption level on creation of this context.
+    EncryptionLevel latched_encryption_level_;
+  };
+
+  QuicPacketWriter* writer() { return writer_; }
+  const QuicPacketWriter* writer() const { return writer_; }
+
+  // Sends an MTU discovery packet of size |target_mtu|.  If the packet is
+  // acknowledged by the peer, the maximum packet size will be increased to
+  // |target_mtu|.
+  void SendMtuDiscoveryPacket(QuicByteCount target_mtu);
+
+  // Sends a connectivity probing packet to |peer_address| with
+  // |probing_writer|. If |probing_writer| is nullptr, will use default
+  // packet writer to write the packet. Returns true if subsequent packets can
+  // be written to the probing writer. If connection is V99, a padded IETF QUIC
+  // PATH_CHALLENGE packet is transmitted; if not V99, a Google QUIC padded PING
+  // packet is transmitted.
+  virtual bool SendConnectivityProbingPacket(
+      QuicPacketWriter* probing_writer,
+      const QuicSocketAddress& peer_address);
+
+  // Disable MTU discovery on this connection.
+  void DisableMtuDiscovery();
+
+  // Sends an MTU discovery packet and updates the MTU discovery alarm.
+  void DiscoverMtu();
+
+  // Sets the session notifier on the SentPacketManager.
+  void SetSessionNotifier(SessionNotifierInterface* session_notifier);
+
+  // Set data producer in framer.
+  void SetDataProducer(QuicStreamFrameDataProducer* data_producer);
+
+  // Set transmission type of next sending packets.
+  void SetTransmissionType(TransmissionType type);
+
+  // Tries to send |message| and returns the message status.
+  // If |flush| is false, this will return a MESSAGE_STATUS_BLOCKED
+  // when the connection is deemed unwritable.
+  virtual MessageStatus SendMessage(QuicMessageId message_id,
+                                    absl::Span<quiche::QuicheMemSlice> message,
+                                    bool flush);
+
+  // Returns the largest payload that will fit into a single MESSAGE frame.
+  // Because overhead can vary during a connection, this method should be
+  // checked for every message.
+  QuicPacketLength GetCurrentLargestMessagePayload() const;
+  // Returns the largest payload that will fit into a single MESSAGE frame at
+  // any point during the connection.  This assumes the version and
+  // connection ID lengths do not change.
+  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
+
+  void SetUnackedMapInitialCapacity();
+
+  virtual int GetUnackedMapInitialCapacity() const {
+    return kDefaultUnackedPacketsInitialCapacity;
+  }
+
+  // Returns the id of the cipher last used for decrypting packets.
+  uint32_t cipher_id() const;
+
+  std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets() {
+    return termination_packets_.get();
+  }
+
+  bool ack_frame_updated() const;
+
+  QuicConnectionHelperInterface* helper() { return helper_; }
+  const QuicConnectionHelperInterface* helper() const { return helper_; }
+  QuicAlarmFactory* alarm_factory() { return alarm_factory_; }
+
+  absl::string_view GetCurrentPacket();
+
+  const QuicFramer& framer() const { return framer_; }
+
+  const QuicPacketCreator& packet_creator() const { return packet_creator_; }
+
+  EncryptionLevel encryption_level() const { return encryption_level_; }
+  EncryptionLevel last_decrypted_level() const {
+    return last_decrypted_packet_level_;
+  }
+
+  const QuicSocketAddress& last_packet_source_address() const {
+    return last_received_packet_info_.source_address;
+  }
+
+  bool fill_up_link_during_probing() const {
+    return fill_up_link_during_probing_;
+  }
+  void set_fill_up_link_during_probing(bool new_value) {
+    fill_up_link_during_probing_ = new_value;
+  }
+
+  // This setting may be changed during the crypto handshake in order to
+  // enable/disable padding of different packets in the crypto handshake.
+  //
+  // This setting should never be set to false in public facing endpoints. It
+  // 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_creator_.set_fully_pad_crypto_handshake_packets(new_value);
+  }
+
+  bool fully_pad_during_crypto_handshake() const {
+    return packet_creator_.fully_pad_crypto_handshake_packets();
+  }
+
+  size_t min_received_before_ack_decimation() const;
+  void set_min_received_before_ack_decimation(size_t new_value);
+
+  // If |defer| is true, configures the connection to defer sending packets in
+  // response to an ACK to the SendAlarm. If |defer| is false, packets may be
+  // sent immediately after receiving an ACK.
+  void set_defer_send_in_response_to_packets(bool defer) {
+    defer_send_in_response_to_packets_ = defer;
+  }
+
+  // Sets the current per-packet options for the connection. The QuicConnection
+  // does not take ownership of |options|; |options| must live for as long as
+  // the QuicConnection is in use.
+  void set_per_packet_options(PerPacketOptions* options) {
+    per_packet_options_ = options;
+  }
+
+  bool IsPathDegrading() const { return is_path_degrading_; }
+
+  // Attempts to process any queued undecryptable packets.
+  void MaybeProcessUndecryptablePackets();
+
+  // Queue a coalesced packet.
+  void QueueCoalescedPacket(const QuicEncryptedPacket& packet);
+
+  // Process previously queued coalesced packets. Returns true if any coalesced
+  // packets have been successfully processed.
+  bool MaybeProcessCoalescedPackets();
+
+  enum PacketContent : uint8_t {
+    NO_FRAMES_RECEIVED,
+    // TODO(fkastenholz): Change name when we get rid of padded ping/
+    // pre-version-99.
+    // Also PATH CHALLENGE and PATH RESPONSE.
+    FIRST_FRAME_IS_PING,
+    SECOND_FRAME_IS_PADDING,
+    NOT_PADDED_PING,  // Set if the packet is not {PING, PADDING}.
+  };
+
+  // Whether the handshake completes from this connection's perspective.
+  bool IsHandshakeComplete() const;
+
+  // Whether peer completes handshake. Only used with TLS handshake.
+  bool IsHandshakeConfirmed() const;
+
+  // Returns the largest received packet number sent by peer.
+  QuicPacketNumber GetLargestReceivedPacket() const;
+
+  // Sets the original destination connection ID on the connection.
+  // This is called by QuicDispatcher when it has replaced the connection ID.
+  void SetOriginalDestinationConnectionId(
+      const QuicConnectionId& original_destination_connection_id);
+
+  // Returns the original destination connection ID used for this connection.
+  QuicConnectionId GetOriginalDestinationConnectionId();
+
+  // Called when ACK alarm goes off. Sends ACKs of those packet number spaces
+  // which have expired ACK timeout. Only used when this connection supports
+  // multiple packet number spaces.
+  void SendAllPendingAcks();
+
+  // Returns true if this connection supports multiple packet number spaces.
+  bool SupportsMultiplePacketNumberSpaces() const;
+
+  // For logging purpose.
+  const QuicAckFrame& ack_frame() const;
+
+  // Install encrypter and decrypter for ENCRYPTION_INITIAL using
+  // |connection_id| as the first client-sent destination connection ID,
+  // or the one sent after an IETF Retry.
+  void InstallInitialCrypters(QuicConnectionId connection_id);
+
+  // Called when version is considered negotiated.
+  void OnSuccessfulVersionNegotiation();
+
+  // Called when self migration succeeds after probing.
+  void OnSuccessfulMigration(bool is_port_change);
+
+  // Called for QUIC+TLS versions when we send transport parameters.
+  void OnTransportParametersSent(
+      const TransportParameters& transport_parameters) const;
+
+  // Called for QUIC+TLS versions when we receive transport parameters.
+  void OnTransportParametersReceived(
+      const TransportParameters& transport_parameters) const;
+
+  // Called for QUIC+TLS versions when we resume cached transport parameters for
+  // 0-RTT.
+  void OnTransportParametersResumed(
+      const TransportParameters& transport_parameters) const;
+
+  // Returns true if ack_alarm_ is set.
+  bool HasPendingAcks() const;
+
+  virtual void OnUserAgentIdKnown(const std::string& user_agent_id);
+
+  // Enables Legacy Version Encapsulation using |server_name| as SNI.
+  // Can only be set if this is a client connection.
+  void EnableLegacyVersionEncapsulation(const std::string& server_name);
+
+  bool use_path_validator() const { return use_path_validator_; }
+
+  // If now is close to idle timeout, returns true and sends a connectivity
+  // probing packet to test the connection for liveness. Otherwise, returns
+  // false.
+  bool MaybeTestLiveness();
+
+  // QuicPathValidator::SendDelegate
+  // Send PATH_CHALLENGE using the given path information. If |writer| is the
+  // default writer, PATH_CHALLENGE can be bundled with other frames, and the
+  // containing packet can be buffered if the writer is blocked. Otherwise,
+  // PATH_CHALLENGE will be written in an individual packet and it will be
+  // dropped if write fails. |data_buffer| will be populated with the payload
+  // for future validation.
+  // Return false if the connection is closed thus the caller will not continue
+  // the validation, otherwise return true.
+  bool SendPathChallenge(const QuicPathFrameBuffer& data_buffer,
+                         const QuicSocketAddress& self_address,
+                         const QuicSocketAddress& peer_address,
+                         const QuicSocketAddress& effective_peer_address,
+                         QuicPacketWriter* writer) override;
+  // If |writer| is the default writer and |peer_address| is the same as
+  // peer_address(), return the PTO of this connection. Otherwise, return 3 *
+  // kInitialRtt.
+  QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address_to_use,
+                           QuicPacketWriter* writer_to_use) const override;
+
+  // Start vaildating the path defined by |context| asynchronously and call the
+  // |result_delegate| after validation finishes. If the connection is
+  // validating another path, cancel and fail that validation before starting
+  // this one.
+  void ValidatePath(
+      std::unique_ptr<QuicPathValidationContext> context,
+      std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
+
+  bool can_receive_ack_frequency_frame() const {
+    return can_receive_ack_frequency_frame_;
+  }
+
+  void set_can_receive_ack_frequency_frame() {
+    can_receive_ack_frequency_frame_ = true;
+  }
+
+  bool is_processing_packet() const { return framer_.is_processing_packet(); }
+
+  bool HasPendingPathValidation() const;
+
+  QuicPathValidationContext* GetPathValidationContext() const;
+
+  void CancelPathValidation();
+
+  // Returns true if the migration succeeds, otherwise returns false (e.g., no
+  // available CIDs, connection disconnected, etc).
+  bool MigratePath(const QuicSocketAddress& self_address,
+                   const QuicSocketAddress& peer_address,
+                   QuicPacketWriter* writer,
+                   bool owns_writer);
+
+  // Called to clear the alternative_path_ when path validation failed on the
+  // client side.
+  void OnPathValidationFailureAtClient();
+
+  void SetSourceAddressTokenToSend(absl::string_view token);
+
+  void SendPing() {
+    SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
+  }
+
+  // Returns one server connection ID that associates the current session in the
+  // session map.
+  virtual QuicConnectionId GetOneActiveServerConnectionId() const;
+
+  // Returns all server connection IDs that have not been removed from the
+  // session map.
+  virtual std::vector<QuicConnectionId> GetActiveServerConnectionIds() const;
+
+  bool validate_client_address() const { return validate_client_addresses_; }
+
+  bool connection_migration_use_new_cid() const {
+    return connection_migration_use_new_cid_;
+  }
+
+  bool count_bytes_on_alternative_path_separately() const {
+    return count_bytes_on_alternative_path_separately_;
+  }
+
+  // Instantiates connection ID manager.
+  void CreateConnectionIdManager();
+
+  QuicConnectionContext* context() { return &context_; }
+  const QuicConnectionContext* context() const { return &context_; }
+
+  void set_tracer(std::unique_ptr<QuicConnectionTracer> tracer) {
+    context_.tracer.swap(tracer);
+  }
+
+  void set_bug_listener(std::unique_ptr<QuicBugListener> bug_listener) {
+    context_.bug_listener.swap(bug_listener);
+  }
+
+  absl::optional<QuicWallTime> quic_bug_10511_43_timestamp() const {
+    return quic_bug_10511_43_timestamp_;
+  }
+
+  const std::string& quic_bug_10511_43_error_detail() const {
+    return quic_bug_10511_43_error_detail_;
+  }
+
+ protected:
+  // Calls cancel() on all the alarms owned by this connection.
+  void CancelAllAlarms();
+
+  // Send a packet to the peer, and takes ownership of the packet if the packet
+  // cannot be written immediately.
+  virtual void SendOrQueuePacket(SerializedPacket packet);
+
+  // Called after a packet is received from a new effective peer address and is
+  // decrypted. Starts validation of effective peer's address change. Calls
+  // OnConnectionMigration as soon as the address changed.
+  void StartEffectivePeerMigration(AddressChangeType type);
+
+  // Called when a effective peer address migration is validated.
+  virtual void OnEffectivePeerMigrationValidated();
+
+  // Get the effective peer address from the packet being processed. For proxied
+  // connections, effective peer address is the address of the endpoint behind
+  // the proxy. For non-proxied connections, effective peer address is the same
+  // as peer address.
+  //
+  // Notes for implementations in subclasses:
+  // - If the connection is not proxied, the overridden method should use the
+  //   base implementation:
+  //
+  //       return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
+  //
+  // - If the connection is proxied, the overridden method may return either of
+  //   the following:
+  //   a) The address of the endpoint behind the proxy. The address is used to
+  //      drive effective peer migration.
+  //   b) An uninitialized address, meaning the effective peer address does not
+  //      change.
+  virtual QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const;
+
+  // Selects and updates the version of the protocol being used by selecting a
+  // version from |available_versions| which is also supported. Returns true if
+  // such a version exists, false otherwise.
+  bool SelectMutualVersion(const ParsedQuicVersionVector& available_versions);
+
+  // Returns the current per-packet options for the connection.
+  PerPacketOptions* per_packet_options() { return per_packet_options_; }
+
+  AddressChangeType active_effective_peer_migration_type() const {
+    return active_effective_peer_migration_type_;
+  }
+
+  // Sends a connection close packet to the peer and includes an ACK if the ACK
+  // is not empty, the |error| is not PACKET_WRITE_ERROR, and it fits.
+  // |ietf_error| may optionally be be used to directly specify the wire
+  // error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
+  // QuicErrorCodeToTransportErrorCode mapping of |error| will be used.
+  virtual void SendConnectionClosePacket(QuicErrorCode error,
+                                         QuicIetfTransportErrorCodes ietf_error,
+                                         const std::string& details);
+
+  // Returns true if the packet should be discarded and not sent.
+  virtual bool ShouldDiscardPacket(EncryptionLevel encryption_level);
+
+  // Retransmits packets continuously until blocked by the congestion control.
+  // If there are no packets to retransmit, does not do anything.
+  void SendProbingRetransmissions();
+
+  // Decides whether to send probing retransmissions, and does so if required.
+  void MaybeSendProbingRetransmissions();
+
+  // Notify various components(Session etc.) that this connection has been
+  // migrated.
+  virtual void OnConnectionMigration();
+
+  // Return whether the packet being processed is a connectivity probing.
+  // A packet is a connectivity probing if it is a padded ping packet with self
+  // and/or peer address changes.
+  bool IsCurrentPacketConnectivityProbing() const;
+
+  // Return true iff the writer is blocked, if blocked, call
+  // visitor_->OnWriteBlocked() to add the connection into the write blocked
+  // list.
+  bool HandleWriteBlocked();
+
+  // Whether connection enforces anti-amplification limit.
+  bool EnforceAntiAmplificationLimit() const;
+
+  void AddBytesReceivedBeforeAddressValidation(size_t length) {
+    default_path_.bytes_received_before_address_validation += length;
+  }
+
+  void set_validate_client_addresses(bool value) {
+    validate_client_addresses_ = value;
+  }
+
+ private:
+  friend class test::QuicConnectionPeer;
+
+  struct QUIC_EXPORT_PRIVATE PendingPathChallenge {
+    QuicPathFrameBuffer received_path_challenge;
+    QuicSocketAddress peer_address;
+  };
+
+  struct QUIC_EXPORT_PRIVATE PathState {
+    PathState() = default;
+
+    PathState(const QuicSocketAddress& alternative_self_address,
+              const QuicSocketAddress& alternative_peer_address,
+              const QuicConnectionId& client_connection_id,
+              const QuicConnectionId& server_connection_id,
+              absl::optional<StatelessResetToken> stateless_reset_token)
+        : self_address(alternative_self_address),
+          peer_address(alternative_peer_address),
+          client_connection_id(client_connection_id),
+          server_connection_id(server_connection_id),
+          stateless_reset_token(stateless_reset_token) {}
+
+    PathState(PathState&& other);
+
+    PathState& operator=(PathState&& other);
+
+    // Reset all the members.
+    void Clear();
+
+    QuicSocketAddress self_address;
+    // The actual peer address behind the proxy if there is any.
+    QuicSocketAddress peer_address;
+    QuicConnectionId client_connection_id;
+    QuicConnectionId server_connection_id;
+    absl::optional<StatelessResetToken> stateless_reset_token;
+    // True if the peer address has been validated. Address is considered
+    // validated when 1) an address token of the peer address is received and
+    // validated, or 2) a HANDSHAKE packet has been successfully processed on
+    // this path, or 3) a path validation on this path has succeeded.
+    bool validated = false;
+    // Used by the sever to apply anti-amplification limit after this path
+    // becomes the default path if |peer_address| hasn't been validated.
+    QuicByteCount bytes_received_before_address_validation = 0;
+    QuicByteCount bytes_sent_before_address_validation = 0;
+    // Points to the send algorithm on the old default path while connection is
+    // validating migrated peer address. Nullptr otherwise.
+    std::unique_ptr<SendAlgorithmInterface> send_algorithm;
+    absl::optional<RttStats> rtt_stats;
+  };
+
+  using QueuedPacketList = std::list<SerializedPacket>;
+
+  // BufferedPacket stores necessary information (encrypted buffer and self/peer
+  // addresses) of those packets which are serialized but failed to send because
+  // socket is blocked. From unacked packet map and send algorithm's
+  // perspective, buffered packets are treated as sent.
+  struct QUIC_EXPORT_PRIVATE BufferedPacket {
+    BufferedPacket(const SerializedPacket& packet,
+                   const QuicSocketAddress& self_address,
+                   const QuicSocketAddress& peer_address);
+    BufferedPacket(char* encrypted_buffer,
+                   QuicPacketLength encrypted_length,
+                   const QuicSocketAddress& self_address,
+                   const QuicSocketAddress& peer_address);
+    BufferedPacket(const BufferedPacket& other) = delete;
+    BufferedPacket(const BufferedPacket&& other) = delete;
+
+    ~BufferedPacket();
+
+    // encrypted_buffer is owned by buffered packet.
+    absl::string_view encrypted_buffer;
+    // Self and peer addresses when the packet is serialized.
+    const QuicSocketAddress self_address;
+    const QuicSocketAddress peer_address;
+  };
+
+  // ReceivedPacketInfo comprises the received packet information, which can be
+  // retrieved before the packet gets successfully decrypted.
+  struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
+    explicit ReceivedPacketInfo(QuicTime receipt_time)
+        : received_bytes_counted(false), receipt_time(receipt_time) {}
+    ReceivedPacketInfo(const QuicSocketAddress& destination_address,
+                       const QuicSocketAddress& source_address,
+                       QuicTime receipt_time)
+        : received_bytes_counted(false),
+          destination_address(destination_address),
+          source_address(source_address),
+          receipt_time(receipt_time) {}
+
+    bool received_bytes_counted;
+    QuicSocketAddress destination_address;
+    QuicSocketAddress source_address;
+    QuicTime receipt_time;
+  };
+
+  // UndecrytablePacket comprises a undecryptable packet and related
+  // information.
+  struct QUIC_EXPORT_PRIVATE UndecryptablePacket {
+    UndecryptablePacket(const QuicEncryptedPacket& packet,
+                        EncryptionLevel encryption_level,
+                        const ReceivedPacketInfo& packet_info)
+        : packet(packet.Clone()),
+          encryption_level(encryption_level),
+          packet_info(packet_info) {}
+
+    std::unique_ptr<QuicEncryptedPacket> packet;
+    EncryptionLevel encryption_level;
+    ReceivedPacketInfo packet_info;
+  };
+
+  // Handles the reverse path validation result depending on connection state:
+  // whether the connection is validating a migrated peer address or is
+  // validating an alternative path.
+  class ReversePathValidationResultDelegate
+      : public QuicPathValidator::ResultDelegate {
+   public:
+    ReversePathValidationResultDelegate(
+        QuicConnection* connection,
+        const QuicSocketAddress& direct_peer_address);
+
+    void OnPathValidationSuccess(
+        std::unique_ptr<QuicPathValidationContext> context) override;
+
+    void OnPathValidationFailure(
+        std::unique_ptr<QuicPathValidationContext> context) override;
+
+   private:
+    QuicConnection* connection_;
+    QuicSocketAddress original_direct_peer_address_;
+    // TODO(b/205023946) Debug-only fields, to be deprecated after the bug is
+    // fixed.
+    QuicSocketAddress peer_address_default_path_;
+    QuicSocketAddress peer_address_alternative_path_;
+    AddressChangeType active_effective_peer_migration_type_;
+  };
+
+  // A class which sets and clears in_on_retransmission_time_out_ when entering
+  // and exiting OnRetransmissionTimeout, respectively.
+  class QUIC_EXPORT_PRIVATE ScopedRetransmissionTimeoutIndicator {
+   public:
+    // |connection| must outlive this indicator.
+    explicit ScopedRetransmissionTimeoutIndicator(QuicConnection* connection);
+
+    ~ScopedRetransmissionTimeoutIndicator();
+
+   private:
+    QuicConnection* connection_;  // Not owned.
+  };
+
+  // If peer uses non-empty connection ID, discards any buffered packets on path
+  // change in IETF QUIC.
+  void MaybeClearQueuedPacketsOnPathChange();
+
+  // Notifies the visitor of the close and marks the connection as disconnected.
+  // Does not send a connection close frame to the peer. It should only be
+  // called by CloseConnection or OnConnectionCloseFrame, OnPublicResetPacket,
+  // and OnAuthenticatedIetfStatelessResetPacket.
+  // |ietf_error| may optionally be be used to directly specify the wire
+  // error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
+  // QuicErrorCodeToTransportErrorCode mapping of |error| will be used.
+  void TearDownLocalConnectionState(QuicErrorCode error,
+                                    QuicIetfTransportErrorCodes ietf_error,
+                                    const std::string& details,
+                                    ConnectionCloseSource source);
+  void TearDownLocalConnectionState(const QuicConnectionCloseFrame& frame,
+                                    ConnectionCloseSource source);
+
+  // Replace server connection ID on the client side from retry packet or
+  // initial packets with a different source connection ID.
+  void ReplaceInitialServerConnectionId(
+      const QuicConnectionId& new_server_connection_id);
+
+  // Given the server_connection_id find if there is already a corresponding
+  // client connection ID used on default/alternative path. If not, find if
+  // there is an unused connection ID.
+  void FindMatchingOrNewClientConnectionIdOrToken(
+      const PathState& default_path, const PathState& alternative_path,
+      const QuicConnectionId& server_connection_id,
+      QuicConnectionId* client_connection_id,
+      absl::optional<StatelessResetToken>* stateless_reset_token);
+
+  // Returns true and sets connection IDs if (self_address, peer_address)
+  // corresponds to either the default path or alternative path. Returns false
+  // otherwise.
+  bool FindOnPathConnectionIds(const QuicSocketAddress& self_address,
+                               const QuicSocketAddress& peer_address,
+                               QuicConnectionId* client_connection_id,
+                               QuicConnectionId* server_connection_id) const;
+
+  // Set default_path_ to the new_path_state and update the connection IDs in
+  // packet creator accordingly.
+  void SetDefaultPathState(PathState new_path_state);
+
+  // Returns true if header contains valid server connection ID.
+  bool ValidateServerConnectionId(const QuicPacketHeader& header) const;
+
+  // Update the connection IDs when client migrates with/without validation.
+  // Returns false if required connection ID is not available.
+  bool UpdateConnectionIdsOnClientMigration(
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address);
+
+  // Retire active peer issued connection IDs after they are no longer used on
+  // any path.
+  void RetirePeerIssuedConnectionIdsNoLongerOnPath();
+
+  // When path validation fails, proactively retire peer issued connection IDs
+  // no longer used on any path.
+  void RetirePeerIssuedConnectionIdsOnPathValidationFailure();
+
+  // Writes the given packet to socket, encrypted with packet's
+  // encryption_level. Returns true on successful write, and false if the writer
+  // was blocked and the write needs to be tried again. Notifies the
+  // SentPacketManager when the write is successful and sets
+  // retransmittable frames to nullptr.
+  // Saves the connection close packet for later transmission, even if the
+  // writer is write blocked.
+  bool WritePacket(SerializedPacket* packet);
+
+  // Enforce AEAD Confidentiality limits by iniating key update or closing
+  // connection if too many packets have been encrypted with the current key.
+  // Returns true if the connection was closed. Should not be called for
+  // termination packets.
+  bool MaybeHandleAeadConfidentialityLimits(const SerializedPacket& packet);
+
+  // Flush packets buffered in the writer, if any.
+  void FlushPackets();
+
+  // Make sure a stop waiting we got from our peer is sane.
+  // Returns nullptr if the frame is valid or an error string if it was invalid.
+  const char* ValidateStopWaitingFrame(
+      const QuicStopWaitingFrame& stop_waiting);
+
+  // Sends a version negotiation packet to the peer.
+  void SendVersionNegotiationPacket(bool ietf_quic, bool has_length_prefix);
+
+  // Clears any accumulated frames from the last received packet.
+  void ClearLastFrames();
+
+  // Deletes and clears any queued packets.
+  void ClearQueuedPackets();
+
+  // Closes the connection if the sent packet manager is tracking too many
+  // outstanding packets.
+  void CloseIfTooManyOutstandingSentPackets();
+
+  // Writes as many queued packets as possible.  The connection must not be
+  // blocked when this is called.
+  void WriteQueuedPackets();
+
+  // Queues |packet| in the hopes that it can be decrypted in the
+  // future, when a new key is installed.
+  void QueueUndecryptablePacket(const QuicEncryptedPacket& packet,
+                                EncryptionLevel decryption_level);
+
+  // Sends any packets which are a response to the last packet, including both
+  // acks and pending writes if an ack opened the congestion window.
+  void MaybeSendInResponseToPacket();
+
+  // Gets the least unacked packet number, which is the next packet number to be
+  // sent if there are no outstanding packets.
+  QuicPacketNumber GetLeastUnacked() const;
+
+  // Sets the ping alarm to the appropriate value, if any.
+  void SetPingAlarm();
+
+  // Sets the retransmission alarm based on SentPacketManager.
+  void SetRetransmissionAlarm();
+
+  // Sets the MTU discovery alarm if necessary.
+  // |sent_packet_number| is the recently sent packet number.
+  void MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number);
+
+  HasRetransmittableData IsRetransmittable(const SerializedPacket& packet);
+  bool IsTerminationPacket(const SerializedPacket& packet,
+                           QuicErrorCode* error_code);
+
+  // Set the size of the packet we are targeting while doing path MTU discovery.
+  void SetMtuDiscoveryTarget(QuicByteCount target);
+
+  // Returns |suggested_max_packet_size| clamped to any limits set by the
+  // underlying writer, connection, or protocol.
+  QuicByteCount GetLimitedMaxPacketSize(
+      QuicByteCount suggested_max_packet_size);
+
+  // Do any work which logically would be done in OnPacket but can not be
+  // safely done until the packet is validated. Returns true if packet can be
+  // handled, false otherwise.
+  bool ProcessValidatedPacket(const QuicPacketHeader& header);
+
+  // Returns true if received |packet_number| can be processed. Please note,
+  // this is called after packet got decrypted successfully.
+  bool ValidateReceivedPacketNumber(QuicPacketNumber packet_number);
+
+  // Consider receiving crypto frame on non crypto stream as memory corruption.
+  bool MaybeConsiderAsMemoryCorruption(const QuicStreamFrame& frame);
+
+  // Check if the connection has no outstanding data to send and notify
+  // congestion controller if it is the case.
+  void CheckIfApplicationLimited();
+
+  // Sets |current_packet_content_| to |type| if applicable. And
+  // starts effective peer migration if current packet is confirmed not a
+  // connectivity probe and |current_effective_peer_migration_type_| indicates
+  // effective peer address change.
+  // Returns true if connection is still alive.
+  ABSL_MUST_USE_RESULT bool UpdatePacketContent(QuicFrameType type);
+
+  // Called when last received ack frame has been processed.
+  // |send_stop_waiting| indicates whether a stop waiting needs to be sent.
+  // |acked_new_packet| is true if a previously-unacked packet was acked.
+  void PostProcessAfterAckFrame(bool send_stop_waiting, bool acked_new_packet);
+
+  // Updates the release time into the future.
+  void UpdateReleaseTimeIntoFuture();
+
+  // Sends generic path probe packet to the peer. If we are not IETF QUIC, will
+  // always send a padded ping, regardless of whether this is a request or not.
+  bool SendGenericPathProbePacket(QuicPacketWriter* probing_writer,
+                                  const QuicSocketAddress& peer_address);
+
+  // Called when an ACK is about to send. Resets ACK related internal states,
+  // e.g., cancels ack_alarm_, resets
+  // num_retransmittable_packets_received_since_last_ack_sent_ etc.
+  void ResetAckStates();
+
+  // Returns true if the ACK frame should be bundled with ACK-eliciting frame.
+  bool ShouldBundleRetransmittableFrameWithAck() const;
+
+  void PopulateStopWaitingFrame(QuicStopWaitingFrame* stop_waiting);
+
+  // Enables multiple packet number spaces support based on handshake protocol
+  // and flags.
+  void MaybeEnableMultiplePacketNumberSpacesSupport();
+
+  // Called to update ACK timeout when an retransmittable frame has been parsed.
+  void MaybeUpdateAckTimeout();
+
+  // Tries to fill coalesced packet with data of higher packet space.
+  void MaybeCoalescePacketOfHigherSpace();
+
+  // Serialize and send coalesced_packet. Returns false if serialization fails
+  // or the write causes errors, otherwise, returns true.
+  bool FlushCoalescedPacket();
+
+  // Returns the encryption level the connection close packet should be sent at,
+  // which is the highest encryption level that peer can guarantee to process.
+  EncryptionLevel GetConnectionCloseEncryptionLevel() const;
+
+  // Called after an ACK frame is successfully processed to update largest
+  // received packet number which contains an ACK frame.
+  void SetLargestReceivedPacketWithAck(QuicPacketNumber new_value);
+
+  // Called when new packets have been acknowledged or old keys have been
+  // discarded.
+  void OnForwardProgressMade();
+
+  // Returns largest received packet number which contains an ACK frame.
+  QuicPacketNumber GetLargestReceivedPacketWithAck() const;
+
+  // Returns the largest packet number that has been sent.
+  QuicPacketNumber GetLargestSentPacket() const;
+
+  // Returns the largest sent packet number that has been ACKed by peer.
+  QuicPacketNumber GetLargestAckedPacket() const;
+
+  // Whether connection is limited by amplification factor.
+  bool LimitedByAmplificationFactor() const;
+
+  // Called before sending a packet to get packet send time and to set the
+  // release time delay in |per_packet_options_|. Return the time when the
+  // packet is scheduled to be released(a.k.a send time), which is NOW + delay.
+  // Returns Now() and does not update release time delay if
+  // |supports_release_time_| is false.
+  QuicTime CalculatePacketSentTime();
+
+  // If we have a previously validate MTU value, e.g. due to a write error,
+  // revert to it and disable MTU discovery.
+  // Return true iff we reverted to a previously validate MTU.
+  bool MaybeRevertToPreviousMtu();
+
+  QuicTime GetPathMtuReductionDeadline() const;
+
+  // Returns path degrading deadline. QuicTime::Zero() means no path degrading
+  // detection is needed.
+  QuicTime GetPathDegradingDeadline() const;
+
+  // Returns true if path degrading should be detected.
+  bool ShouldDetectPathDegrading() const;
+
+  // Returns network blackhole deadline. QuicTime::Zero() means no blackhole
+  // detection is needed.
+  QuicTime GetNetworkBlackholeDeadline() const;
+
+  // Returns true if network blackhole should be detected.
+  bool ShouldDetectBlackhole() const;
+
+  // Returns retransmission deadline.
+  QuicTime GetRetransmissionDeadline() const;
+
+  // Validate connection IDs used during the handshake. Closes the connection
+  // on validation failure.
+  bool ValidateConfigConnectionIds(const QuicConfig& config);
+
+  // Called when ACK alarm goes off. Try to bundle crypto data with ACKs.
+  void MaybeBundleCryptoDataWithAcks();
+
+  // Returns true if an undecryptable packet of |decryption_level| should be
+  // buffered (such that connection can try to decrypt it later).
+  bool ShouldEnqueueUnDecryptablePacket(EncryptionLevel decryption_level,
+                                        bool has_decryption_key) const;
+
+  // Returns string which contains undecryptable packets information.
+  std::string UndecryptablePacketsInfo() const;
+
+  // Sets the max packet length on the packet creator if needed.
+  void MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+
+  // Sets internal state to enable or disable Legacy Version Encapsulation.
+  void MaybeActivateLegacyVersionEncapsulation();
+  void MaybeDisactivateLegacyVersionEncapsulation();
+
+  // For Google Quic, if the current packet is connectivity probing packet, call
+  // session OnPacketReceived() which eventually sends connectivity probing
+  // response on server side. And no-op on client side. And for both Google Quic
+  // and IETF Quic, start migration if the current packet is a non-probing
+  // packet.
+  // TODO(danzh) rename to MaybeRespondToPeerMigration() when Google Quic is
+  // deprecated.
+  void MaybeRespondToConnectivityProbingOrMigration();
+
+  // Called in IETF QUIC. Start peer migration if a non-probing frame is
+  // received and the current packet number is largest received so far.
+  void MaybeStartIetfPeerMigration();
+
+  // Send PATH_RESPONSE to the given peer address.
+  bool SendPathResponse(const QuicPathFrameBuffer& data_buffer,
+                        const QuicSocketAddress& peer_address_to_send,
+                        const QuicSocketAddress& effective_peer_address);
+
+  // Update both connection's and packet creator's peer address.
+  void UpdatePeerAddress(QuicSocketAddress peer_address);
+
+  // Send PING at encryption level.
+  void SendPingAtLevel(EncryptionLevel level);
+
+  // Write the given packet with |self_address| and |peer_address| using
+  // |writer|.
+  bool WritePacketUsingWriter(std::unique_ptr<SerializedPacket> packet,
+                              QuicPacketWriter* writer,
+                              const QuicSocketAddress& self_address,
+                              const QuicSocketAddress& peer_address,
+                              bool measure_rtt);
+
+  // Increment bytes sent/received on the alternative path if the current packet
+  // is sent/received on that path.
+  void MaybeUpdateBytesSentToAlternativeAddress(
+      const QuicSocketAddress& peer_address,
+      QuicByteCount sent_packet_size);
+  void MaybeUpdateBytesReceivedFromAlternativeAddress(
+      QuicByteCount received_packet_size);
+
+  // TODO(danzh) pass in PathState of the incoming packet or the packet sent
+  // once PathState is used in packet creator. Return true if the given self
+  // address and peer address is the same as the self address and peer address
+  // of the default path.
+  bool IsDefaultPath(const QuicSocketAddress& self_address,
+                     const QuicSocketAddress& peer_address) const;
+
+  // Return true if the |self_address| and |peer_address| is the same as the
+  // self address and peer address of the alternative path.
+  bool IsAlternativePath(const QuicSocketAddress& self_address,
+                         const QuicSocketAddress& peer_address) const;
+
+  // Restore connection default path and congestion control state to the last
+  // validated path and its state. Called after fail to validate peer address
+  // upon detecting a peer migration.
+  void RestoreToLastValidatedPath(
+      QuicSocketAddress original_direct_peer_address);
+
+  // Return true if the current incoming packet is from a peer address that is
+  // validated.
+  bool IsReceivedPeerAddressValidated() const;
+
+  // Called after receiving PATH_CHALLENGE. Update packet content and
+  // alternative path state if the current packet is from a non-default path.
+  // Return true if framer should continue processing the packet.
+  bool OnPathChallengeFrameInternal(const QuicPathChallengeFrame& frame);
+
+  virtual std::unique_ptr<QuicSelfIssuedConnectionIdManager>
+  MakeSelfIssuedConnectionIdManager();
+
+  // Called on peer IP change or restoring to previous address to reset
+  // congestion window, RTT stats, retransmission timer, etc. Only used in IETF
+  // QUIC.
+  std::unique_ptr<SendAlgorithmInterface> OnPeerIpAddressChanged();
+
+  // Process NewConnectionIdFrame either sent from peer or synsthesized from
+  // preferred_address transport parameter.
+  bool OnNewConnectionIdFrameInner(const QuicNewConnectionIdFrame& frame);
+
+  // Called to patch missing client connection ID on default/alternative paths
+  // when a new client connection ID is received.
+  void OnClientConnectionIdAvailable();
+
+  // Returns true if connection needs to set retransmission alarm after a packet
+  // gets sent.
+  bool ShouldSetRetransmissionAlarmOnPacketSent(bool in_flight,
+                                                EncryptionLevel level) const;
+
+  QuicConnectionContext context_;
+
+  QuicFramer framer_;
+
+  // Contents received in the current packet, especially used to identify
+  // whether the current packet is a padded PING packet.
+  PacketContent current_packet_content_;
+  // Set to true as soon as the packet currently being processed has been
+  // detected as a connectivity probing.
+  // Always false outside the context of ProcessUdpPacket().
+  bool is_current_packet_connectivity_probing_;
+
+  bool has_path_challenge_in_current_packet_;
+
+  // Caches the current effective peer migration type if a effective peer
+  // migration might be initiated. As soon as the current packet is confirmed
+  // not a connectivity probe, effective peer migration will start.
+  AddressChangeType current_effective_peer_migration_type_;
+  QuicConnectionHelperInterface* helper_;  // Not owned.
+  QuicAlarmFactory* alarm_factory_;        // Not owned.
+  PerPacketOptions* per_packet_options_;   // Not owned.
+  QuicPacketWriter* writer_;  // Owned or not depending on |owns_writer_|.
+  bool owns_writer_;
+  // Encryption level for new packets. Should only be changed via
+  // SetDefaultEncryptionLevel().
+  EncryptionLevel encryption_level_;
+  const QuicClock* clock_;
+  QuicRandom* random_generator_;
+
+  // On the server, the connection ID is set when receiving the first packet.
+  // This variable ensures we only set it this way once.
+  bool client_connection_id_is_set_;
+
+  // Whether we've already replaced our server connection ID due to receiving an
+  // INITIAL packet with a different source connection ID. Only used on client.
+  bool server_connection_id_replaced_by_initial_ = false;
+  // Address on the last successfully processed packet received from the
+  // direct peer.
+
+  // Other than initialization, do not modify it directly, use
+  // UpdatePeerAddress() instead.
+  QuicSocketAddress direct_peer_address_;
+  // The default path on which the endpoint sends non-probing packets.
+  // The send algorithm and RTT stats of this path are stored in
+  // |sent_packet_manager_| instead of in this object.
+  PathState default_path_;
+
+  // Records change type when the effective peer initiates migration to a new
+  // address. Reset to NO_CHANGE after effective peer migration is validated.
+  AddressChangeType active_effective_peer_migration_type_;
+
+  // Records highest sent packet number when effective peer migration is
+  // started.
+  QuicPacketNumber highest_packet_sent_before_effective_peer_migration_;
+
+  // True if Key Update is supported on this connection.
+  bool support_key_update_for_connection_;
+
+  // Tracks the lowest packet sent in the current key phase. Will be
+  // uninitialized before the first one-RTT packet has been sent or after a
+  // key update but before the first packet has been sent.
+  QuicPacketNumber lowest_packet_sent_in_current_key_phase_;
+
+  // True if the last packet has gotten far enough in the framer to be
+  // decrypted.
+  bool last_packet_decrypted_;
+  QuicByteCount last_size_;  // Size of the last received packet.
+  // TODO(rch): remove this when b/27221014 is fixed.
+  const char* current_packet_data_;  // UDP payload of packet currently being
+                                     // parsed or nullptr.
+  EncryptionLevel last_decrypted_packet_level_;
+  QuicPacketHeader last_header_;
+  bool should_last_packet_instigate_acks_;
+
+  // Track some peer state so we can do less bookkeeping
+  // Largest sequence sent by the peer which had an ack frame (latest ack info).
+  // Do not read or write directly, use GetLargestReceivedPacketWithAck() and
+  // SetLargestReceivedPacketWithAck() instead.
+  QuicPacketNumber largest_seen_packet_with_ack_;
+  // Largest packet number sent by the peer which had an ACK frame per packet
+  // number space. Only used when this connection supports multiple packet
+  // number spaces.
+  QuicPacketNumber largest_seen_packets_with_ack_[NUM_PACKET_NUMBER_SPACES];
+
+  // Largest packet number sent by the peer which had a stop waiting frame.
+  QuicPacketNumber largest_seen_packet_with_stop_waiting_;
+
+  // Collection of packets which were received before encryption was
+  // established, but which could not be decrypted.  We buffer these on
+  // the assumption that they could not be processed because they were
+  // sent with the INITIAL encryption and the CHLO message was lost.
+  std::deque<UndecryptablePacket> undecryptable_packets_;
+
+  // Collection of coalesced packets which were received while processing
+  // the current packet.
+  quiche::QuicheCircularDeque<std::unique_ptr<QuicEncryptedPacket>>
+      received_coalesced_packets_;
+
+  // Maximum number of undecryptable packets the connection will store.
+  size_t max_undecryptable_packets_;
+
+  // Maximum number of tracked packets.
+  QuicPacketCount max_tracked_packets_;
+
+  // Contains the connection close packets if the connection has been closed.
+  std::unique_ptr<std::vector<std::unique_ptr<QuicEncryptedPacket>>>
+      termination_packets_;
+
+  // Determines whether or not a connection close packet is sent to the peer
+  // after idle timeout due to lack of network activity. During the handshake,
+  // a connection close packet is sent, but not after.
+  ConnectionCloseBehavior idle_timeout_connection_close_behavior_;
+
+  // When > 0, close the QUIC connection after this number of RTOs.
+  size_t num_rtos_for_blackhole_detection_;
+
+  // Statistics for this session.
+  QuicConnectionStats stats_;
+
+  UberReceivedPacketManager uber_received_packet_manager_;
+
+  // Indicates how many consecutive times an ack has arrived which indicates
+  // the peer needs to stop waiting for some packets.
+  // TODO(fayang): remove this when deprecating Q043.
+  int stop_waiting_count_;
+
+  // Indicates the retransmission alarm needs to be set.
+  bool pending_retransmission_alarm_;
+
+  // If true, defer sending data in response to received packets to the
+  // SendAlarm.
+  bool defer_send_in_response_to_packets_;
+
+  // The timeout for PING.
+  QuicTime::Delta ping_timeout_;
+
+  // Initial timeout for how long the wire can have no retransmittable packets.
+  QuicTime::Delta initial_retransmittable_on_wire_timeout_;
+
+  // Indicates how many retransmittable-on-wire pings have been emitted without
+  // receiving any new data in between.
+  int consecutive_retransmittable_on_wire_ping_count_;
+
+  // Indicates how many retransmittable-on-wire pings have been emitted.
+  int retransmittable_on_wire_ping_count_;
+
+  // Arena to store class implementations within the QuicConnection.
+  QuicConnectionArena arena_;
+
+  // An alarm that fires when an ACK should be sent to the peer.
+  QuicArenaScopedPtr<QuicAlarm> ack_alarm_;
+  // An alarm that fires when a packet needs to be retransmitted.
+  QuicArenaScopedPtr<QuicAlarm> retransmission_alarm_;
+  // An alarm that is scheduled when the SentPacketManager requires a delay
+  // before sending packets and fires when the packet may be sent.
+  QuicArenaScopedPtr<QuicAlarm> send_alarm_;
+  // An alarm that fires when a ping should be sent.
+  QuicArenaScopedPtr<QuicAlarm> ping_alarm_;
+  // An alarm that fires when an MTU probe should be sent.
+  QuicArenaScopedPtr<QuicAlarm> mtu_discovery_alarm_;
+  // An alarm that fires to process undecryptable packets when new decyrption
+  // keys are available.
+  QuicArenaScopedPtr<QuicAlarm> process_undecryptable_packets_alarm_;
+  // An alarm that fires to discard keys for the previous key phase some time
+  // after a key update has completed.
+  QuicArenaScopedPtr<QuicAlarm> discard_previous_one_rtt_keys_alarm_;
+  // An alarm that fires to discard 0-RTT decryption keys some time after the
+  // first 1-RTT packet has been decrypted. Only used on server connections with
+  // TLS handshaker.
+  QuicArenaScopedPtr<QuicAlarm> discard_zero_rtt_decryption_keys_alarm_;
+  // Neither visitor is owned by this class.
+  QuicConnectionVisitorInterface* visitor_;
+  QuicConnectionDebugVisitor* debug_visitor_;
+
+  QuicPacketCreator packet_creator_;
+
+  // Information about the last received QUIC packet, which may not have been
+  // successfully decrypted and processed.
+  ReceivedPacketInfo last_received_packet_info_;
+
+  // Sent packet manager which tracks the status of packets sent by this
+  // connection and contains the send and receive algorithms to determine when
+  // to send packets.
+  QuicSentPacketManager sent_packet_manager_;
+
+  // Indicates whether connection version has been negotiated.
+  // Always true for server connections.
+  bool version_negotiated_;
+
+  // Tracks if the connection was created by the server or the client.
+  Perspective perspective_;
+
+  // True by default.  False if we've received or sent an explicit connection
+  // close.
+  bool connected_;
+
+  // Destination connection ID of the last received packet. If this ID is the
+  // original server connection ID chosen by client and server replaces it with
+  // a different ID, last_packet_destination_connection_id_ is set to the
+  // replacement connection ID on the server side.
+  QuicConnectionId last_packet_destination_connection_id_;
+
+  // Set to false if the connection should not send truncated connection IDs to
+  // the peer, even if the peer supports it.
+  bool can_truncate_connection_ids_;
+
+  // If non-empty this contains the set of versions received in a
+  // version negotiation packet.
+  ParsedQuicVersionVector server_supported_versions_;
+
+  // The number of MTU probes already sent.
+  size_t mtu_probe_count_;
+
+  // The value of |long_term_mtu_| prior to the last successful MTU increase.
+  // 0 means either
+  // - MTU discovery has never been enabled, or
+  // - MTU discovery has been enabled, but the connection got a packet write
+  //   error with a new (successfully probed) MTU, so it reverted
+  //   |long_term_mtu_| to the value before the last increase.
+  QuicPacketLength previous_validated_mtu_;
+  // The value of the MTU regularly used by the connection. This is different
+  // from the value returned by max_packet_size(), as max_packet_size() returns
+  // the value of the MTU as currently used by the serializer, so if
+  // serialization of an MTU probe is in progress, those two values will be
+  // different.
+  QuicByteCount long_term_mtu_;
+
+  // The maximum UDP payload size that our peer has advertised support for.
+  // Defaults to kDefaultMaxPacketSizeTransportParam until received from peer.
+  QuicByteCount peer_max_packet_size_;
+
+  // The size of the largest packet received from peer.
+  QuicByteCount largest_received_packet_size_;
+
+  // Indicates whether a write error is encountered currently. This is used to
+  // avoid infinite write errors.
+  bool write_error_occurred_;
+
+  // Indicates not to send or process stop waiting frames.
+  bool no_stop_waiting_frames_;
+
+  // Consecutive number of sent packets which have no retransmittable frames.
+  size_t consecutive_num_packets_with_no_retransmittable_frames_;
+
+  // After this many packets sent without retransmittable frames, an artificial
+  // retransmittable frame(a WINDOW_UPDATE) will be created to solicit an ack
+  // from the peer. Default to kMaxConsecutiveNonRetransmittablePackets.
+  size_t max_consecutive_num_packets_with_no_retransmittable_frames_;
+
+  // If true, bundle an ack-eliciting frame with an ACK if the PTO or RTO alarm
+  // have previously fired.
+  bool bundle_retransmittable_with_pto_ack_;
+
+  // If true, the connection will fill up the pipe with extra data whenever the
+  // congestion controller needs it in order to make a bandwidth estimate.  This
+  // is useful if the application pesistently underutilizes the link, but still
+  // relies on having a reasonable bandwidth estimate from the connection, e.g.
+  // for real time applications.
+  bool fill_up_link_during_probing_;
+
+  // If true, the probing retransmission will not be started again.  This is
+  // used to safeguard against an accidental tail recursion in probing
+  // retransmission code.
+  bool probing_retransmission_pending_;
+
+  // Id of latest sent control frame. 0 if no control frame has been sent.
+  QuicControlFrameId last_control_frame_id_;
+
+  // True if the peer is unreachable on the current path.
+  bool is_path_degrading_;
+
+  // True if an ack frame is being processed.
+  bool processing_ack_frame_;
+
+  // True if the writer supports release timestamp.
+  bool supports_release_time_;
+
+  std::unique_ptr<QuicPeerIssuedConnectionIdManager> peer_issued_cid_manager_;
+  std::unique_ptr<QuicSelfIssuedConnectionIdManager> self_issued_cid_manager_;
+
+  // Time this connection can release packets into the future.
+  QuicTime::Delta release_time_into_future_;
+
+  // Payload of most recently transmitted IETF QUIC connectivity
+  // probe packet (the PATH_CHALLENGE payload). This implementation transmits
+  // only one PATH_CHALLENGE per connectivity probe, so only one
+  // QuicPathFrameBuffer is needed.
+  std::unique_ptr<QuicPathFrameBuffer> transmitted_connectivity_probe_payload_;
+
+  // Payloads that were received in the most recent probe. This needs to be a
+  // Deque because the peer might no be using this implementation, and others
+  // might send a packet with more than one PATH_CHALLENGE, so all need to be
+  // saved and responded to.
+  // TODO(danzh) deprecate this field when deprecating
+  // --quic_send_path_response.
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer>
+      received_path_challenge_payloads_;
+
+  // When we receive a RETRY packet or some INITIAL packets, we replace
+  // |server_connection_id_| with the value from that packet and save off the
+  // original value of |server_connection_id_| into
+  // |original_destination_connection_id_| for validation.
+  absl::optional<QuicConnectionId> original_destination_connection_id_;
+
+  // The connection ID that replaces original_destination_connection_id_.
+  QuicConnectionId original_destination_connection_id_replacement_;
+
+  // After we receive a RETRY packet, |retry_source_connection_id_| contains
+  // the source connection ID from that packet.
+  absl::optional<QuicConnectionId> retry_source_connection_id_;
+
+  // Used to store content of packets which cannot be sent because of write
+  // blocked. Packets' encrypted buffers are copied and owned by
+  // buffered_packets_. From unacked_packet_map (and congestion control)'s
+  // perspective, those packets are considered sent.
+  std::list<BufferedPacket> buffered_packets_;
+
+  // Used to coalesce packets of different encryption level into the same UDP
+  // datagram. Connection stops trying to coalesce packets if a forward secure
+  // packet gets acknowledged.
+  QuicCoalescedPacket coalesced_packet_;
+
+  QuicConnectionMtuDiscoverer mtu_discoverer_;
+
+  QuicNetworkBlackholeDetector blackhole_detector_;
+
+  QuicIdleNetworkDetector idle_network_detector_;
+
+  bool blackhole_detection_disabled_ = false;
+
+  const bool default_enable_5rto_blackhole_detection_ =
+      GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2);
+
+  // Whether the Legacy Version Encapsulation feature is enabled.
+  bool legacy_version_encapsulation_enabled_ = false;
+  // Whether we are in the middle of sending a packet using Legacy Version
+  // Encapsulation.
+  bool legacy_version_encapsulation_in_progress_ = false;
+  // SNI to send when using Legacy Version Encapsulation.
+  std::string legacy_version_encapsulation_sni_;
+  // True if next packet is intended to consume remaining space in the
+  // coalescer.
+  bool fill_coalesced_packet_ = false;
+
+  size_t anti_amplification_factor_ =
+      GetQuicFlag(FLAGS_quic_anti_amplification_factor);
+
+  bool use_path_validator_ =
+      GetQuicReloadableFlag(quic_pass_path_response_to_validator);
+
+  // True if AckFrequencyFrame is supported.
+  bool can_receive_ack_frequency_frame_ = false;
+
+  // Indicate whether coalescing is done.
+  bool coalescing_done_ = false;
+
+  // Indicate whether any ENCRYPTION_HANDSHAKE packet has been sent.
+  bool handshake_packet_sent_ = false;
+
+  // Indicate whether to send an AckFrequencyFrame upon handshake completion.
+  // The AckFrequencyFrame sent will updates client's max_ack_delay, which if
+  // chosen properly can reduce the CPU and bandwidth usage for ACK frames.
+  bool send_ack_frequency_on_handshake_completion_ = false;
+
+  // Indicate whether AckFrequency frame has been sent.
+  bool ack_frequency_sent_ = false;
+
+  // True if a 0-RTT decrypter was or is installed at some point in the
+  // connection's lifetime.
+  bool had_zero_rtt_decrypter_ = false;
+
+  // True after the first 1-RTT packet has successfully decrypted.
+  bool have_decrypted_first_one_rtt_packet_ = false;
+
+  // True if we are currently processing OnRetransmissionTimeout.
+  bool in_on_retransmission_time_out_ = false;
+
+  QuicPathValidator path_validator_;
+
+  // Stores information of a path which maybe used as default path in the
+  // future. On the client side, it gets created when the client starts
+  // validating a new path and gets cleared once it becomes the default path or
+  // the path validation fails or replaced by a newer path of interest. On the
+  // server side, alternative_path gets created when server: 1) receives
+  // PATH_CHALLENGE on non-default path, or 2) switches to a not yet validated
+  // default path such that it needs to store the previous validated default
+  // path.
+  // Note that if alternative_path_ stores a validated path information (case
+  // 2), do not override it on receiving PATH_CHALLENGE (case 1).
+  PathState alternative_path_;
+
+  // This field is used to debug b/177312785.
+  QuicFrameType most_recent_frame_type_;
+
+  bool count_bytes_on_alternative_path_separately_ =
+      GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately);
+
+  // If true, upon seeing a new client address, validate the client address.
+  bool validate_client_addresses_ = false;
+
+  // Indicates whether we should proactively validate peer address on a
+  // PATH_CHALLENGE received.
+  bool should_proactively_validate_peer_address_on_path_challenge_ = false;
+
+  // Enable this via reloadable flag once this feature is complete.
+  bool connection_migration_use_new_cid_ = false;
+
+  const bool flush_after_coalesce_higher_space_packets_ =
+      GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets);
+
+  // Records the 1-RTT connection close frame sent.
+  // TODO(b/180103273): remove this after the bug gets fixed.
+  absl::optional<QuicConnectionCloseFrame> connection_close_frame_sent_;
+
+  // If true, send connection close packet on INVALID_VERSION.
+  bool send_connection_close_for_invalid_version_ = false;
+
+  // TODO(b/205023946) Debug-only fields, to be deprecated after the bug is
+  // fixed.
+  absl::optional<QuicWallTime> quic_bug_10511_43_timestamp_;
+  std::string quic_bug_10511_43_error_detail_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
diff --git a/quiche/quic/core/quic_connection_context.cc b/quiche/quic/core/quic_connection_context.cc
new file mode 100644
index 0000000..d8dfbac
--- /dev/null
+++ b/quiche/quic/core/quic_connection_context.cc
@@ -0,0 +1,36 @@
+// Copyright 2021 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 "quiche/quic/core/quic_connection_context.h"
+
+#include "quiche/common/platform/api/quiche_thread_local.h"
+
+namespace quic {
+namespace {
+DEFINE_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, QuicConnectionContext);
+}  // namespace
+
+// static
+QuicConnectionContext* QuicConnectionContext::Current() {
+  return GET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext);
+}
+
+QuicConnectionContextSwitcher::QuicConnectionContextSwitcher(
+    QuicConnectionContext* new_context)
+    : old_context_(QuicConnectionContext::Current()) {
+  SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, new_context);
+  if (new_context && new_context->tracer) {
+    new_context->tracer->Activate();
+  }
+}
+
+QuicConnectionContextSwitcher::~QuicConnectionContextSwitcher() {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  if (current && current->tracer) {
+    current->tracer->Deactivate();
+  }
+  SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, old_context_);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_context.h b/quiche/quic/core/quic_connection_context.h
new file mode 100644
index 0000000..192002e
--- /dev/null
+++ b/quiche/quic/core/quic_connection_context.h
@@ -0,0 +1,133 @@
+// Copyright 2021 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_CONNECTION_CONTEXT_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
+
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+// QuicConnectionTracer is responsible for emit trace messages for a single
+// QuicConnection.
+// QuicConnectionTracer is part of the QuicConnectionContext.
+class QUIC_EXPORT_PRIVATE QuicConnectionTracer {
+ public:
+  virtual ~QuicConnectionTracer() = default;
+
+  // Emit a trace message from a string literal. The trace may simply remember
+  // the address of the literal in this function and read it at a later time.
+  virtual void PrintLiteral(const char* literal) = 0;
+
+  // Emit a trace message from a string_view. Unlike PrintLiteral, this function
+  // will not read |s| after it returns.
+  virtual void PrintString(absl::string_view s) = 0;
+
+  // Emit a trace message from printf-style arguments.
+  template <typename... Args>
+  void Printf(const absl::FormatSpec<Args...>& format, const Args&... args) {
+    std::string s = absl::StrFormat(format, args...);
+    PrintString(s);
+  }
+
+ private:
+  friend class QuicConnectionContextSwitcher;
+
+  // Called by QuicConnectionContextSwitcher, when |this| becomes the current
+  // thread's QUIC connection tracer.
+  //
+  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
+  // constructor/destructor, they always come in pairs.
+  virtual void Activate() {}
+
+  // Called by QuicConnectionContextSwitcher, when |this| stops from being the
+  // current thread's QUIC connection tracer.
+  //
+  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
+  // constructor/destructor, they always come in pairs.
+  virtual void Deactivate() {}
+};
+
+// QuicBugListener is a helper class for implementing QUIC_BUG. The QUIC_BUG
+// implementation can send the bug information into quic::CurrentBugListener().
+class QUIC_EXPORT_PRIVATE QuicBugListener {
+ public:
+  virtual ~QuicBugListener() = default;
+  virtual void OnQuicBug(const char* bug_id, const char* file, int line,
+                         absl::string_view bug_message) = 0;
+};
+
+// QuicConnectionContext is a per-QuicConnection context that includes
+// facilities useable by any part of a QuicConnection. A QuicConnectionContext
+// is owned by a QuicConnection.
+//
+// The 'top-level' QuicConnection functions are responsible for maintaining the
+// thread-local QuicConnectionContext pointer, such that any function called by
+// them(directly or indirectly) can access the context.
+//
+// Like QuicConnection, all facilities in QuicConnectionContext are assumed to
+// be called from a single thread at a time, they are NOT thread-safe.
+struct QUIC_EXPORT_PRIVATE QuicConnectionContext final {
+  // Get the context on the current executing thread. nullptr if the current
+  // function is not called from a 'top-level' QuicConnection function.
+  static QuicConnectionContext* Current();
+
+  std::unique_ptr<QuicConnectionTracer> tracer;
+  std::unique_ptr<QuicBugListener> bug_listener;
+};
+
+// QuicConnectionContextSwitcher is a RAII object used for maintaining the
+// thread-local QuicConnectionContext pointer.
+class QUIC_EXPORT_PRIVATE QuicConnectionContextSwitcher final {
+ public:
+  // The constructor switches from QuicConnectionContext::Current() to
+  // |new_context|.
+  explicit QuicConnectionContextSwitcher(QuicConnectionContext* new_context);
+
+  // The destructor switches from QuicConnectionContext::Current() back to the
+  // old context.
+  ~QuicConnectionContextSwitcher();
+
+ private:
+  QuicConnectionContext* old_context_;
+};
+
+// Emit a trace message from a string literal to the current tracer(if any).
+inline void QUIC_TRACELITERAL(const char* literal) {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  if (current && current->tracer) {
+    current->tracer->PrintLiteral(literal);
+  }
+}
+
+// Emit a trace message from a string_view to the current tracer(if any).
+inline void QUIC_TRACESTRING(absl::string_view s) {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  if (current && current->tracer) {
+    current->tracer->PrintString(s);
+  }
+}
+
+// Emit a trace message from printf-style arguments to the current tracer(if
+// any).
+template <typename... Args>
+void QUIC_TRACEPRINTF(const absl::FormatSpec<Args...>& format,
+                      const Args&... args) {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  if (current && current->tracer) {
+    current->tracer->Printf(format, args...);
+  }
+}
+
+inline QuicBugListener* CurrentBugListener() {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  return (current != nullptr) ? current->bug_listener.get() : nullptr;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
diff --git a/quiche/quic/core/quic_connection_context_test.cc b/quiche/quic/core/quic_connection_context_test.cc
new file mode 100644
index 0000000..0b87d01
--- /dev/null
+++ b/quiche/quic/core/quic_connection_context_test.cc
@@ -0,0 +1,173 @@
+// Copyright 2021 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 "quiche/quic/core/quic_connection_context.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_thread.h"
+
+using testing::ElementsAre;
+
+namespace quic {
+namespace {
+
+class TraceCollector : public QuicConnectionTracer {
+ public:
+  ~TraceCollector() override = default;
+
+  void PrintLiteral(const char* literal) override { trace_.push_back(literal); }
+
+  void PrintString(absl::string_view s) override {
+    trace_.push_back(std::string(s));
+  }
+
+  const std::vector<std::string>& trace() const { return trace_; }
+
+ private:
+  std::vector<std::string> trace_;
+};
+
+struct FakeConnection {
+  FakeConnection() { context.tracer = std::make_unique<TraceCollector>(); }
+
+  const std::vector<std::string>& trace() const {
+    return static_cast<const TraceCollector*>(context.tracer.get())->trace();
+  }
+
+  QuicConnectionContext context;
+};
+
+void SimpleSwitch() {
+  FakeConnection connection;
+
+  // These should be ignored since current context is nullptr.
+  EXPECT_EQ(QuicConnectionContext::Current(), nullptr);
+  QUIC_TRACELITERAL("before switch: literal");
+  QUIC_TRACESTRING(std::string("before switch: string"));
+  QUIC_TRACEPRINTF("%s: %s", "before switch", "printf");
+
+  {
+    QuicConnectionContextSwitcher switcher(&connection.context);
+    QUIC_TRACELITERAL("literal");
+    QUIC_TRACESTRING(std::string("string"));
+    QUIC_TRACEPRINTF("%s", "printf");
+  }
+
+  EXPECT_EQ(QuicConnectionContext::Current(), nullptr);
+  QUIC_TRACELITERAL("after switch: literal");
+  QUIC_TRACESTRING(std::string("after switch: string"));
+  QUIC_TRACEPRINTF("%s: %s", "after switch", "printf");
+
+  EXPECT_THAT(connection.trace(), ElementsAre("literal", "string", "printf"));
+}
+
+void NestedSwitch() {
+  FakeConnection outer, inner;
+
+  {
+    QuicConnectionContextSwitcher switcher(&outer.context);
+    QUIC_TRACELITERAL("outer literal 0");
+    QUIC_TRACESTRING(std::string("outer string 0"));
+    QUIC_TRACEPRINTF("%s %s %d", "outer", "printf", 0);
+
+    {
+      QuicConnectionContextSwitcher switcher(&inner.context);
+      QUIC_TRACELITERAL("inner literal");
+      QUIC_TRACESTRING(std::string("inner string"));
+      QUIC_TRACEPRINTF("%s %s", "inner", "printf");
+    }
+
+    QUIC_TRACELITERAL("outer literal 1");
+    QUIC_TRACESTRING(std::string("outer string 1"));
+    QUIC_TRACEPRINTF("%s %s %d", "outer", "printf", 1);
+  }
+
+  EXPECT_THAT(outer.trace(), ElementsAre("outer literal 0", "outer string 0",
+                                         "outer printf 0", "outer literal 1",
+                                         "outer string 1", "outer printf 1"));
+
+  EXPECT_THAT(inner.trace(),
+              ElementsAre("inner literal", "inner string", "inner printf"));
+}
+
+void AlternatingSwitch() {
+  FakeConnection zero, one, two;
+  for (int i = 0; i < 15; ++i) {
+    FakeConnection* connection =
+        ((i % 3) == 0) ? &zero : (((i % 3) == 1) ? &one : &two);
+
+    QuicConnectionContextSwitcher switcher(&connection->context);
+    QUIC_TRACEPRINTF("%d", i);
+  }
+
+  EXPECT_THAT(zero.trace(), ElementsAre("0", "3", "6", "9", "12"));
+  EXPECT_THAT(one.trace(), ElementsAre("1", "4", "7", "10", "13"));
+  EXPECT_THAT(two.trace(), ElementsAre("2", "5", "8", "11", "14"));
+}
+
+typedef void (*ThreadFunction)();
+
+template <ThreadFunction func>
+class TestThread : public QuicThread {
+ public:
+  TestThread() : QuicThread("TestThread") {}
+  ~TestThread() override = default;
+
+ protected:
+  void Run() override { func(); }
+};
+
+template <ThreadFunction func>
+void RunInThreads(size_t n_threads) {
+  using ThreadType = TestThread<func>;
+  std::vector<ThreadType> threads(n_threads);
+
+  for (ThreadType& t : threads) {
+    t.Start();
+  }
+
+  for (ThreadType& t : threads) {
+    t.Join();
+  }
+}
+
+class QuicConnectionContextTest : public QuicTest {
+ protected:
+};
+
+TEST_F(QuicConnectionContextTest, NullTracerOK) {
+  FakeConnection connection;
+  std::unique_ptr<QuicConnectionTracer> tracer;
+
+  {
+    QuicConnectionContextSwitcher switcher(&connection.context);
+    QUIC_TRACELITERAL("msg 1 recorded");
+  }
+
+  connection.context.tracer.swap(tracer);
+
+  {
+    QuicConnectionContextSwitcher switcher(&connection.context);
+    // Should be a no-op since connection.context.tracer is nullptr.
+    QUIC_TRACELITERAL("msg 2 ignored");
+  }
+
+  EXPECT_THAT(static_cast<TraceCollector*>(tracer.get())->trace(),
+              ElementsAre("msg 1 recorded"));
+}
+
+TEST_F(QuicConnectionContextTest, TestSimpleSwitch) {
+  RunInThreads<SimpleSwitch>(10);
+}
+
+TEST_F(QuicConnectionContextTest, TestNestedSwitch) {
+  RunInThreads<NestedSwitch>(10);
+}
+
+TEST_F(QuicConnectionContextTest, TestAlternatingSwitch) {
+  RunInThreads<AlternatingSwitch>(10);
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_id.cc b/quiche/quic/core/quic_connection_id.cc
new file mode 100644
index 0000000..3103cf2
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id.cc
@@ -0,0 +1,180 @@
+// Copyright 2018 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 "quiche/quic/core/quic_connection_id.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <iomanip>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "third_party/boringssl/src/include/openssl/siphash.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+namespace {
+
+// QuicConnectionIdHasher can be used to generate a stable connection ID hash
+// function that will return the same value for two equal connection IDs for
+// the duration of process lifetime. It is meant to be used as input to data
+// structures that do not outlast process lifetime. A new key is generated once
+// per process to prevent attackers from crafting connection IDs in such a way
+// that they always land in the same hash bucket.
+class QuicConnectionIdHasher {
+ public:
+  inline QuicConnectionIdHasher()
+      : QuicConnectionIdHasher(QuicRandom::GetInstance()) {}
+
+  explicit inline QuicConnectionIdHasher(QuicRandom* random) {
+    random->RandBytes(&sip_hash_key_, sizeof(sip_hash_key_));
+  }
+
+  inline size_t Hash(const char* input, size_t input_len) const {
+    return static_cast<size_t>(SIPHASH_24(
+        sip_hash_key_, reinterpret_cast<const uint8_t*>(input), input_len));
+  }
+
+ private:
+  uint64_t sip_hash_key_[2];
+};
+
+}  // namespace
+
+QuicConnectionId::QuicConnectionId() : QuicConnectionId(nullptr, 0) {
+  static_assert(offsetof(QuicConnectionId, padding_) ==
+                    offsetof(QuicConnectionId, length_),
+                "bad offset");
+  static_assert(sizeof(QuicConnectionId) <= 16, "bad size");
+}
+
+QuicConnectionId::QuicConnectionId(const char* data, uint8_t length) {
+  length_ = length;
+  if (length_ == 0) {
+    return;
+  }
+  if (length_ <= sizeof(data_short_)) {
+    memcpy(data_short_, data, length_);
+    return;
+  }
+  data_long_ = reinterpret_cast<char*>(malloc(length_));
+  QUICHE_CHECK_NE(nullptr, data_long_);
+  memcpy(data_long_, data, length_);
+}
+
+QuicConnectionId::QuicConnectionId(const absl::Span<const uint8_t> data)
+    : QuicConnectionId(reinterpret_cast<const char*>(data.data()),
+                       data.length()) {}
+
+QuicConnectionId::~QuicConnectionId() {
+  if (length_ > sizeof(data_short_)) {
+    free(data_long_);
+    data_long_ = nullptr;
+  }
+}
+
+QuicConnectionId::QuicConnectionId(const QuicConnectionId& other)
+    : QuicConnectionId(other.data(), other.length()) {}
+
+QuicConnectionId& QuicConnectionId::operator=(const QuicConnectionId& other) {
+  set_length(other.length());
+  memcpy(mutable_data(), other.data(), length_);
+  return *this;
+}
+
+const char* QuicConnectionId::data() const {
+  if (length_ <= sizeof(data_short_)) {
+    return data_short_;
+  }
+  return data_long_;
+}
+
+char* QuicConnectionId::mutable_data() {
+  if (length_ <= sizeof(data_short_)) {
+    return data_short_;
+  }
+  return data_long_;
+}
+
+uint8_t QuicConnectionId::length() const { return length_; }
+
+void QuicConnectionId::set_length(uint8_t length) {
+  char temporary_data[sizeof(data_short_)];
+  if (length > sizeof(data_short_)) {
+    if (length_ <= sizeof(data_short_)) {
+      // Copy data from data_short_ to data_long_.
+      memcpy(temporary_data, data_short_, length_);
+      data_long_ = reinterpret_cast<char*>(malloc(length));
+      QUICHE_CHECK_NE(nullptr, data_long_);
+      memcpy(data_long_, temporary_data, length_);
+    } else {
+      // Resize data_long_.
+      char* realloc_result =
+          reinterpret_cast<char*>(realloc(data_long_, length));
+      QUICHE_CHECK_NE(nullptr, realloc_result);
+      data_long_ = realloc_result;
+    }
+  } else if (length_ > sizeof(data_short_)) {
+    // Copy data from data_long_ to data_short_.
+    memcpy(temporary_data, data_long_, length);
+    free(data_long_);
+    data_long_ = nullptr;
+    memcpy(data_short_, temporary_data, length);
+  }
+  length_ = length;
+}
+
+bool QuicConnectionId::IsEmpty() const { return length_ == 0; }
+
+size_t QuicConnectionId::Hash() const {
+  static const QuicConnectionIdHasher hasher = QuicConnectionIdHasher();
+  return hasher.Hash(data(), length_);
+}
+
+std::string QuicConnectionId::ToString() const {
+  if (IsEmpty()) {
+    return std::string("0");
+  }
+  return absl::BytesToHexString(absl::string_view(data(), length_));
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicConnectionId& v) {
+  os << v.ToString();
+  return os;
+}
+
+bool QuicConnectionId::operator==(const QuicConnectionId& v) const {
+  return length_ == v.length_ && memcmp(data(), v.data(), length_) == 0;
+}
+
+bool QuicConnectionId::operator!=(const QuicConnectionId& v) const {
+  return !(v == *this);
+}
+
+bool QuicConnectionId::operator<(const QuicConnectionId& v) const {
+  if (length_ < v.length_) {
+    return true;
+  }
+  if (length_ > v.length_) {
+    return false;
+  }
+  return memcmp(data(), v.data(), length_) < 0;
+}
+
+QuicConnectionId EmptyQuicConnectionId() { return QuicConnectionId(); }
+
+static_assert(kQuicDefaultConnectionIdLength == sizeof(uint64_t),
+              "kQuicDefaultConnectionIdLength changed");
+static_assert(kQuicDefaultConnectionIdLength == PACKET_8BYTE_CONNECTION_ID,
+              "kQuicDefaultConnectionIdLength changed");
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_id.h b/quiche/quic/core/quic_connection_id.h
new file mode 100644
index 0000000..52f1501
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id.h
@@ -0,0 +1,142 @@
+// Copyright 2018 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_CONNECTION_ID_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/types/span.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+enum QuicConnectionIdLength {
+  PACKET_0BYTE_CONNECTION_ID = 0,
+  PACKET_8BYTE_CONNECTION_ID = 8,
+};
+
+// This is a property of QUIC headers, it indicates whether the connection ID
+// should actually be sent over the wire (or was sent on received packets).
+enum QuicConnectionIdIncluded : uint8_t {
+  CONNECTION_ID_PRESENT = 1,
+  CONNECTION_ID_ABSENT = 2,
+};
+
+// Maximum connection ID length supported by versions that use the encoding from
+// draft-ietf-quic-invariants-06.
+const uint8_t kQuicMaxConnectionIdWithLengthPrefixLength = 20;
+
+// Maximum connection ID length supported by versions that use the encoding from
+// draft-ietf-quic-invariants-05.
+const uint8_t kQuicMaxConnectionId4BitLength = 18;
+
+// kQuicDefaultConnectionIdLength is the only supported length for QUIC
+// versions < v99, and is the default picked for all versions.
+const uint8_t kQuicDefaultConnectionIdLength = 8;
+
+// According to the IETF spec, the initial server connection ID generated by
+// the client must be at least this long.
+const uint8_t kQuicMinimumInitialConnectionIdLength = 8;
+
+class QUIC_EXPORT_PRIVATE QuicConnectionId {
+ public:
+  // Creates a connection ID of length zero.
+  QuicConnectionId();
+
+  // Creates a connection ID from network order bytes.
+  QuicConnectionId(const char* data, uint8_t length);
+  QuicConnectionId(const absl::Span<const uint8_t> data);
+
+  // Creates a connection ID from another connection ID.
+  QuicConnectionId(const QuicConnectionId& other);
+
+  // Assignment operator.
+  QuicConnectionId& operator=(const QuicConnectionId& other);
+
+  ~QuicConnectionId();
+
+  // Returns the length of the connection ID, in bytes.
+  uint8_t length() const;
+
+  // Sets the length of the connection ID, in bytes.
+  // WARNING: Calling set_length() can change the in-memory location of the
+  // connection ID. Callers must therefore ensure they call data() or
+  // mutable_data() after they call set_length().
+  void set_length(uint8_t length);
+
+  // Returns a pointer to the connection ID bytes, in network byte order.
+  const char* data() const;
+
+  // Returns a mutable pointer to the connection ID bytes,
+  // in network byte order.
+  char* mutable_data();
+
+  // Returns whether the connection ID has length zero.
+  bool IsEmpty() const;
+
+  // Hash() is required to use connection IDs as keys in hash tables.
+  // During the lifetime of a process, the output of Hash() is guaranteed to be
+  // the same for connection IDs that are equal to one another. Note however
+  // that this property is not guaranteed across process lifetimes. This makes
+  // Hash() suitable for data structures such as hash tables but not for sending
+  // a hash over the network.
+  size_t Hash() const;
+
+  // Generates an ASCII string that represents
+  // the contents of the connection ID, or "0" if it is empty.
+  std::string ToString() const;
+
+  // operator<< allows easily logging connection IDs.
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const QuicConnectionId& v);
+
+  bool operator==(const QuicConnectionId& v) const;
+  bool operator!=(const QuicConnectionId& v) const;
+  // operator< is required to use connection IDs as keys in hash tables.
+  bool operator<(const QuicConnectionId& v) const;
+
+ private:
+  // The connection ID is represented in network byte order.
+  union {
+    // If the connection ID fits in |data_short_|, it is stored in the
+    // first |length_| bytes of |data_short_|.
+    // Otherwise it is stored in |data_long_| which is guaranteed to have a size
+    // equal to |length_|.
+    // A value of 11 was chosen because our commonly used connection ID length
+    // is 8 and with the length, the class is padded to at least 12 bytes
+    // anyway.
+    struct {
+      uint8_t padding_;  // Match length_ field of the other union member.
+      char data_short_[11];
+    };
+    struct {
+      uint8_t length_;  // length of the connection ID, in bytes.
+      char* data_long_;
+    };
+  };
+};
+
+// Creates a connection ID of length zero, unless the restart flag
+// quic_connection_ids_network_byte_order is false in which case
+// it returns an 8-byte all-zeroes connection ID.
+QUIC_EXPORT_PRIVATE QuicConnectionId EmptyQuicConnectionId();
+
+// QuicConnectionIdHash can be passed as hash argument to hash tables.
+// During the lifetime of a process, the output of QuicConnectionIdHash is
+// guaranteed to be the same for connection IDs that are equal to one another.
+// Note however that this property is not guaranteed across process lifetimes.
+// This makes QuicConnectionIdHash suitable for data structures such as hash
+// tables but not for sending a hash over the network.
+class QUIC_EXPORT_PRIVATE QuicConnectionIdHash {
+ public:
+  size_t operator()(QuicConnectionId const& connection_id) const noexcept {
+    return connection_id.Hash();
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
diff --git a/quiche/quic/core/quic_connection_id_manager.cc b/quiche/quic/core/quic_connection_id_manager.cc
new file mode 100644
index 0000000..db9d097
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id_manager.cc
@@ -0,0 +1,460 @@
+// 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 "quiche/quic/core/quic_connection_id_manager.h"
+
+#include <cstdio>
+
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+QuicConnectionIdData::QuicConnectionIdData(
+    const QuicConnectionId& connection_id,
+    uint64_t sequence_number,
+    const StatelessResetToken& stateless_reset_token)
+    : connection_id(connection_id),
+      sequence_number(sequence_number),
+      stateless_reset_token(stateless_reset_token) {}
+
+namespace {
+
+class RetirePeerIssuedConnectionIdAlarm
+    : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit RetirePeerIssuedConnectionIdAlarm(
+      QuicConnectionIdManagerVisitorInterface* visitor,
+      QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context), visitor_(visitor) {}
+  RetirePeerIssuedConnectionIdAlarm(const RetirePeerIssuedConnectionIdAlarm&) =
+      delete;
+  RetirePeerIssuedConnectionIdAlarm& operator=(
+      const RetirePeerIssuedConnectionIdAlarm&) = delete;
+
+  void OnAlarm() override { visitor_->OnPeerIssuedConnectionIdRetired(); }
+
+ private:
+  QuicConnectionIdManagerVisitorInterface* visitor_;
+};
+
+std::vector<QuicConnectionIdData>::const_iterator FindConnectionIdData(
+    const std::vector<QuicConnectionIdData>& cid_data_vector,
+    const QuicConnectionId& cid) {
+  return std::find_if(cid_data_vector.begin(), cid_data_vector.end(),
+                      [&cid](const QuicConnectionIdData& cid_data) {
+                        return cid == cid_data.connection_id;
+                      });
+}
+
+std::vector<QuicConnectionIdData>::iterator FindConnectionIdData(
+    std::vector<QuicConnectionIdData>* cid_data_vector,
+    const QuicConnectionId& cid) {
+  return std::find_if(cid_data_vector->begin(), cid_data_vector->end(),
+                      [&cid](const QuicConnectionIdData& cid_data) {
+                        return cid == cid_data.connection_id;
+                      });
+}
+
+}  // namespace
+
+QuicPeerIssuedConnectionIdManager::QuicPeerIssuedConnectionIdManager(
+    size_t active_connection_id_limit,
+    const QuicConnectionId& initial_peer_issued_connection_id,
+    const QuicClock* clock, QuicAlarmFactory* alarm_factory,
+    QuicConnectionIdManagerVisitorInterface* visitor,
+    QuicConnectionContext* context)
+    : active_connection_id_limit_(active_connection_id_limit),
+      clock_(clock),
+      retire_connection_id_alarm_(alarm_factory->CreateAlarm(
+          new RetirePeerIssuedConnectionIdAlarm(visitor, context))) {
+  QUICHE_DCHECK_GE(active_connection_id_limit_, 2u);
+  QUICHE_DCHECK(!initial_peer_issued_connection_id.IsEmpty());
+  active_connection_id_data_.emplace_back<const QuicConnectionId&, uint64_t,
+                                          const StatelessResetToken&>(
+      initial_peer_issued_connection_id,
+      /*sequence_number=*/0u, {});
+  recent_new_connection_id_sequence_numbers_.Add(0u, 1u);
+}
+
+QuicPeerIssuedConnectionIdManager::~QuicPeerIssuedConnectionIdManager() {
+  retire_connection_id_alarm_->Cancel();
+}
+
+bool QuicPeerIssuedConnectionIdManager::IsConnectionIdNew(
+    const QuicNewConnectionIdFrame& frame) {
+  auto is_old_connection_id = [&frame](const QuicConnectionIdData& cid_data) {
+    return cid_data.connection_id == frame.connection_id;
+  };
+  if (std::any_of(active_connection_id_data_.begin(),
+                  active_connection_id_data_.end(), is_old_connection_id)) {
+    return false;
+  }
+  if (std::any_of(unused_connection_id_data_.begin(),
+                  unused_connection_id_data_.end(), is_old_connection_id)) {
+    return false;
+  }
+  if (std::any_of(to_be_retired_connection_id_data_.begin(),
+                  to_be_retired_connection_id_data_.end(),
+                  is_old_connection_id)) {
+    return false;
+  }
+  return true;
+}
+
+void QuicPeerIssuedConnectionIdManager::PrepareToRetireConnectionIdPriorTo(
+    uint64_t retire_prior_to,
+    std::vector<QuicConnectionIdData>* cid_data_vector) {
+  auto it2 = cid_data_vector->begin();
+  for (auto it = cid_data_vector->begin(); it != cid_data_vector->end(); ++it) {
+    if (it->sequence_number >= retire_prior_to) {
+      *it2++ = *it;
+    } else {
+      to_be_retired_connection_id_data_.push_back(*it);
+      if (!retire_connection_id_alarm_->IsSet()) {
+        retire_connection_id_alarm_->Set(clock_->ApproximateNow());
+      }
+    }
+  }
+  cid_data_vector->erase(it2, cid_data_vector->end());
+}
+
+QuicErrorCode QuicPeerIssuedConnectionIdManager::OnNewConnectionIdFrame(
+    const QuicNewConnectionIdFrame& frame,
+    std::string* error_detail) {
+  if (recent_new_connection_id_sequence_numbers_.Contains(
+          frame.sequence_number)) {
+    // This frame has a recently seen sequence number. Ignore.
+    return QUIC_NO_ERROR;
+  }
+  if (!IsConnectionIdNew(frame)) {
+    *error_detail =
+        "Received a NEW_CONNECTION_ID frame that reuses a previously seen Id.";
+    return IETF_QUIC_PROTOCOL_VIOLATION;
+  }
+
+  recent_new_connection_id_sequence_numbers_.AddOptimizedForAppend(
+      frame.sequence_number, frame.sequence_number + 1);
+
+  if (recent_new_connection_id_sequence_numbers_.Size() >
+      kMaxNumConnectionIdSequenceNumberIntervals) {
+    *error_detail =
+        "Too many disjoint connection Id sequence number intervals.";
+    return IETF_QUIC_PROTOCOL_VIOLATION;
+  }
+
+  // QuicFramer::ProcessNewConnectionIdFrame guarantees that
+  // frame.sequence_number >= frame.retire_prior_to, and hence there is no need
+  // to check that.
+  if (frame.sequence_number < max_new_connection_id_frame_retire_prior_to_) {
+    // Later frames have asked for retirement of the current frame.
+    to_be_retired_connection_id_data_.emplace_back(frame.connection_id,
+                                                   frame.sequence_number,
+                                                   frame.stateless_reset_token);
+    if (!retire_connection_id_alarm_->IsSet()) {
+      retire_connection_id_alarm_->Set(clock_->ApproximateNow());
+    }
+    return QUIC_NO_ERROR;
+  }
+  if (frame.retire_prior_to > max_new_connection_id_frame_retire_prior_to_) {
+    max_new_connection_id_frame_retire_prior_to_ = frame.retire_prior_to;
+    PrepareToRetireConnectionIdPriorTo(frame.retire_prior_to,
+                                       &active_connection_id_data_);
+    PrepareToRetireConnectionIdPriorTo(frame.retire_prior_to,
+                                       &unused_connection_id_data_);
+  }
+
+  if (active_connection_id_data_.size() + unused_connection_id_data_.size() >=
+      active_connection_id_limit_) {
+    *error_detail = "Peer provides more connection IDs than the limit.";
+    return QUIC_CONNECTION_ID_LIMIT_ERROR;
+  }
+
+  unused_connection_id_data_.emplace_back(
+      frame.connection_id, frame.sequence_number, frame.stateless_reset_token);
+  return QUIC_NO_ERROR;
+}
+
+const QuicConnectionIdData*
+QuicPeerIssuedConnectionIdManager::ConsumeOneUnusedConnectionId() {
+  if (unused_connection_id_data_.empty()) {
+    return nullptr;
+  }
+  active_connection_id_data_.push_back(unused_connection_id_data_.back());
+  unused_connection_id_data_.pop_back();
+  return &active_connection_id_data_.back();
+}
+
+void QuicPeerIssuedConnectionIdManager::PrepareToRetireActiveConnectionId(
+    const QuicConnectionId& cid) {
+  auto it = FindConnectionIdData(active_connection_id_data_, cid);
+  if (it == active_connection_id_data_.end()) {
+    // The cid has already been retired.
+    return;
+  }
+  to_be_retired_connection_id_data_.push_back(*it);
+  active_connection_id_data_.erase(it);
+  if (!retire_connection_id_alarm_->IsSet()) {
+    retire_connection_id_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicPeerIssuedConnectionIdManager::MaybeRetireUnusedConnectionIds(
+    const std::vector<QuicConnectionId>& active_connection_ids_on_path) {
+  std::vector<QuicConnectionId> cids_to_retire;
+  for (const auto& cid_data : active_connection_id_data_) {
+    if (std::find(active_connection_ids_on_path.begin(),
+                  active_connection_ids_on_path.end(),
+                  cid_data.connection_id) ==
+        active_connection_ids_on_path.end()) {
+      cids_to_retire.push_back(cid_data.connection_id);
+    }
+  }
+  for (const auto& cid : cids_to_retire) {
+    PrepareToRetireActiveConnectionId(cid);
+  }
+}
+
+bool QuicPeerIssuedConnectionIdManager::IsConnectionIdActive(
+    const QuicConnectionId& cid) const {
+  return FindConnectionIdData(active_connection_id_data_, cid) !=
+         active_connection_id_data_.end();
+}
+
+std::vector<uint64_t> QuicPeerIssuedConnectionIdManager::
+    ConsumeToBeRetiredConnectionIdSequenceNumbers() {
+  std::vector<uint64_t> result;
+  for (auto const& cid_data : to_be_retired_connection_id_data_) {
+    result.push_back(cid_data.sequence_number);
+  }
+  to_be_retired_connection_id_data_.clear();
+  return result;
+}
+
+void QuicPeerIssuedConnectionIdManager::ReplaceConnectionId(
+    const QuicConnectionId& old_connection_id,
+    const QuicConnectionId& new_connection_id) {
+  auto it1 =
+      FindConnectionIdData(&active_connection_id_data_, old_connection_id);
+  if (it1 != active_connection_id_data_.end()) {
+    it1->connection_id = new_connection_id;
+    return;
+  }
+  auto it2 = FindConnectionIdData(&to_be_retired_connection_id_data_,
+                                  old_connection_id);
+  if (it2 != to_be_retired_connection_id_data_.end()) {
+    it2->connection_id = new_connection_id;
+  }
+}
+
+namespace {
+
+class RetireSelfIssuedConnectionIdAlarmDelegate
+    : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit RetireSelfIssuedConnectionIdAlarmDelegate(
+      QuicSelfIssuedConnectionIdManager* connection_id_manager,
+      QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context),
+        connection_id_manager_(connection_id_manager) {}
+  RetireSelfIssuedConnectionIdAlarmDelegate(
+      const RetireSelfIssuedConnectionIdAlarmDelegate&) = delete;
+  RetireSelfIssuedConnectionIdAlarmDelegate& operator=(
+      const RetireSelfIssuedConnectionIdAlarmDelegate&) = delete;
+
+  void OnAlarm() override { connection_id_manager_->RetireConnectionId(); }
+
+ private:
+  QuicSelfIssuedConnectionIdManager* connection_id_manager_;
+};
+
+}  // namespace
+
+QuicSelfIssuedConnectionIdManager::QuicSelfIssuedConnectionIdManager(
+    size_t active_connection_id_limit,
+    const QuicConnectionId& initial_connection_id, const QuicClock* clock,
+    QuicAlarmFactory* alarm_factory,
+    QuicConnectionIdManagerVisitorInterface* visitor,
+    QuicConnectionContext* context)
+    : active_connection_id_limit_(active_connection_id_limit),
+      clock_(clock),
+      visitor_(visitor),
+      retire_connection_id_alarm_(alarm_factory->CreateAlarm(
+          new RetireSelfIssuedConnectionIdAlarmDelegate(this, context))),
+      last_connection_id_(initial_connection_id),
+      next_connection_id_sequence_number_(1u),
+      last_connection_id_consumed_by_self_sequence_number_(0u) {
+  active_connection_ids_.emplace_back(initial_connection_id, 0u);
+}
+
+QuicSelfIssuedConnectionIdManager::~QuicSelfIssuedConnectionIdManager() {
+  retire_connection_id_alarm_->Cancel();
+}
+
+QuicConnectionId QuicSelfIssuedConnectionIdManager::GenerateNewConnectionId(
+    const QuicConnectionId& old_connection_id) const {
+  return QuicUtils::CreateReplacementConnectionId(old_connection_id);
+}
+
+QuicNewConnectionIdFrame
+QuicSelfIssuedConnectionIdManager::IssueNewConnectionId() {
+  QuicNewConnectionIdFrame frame;
+  frame.connection_id = GenerateNewConnectionId(last_connection_id_);
+  frame.sequence_number = next_connection_id_sequence_number_++;
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  visitor_->OnNewConnectionIdIssued(frame.connection_id);
+  active_connection_ids_.emplace_back(frame.connection_id,
+                                      frame.sequence_number);
+  frame.retire_prior_to = active_connection_ids_.front().second;
+  last_connection_id_ = frame.connection_id;
+  return frame;
+}
+
+QuicNewConnectionIdFrame
+QuicSelfIssuedConnectionIdManager::IssueNewConnectionIdForPreferredAddress() {
+  QuicNewConnectionIdFrame frame = IssueNewConnectionId();
+  QUICHE_DCHECK_EQ(frame.sequence_number, 1u);
+  return frame;
+}
+
+QuicErrorCode QuicSelfIssuedConnectionIdManager::OnRetireConnectionIdFrame(
+    const QuicRetireConnectionIdFrame& frame,
+    QuicTime::Delta pto_delay,
+    std::string* error_detail) {
+  QUICHE_DCHECK(!active_connection_ids_.empty());
+  if (frame.sequence_number > active_connection_ids_.back().second) {
+    *error_detail = "To be retired connecton ID is never issued.";
+    return IETF_QUIC_PROTOCOL_VIOLATION;
+  }
+
+  auto it =
+      std::find_if(active_connection_ids_.begin(), active_connection_ids_.end(),
+                   [&frame](const std::pair<QuicConnectionId, uint64_t>& p) {
+                     return p.second == frame.sequence_number;
+                   });
+  // The corresponding connection ID has been retired. Ignore.
+  if (it == active_connection_ids_.end()) {
+    return QUIC_NO_ERROR;
+  }
+
+  if (to_be_retired_connection_ids_.size() + active_connection_ids_.size() >=
+      kMaxNumConnectonIdsInUse) {
+    // Close connection if the number of connection IDs in use will exeed the
+    // limit, i.e., peer retires connection ID too fast.
+    *error_detail = "There are too many connection IDs in use.";
+    return QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE;
+  }
+
+  QuicTime retirement_time = clock_->ApproximateNow() + 3 * pto_delay;
+  if (!to_be_retired_connection_ids_.empty()) {
+    retirement_time =
+        std::max(retirement_time, to_be_retired_connection_ids_.back().second);
+  }
+
+  to_be_retired_connection_ids_.emplace_back(it->first, retirement_time);
+  if (!retire_connection_id_alarm_->IsSet()) {
+    retire_connection_id_alarm_->Set(retirement_time);
+  }
+
+  active_connection_ids_.erase(it);
+  MaybeSendNewConnectionIds();
+
+  return QUIC_NO_ERROR;
+}
+
+std::vector<QuicConnectionId>
+QuicSelfIssuedConnectionIdManager::GetUnretiredConnectionIds() const {
+  std::vector<QuicConnectionId> unretired_ids;
+  for (const auto& cid_pair : to_be_retired_connection_ids_) {
+    unretired_ids.push_back(cid_pair.first);
+  }
+  for (const auto& cid_pair : active_connection_ids_) {
+    unretired_ids.push_back(cid_pair.first);
+  }
+  return unretired_ids;
+}
+
+QuicConnectionId QuicSelfIssuedConnectionIdManager::GetOneActiveConnectionId()
+    const {
+  QUICHE_DCHECK(!active_connection_ids_.empty());
+  return active_connection_ids_.front().first;
+}
+
+void QuicSelfIssuedConnectionIdManager::RetireConnectionId() {
+  if (to_be_retired_connection_ids_.empty()) {
+    QUIC_BUG(quic_bug_12420_1)
+        << "retire_connection_id_alarm fired but there is no connection ID "
+           "to be retired.";
+    return;
+  }
+  QuicTime now = clock_->ApproximateNow();
+  auto it = to_be_retired_connection_ids_.begin();
+  do {
+    visitor_->OnSelfIssuedConnectionIdRetired(it->first);
+    ++it;
+  } while (it != to_be_retired_connection_ids_.end() && it->second <= now);
+  to_be_retired_connection_ids_.erase(to_be_retired_connection_ids_.begin(),
+                                      it);
+  // Set the alarm again if there is another connection ID to be removed.
+  if (!to_be_retired_connection_ids_.empty()) {
+    retire_connection_id_alarm_->Set(
+        to_be_retired_connection_ids_.front().second);
+  }
+}
+
+void QuicSelfIssuedConnectionIdManager::MaybeSendNewConnectionIds() {
+  while (active_connection_ids_.size() < active_connection_id_limit_) {
+    QuicNewConnectionIdFrame frame = IssueNewConnectionId();
+    if (!visitor_->SendNewConnectionId(frame)) {
+      break;
+    }
+  }
+}
+
+bool QuicSelfIssuedConnectionIdManager::HasConnectionIdToConsume() const {
+  for (const auto& active_cid_data : active_connection_ids_) {
+    if (active_cid_data.second >
+        last_connection_id_consumed_by_self_sequence_number_) {
+      return true;
+    }
+  }
+  return false;
+}
+
+absl::optional<QuicConnectionId>
+QuicSelfIssuedConnectionIdManager::ConsumeOneConnectionId() {
+  for (const auto& active_cid_data : active_connection_ids_) {
+    if (active_cid_data.second >
+        last_connection_id_consumed_by_self_sequence_number_) {
+      // Since connection IDs in active_connection_ids_ has monotonically
+      // increasing sequence numbers, the returned connection ID has the
+      // smallest sequence number among all unconsumed active connection IDs.
+      last_connection_id_consumed_by_self_sequence_number_ =
+          active_cid_data.second;
+      return active_cid_data.first;
+    }
+  }
+  return absl::nullopt;
+}
+
+bool QuicSelfIssuedConnectionIdManager::IsConnectionIdInUse(
+    const QuicConnectionId& cid) const {
+  for (const auto& active_cid_data : active_connection_ids_) {
+    if (active_cid_data.first == cid) {
+      return true;
+    }
+  }
+  for (const auto& to_be_retired_cid_data : to_be_retired_connection_ids_) {
+    if (to_be_retired_cid_data.first == cid) {
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_id_manager.h b/quiche/quic/core/quic_connection_id_manager.h
new file mode 100644
index 0000000..11454df
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id_manager.h
@@ -0,0 +1,195 @@
+// 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.
+
+// QuicPeerIssuedConnectionIdManager handles the states associated with receving
+// and retiring peer issued connection Ids.
+// QuicSelfIssuedConnectionIdManager handles the states associated with
+// connection Ids issued by the current end point.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicConnectionIdManagerPeer;
+}  // namespace test
+
+struct QUIC_EXPORT_PRIVATE QuicConnectionIdData {
+  QuicConnectionIdData(const QuicConnectionId& connection_id,
+                       uint64_t sequence_number,
+                       const StatelessResetToken& stateless_reset_token);
+
+  QuicConnectionId connection_id;
+  uint64_t sequence_number;
+  StatelessResetToken stateless_reset_token;
+};
+
+// Used by QuicSelfIssuedConnectionIdManager
+// and QuicPeerIssuedConnectionIdManager.
+class QUIC_EXPORT_PRIVATE QuicConnectionIdManagerVisitorInterface {
+ public:
+  virtual ~QuicConnectionIdManagerVisitorInterface() = default;
+  virtual void OnPeerIssuedConnectionIdRetired() = 0;
+  virtual bool SendNewConnectionId(const QuicNewConnectionIdFrame& frame) = 0;
+  virtual void OnNewConnectionIdIssued(
+      const QuicConnectionId& connection_id) = 0;
+  virtual void OnSelfIssuedConnectionIdRetired(
+      const QuicConnectionId& connection_id) = 0;
+};
+
+class QUIC_EXPORT_PRIVATE QuicPeerIssuedConnectionIdManager {
+ public:
+  // QuicPeerIssuedConnectionIdManager should be instantiated only when a peer
+  // issued-non empty connection ID is received.
+  QuicPeerIssuedConnectionIdManager(
+      size_t active_connection_id_limit,
+      const QuicConnectionId& initial_peer_issued_connection_id,
+      const QuicClock* clock, QuicAlarmFactory* alarm_factory,
+      QuicConnectionIdManagerVisitorInterface* visitor,
+      QuicConnectionContext* context);
+
+  ~QuicPeerIssuedConnectionIdManager();
+
+  QuicErrorCode OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame,
+                                       std::string* error_detail);
+
+  bool HasUnusedConnectionId() const {
+    return !unused_connection_id_data_.empty();
+  }
+
+  // Returns the data associated with an unused connection Id. After the call,
+  // the Id is marked as used. Returns nullptr if there is no unused connection
+  // Id.
+  const QuicConnectionIdData* ConsumeOneUnusedConnectionId();
+
+  // Add each active connection Id that is no longer on path to the pending
+  // retirement connection Id list.
+  void MaybeRetireUnusedConnectionIds(
+      const std::vector<QuicConnectionId>& active_connection_ids_on_path);
+
+  bool IsConnectionIdActive(const QuicConnectionId& cid) const;
+
+  // Get the sequence numbers of all the connection Ids pending retirement when
+  // it is safe to retires these Ids.
+  std::vector<uint64_t> ConsumeToBeRetiredConnectionIdSequenceNumbers();
+
+  // If old_connection_id is still tracked by QuicPeerIssuedConnectionIdManager,
+  // replace it with new_connection_id. Otherwise, this is a no-op.
+  void ReplaceConnectionId(const QuicConnectionId& old_connection_id,
+                           const QuicConnectionId& new_connection_id);
+
+ private:
+  friend class test::QuicConnectionIdManagerPeer;
+
+  // Add the connection Id to the pending retirement connection Id list and
+  // schedule an alarm if needed.
+  void PrepareToRetireActiveConnectionId(const QuicConnectionId& cid);
+
+  bool IsConnectionIdNew(const QuicNewConnectionIdFrame& frame);
+
+  void PrepareToRetireConnectionIdPriorTo(
+      uint64_t retire_prior_to,
+      std::vector<QuicConnectionIdData>* cid_data_vector);
+
+  size_t active_connection_id_limit_;
+  const QuicClock* clock_;
+  std::unique_ptr<QuicAlarm> retire_connection_id_alarm_;
+  std::vector<QuicConnectionIdData> active_connection_id_data_;
+  std::vector<QuicConnectionIdData> unused_connection_id_data_;
+  std::vector<QuicConnectionIdData> to_be_retired_connection_id_data_;
+  // Track sequence numbers of recent NEW_CONNECTION_ID frames received from
+  // the peer.
+  QuicIntervalSet<uint64_t> recent_new_connection_id_sequence_numbers_;
+  uint64_t max_new_connection_id_frame_retire_prior_to_ = 0u;
+};
+
+class QUIC_EXPORT_PRIVATE QuicSelfIssuedConnectionIdManager {
+ public:
+  QuicSelfIssuedConnectionIdManager(
+      size_t active_connection_id_limit,
+      const QuicConnectionId& initial_connection_id, const QuicClock* clock,
+      QuicAlarmFactory* alarm_factory,
+      QuicConnectionIdManagerVisitorInterface* visitor,
+      QuicConnectionContext* context);
+
+  virtual ~QuicSelfIssuedConnectionIdManager();
+
+  QuicNewConnectionIdFrame IssueNewConnectionIdForPreferredAddress();
+
+  QuicErrorCode OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame,
+      QuicTime::Delta pto_delay,
+      std::string* error_detail);
+
+  std::vector<QuicConnectionId> GetUnretiredConnectionIds() const;
+
+  QuicConnectionId GetOneActiveConnectionId() const;
+
+  // Called when the retire_connection_id alarm_ fires. Removes the to be
+  // retired connection ID locally.
+  void RetireConnectionId();
+
+  // Sends new connection IDs if more can be sent.
+  void MaybeSendNewConnectionIds();
+
+  // The two functions are called on the client side to associate a client
+  // connection ID with a new probing/migration path when client uses
+  // non-empty connection ID.
+  bool HasConnectionIdToConsume() const;
+  absl::optional<QuicConnectionId> ConsumeOneConnectionId();
+
+  // Returns true if the given connection ID is issued by the
+  // QuicSelfIssuedConnectionIdManager and not retired locally yet. Called to
+  // tell if a received packet has a valid connection ID.
+  bool IsConnectionIdInUse(const QuicConnectionId& cid) const;
+
+  virtual QuicConnectionId GenerateNewConnectionId(
+      const QuicConnectionId& old_connection_id) const;
+
+ private:
+  friend class test::QuicConnectionIdManagerPeer;
+
+  QuicNewConnectionIdFrame IssueNewConnectionId();
+
+  // This should be set to the min of:
+  // (1) # of active connection IDs that peer can maintain.
+  // (2) maximum # of active connection IDs self plans to issue.
+  size_t active_connection_id_limit_;
+  const QuicClock* clock_;
+  QuicConnectionIdManagerVisitorInterface* visitor_;
+  // This tracks connection IDs issued to the peer but not retired by the peer.
+  // Each pair is a connection ID and its sequence number.
+  std::vector<std::pair<QuicConnectionId, uint64_t>> active_connection_ids_;
+  // This tracks connection IDs retired by the peer but has not been retired
+  // locally. Each pair is a connection ID and the time by which it should be
+  // retired.
+  std::vector<std::pair<QuicConnectionId, QuicTime>>
+      to_be_retired_connection_ids_;
+  // An alarm that fires when a connection ID should be retired.
+  std::unique_ptr<QuicAlarm> retire_connection_id_alarm_;
+  // State of the last issued connection Id.
+  QuicConnectionId last_connection_id_;
+  uint64_t next_connection_id_sequence_number_;
+  // The sequence number of last connection ID consumed.
+  uint64_t last_connection_id_consumed_by_self_sequence_number_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
diff --git a/quiche/quic/core/quic_connection_id_manager_test.cc b/quiche/quic/core/quic_connection_id_manager_test.cc
new file mode 100644
index 0000000..57e6b87
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id_manager_test.cc
@@ -0,0 +1,964 @@
+// Copyright 2013 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 "quiche/quic/core/quic_connection_id_manager.h"
+#include <cstddef>
+
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_connection_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace {
+
+using ::quic::test::IsError;
+using ::quic::test::IsQuicNoError;
+using ::quic::test::QuicConnectionIdManagerPeer;
+using ::quic::test::TestConnectionId;
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::IsNull;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+class TestPeerIssuedConnectionIdManagerVisitor
+    : public QuicConnectionIdManagerVisitorInterface {
+ public:
+  void SetPeerIssuedConnectionIdManager(
+      QuicPeerIssuedConnectionIdManager* peer_issued_connection_id_manager) {
+    peer_issued_connection_id_manager_ = peer_issued_connection_id_manager;
+  }
+
+  void OnPeerIssuedConnectionIdRetired() override {
+    // Replace current connection Id if it has been retired.
+    if (!peer_issued_connection_id_manager_->IsConnectionIdActive(
+            current_peer_issued_connection_id_)) {
+      current_peer_issued_connection_id_ =
+          peer_issued_connection_id_manager_->ConsumeOneUnusedConnectionId()
+              ->connection_id;
+    }
+    // Retire all the to-be-retired connection Ids.
+    most_recent_retired_connection_id_sequence_numbers_ =
+        peer_issued_connection_id_manager_
+            ->ConsumeToBeRetiredConnectionIdSequenceNumbers();
+  }
+
+  const std::vector<uint64_t>&
+  most_recent_retired_connection_id_sequence_numbers() {
+    return most_recent_retired_connection_id_sequence_numbers_;
+  }
+
+  void SetCurrentPeerConnectionId(QuicConnectionId cid) {
+    current_peer_issued_connection_id_ = cid;
+  }
+
+  const QuicConnectionId& GetCurrentPeerConnectionId() {
+    return current_peer_issued_connection_id_;
+  }
+
+  bool SendNewConnectionId(const QuicNewConnectionIdFrame& /*frame*/) override {
+    return false;
+  }
+  void OnNewConnectionIdIssued(
+      const QuicConnectionId& /*connection_id*/) override {}
+  void OnSelfIssuedConnectionIdRetired(
+      const QuicConnectionId& /*connection_id*/) override {}
+
+ private:
+  QuicPeerIssuedConnectionIdManager* peer_issued_connection_id_manager_ =
+      nullptr;
+  QuicConnectionId current_peer_issued_connection_id_;
+  std::vector<uint64_t> most_recent_retired_connection_id_sequence_numbers_;
+};
+
+class QuicPeerIssuedConnectionIdManagerTest : public QuicTest {
+ public:
+  QuicPeerIssuedConnectionIdManagerTest()
+      : peer_issued_cid_manager_(
+            /*active_connection_id_limit=*/2, initial_connection_id_, &clock_,
+            &alarm_factory_, &cid_manager_visitor_, /*context=*/nullptr) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+    cid_manager_visitor_.SetPeerIssuedConnectionIdManager(
+        &peer_issued_cid_manager_);
+    cid_manager_visitor_.SetCurrentPeerConnectionId(initial_connection_id_);
+    retire_peer_issued_cid_alarm_ =
+        QuicConnectionIdManagerPeer::GetRetirePeerIssuedConnectionIdAlarm(
+            &peer_issued_cid_manager_);
+  }
+
+ protected:
+  MockClock clock_;
+  test::MockAlarmFactory alarm_factory_;
+  TestPeerIssuedConnectionIdManagerVisitor cid_manager_visitor_;
+  QuicConnectionId initial_connection_id_ = TestConnectionId(0);
+  QuicPeerIssuedConnectionIdManager peer_issued_cid_manager_;
+  QuicAlarm* retire_peer_issued_cid_alarm_ = nullptr;
+  std::string error_details_;
+};
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ConnectionIdSequenceWhenMigrationSucceed) {
+  {
+    // Receives CID #1 from peer.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+
+    // Start to use CID #1 for alternative path.
+    const QuicConnectionIdData* aternative_connection_id_data =
+        peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    ASSERT_THAT(aternative_connection_id_data, testing::NotNull());
+    EXPECT_EQ(aternative_connection_id_data->connection_id,
+              TestConnectionId(1));
+    EXPECT_EQ(aternative_connection_id_data->stateless_reset_token,
+              frame.stateless_reset_token);
+
+    // Connection migration succeed. Prepares to retire CID #0.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {TestConnectionId(1)});
+    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(1));
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(0u));
+  }
+
+  {
+    // Receives CID #2 from peer since CID #0 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 1u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #2 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration succeed. Prepares to retire CID #1.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {TestConnectionId(2)});
+    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(2));
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(1u));
+  }
+
+  {
+    // Receives CID #3 from peer since CID #1 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(3);
+    frame.sequence_number = 3u;
+    frame.retire_prior_to = 2u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #3 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration succeed. Prepares to retire CID #2.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {TestConnectionId(3)});
+    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(3));
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(2u));
+  }
+
+  {
+    // Receives CID #4 from peer since CID #2 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(4);
+    frame.sequence_number = 4u;
+    frame.retire_prior_to = 3u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ConnectionIdSequenceWhenMigrationFail) {
+  {
+    // Receives CID #1 from peer.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #1 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration fails. Prepares to retire CID #1.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {initial_connection_id_});
+    // Actually retires CID #1.
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(1u));
+  }
+
+  {
+    // Receives CID #2 from peer since CID #1 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #2 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration fails again. Prepares to retire CID #2.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {initial_connection_id_});
+    // Actually retires CID #2.
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(2u));
+  }
+
+  {
+    // Receives CID #3 from peer since CID #2 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(3);
+    frame.sequence_number = 3u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #3 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration succeed. Prepares to retire CID #0.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {TestConnectionId(3)});
+    // After CID #3 is default (i.e., when there is no pending frame to write
+    // associated with CID #0), #0 can actually be retired.
+    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(3));
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(0u));
+  }
+
+  {
+    // Receives CID #4 from peer since CID #0 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(4);
+    frame.sequence_number = 4u;
+    frame.retire_prior_to = 3u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    EXPECT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    EXPECT_FALSE(retire_peer_issued_cid_alarm_->IsSet());
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ReceivesNewConnectionIdOutOfOrder) {
+  {
+    // Receives new CID #1 that retires prior to #0.
+    // Outcome: (active: #0 unused: #1)
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #1 for alternative path.
+    // Outcome: (active: #0 #1 unused: None)
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+  }
+
+  {
+    // Receives new CID #3 that retires prior to #2.
+    // Outcome: (active: None unused: #3)
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(3);
+    frame.sequence_number = 3u;
+    frame.retire_prior_to = 2u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    // Receives new CID #2 that retires prior to #1.
+    // Outcome: (active: None unused: #3, #2)
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 1u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    EXPECT_FALSE(
+        peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(0)));
+    EXPECT_FALSE(
+        peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(1)));
+    // When there is no frame associated with #0 and #1 to write, replace the
+    // in-use CID with an unused CID (#2) and retires #0 & #1.
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(0u, 1u));
+    EXPECT_EQ(cid_manager_visitor_.GetCurrentPeerConnectionId(),
+              TestConnectionId(2));
+    // Get another unused CID for path validation.
+    EXPECT_EQ(
+        peer_issued_cid_manager_.ConsumeOneUnusedConnectionId()->connection_id,
+        TestConnectionId(3));
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       VisitedNewConnectionIdFrameIsIgnored) {
+  // Receives new CID #1 that retires prior to #0.
+  // Outcome: (active: #0 unused: #1)
+  QuicNewConnectionIdFrame frame;
+  frame.connection_id = TestConnectionId(1);
+  frame.sequence_number = 1u;
+  frame.retire_prior_to = 0u;
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  ASSERT_THAT(
+      peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+      IsQuicNoError());
+  // Start to use CID #1 for alternative path.
+  // Outcome: (active: #0 #1 unused: None)
+  peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+  // Prepare to retire CID #1 as path validation fails.
+  peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+      {initial_connection_id_});
+  // Actually retires CID #1.
+  ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+  alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+  EXPECT_THAT(
+      cid_manager_visitor_.most_recent_retired_connection_id_sequence_numbers(),
+      ElementsAre(1u));
+  // Receives the same frame again. Should be a no-op.
+  ASSERT_THAT(
+      peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+      IsQuicNoError());
+  EXPECT_THAT(peer_issued_cid_manager_.ConsumeOneUnusedConnectionId(),
+              testing::IsNull());
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ErrorWhenActiveConnectionIdLimitExceeded) {
+  {
+    // Receives new CID #1 that retires prior to #0.
+    // Outcome: (active: #0 unused: #1)
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsError(QUIC_CONNECTION_ID_LIMIT_ERROR));
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ErrorWhenTheSameConnectionIdIsSeenWithDifferentSequenceNumbers) {
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 1u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(TestConnectionId(2));
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       NewConnectionIdFrameWithTheSameSequenceNumberIsIgnored) {
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(TestConnectionId(2));
+    EXPECT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    EXPECT_EQ(
+        peer_issued_cid_manager_.ConsumeOneUnusedConnectionId()->connection_id,
+        TestConnectionId(1));
+    EXPECT_THAT(peer_issued_cid_manager_.ConsumeOneUnusedConnectionId(),
+                IsNull());
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ErrorWhenThereAreTooManyGapsInIssuedConnectionIdSequenceNumbers) {
+  // Add 20 intervals: [0, 1), [2, 3), ..., [38,39)
+  for (int i = 2; i <= 38; i += 2) {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(i);
+    frame.sequence_number = i;
+    frame.retire_prior_to = i;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  // Interval [40, 41) goes over the limit.
+  QuicNewConnectionIdFrame frame;
+  frame.connection_id = TestConnectionId(40);
+  frame.sequence_number = 40u;
+  frame.retire_prior_to = 40u;
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  ASSERT_THAT(
+      peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+      IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest, ReplaceConnectionId) {
+  ASSERT_TRUE(
+      peer_issued_cid_manager_.IsConnectionIdActive(initial_connection_id_));
+  peer_issued_cid_manager_.ReplaceConnectionId(initial_connection_id_,
+                                               TestConnectionId(1));
+  EXPECT_FALSE(
+      peer_issued_cid_manager_.IsConnectionIdActive(initial_connection_id_));
+  EXPECT_TRUE(
+      peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(1)));
+}
+
+class TestSelfIssuedConnectionIdManagerVisitor
+    : public QuicConnectionIdManagerVisitorInterface {
+ public:
+  void OnPeerIssuedConnectionIdRetired() override {}
+
+  MOCK_METHOD(bool,
+              SendNewConnectionId,
+              (const QuicNewConnectionIdFrame& frame),
+              (override));
+  MOCK_METHOD(void,
+              OnNewConnectionIdIssued,
+              (const QuicConnectionId& connection_id),
+              (override));
+  MOCK_METHOD(void,
+              OnSelfIssuedConnectionIdRetired,
+              (const QuicConnectionId& connection_id),
+              (override));
+};
+
+class QuicSelfIssuedConnectionIdManagerTest : public QuicTest {
+ public:
+  QuicSelfIssuedConnectionIdManagerTest()
+      : cid_manager_(/*active_connection_id_limit*/ 2, initial_connection_id_,
+                     &clock_, &alarm_factory_, &cid_manager_visitor_,
+                     /*context=*/nullptr) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+    retire_self_issued_cid_alarm_ =
+        QuicConnectionIdManagerPeer::GetRetireSelfIssuedConnectionIdAlarm(
+            &cid_manager_);
+  }
+
+ protected:
+  MockClock clock_;
+  test::MockAlarmFactory alarm_factory_;
+  TestSelfIssuedConnectionIdManagerVisitor cid_manager_visitor_;
+  QuicConnectionId initial_connection_id_ = TestConnectionId(0);
+  StrictMock<QuicSelfIssuedConnectionIdManager> cid_manager_;
+  QuicAlarm* retire_self_issued_cid_alarm_ = nullptr;
+  std::string error_details_;
+  QuicTime::Delta pto_delay_ = QuicTime::Delta::FromMilliseconds(10);
+};
+
+MATCHER_P3(ExpectedNewConnectionIdFrame,
+           connection_id,
+           sequence_number,
+           retire_prior_to,
+           "") {
+  return (arg.connection_id == connection_id) &&
+         (arg.sequence_number == sequence_number) &&
+         (arg.retire_prior_to == retire_prior_to);
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       RetireSelfIssuedConnectionIdInOrder) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  QuicConnectionId cid4 = cid_manager_.GenerateNewConnectionId(cid3);
+  QuicConnectionId cid5 = cid_manager_.GenerateNewConnectionId(cid4);
+
+  // Sends CID #1 to peer.
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
+  EXPECT_CALL(cid_manager_visitor_,
+              SendNewConnectionId(ExpectedNewConnectionIdFrame(cid1, 1u, 0u)))
+      .WillOnce(Return(true));
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  {
+    // Peer retires CID #0;
+    // Sends CID #2 and asks peer to retire CIDs prior to #1.
+    // Outcome: (#1, #2) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid2));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid2, 2u, 1u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 0u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #1;
+    // Sends CID #3 and asks peer to retire CIDs prior to #2.
+    // Outcome: (#2, #3) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid3));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid3, 3u, 2u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 1u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #2;
+    // Sends CID #4 and asks peer to retire CIDs prior to #3.
+    // Outcome: (#3, #4) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid4));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid4, 4u, 3u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 2u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #3;
+    // Sends CID #5 and asks peer to retire CIDs prior to #4.
+    // Outcome: (#4, #5) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid5));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid5, 5u, 4u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 3u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       RetireSelfIssuedConnectionIdOutOfOrder) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  QuicConnectionId cid4 = cid_manager_.GenerateNewConnectionId(cid3);
+
+  // Sends CID #1 to peer.
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
+  EXPECT_CALL(cid_manager_visitor_,
+              SendNewConnectionId(ExpectedNewConnectionIdFrame(cid1, 1u, 0u)))
+      .WillOnce(Return(true));
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  {
+    // Peer retires CID #1;
+    // Sends CID #2 and asks peer to retire CIDs prior to #0.
+    // Outcome: (#0, #2) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid2));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid2, 2u, 0u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 1u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #1 again. This is a no-op.
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 1u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #0;
+    // Sends CID #3 and asks peer to retire CIDs prior to #2.
+    // Outcome: (#2, #3) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid3));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid3, 3u, 2u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 0u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #3;
+    // Sends CID #4 and asks peer to retire CIDs prior to #2.
+    // Outcome: (#2, #4) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid4));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid4, 4u, 2u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 3u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #0 again. This is a no-op.
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 0u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       ScheduleConnectionIdRetirementOneAtATime) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .Times(3)
+      .WillRepeatedly(Return(true));
+  QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
+  QuicRetireConnectionIdFrame retire_cid_frame;
+
+  // CID #1 is sent to peer.
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  // CID #0's retirement is scheduled and CID #2 is sent to peer.
+  retire_cid_frame.sequence_number = 0u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsQuicNoError());
+  // While CID #0's retirement is scheduled, it is not retired yet.
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid0, cid1, cid2));
+  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
+  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
+            clock_.ApproximateNow() + connection_id_expire_timeout);
+
+  // CID #0 is actually retired.
+  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
+  clock_.AdvanceTime(connection_id_expire_timeout);
+  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid1, cid2));
+  EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
+
+  // CID #1's retirement is scheduled and CID #3 is sent to peer.
+  retire_cid_frame.sequence_number = 1u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsQuicNoError());
+  // While CID #1's retirement is scheduled, it is not retired yet.
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid1, cid2, cid3));
+  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
+  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
+            clock_.ApproximateNow() + connection_id_expire_timeout);
+
+  // CID #1 is actually retired.
+  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
+  clock_.AdvanceTime(connection_id_expire_timeout);
+  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid2, cid3));
+  EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       ScheduleMultipleConnectionIdRetirement) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .Times(3)
+      .WillRepeatedly(Return(true));
+  QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
+  QuicRetireConnectionIdFrame retire_cid_frame;
+
+  // CID #1 is sent to peer.
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  // CID #0's retirement is scheduled and CID #2 is sent to peer.
+  retire_cid_frame.sequence_number = 0u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsQuicNoError());
+
+  clock_.AdvanceTime(connection_id_expire_timeout * 0.25);
+
+  // CID #1's retirement is scheduled and CID #3 is sent to peer.
+  retire_cid_frame.sequence_number = 1u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsQuicNoError());
+
+  // While CID #0, #1s retirement is scheduled, they are not retired yet.
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid0, cid1, cid2, cid3));
+  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
+  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
+            clock_.ApproximateNow() + connection_id_expire_timeout * 0.75);
+
+  // CID #0 is actually retired.
+  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
+  clock_.AdvanceTime(connection_id_expire_timeout * 0.75);
+  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid1, cid2, cid3));
+  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
+  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
+            clock_.ApproximateNow() + connection_id_expire_timeout * 0.25);
+
+  // CID #1 is actually retired.
+  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
+  clock_.AdvanceTime(connection_id_expire_timeout * 0.25);
+  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid2, cid3));
+  EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       AllExpiredConnectionIdsAreRetiredInOneBatch) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  QuicConnectionId cid;
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .Times(3)
+      .WillRepeatedly(Return(true));
+  QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
+  QuicRetireConnectionIdFrame retire_cid_frame;
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid0));
+  EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
+  EXPECT_FALSE(cid_manager_.ConsumeOneConnectionId().has_value());
+
+  // CID #1 is sent to peer.
+  cid_manager_.MaybeSendNewConnectionIds();
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid1));
+  EXPECT_TRUE(cid_manager_.HasConnectionIdToConsume());
+  cid = *cid_manager_.ConsumeOneConnectionId();
+  EXPECT_EQ(cid1, cid);
+  EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
+
+  // CID #0's retirement is scheduled and CID #2 is sent to peer.
+  retire_cid_frame.sequence_number = 0u;
+  cid_manager_.OnRetireConnectionIdFrame(retire_cid_frame, pto_delay_,
+                                         &error_details_);
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid0));
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid1));
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid2));
+  EXPECT_TRUE(cid_manager_.HasConnectionIdToConsume());
+  cid = *cid_manager_.ConsumeOneConnectionId();
+  EXPECT_EQ(cid2, cid);
+  EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
+
+  clock_.AdvanceTime(connection_id_expire_timeout * 0.1);
+
+  // CID #1's retirement is scheduled and CID #3 is sent to peer.
+  retire_cid_frame.sequence_number = 1u;
+  cid_manager_.OnRetireConnectionIdFrame(retire_cid_frame, pto_delay_,
+                                         &error_details_);
+
+  {
+    // CID #0 & #1 are retired in a single alarm fire.
+    clock_.AdvanceTime(connection_id_expire_timeout);
+    testing::InSequence s;
+    EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
+    EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
+    alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+    EXPECT_FALSE(cid_manager_.IsConnectionIdInUse(cid0));
+    EXPECT_FALSE(cid_manager_.IsConnectionIdInUse(cid1));
+    EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid2));
+    EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+                ElementsAre(cid2, cid3));
+    EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
+  }
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       ErrorWhenRetireConnectionIdNeverIssued) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+
+  // CID #1 is sent to peer.
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(1);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .WillOnce(Return(true));
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  // CID #2 is never issued.
+  QuicRetireConnectionIdFrame retire_cid_frame;
+  retire_cid_frame.sequence_number = 2u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       ErrorWhenTooManyConnectionIdWaitingToBeRetired) {
+  // CID #0 & #1 are issued.
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_));
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .WillOnce(Return(true));
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  // Add 8 connection IDs to the to-be-retired list.
+  QuicConnectionId last_connection_id =
+      cid_manager_.GenerateNewConnectionId(initial_connection_id_);
+  for (int i = 0; i < 8; ++i) {
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_));
+    EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = i;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+    last_connection_id =
+        cid_manager_.GenerateNewConnectionId(last_connection_id);
+  }
+  QuicRetireConnectionIdFrame retire_cid_frame;
+  retire_cid_frame.sequence_number = 8u;
+  // This would have push the number of to-be-retired connection IDs over its
+  // limit.
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsError(QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE));
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       DoNotIssueConnectionIdVoluntarilyIfOneHasIssuedForPerferredAddress) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
+  ASSERT_THAT(cid_manager_.IssueNewConnectionIdForPreferredAddress(),
+              ExpectedNewConnectionIdFrame(cid1, 1u, 0u));
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid0, cid1));
+
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(0);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_)).Times(0);
+  cid_manager_.MaybeSendNewConnectionIds();
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_id_test.cc b/quiche/quic/core/quic_connection_id_test.cc
new file mode 100644
index 0000000..f421e95
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id_test.cc
@@ -0,0 +1,181 @@
+// Copyright 2018 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 "quiche/quic/core/quic_connection_id.h"
+
+#include <cstdint>
+#include <cstring>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace {
+
+class QuicConnectionIdTest : public QuicTest {};
+
+TEST_F(QuicConnectionIdTest, Empty) {
+  QuicConnectionId connection_id_empty = EmptyQuicConnectionId();
+  EXPECT_TRUE(connection_id_empty.IsEmpty());
+}
+
+TEST_F(QuicConnectionIdTest, DefaultIsEmpty) {
+  QuicConnectionId connection_id_empty = QuicConnectionId();
+  EXPECT_TRUE(connection_id_empty.IsEmpty());
+}
+
+TEST_F(QuicConnectionIdTest, NotEmpty) {
+  QuicConnectionId connection_id = test::TestConnectionId(1);
+  EXPECT_FALSE(connection_id.IsEmpty());
+}
+
+TEST_F(QuicConnectionIdTest, ZeroIsNotEmpty) {
+  QuicConnectionId connection_id = test::TestConnectionId(0);
+  EXPECT_FALSE(connection_id.IsEmpty());
+}
+
+TEST_F(QuicConnectionIdTest, Data) {
+  char connection_id_data[kQuicDefaultConnectionIdLength];
+  memset(connection_id_data, 0x42, sizeof(connection_id_data));
+  QuicConnectionId connection_id1 =
+      QuicConnectionId(connection_id_data, sizeof(connection_id_data));
+  QuicConnectionId connection_id2 =
+      QuicConnectionId(connection_id_data, sizeof(connection_id_data));
+  EXPECT_EQ(connection_id1, connection_id2);
+  EXPECT_EQ(connection_id1.length(), kQuicDefaultConnectionIdLength);
+  EXPECT_EQ(connection_id1.data(), connection_id1.mutable_data());
+  EXPECT_EQ(0, memcmp(connection_id1.data(), connection_id2.data(),
+                      sizeof(connection_id_data)));
+  EXPECT_EQ(0, memcmp(connection_id1.data(), connection_id_data,
+                      sizeof(connection_id_data)));
+  connection_id2.mutable_data()[0] = 0x33;
+  EXPECT_NE(connection_id1, connection_id2);
+  static const uint8_t kNewLength = 4;
+  connection_id2.set_length(kNewLength);
+  EXPECT_EQ(kNewLength, connection_id2.length());
+}
+
+TEST_F(QuicConnectionIdTest, SpanData) {
+  QuicConnectionId connection_id = QuicConnectionId({0x01, 0x02, 0x03});
+  EXPECT_EQ(connection_id.length(), 3);
+  QuicConnectionId empty_connection_id =
+      QuicConnectionId(absl::Span<uint8_t>());
+  EXPECT_EQ(empty_connection_id.length(), 0);
+  QuicConnectionId connection_id2 = QuicConnectionId({
+      0x01,
+      0x02,
+      0x03,
+      0x04,
+      0x05,
+      0x06,
+      0x07,
+      0x08,
+      0x09,
+      0x0a,
+      0x0b,
+      0x0c,
+      0x0d,
+      0x0e,
+      0x0f,
+      0x10,
+  });
+  EXPECT_EQ(connection_id2.length(), 16);
+}
+
+TEST_F(QuicConnectionIdTest, DoubleConvert) {
+  QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
+  QuicConnectionId connection_id64_2 = test::TestConnectionId(42);
+  QuicConnectionId connection_id64_3 =
+      test::TestConnectionId(UINT64_C(0xfedcba9876543210));
+  EXPECT_EQ(connection_id64_1,
+            test::TestConnectionId(
+                test::TestConnectionIdToUInt64(connection_id64_1)));
+  EXPECT_EQ(connection_id64_2,
+            test::TestConnectionId(
+                test::TestConnectionIdToUInt64(connection_id64_2)));
+  EXPECT_EQ(connection_id64_3,
+            test::TestConnectionId(
+                test::TestConnectionIdToUInt64(connection_id64_3)));
+  EXPECT_NE(connection_id64_1, connection_id64_2);
+  EXPECT_NE(connection_id64_1, connection_id64_3);
+  EXPECT_NE(connection_id64_2, connection_id64_3);
+}
+
+TEST_F(QuicConnectionIdTest, Hash) {
+  QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
+  QuicConnectionId connection_id64_1b = test::TestConnectionId(1);
+  QuicConnectionId connection_id64_2 = test::TestConnectionId(42);
+  QuicConnectionId connection_id64_3 =
+      test::TestConnectionId(UINT64_C(0xfedcba9876543210));
+  EXPECT_EQ(connection_id64_1.Hash(), connection_id64_1b.Hash());
+  EXPECT_NE(connection_id64_1.Hash(), connection_id64_2.Hash());
+  EXPECT_NE(connection_id64_1.Hash(), connection_id64_3.Hash());
+  EXPECT_NE(connection_id64_2.Hash(), connection_id64_3.Hash());
+
+  // Verify that any two all-zero connection IDs of different lengths never
+  // have the same hash.
+  const char connection_id_bytes[255] = {};
+  for (uint8_t i = 0; i < sizeof(connection_id_bytes) - 1; ++i) {
+    QuicConnectionId connection_id_i(connection_id_bytes, i);
+    for (uint8_t j = i + 1; j < sizeof(connection_id_bytes); ++j) {
+      QuicConnectionId connection_id_j(connection_id_bytes, j);
+      EXPECT_NE(connection_id_i.Hash(), connection_id_j.Hash());
+    }
+  }
+}
+
+TEST_F(QuicConnectionIdTest, AssignAndCopy) {
+  QuicConnectionId connection_id = test::TestConnectionId(1);
+  QuicConnectionId connection_id2 = test::TestConnectionId(2);
+  connection_id = connection_id2;
+  EXPECT_EQ(connection_id, test::TestConnectionId(2));
+  EXPECT_NE(connection_id, test::TestConnectionId(1));
+  connection_id = QuicConnectionId(test::TestConnectionId(1));
+  EXPECT_EQ(connection_id, test::TestConnectionId(1));
+  EXPECT_NE(connection_id, test::TestConnectionId(2));
+}
+
+TEST_F(QuicConnectionIdTest, ChangeLength) {
+  QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
+  QuicConnectionId connection_id64_2 = test::TestConnectionId(2);
+  QuicConnectionId connection_id136_2 = test::TestConnectionId(2);
+  connection_id136_2.set_length(17);
+  memset(connection_id136_2.mutable_data() + 8, 0, 9);
+  char connection_id136_2_bytes[17] = {0, 0, 0, 0, 0, 0, 0, 2, 0,
+                                       0, 0, 0, 0, 0, 0, 0, 0};
+  QuicConnectionId connection_id136_2b(connection_id136_2_bytes,
+                                       sizeof(connection_id136_2_bytes));
+  EXPECT_EQ(connection_id136_2, connection_id136_2b);
+  QuicConnectionId connection_id = connection_id64_1;
+  connection_id.set_length(17);
+  EXPECT_NE(connection_id64_1, connection_id);
+  // Check resizing big to small.
+  connection_id.set_length(8);
+  EXPECT_EQ(connection_id64_1, connection_id);
+  // Check resizing small to big.
+  connection_id.set_length(17);
+  memset(connection_id.mutable_data(), 0, connection_id.length());
+  memcpy(connection_id.mutable_data(), connection_id64_2.data(),
+         connection_id64_2.length());
+  EXPECT_EQ(connection_id136_2, connection_id);
+  EXPECT_EQ(connection_id136_2b, connection_id);
+  QuicConnectionId connection_id120(connection_id136_2_bytes, 15);
+  connection_id.set_length(15);
+  EXPECT_EQ(connection_id120, connection_id);
+  // Check resizing big to big.
+  QuicConnectionId connection_id2 = connection_id120;
+  connection_id2.set_length(17);
+  connection_id2.mutable_data()[15] = 0;
+  connection_id2.mutable_data()[16] = 0;
+  EXPECT_EQ(connection_id136_2, connection_id2);
+  EXPECT_EQ(connection_id136_2b, connection_id2);
+}
+
+}  // namespace
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_stats.cc b/quiche/quic/core/quic_connection_stats.cc
new file mode 100644
index 0000000..bb53ca5
--- /dev/null
+++ b/quiche/quic/core/quic_connection_stats.cc
@@ -0,0 +1,72 @@
+// Copyright 2013 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 "quiche/quic/core/quic_connection_stats.h"
+
+namespace quic {
+
+std::ostream& operator<<(std::ostream& os, const QuicConnectionStats& s) {
+  os << "{ bytes_sent: " << s.bytes_sent;
+  os << " packets_sent: " << s.packets_sent;
+  os << " stream_bytes_sent: " << s.stream_bytes_sent;
+  os << " packets_discarded: " << s.packets_discarded;
+  os << " bytes_received: " << s.bytes_received;
+  os << " packets_received: " << s.packets_received;
+  os << " packets_processed: " << s.packets_processed;
+  os << " stream_bytes_received: " << s.stream_bytes_received;
+  os << " bytes_retransmitted: " << s.bytes_retransmitted;
+  os << " packets_retransmitted: " << s.packets_retransmitted;
+  os << " bytes_spuriously_retransmitted: " << s.bytes_spuriously_retransmitted;
+  os << " packets_spuriously_retransmitted: "
+     << s.packets_spuriously_retransmitted;
+  os << " packets_lost: " << s.packets_lost;
+  os << " slowstart_packets_sent: " << s.slowstart_packets_sent;
+  os << " slowstart_packets_lost: " << s.slowstart_packets_lost;
+  os << " slowstart_bytes_lost: " << s.slowstart_bytes_lost;
+  os << " packets_dropped: " << s.packets_dropped;
+  os << " undecryptable_packets_received_before_handshake_complete: "
+     << s.undecryptable_packets_received_before_handshake_complete;
+  os << " crypto_retransmit_count: " << s.crypto_retransmit_count;
+  os << " loss_timeout_count: " << s.loss_timeout_count;
+  os << " tlp_count: " << s.tlp_count;
+  os << " rto_count: " << s.rto_count;
+  os << " pto_count: " << s.pto_count;
+  os << " min_rtt_us: " << s.min_rtt_us;
+  os << " srtt_us: " << s.srtt_us;
+  os << " egress_mtu: " << s.egress_mtu;
+  os << " max_egress_mtu: " << s.max_egress_mtu;
+  os << " ingress_mtu: " << s.ingress_mtu;
+  os << " estimated_bandwidth: " << s.estimated_bandwidth;
+  os << " packets_reordered: " << s.packets_reordered;
+  os << " max_sequence_reordering: " << s.max_sequence_reordering;
+  os << " max_time_reordering_us: " << s.max_time_reordering_us;
+  os << " tcp_loss_events: " << s.tcp_loss_events;
+  os << " connection_creation_time: "
+     << s.connection_creation_time.ToDebuggingValue();
+  os << " blocked_frames_received: " << s.blocked_frames_received;
+  os << " blocked_frames_sent: " << s.blocked_frames_sent;
+  os << " num_connectivity_probing_received: "
+     << s.num_connectivity_probing_received;
+  os << " retry_packet_processed: "
+     << (s.retry_packet_processed ? "yes" : "no");
+  os << " num_coalesced_packets_received: " << s.num_coalesced_packets_received;
+  os << " num_coalesced_packets_processed: "
+     << s.num_coalesced_packets_processed;
+  os << " num_ack_aggregation_epochs: " << s.num_ack_aggregation_epochs;
+  os << " sent_legacy_version_encapsulated_packets: "
+     << s.sent_legacy_version_encapsulated_packets;
+  os << " key_update_count: " << s.key_update_count;
+  os << " num_failed_authentication_packets_received: "
+     << s.num_failed_authentication_packets_received;
+  os << " num_tls_server_zero_rtt_packets_received_after_discarding_decrypter: "
+     << s.num_tls_server_zero_rtt_packets_received_after_discarding_decrypter;
+  os << " address_validated_via_decrypting_packet: "
+     << s.address_validated_via_decrypting_packet;
+  os << " address_validated_via_token: " << s.address_validated_via_token;
+  os << " }";
+
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_stats.h b/quiche/quic/core/quic_connection_stats.h
new file mode 100644
index 0000000..46ccf3e
--- /dev/null
+++ b/quiche/quic/core/quic_connection_stats.h
@@ -0,0 +1,241 @@
+// Copyright 2013 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_CONNECTION_STATS_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
+
+#include <cstdint>
+#include <ostream>
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_time_accumulator.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Structure to hold stats for a QuicConnection.
+struct QUIC_EXPORT_PRIVATE QuicConnectionStats {
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicConnectionStats& s);
+
+  QuicByteCount bytes_sent = 0;  // Includes retransmissions.
+  QuicPacketCount packets_sent = 0;
+  // Non-retransmitted bytes sent in a stream frame.
+  QuicByteCount stream_bytes_sent = 0;
+  // Packets serialized and discarded before sending.
+  QuicPacketCount packets_discarded = 0;
+
+  // These include version negotiation and public reset packets, which do not
+  // have packet numbers or frame data.
+  QuicByteCount bytes_received = 0;  // Includes duplicate data for a stream.
+  // Includes packets which were not processable.
+  QuicPacketCount packets_received = 0;
+  // Excludes packets which were not processable.
+  QuicPacketCount packets_processed = 0;
+  QuicByteCount stream_bytes_received = 0;  // Bytes received in a stream frame.
+
+  QuicByteCount bytes_retransmitted = 0;
+  QuicPacketCount packets_retransmitted = 0;
+
+  QuicByteCount bytes_spuriously_retransmitted = 0;
+  QuicPacketCount packets_spuriously_retransmitted = 0;
+  // Number of packets abandoned as lost by the loss detection algorithm.
+  QuicPacketCount packets_lost = 0;
+  QuicPacketCount packet_spuriously_detected_lost = 0;
+
+  // The sum of loss detection response times of all lost packets, in number of
+  // round trips.
+  // Given a packet detected as lost:
+  //   T(S)                            T(1Rtt)    T(D)
+  //     |_________________________________|_______|
+  // Where
+  //   T(S) is the time when the packet is sent.
+  //   T(1Rtt) is one rtt after T(S), using the rtt at the time of detection.
+  //   T(D) is the time of detection, i.e. when the packet is declared as lost.
+  // The loss detection response time is defined as
+  //     (T(D) - T(S)) / (T(1Rtt) - T(S))
+  //
+  // The average loss detection response time is this number divided by
+  // |packets_lost|. Smaller result means detection is faster.
+  float total_loss_detection_response_time = 0.0;
+
+  // Number of times this connection went through the slow start phase.
+  uint32_t slowstart_count = 0;
+  // Number of round trips spent in slow start.
+  uint32_t slowstart_num_rtts = 0;
+  // Number of packets sent in slow start.
+  QuicPacketCount slowstart_packets_sent = 0;
+  // Number of bytes sent in slow start.
+  QuicByteCount slowstart_bytes_sent = 0;
+  // Number of packets lost exiting slow start.
+  QuicPacketCount slowstart_packets_lost = 0;
+  // Number of bytes lost exiting slow start.
+  QuicByteCount slowstart_bytes_lost = 0;
+  // Time spent in slow start. Populated for BBRv1 and BBRv2.
+  QuicTimeAccumulator slowstart_duration;
+
+  // Number of PROBE_BW cycles. Populated for BBRv1 and BBRv2.
+  uint32_t bbr_num_cycles = 0;
+  // Number of PROBE_BW cycles shortened for reno coexistence. BBRv2 only.
+  uint32_t bbr_num_short_cycles_for_reno_coexistence = 0;
+  // Whether BBR exited STARTUP due to excessive loss. Populated for BBRv1 and
+  // BBRv2.
+  bool bbr_exit_startup_due_to_loss = false;
+
+  QuicPacketCount packets_dropped = 0;  // Duplicate or less than least unacked.
+
+  // Packets that failed to decrypt when they were first received,
+  // before the handshake was complete.
+  QuicPacketCount undecryptable_packets_received_before_handshake_complete = 0;
+
+  size_t crypto_retransmit_count = 0;
+  // Count of times the loss detection alarm fired.  At least one packet should
+  // be lost when the alarm fires.
+  size_t loss_timeout_count = 0;
+  size_t tlp_count = 0;
+  size_t rto_count = 0;  // Count of times the rto timer fired.
+  size_t pto_count = 0;
+
+  int64_t min_rtt_us = 0;  // Minimum RTT in microseconds.
+  int64_t srtt_us = 0;     // Smoothed RTT in microseconds.
+  int64_t cwnd_bootstrapping_rtt_us = 0;  // RTT used in cwnd_bootstrapping.
+  // The connection's |long_term_mtu_| used for sending packets, populated by
+  // QuicConnection::GetStats().
+  QuicByteCount egress_mtu = 0;
+  // The maximum |long_term_mtu_| the connection ever used.
+  QuicByteCount max_egress_mtu = 0;
+  // Size of the largest packet received from the peer, populated by
+  // QuicConnection::GetStats().
+  QuicByteCount ingress_mtu = 0;
+  QuicBandwidth estimated_bandwidth = QuicBandwidth::Zero();
+
+  // Reordering stats for received packets.
+  // Number of packets received out of packet number order.
+  QuicPacketCount packets_reordered = 0;
+  // Maximum reordering observed in packet number space.
+  QuicPacketCount max_sequence_reordering = 0;
+  // Maximum reordering observed in microseconds
+  int64_t max_time_reordering_us = 0;
+
+  // Maximum sequence reordering observed from acked packets.
+  QuicPacketCount sent_packets_max_sequence_reordering = 0;
+  // Number of times that a packet is not detected as lost per reordering_shift,
+  // but would have been if the reordering_shift increases by one.
+  QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
+
+  // The following stats are used only in TcpCubicSender.
+  // The number of loss events from TCP's perspective.  Each loss event includes
+  // one or more lost packets.
+  uint32_t tcp_loss_events = 0;
+
+  // Creation time, as reported by the QuicClock.
+  QuicTime connection_creation_time = QuicTime::Zero();
+
+  // Handshake completion time.
+  QuicTime handshake_completion_time = QuicTime::Zero();
+
+  uint64_t blocked_frames_received = 0;
+  uint64_t blocked_frames_sent = 0;
+
+  // Number of connectivity probing packets received by this connection.
+  uint64_t num_connectivity_probing_received = 0;
+
+  // Whether a RETRY packet was successfully processed.
+  bool retry_packet_processed = false;
+
+  // Number of received coalesced packets.
+  uint64_t num_coalesced_packets_received = 0;
+  // Number of successfully processed coalesced packets.
+  uint64_t num_coalesced_packets_processed = 0;
+  // Number of ack aggregation epochs. For the same number of bytes acked, the
+  // smaller this value, the more ack aggregation is going on.
+  uint64_t num_ack_aggregation_epochs = 0;
+
+  // Whether overshooting is detected (and pacing rate decreases) during start
+  // up with network parameters adjusted.
+  bool overshooting_detected_with_network_parameters_adjusted = false;
+
+  // Whether there is any non app-limited bandwidth sample.
+  bool has_non_app_limited_sample = false;
+
+  // Packet number of first decrypted packet.
+  QuicPacketNumber first_decrypted_packet;
+
+  // Max consecutive retransmission timeout before making forward progress.
+  size_t max_consecutive_rto_with_forward_progress = 0;
+
+  // Number of sent packets that were encapsulated using Legacy Version
+  // Encapsulation.
+  QuicPacketCount sent_legacy_version_encapsulated_packets = 0;
+
+  // Number of times when the connection tries to send data but gets throttled
+  // by amplification factor.
+  size_t num_amplification_throttling = 0;
+
+  // Number of key phase updates that have occurred. In the case of a locally
+  // initiated key update, this is incremented when the keys are updated, before
+  // the peer has acknowledged the key update.
+  uint32_t key_update_count = 0;
+
+  // Counts the number of undecryptable packets received across all keys. Does
+  // not include packets where a decryption key for that level was absent.
+  QuicPacketCount num_failed_authentication_packets_received = 0;
+
+  // Counts the number of QUIC+TLS 0-RTT packets received after 0-RTT decrypter
+  // was discarded, only on server connections.
+  QuicPacketCount
+      num_tls_server_zero_rtt_packets_received_after_discarding_decrypter = 0;
+
+  // True if address is validated via decrypting HANDSHAKE or 1-RTT packet.
+  bool address_validated_via_decrypting_packet = false;
+
+  // True if address is validated via validating token received in INITIAL
+  // packet.
+  bool address_validated_via_token = false;
+
+  size_t ping_frames_sent = 0;
+
+  // Number of detected peer address changes which changes to a peer address
+  // validated by earlier path validation.
+  size_t num_peer_migration_to_proactively_validated_address = 0;
+  // Number of detected peer address changes which triggers reverse path
+  // validation.
+  size_t num_reverse_path_validtion_upon_migration = 0;
+  // Number of detected peer migrations which either succeed reverse path
+  // validation or no need to be validated.
+  size_t num_validated_peer_migration = 0;
+  // Number of detected peer migrations which triggered reverse path validation
+  // and failed and fell back to the old path.
+  size_t num_invalid_peer_migration = 0;
+  // Number of detected peer migrations which triggered reverse path validation
+  // which was canceled because the peer migrated again. Such migration is also
+  // counted as invalid peer migration.
+  size_t num_peer_migration_while_validating_default_path = 0;
+  // Number of NEW_CONNECTION_ID frames sent.
+  size_t num_new_connection_id_sent = 0;
+  // Number of RETIRE_CONNECTION_ID frames sent.
+  size_t num_retire_connection_id_sent = 0;
+
+  struct QUIC_NO_EXPORT TlsServerOperationStats {
+    bool success = false;
+    // If the operation is performed asynchronously, how long did it take.
+    // Zero() for synchronous operations.
+    QuicTime::Delta async_latency = QuicTime::Delta::Zero();
+  };
+
+  // The TLS server op stats only have values when the corresponding operation
+  // is performed by TlsServerHandshaker. If an operation is done within
+  // BoringSSL, e.g. ticket decrypted without using
+  // TlsServerHandshaker::SessionTicketOpen, it will not be recorded here.
+  absl::optional<TlsServerOperationStats> tls_server_select_cert_stats;
+  absl::optional<TlsServerOperationStats> tls_server_compute_signature_stats;
+  absl::optional<TlsServerOperationStats> tls_server_decrypt_ticket_stats;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
new file mode 100644
index 0000000..1311afe
--- /dev/null
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -0,0 +1,15834 @@
+// 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 "quiche/quic/core/quic_connection.h"
+
+#include <errno.h>
+
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/congestion_control/loss_detection_interface.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/frames/quic_connection_close_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_path_response_frame.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_coalesced_packet_peer.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_packet_creator_peer.h"
+#include "quiche/quic/test_tools/quic_path_validator_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_data_producer.h"
+#include "quiche/quic/test_tools/simple_session_notifier.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::DoAll;
+using testing::ElementsAre;
+using testing::Ge;
+using testing::IgnoreResult;
+using testing::InSequence;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::Lt;
+using testing::Ref;
+using testing::Return;
+using testing::SaveArg;
+using testing::SetArgPointee;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char data1[] = "foo data";
+const char data2[] = "bar data";
+
+const bool kHasStopWaiting = true;
+
+const int kDefaultRetransmissionTimeMs = 500;
+
+DiversificationNonce kTestDiversificationNonce = {
+    'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a',
+    'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b',
+    'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b',
+};
+
+const StatelessResetToken kTestStatelessResetToken{
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
+
+const QuicSocketAddress kPeerAddress =
+    QuicSocketAddress(QuicIpAddress::Loopback6(),
+                      /*port=*/12345);
+const QuicSocketAddress kSelfAddress =
+    QuicSocketAddress(QuicIpAddress::Loopback6(),
+                      /*port=*/443);
+
+QuicStreamId GetNthClientInitiatedStreamId(int n,
+                                           QuicTransportVersion version) {
+  return QuicUtils::GetFirstBidirectionalStreamId(version,
+                                                  Perspective::IS_CLIENT) +
+         n * 2;
+}
+
+QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      return INITIAL;
+    case ENCRYPTION_HANDSHAKE:
+      return HANDSHAKE;
+    case ENCRYPTION_ZERO_RTT:
+      return ZERO_RTT_PROTECTED;
+    case ENCRYPTION_FORWARD_SECURE:
+      QUICHE_DCHECK(false);
+      return INVALID_PACKET_TYPE;
+    default:
+      QUICHE_DCHECK(false);
+      return INVALID_PACKET_TYPE;
+  }
+}
+
+// A NullEncrypterWithConfidentialityLimit is a NullEncrypter that allows
+// specifying the confidentiality limit on the maximum number of packets that
+// may be encrypted per key phase in TLS+QUIC.
+class NullEncrypterWithConfidentialityLimit : public NullEncrypter {
+ public:
+  NullEncrypterWithConfidentialityLimit(Perspective perspective,
+                                        QuicPacketCount confidentiality_limit)
+      : NullEncrypter(perspective),
+        confidentiality_limit_(confidentiality_limit) {}
+
+  QuicPacketCount GetConfidentialityLimit() const override {
+    return confidentiality_limit_;
+  }
+
+ private:
+  QuicPacketCount confidentiality_limit_;
+};
+
+class StrictTaggingDecrypterWithIntegrityLimit : public StrictTaggingDecrypter {
+ public:
+  StrictTaggingDecrypterWithIntegrityLimit(uint8_t tag,
+                                           QuicPacketCount integrity_limit)
+      : StrictTaggingDecrypter(tag), integrity_limit_(integrity_limit) {}
+
+  QuicPacketCount GetIntegrityLimit() const override {
+    return integrity_limit_;
+  }
+
+ private:
+  QuicPacketCount integrity_limit_;
+};
+
+class TestConnectionHelper : public QuicConnectionHelperInterface {
+ public:
+  TestConnectionHelper(MockClock* clock, MockRandom* random_generator)
+      : clock_(clock), random_generator_(random_generator) {
+    clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+  TestConnectionHelper(const TestConnectionHelper&) = delete;
+  TestConnectionHelper& operator=(const TestConnectionHelper&) = delete;
+
+  // QuicConnectionHelperInterface
+  const QuicClock* GetClock() const override { return clock_; }
+
+  QuicRandom* GetRandomGenerator() override { return random_generator_; }
+
+  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override {
+    return &buffer_allocator_;
+  }
+
+ private:
+  MockClock* clock_;
+  MockRandom* random_generator_;
+  quiche::SimpleBufferAllocator buffer_allocator_;
+};
+
+class TestConnection : public QuicConnection {
+ public:
+  TestConnection(QuicConnectionId connection_id,
+                 QuicSocketAddress initial_self_address,
+                 QuicSocketAddress initial_peer_address,
+                 TestConnectionHelper* helper, TestAlarmFactory* alarm_factory,
+                 TestPacketWriter* writer, Perspective perspective,
+                 ParsedQuicVersion version)
+      : QuicConnection(connection_id, initial_self_address,
+                       initial_peer_address, helper, alarm_factory, writer,
+                       /* owns_writer= */ false, perspective,
+                       SupportedVersions(version)),
+        notifier_(nullptr) {
+    writer->set_perspective(perspective);
+    SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                 std::make_unique<NullEncrypter>(perspective));
+    SetDataProducer(&producer_);
+    ON_CALL(*this, OnSerializedPacket(_))
+        .WillByDefault([this](SerializedPacket packet) {
+          QuicConnection::OnSerializedPacket(std::move(packet));
+        });
+  }
+  TestConnection(const TestConnection&) = delete;
+  TestConnection& operator=(const TestConnection&) = delete;
+
+  MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket packet), (override));
+
+  void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
+    QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
+  }
+
+  void SetLossAlgorithm(LossDetectionInterface* loss_algorithm) {
+    QuicConnectionPeer::SetLossAlgorithm(this, loss_algorithm);
+  }
+
+  void SendPacket(EncryptionLevel /*level*/, uint64_t packet_number,
+                  std::unique_ptr<QuicPacket> packet,
+                  HasRetransmittableData retransmittable, bool has_ack,
+                  bool has_pending_frames) {
+    ScopedPacketFlusher flusher(this);
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length =
+        QuicConnectionPeer::GetFramer(this)->EncryptPayload(
+            ENCRYPTION_INITIAL, QuicPacketNumber(packet_number), *packet,
+            buffer, kMaxOutgoingPacketSize);
+    SerializedPacket serialized_packet(
+        QuicPacketNumber(packet_number), PACKET_4BYTE_PACKET_NUMBER, buffer,
+        encrypted_length, has_ack, has_pending_frames);
+    serialized_packet.peer_address = kPeerAddress;
+    if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
+      serialized_packet.retransmittable_frames.push_back(
+          QuicFrame(QuicPingFrame()));
+    }
+    OnSerializedPacket(std::move(serialized_packet));
+  }
+
+  QuicConsumedData SaveAndSendStreamData(QuicStreamId id,
+                                         absl::string_view data,
+                                         QuicStreamOffset offset,
+                                         StreamSendingState state) {
+    ScopedPacketFlusher flusher(this);
+    producer_.SaveStreamData(id, data);
+    if (notifier_ != nullptr) {
+      return notifier_->WriteOrBufferData(id, data.length(), state);
+    }
+    return QuicConnection::SendStreamData(id, data.length(), offset, state);
+  }
+
+  QuicConsumedData SendStreamDataWithString(QuicStreamId id,
+                                            absl::string_view data,
+                                            QuicStreamOffset offset,
+                                            StreamSendingState state) {
+    ScopedPacketFlusher flusher(this);
+    if (!QuicUtils::IsCryptoStreamId(transport_version(), id) &&
+        this->encryption_level() == ENCRYPTION_INITIAL) {
+      this->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+      if (perspective() == Perspective::IS_CLIENT && !IsHandshakeComplete()) {
+        OnHandshakeComplete();
+      }
+      if (version().SupportsAntiAmplificationLimit()) {
+        QuicConnectionPeer::SetAddressValidated(this);
+      }
+    }
+    return SaveAndSendStreamData(id, data, offset, state);
+  }
+
+  QuicConsumedData SendApplicationDataAtLevel(EncryptionLevel encryption_level,
+                                              QuicStreamId id,
+                                              absl::string_view data,
+                                              QuicStreamOffset offset,
+                                              StreamSendingState state) {
+    ScopedPacketFlusher flusher(this);
+    QUICHE_DCHECK(encryption_level >= ENCRYPTION_ZERO_RTT);
+    SetEncrypter(encryption_level, std::make_unique<TaggingEncrypter>(0x01));
+    SetDefaultEncryptionLevel(encryption_level);
+    return SaveAndSendStreamData(id, data, offset, state);
+  }
+
+  QuicConsumedData SendStreamData3() {
+    return SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(1, transport_version()), "food", 0,
+        NO_FIN);
+  }
+
+  QuicConsumedData SendStreamData5() {
+    return SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(2, transport_version()), "food2", 0,
+        NO_FIN);
+  }
+
+  // Ensures the connection can write stream data before writing.
+  QuicConsumedData EnsureWritableAndSendStreamData5() {
+    EXPECT_TRUE(CanWrite(HAS_RETRANSMITTABLE_DATA));
+    return SendStreamData5();
+  }
+
+  // The crypto stream has special semantics so that it is not blocked by a
+  // congestion window limitation, and also so that it gets put into a separate
+  // packet (so that it is easier to reason about a crypto frame not being
+  // split needlessly across packet boundaries).  As a result, we have separate
+  // tests for some cases for this stream.
+  QuicConsumedData SendCryptoStreamData() {
+    QuicStreamOffset offset = 0;
+    absl::string_view data("chlo");
+    if (!QuicVersionUsesCryptoFrames(transport_version())) {
+      return SendCryptoDataWithString(data, offset);
+    }
+    producer_.SaveCryptoData(ENCRYPTION_INITIAL, offset, data);
+    size_t bytes_written;
+    if (notifier_) {
+      bytes_written =
+          notifier_->WriteCryptoData(ENCRYPTION_INITIAL, data.length(), offset);
+    } else {
+      bytes_written = QuicConnection::SendCryptoData(ENCRYPTION_INITIAL,
+                                                     data.length(), offset);
+    }
+    return QuicConsumedData(bytes_written, /*fin_consumed*/ false);
+  }
+
+  QuicConsumedData SendCryptoDataWithString(absl::string_view data,
+                                            QuicStreamOffset offset) {
+    return SendCryptoDataWithString(data, offset, ENCRYPTION_INITIAL);
+  }
+
+  QuicConsumedData SendCryptoDataWithString(absl::string_view data,
+                                            QuicStreamOffset offset,
+                                            EncryptionLevel encryption_level) {
+    if (!QuicVersionUsesCryptoFrames(transport_version())) {
+      return SendStreamDataWithString(
+          QuicUtils::GetCryptoStreamId(transport_version()), data, offset,
+          NO_FIN);
+    }
+    producer_.SaveCryptoData(encryption_level, offset, data);
+    size_t bytes_written;
+    if (notifier_) {
+      bytes_written =
+          notifier_->WriteCryptoData(encryption_level, data.length(), offset);
+    } else {
+      bytes_written = QuicConnection::SendCryptoData(encryption_level,
+                                                     data.length(), offset);
+    }
+    return QuicConsumedData(bytes_written, /*fin_consumed*/ false);
+  }
+
+  void set_version(ParsedQuicVersion version) {
+    QuicConnectionPeer::GetFramer(this)->set_version(version);
+  }
+
+  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+    QuicConnectionPeer::GetFramer(this)->SetSupportedVersions(versions);
+    writer()->SetSupportedVersions(versions);
+  }
+
+  // This should be called before setting customized encrypters/decrypters for
+  // connection and peer creator.
+  void set_perspective(Perspective perspective) {
+    writer()->set_perspective(perspective);
+    QuicConnectionPeer::ResetPeerIssuedConnectionIdManager(this);
+    QuicConnectionPeer::SetPerspective(this, perspective);
+    QuicSentPacketManagerPeer::SetPerspective(
+        QuicConnectionPeer::GetSentPacketManager(this), perspective);
+    QuicConnectionPeer::GetFramer(this)->SetInitialObfuscators(
+        TestConnectionId());
+    for (EncryptionLevel level : {ENCRYPTION_ZERO_RTT, ENCRYPTION_HANDSHAKE,
+                                  ENCRYPTION_FORWARD_SECURE}) {
+      if (QuicConnectionPeer::GetFramer(this)->HasEncrypterOfEncryptionLevel(
+              level)) {
+        SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
+      }
+      if (QuicConnectionPeer::GetFramer(this)->HasDecrypterOfEncryptionLevel(
+              level)) {
+        InstallDecrypter(level, std::make_unique<NullDecrypter>(perspective));
+      }
+    }
+  }
+
+  // Enable path MTU discovery.  Assumes that the test is performed from the
+  // server perspective and the higher value of MTU target is used.
+  void EnablePathMtuDiscovery(MockSendAlgorithm* send_algorithm) {
+    ASSERT_EQ(Perspective::IS_SERVER, perspective());
+
+    if (GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server)) {
+      OnConfigNegotiated();
+    } else {
+      QuicConfig config;
+      QuicTagVector connection_options;
+      connection_options.push_back(kMTUH);
+      config.SetInitialReceivedConnectionOptions(connection_options);
+      EXPECT_CALL(*send_algorithm, SetFromConfig(_, _));
+      SetFromConfig(config);
+    }
+
+    // Normally, the pacing would be disabled in the test, but calling
+    // SetFromConfig enables it.  Set nearly-infinite bandwidth to make the
+    // pacing algorithm work.
+    EXPECT_CALL(*send_algorithm, PacingRate(_))
+        .WillRepeatedly(Return(QuicBandwidth::Infinite()));
+  }
+
+  TestAlarmFactory::TestAlarm* GetAckAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetAckAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetPingAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetPingAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetRetransmissionAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetRetransmissionAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetSendAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetSendAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetTimeoutAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetIdleNetworkDetectorAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetMtuDiscoveryAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetMtuDiscoveryAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetProcessUndecryptablePacketsAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetDiscardPreviousOneRttKeysAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetDiscardZeroRttDecryptionKeysAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetBlackholeDetectorAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetBlackholeDetectorAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetRetirePeerIssuedConnectionIdAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetRetirePeerIssuedConnectionIdAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetRetireSelfIssuedConnectionIdAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetRetireSelfIssuedConnectionIdAlarm(this));
+  }
+
+  void PathDegradingTimeout() {
+    QUICHE_DCHECK(PathDegradingDetectionInProgress());
+    GetBlackholeDetectorAlarm()->Fire();
+  }
+
+  bool PathDegradingDetectionInProgress() {
+    return QuicConnectionPeer::GetPathDegradingDeadline(this).IsInitialized();
+  }
+
+  bool BlackholeDetectionInProgress() {
+    return QuicConnectionPeer::GetBlackholeDetectionDeadline(this)
+        .IsInitialized();
+  }
+
+  bool PathMtuReductionDetectionInProgress() {
+    return QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(this)
+        .IsInitialized();
+  }
+
+  void SetMaxTailLossProbes(size_t max_tail_loss_probes) {
+    QuicSentPacketManagerPeer::SetMaxTailLossProbes(
+        QuicConnectionPeer::GetSentPacketManager(this), max_tail_loss_probes);
+  }
+
+  QuicByteCount GetBytesInFlight() {
+    return QuicConnectionPeer::GetSentPacketManager(this)->GetBytesInFlight();
+  }
+
+  void set_notifier(SimpleSessionNotifier* notifier) { notifier_ = notifier; }
+
+  void ReturnEffectivePeerAddressForNextPacket(const QuicSocketAddress& addr) {
+    next_effective_peer_addr_ = std::make_unique<QuicSocketAddress>(addr);
+  }
+
+  bool PtoEnabled() {
+    if (QuicConnectionPeer::GetSentPacketManager(this)->pto_enabled()) {
+      // TLP/RTO related tests are stale when PTO is enabled.
+      QUICHE_DCHECK(PROTOCOL_TLS1_3 == version().handshake_protocol ||
+                    GetQuicRestartFlag(quic_default_on_pto2));
+      return true;
+    }
+    return false;
+  }
+
+  void SendOrQueuePacket(SerializedPacket packet) override {
+    QuicConnection::SendOrQueuePacket(std::move(packet));
+    self_address_on_default_path_while_sending_packet_ = self_address();
+  }
+
+  QuicSocketAddress self_address_on_default_path_while_sending_packet() {
+    return self_address_on_default_path_while_sending_packet_;
+  }
+
+  SimpleDataProducer* producer() { return &producer_; }
+
+  using QuicConnection::active_effective_peer_migration_type;
+  using QuicConnection::IsCurrentPacketConnectivityProbing;
+  using QuicConnection::SelectMutualVersion;
+  using QuicConnection::SendProbingRetransmissions;
+  using QuicConnection::set_defer_send_in_response_to_packets;
+
+ protected:
+  QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const override {
+    if (next_effective_peer_addr_) {
+      return *std::move(next_effective_peer_addr_);
+    }
+    return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
+  }
+
+ private:
+  TestPacketWriter* writer() {
+    return static_cast<TestPacketWriter*>(QuicConnection::writer());
+  }
+
+  SimpleDataProducer producer_;
+
+  SimpleSessionNotifier* notifier_;
+
+  std::unique_ptr<QuicSocketAddress> next_effective_peer_addr_;
+
+  QuicSocketAddress self_address_on_default_path_while_sending_packet_;
+};
+
+enum class AckResponse { kDefer, kImmediate };
+
+// Run tests with combinations of {ParsedQuicVersion, AckResponse}.
+struct TestParams {
+  TestParams(ParsedQuicVersion version, AckResponse ack_response,
+             bool no_stop_waiting)
+      : version(version),
+        ack_response(ack_response),
+        no_stop_waiting(no_stop_waiting) {}
+
+  ParsedQuicVersion version;
+  AckResponse ack_response;
+  bool no_stop_waiting;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version), "_",
+      (p.ack_response == AckResponse::kDefer ? "defer" : "immediate"), "_",
+      (p.no_stop_waiting ? "No" : ""), "StopWaiting");
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  QuicFlagSaver flags;
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
+    for (AckResponse ack_response :
+         {AckResponse::kDefer, AckResponse::kImmediate}) {
+      params.push_back(
+          TestParams(all_supported_versions[i], ack_response, true));
+      if (!all_supported_versions[i].HasIetfInvariantHeader()) {
+        params.push_back(
+            TestParams(all_supported_versions[i], ack_response, false));
+      }
+    }
+  }
+  return params;
+}
+
+class QuicConnectionTest : public QuicTestWithParam<TestParams> {
+ public:
+  // For tests that do silent connection closes, no such packet is generated. In
+  // order to verify the contents of the OnConnectionClosed upcall, EXPECTs
+  // should invoke this method, saving the frame, and then the test can verify
+  // the contents.
+  void SaveConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
+                                ConnectionCloseSource /*source*/) {
+    saved_connection_close_frame_ = frame;
+    connection_close_frame_count_++;
+  }
+
+ protected:
+  QuicConnectionTest()
+      : connection_id_(TestConnectionId()),
+        framer_(SupportedVersions(version()), QuicTime::Zero(),
+                Perspective::IS_CLIENT, connection_id_.length()),
+        send_algorithm_(new StrictMock<MockSendAlgorithm>),
+        loss_algorithm_(new MockLossAlgorithm()),
+        helper_(new TestConnectionHelper(&clock_, &random_generator_)),
+        alarm_factory_(new TestAlarmFactory()),
+        peer_framer_(SupportedVersions(version()), QuicTime::Zero(),
+                     Perspective::IS_SERVER, connection_id_.length()),
+        peer_creator_(connection_id_, &peer_framer_,
+                      /*delegate=*/nullptr),
+        writer_(
+            new TestPacketWriter(version(), &clock_, Perspective::IS_CLIENT)),
+        connection_(connection_id_, kSelfAddress, kPeerAddress, helper_.get(),
+                    alarm_factory_.get(), writer_.get(), Perspective::IS_CLIENT,
+                    version()),
+        creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
+        manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
+        frame1_(0, false, 0, absl::string_view(data1)),
+        frame2_(0, false, 3, absl::string_view(data2)),
+        crypto_frame_(ENCRYPTION_INITIAL, 0, absl::string_view(data1)),
+        packet_number_length_(PACKET_4BYTE_PACKET_NUMBER),
+        connection_id_included_(CONNECTION_ID_PRESENT),
+        notifier_(&connection_),
+        connection_close_frame_count_(0) {
+    QUIC_DVLOG(2) << "QuicConnectionTest(" << PrintToString(GetParam()) << ")";
+    connection_.set_defer_send_in_response_to_packets(GetParam().ack_response ==
+                                                      AckResponse::kDefer);
+    framer_.SetInitialObfuscators(TestConnectionId());
+    connection_.InstallInitialCrypters(TestConnectionId());
+    CrypterPair crypters;
+    CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version(),
+                                          TestConnectionId(), &crypters);
+    peer_creator_.SetEncrypter(ENCRYPTION_INITIAL,
+                               std::move(crypters.encrypter));
+    if (version().KnowsWhichDecrypterToUse()) {
+      peer_framer_.InstallDecrypter(ENCRYPTION_INITIAL,
+                                    std::move(crypters.decrypter));
+    } else {
+      peer_framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                                std::move(crypters.decrypter));
+    }
+    for (EncryptionLevel level :
+         {ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
+      peer_creator_.SetEncrypter(
+          level, std::make_unique<NullEncrypter>(peer_framer_.perspective()));
+    }
+    QuicFramerPeer::SetLastSerializedServerConnectionId(
+        QuicConnectionPeer::GetFramer(&connection_), connection_id_);
+    QuicFramerPeer::SetLastWrittenPacketNumberLength(
+        QuicConnectionPeer::GetFramer(&connection_), packet_number_length_);
+    if (version().HasIetfInvariantHeader()) {
+      EXPECT_TRUE(QuicConnectionPeer::GetNoStopWaitingFrames(&connection_));
+    } else {
+      QuicConnectionPeer::SetNoStopWaitingFrames(&connection_,
+                                                 GetParam().no_stop_waiting);
+    }
+    QuicStreamId stream_id;
+    if (QuicVersionUsesCryptoFrames(version().transport_version)) {
+      stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+          version().transport_version, Perspective::IS_CLIENT);
+    } else {
+      stream_id = QuicUtils::GetCryptoStreamId(version().transport_version);
+    }
+    frame1_.stream_id = stream_id;
+    frame2_.stream_id = stream_id;
+    connection_.set_visitor(&visitor_);
+    connection_.SetSessionNotifier(&notifier_);
+    connection_.set_notifier(&notifier_);
+    connection_.SetSendAlgorithm(send_algorithm_);
+    connection_.SetLossAlgorithm(loss_algorithm_.get());
+    EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, OnPacketNeutered(_)).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+        .WillRepeatedly(Return(kDefaultTCPMSS));
+    EXPECT_CALL(*send_algorithm_, PacingRate(_))
+        .WillRepeatedly(Return(QuicBandwidth::Zero()));
+    EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(QuicBandwidth::Zero()));
+    EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_))
+        .Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
+        .Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
+        .Times(AnyNumber());
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnPacketDecrypted(_)).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnCanWrite())
+        .WillRepeatedly(Invoke(&notifier_, &SimpleSessionNotifier::OnCanWrite));
+    EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(visitor_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged())
+        .Times(testing::AtMost(1));
+    EXPECT_CALL(*loss_algorithm_, GetLossTimeout())
+        .WillRepeatedly(Return(QuicTime::Zero()));
+    EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+        .Times(AnyNumber());
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_START));
+    if (connection_.version().KnowsWhichDecrypterToUse()) {
+      connection_.InstallDecrypter(
+          ENCRYPTION_FORWARD_SECURE,
+          std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    }
+    peer_creator_.SetDefaultPeerAddress(kSelfAddress);
+  }
+
+  QuicConnectionTest(const QuicConnectionTest&) = delete;
+  QuicConnectionTest& operator=(const QuicConnectionTest&) = delete;
+
+  ParsedQuicVersion version() { return GetParam().version; }
+
+  QuicStopWaitingFrame* stop_waiting() {
+    QuicConnectionPeer::PopulateStopWaitingFrame(&connection_, &stop_waiting_);
+    return &stop_waiting_;
+  }
+
+  QuicPacketNumber least_unacked() {
+    if (writer_->stop_waiting_frames().empty()) {
+      return QuicPacketNumber();
+    }
+    return writer_->stop_waiting_frames()[0].least_unacked;
+  }
+
+  void use_tagging_decrypter() { writer_->use_tagging_decrypter(); }
+
+  void SetClientConnectionId(const QuicConnectionId& client_connection_id) {
+    connection_.set_client_connection_id(client_connection_id);
+    writer_->framer()->framer()->SetExpectedClientConnectionIdLength(
+        client_connection_id.length());
+  }
+
+  void SetDecrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicDecrypter> decrypter) {
+    if (connection_.version().KnowsWhichDecrypterToUse()) {
+      connection_.InstallDecrypter(level, std::move(decrypter));
+    } else {
+      connection_.SetDecrypter(level, std::move(decrypter));
+    }
+  }
+
+  void ProcessPacket(uint64_t number) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacket(number);
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+  }
+
+  void ProcessReceivedPacket(const QuicSocketAddress& self_address,
+                             const QuicSocketAddress& peer_address,
+                             const QuicReceivedPacket& packet) {
+    connection_.ProcessUdpPacket(self_address, peer_address, packet);
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+  }
+
+  QuicFrame MakeCryptoFrame() const {
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      return QuicFrame(new QuicCryptoFrame(crypto_frame_));
+    }
+    return QuicFrame(QuicStreamFrame(
+        QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+        0u, absl::string_view()));
+  }
+
+  void ProcessFramePacket(QuicFrame frame) {
+    ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress,
+                                    ENCRYPTION_FORWARD_SECURE);
+  }
+
+  void ProcessFramePacketWithAddresses(QuicFrame frame,
+                                       QuicSocketAddress self_address,
+                                       QuicSocketAddress peer_address,
+                                       EncryptionLevel level) {
+    QuicFrames frames;
+    frames.push_back(QuicFrame(frame));
+    return ProcessFramesPacketWithAddresses(frames, self_address, peer_address,
+                                            level);
+  }
+
+  std::unique_ptr<QuicReceivedPacket> ConstructPacket(QuicFrames frames,
+                                                      EncryptionLevel level,
+                                                      char* buffer,
+                                                      size_t buffer_len) {
+    QUICHE_DCHECK(peer_framer_.HasEncrypterOfEncryptionLevel(level));
+    peer_creator_.set_encryption_level(level);
+    QuicPacketCreatorPeer::SetSendVersionInPacket(
+        &peer_creator_,
+        level < ENCRYPTION_FORWARD_SECURE &&
+            connection_.perspective() == Perspective::IS_SERVER);
+
+    SerializedPacket serialized_packet =
+        QuicPacketCreatorPeer::SerializeAllFrames(&peer_creator_, frames,
+                                                  buffer, buffer_len);
+    return std::make_unique<QuicReceivedPacket>(
+        serialized_packet.encrypted_buffer, serialized_packet.encrypted_length,
+        clock_.Now());
+  }
+
+  void ProcessFramesPacketWithAddresses(QuicFrames frames,
+                                        QuicSocketAddress self_address,
+                                        QuicSocketAddress peer_address,
+                                        EncryptionLevel level) {
+    char buffer[kMaxOutgoingPacketSize];
+    connection_.ProcessUdpPacket(
+        self_address, peer_address,
+        *ConstructPacket(std::move(frames), level, buffer,
+                         kMaxOutgoingPacketSize));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+  }
+
+  // Bypassing the packet creator is unrealistic, but allows us to process
+  // packets the QuicPacketCreator won't allow us to create.
+  void ForceProcessFramePacket(QuicFrame frame) {
+    QuicFrames frames;
+    frames.push_back(QuicFrame(frame));
+    bool send_version = connection_.perspective() == Perspective::IS_SERVER;
+    if (connection_.version().KnowsWhichDecrypterToUse()) {
+      send_version = true;
+    }
+    QuicPacketCreatorPeer::SetSendVersionInPacket(&peer_creator_, send_version);
+    QuicPacketHeader header;
+    QuicPacketCreatorPeer::FillPacketHeader(&peer_creator_, &header);
+    char encrypted_buffer[kMaxOutgoingPacketSize];
+    size_t length = peer_framer_.BuildDataPacket(
+        header, frames, encrypted_buffer, kMaxOutgoingPacketSize,
+        ENCRYPTION_INITIAL);
+    QUICHE_DCHECK_GT(length, 0u);
+
+    const size_t encrypted_length = peer_framer_.EncryptInPlace(
+        ENCRYPTION_INITIAL, header.packet_number,
+        GetStartOfEncryptedData(peer_framer_.version().transport_version,
+                                header),
+        length, kMaxOutgoingPacketSize, encrypted_buffer);
+    QUICHE_DCHECK_GT(encrypted_length, 0u);
+
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(encrypted_buffer, encrypted_length, clock_.Now()));
+  }
+
+  size_t ProcessFramePacketAtLevel(uint64_t number, QuicFrame frame,
+                                   EncryptionLevel level) {
+    QuicFrames frames;
+    frames.push_back(frame);
+    return ProcessFramesPacketAtLevel(number, frames, level);
+  }
+
+  size_t ProcessFramesPacketAtLevel(uint64_t number, const QuicFrames& frames,
+                                    EncryptionLevel level) {
+    QuicPacketHeader header = ConstructPacketHeader(number, level);
+    // Set the correct encryption level and encrypter on peer_creator and
+    // peer_framer, respectively.
+    peer_creator_.set_encryption_level(level);
+    if (QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_) >
+        ENCRYPTION_INITIAL) {
+      peer_framer_.SetEncrypter(
+          QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+          std::make_unique<TaggingEncrypter>(0x01));
+      // Set the corresponding decrypter.
+      if (connection_.version().KnowsWhichDecrypterToUse()) {
+        connection_.InstallDecrypter(
+            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+            std::make_unique<StrictTaggingDecrypter>(0x01));
+      } else {
+        connection_.SetDecrypter(
+            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+            std::make_unique<StrictTaggingDecrypter>(0x01));
+      }
+    }
+    std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
+                                    buffer, kMaxOutgoingPacketSize);
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+    return encrypted_length;
+  }
+
+  struct PacketInfo {
+    PacketInfo(uint64_t packet_number, QuicFrames frames, EncryptionLevel level)
+        : packet_number(packet_number), frames(frames), level(level) {}
+
+    uint64_t packet_number;
+    QuicFrames frames;
+    EncryptionLevel level;
+  };
+
+  size_t ProcessCoalescedPacket(std::vector<PacketInfo> packets) {
+    char coalesced_buffer[kMaxOutgoingPacketSize];
+    size_t coalesced_size = 0;
+    bool contains_initial = false;
+    for (const auto& packet : packets) {
+      QuicPacketHeader header =
+          ConstructPacketHeader(packet.packet_number, packet.level);
+      // Set the correct encryption level and encrypter on peer_creator and
+      // peer_framer, respectively.
+      peer_creator_.set_encryption_level(packet.level);
+      if (packet.level == ENCRYPTION_INITIAL) {
+        contains_initial = true;
+      }
+      if (QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_) >
+          ENCRYPTION_INITIAL) {
+        peer_framer_.SetEncrypter(
+            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+            std::make_unique<TaggingEncrypter>(0x01));
+        // Set the corresponding decrypter.
+        if (connection_.version().KnowsWhichDecrypterToUse()) {
+          connection_.InstallDecrypter(
+              QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+              std::make_unique<StrictTaggingDecrypter>(0x01));
+        } else {
+          connection_.SetDecrypter(
+              QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+              std::make_unique<StrictTaggingDecrypter>(0x01));
+        }
+      }
+      std::unique_ptr<QuicPacket> constructed_packet(
+          ConstructPacket(header, packet.frames));
+
+      char buffer[kMaxOutgoingPacketSize];
+      size_t encrypted_length = peer_framer_.EncryptPayload(
+          packet.level, QuicPacketNumber(packet.packet_number),
+          *constructed_packet, buffer, kMaxOutgoingPacketSize);
+      QUICHE_DCHECK_LE(coalesced_size + encrypted_length,
+                       kMaxOutgoingPacketSize);
+      memcpy(coalesced_buffer + coalesced_size, buffer, encrypted_length);
+      coalesced_size += encrypted_length;
+    }
+    if (contains_initial) {
+      // Padded coalesced packet to full if it contains initial packet.
+      memset(coalesced_buffer + coalesced_size, '0',
+             kMaxOutgoingPacketSize - coalesced_size);
+    }
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(coalesced_buffer, coalesced_size, clock_.Now(),
+                           false));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+    return coalesced_size;
+  }
+
+  size_t ProcessDataPacket(uint64_t number) {
+    return ProcessDataPacketAtLevel(number, false, ENCRYPTION_FORWARD_SECURE);
+  }
+
+  size_t ProcessDataPacket(QuicPacketNumber packet_number) {
+    return ProcessDataPacketAtLevel(packet_number, false,
+                                    ENCRYPTION_FORWARD_SECURE);
+  }
+
+  size_t ProcessDataPacketAtLevel(QuicPacketNumber packet_number,
+                                  bool has_stop_waiting,
+                                  EncryptionLevel level) {
+    return ProcessDataPacketAtLevel(packet_number.ToUint64(), has_stop_waiting,
+                                    level);
+  }
+
+  size_t ProcessCryptoPacketAtLevel(uint64_t number, EncryptionLevel level) {
+    QuicPacketHeader header = ConstructPacketHeader(number, level);
+    QuicFrames frames;
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      frames.push_back(QuicFrame(&crypto_frame_));
+    } else {
+      frames.push_back(QuicFrame(frame1_));
+    }
+    if (level == ENCRYPTION_INITIAL) {
+      frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+    }
+    std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
+    char buffer[kMaxOutgoingPacketSize];
+    peer_creator_.set_encryption_level(level);
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
+                                    buffer, kMaxOutgoingPacketSize);
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+    return encrypted_length;
+  }
+
+  size_t ProcessDataPacketAtLevel(uint64_t number, bool has_stop_waiting,
+                                  EncryptionLevel level) {
+    std::unique_ptr<QuicPacket> packet(
+        ConstructDataPacket(number, has_stop_waiting, level));
+    char buffer[kMaxOutgoingPacketSize];
+    peer_creator_.set_encryption_level(level);
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
+                                    buffer, kMaxOutgoingPacketSize);
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+    return encrypted_length;
+  }
+
+  void ProcessClosePacket(uint64_t number) {
+    std::unique_ptr<QuicPacket> packet(ConstructClosePacket(number));
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length = peer_framer_.EncryptPayload(
+        ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(number), *packet, buffer,
+        kMaxOutgoingPacketSize);
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
+  }
+
+  QuicByteCount SendStreamDataToPeer(QuicStreamId id, absl::string_view data,
+                                     QuicStreamOffset offset,
+                                     StreamSendingState state,
+                                     QuicPacketNumber* last_packet) {
+    QuicByteCount packet_size;
+    // Save the last packet's size.
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AnyNumber())
+        .WillRepeatedly(SaveArg<3>(&packet_size));
+    connection_.SendStreamDataWithString(id, data, offset, state);
+    if (last_packet != nullptr) {
+      *last_packet = creator_->packet_number();
+    }
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AnyNumber());
+    return packet_size;
+  }
+
+  void SendAckPacketToPeer() {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    {
+      QuicConnection::ScopedPacketFlusher flusher(&connection_);
+      connection_.SendAck();
+    }
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AnyNumber());
+  }
+
+  void SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error,
+                     QuicStreamOffset bytes_written) {
+    notifier_.WriteOrBufferRstStream(id, error, bytes_written);
+    connection_.OnStreamReset(id, error);
+  }
+
+  void SendPing() { notifier_.WriteOrBufferPing(); }
+
+  MessageStatus SendMessage(absl::string_view message) {
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    quiche::QuicheMemSlice slice(quiche::QuicheBuffer::Copy(
+        connection_.helper()->GetStreamSendBufferAllocator(), message));
+    return connection_.SendMessage(1, absl::MakeSpan(&slice, 1), false);
+  }
+
+  void ProcessAckPacket(uint64_t packet_number, QuicAckFrame* frame) {
+    if (packet_number > 1) {
+      QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, packet_number - 1);
+    } else {
+      QuicPacketCreatorPeer::ClearPacketNumber(&peer_creator_);
+    }
+    ProcessFramePacket(QuicFrame(frame));
+  }
+
+  void ProcessAckPacket(QuicAckFrame* frame) {
+    ProcessFramePacket(QuicFrame(frame));
+  }
+
+  void ProcessStopWaitingPacket(QuicStopWaitingFrame frame) {
+    ProcessFramePacket(QuicFrame(frame));
+  }
+
+  size_t ProcessStopWaitingPacketAtLevel(uint64_t number,
+                                         QuicStopWaitingFrame frame,
+                                         EncryptionLevel /*level*/) {
+    return ProcessFramePacketAtLevel(number, QuicFrame(frame),
+                                     ENCRYPTION_ZERO_RTT);
+  }
+
+  void ProcessGoAwayPacket(QuicGoAwayFrame* frame) {
+    ProcessFramePacket(QuicFrame(frame));
+  }
+
+  bool IsMissing(uint64_t number) {
+    return IsAwaitingPacket(connection_.ack_frame(), QuicPacketNumber(number),
+                            QuicPacketNumber());
+  }
+
+  std::unique_ptr<QuicPacket> ConstructPacket(const QuicPacketHeader& header,
+                                              const QuicFrames& frames) {
+    auto packet = BuildUnsizedDataPacket(&peer_framer_, header, frames);
+    EXPECT_NE(nullptr, packet.get());
+    return packet;
+  }
+
+  QuicPacketHeader ConstructPacketHeader(uint64_t number,
+                                         EncryptionLevel level) {
+    QuicPacketHeader header;
+    if (peer_framer_.version().HasIetfInvariantHeader() &&
+        level < ENCRYPTION_FORWARD_SECURE) {
+      // Set long header type accordingly.
+      header.version_flag = true;
+      header.form = IETF_QUIC_LONG_HEADER_PACKET;
+      header.long_packet_type = EncryptionlevelToLongHeaderType(level);
+      if (QuicVersionHasLongHeaderLengths(
+              peer_framer_.version().transport_version)) {
+        header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+        if (header.long_packet_type == INITIAL) {
+          header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+        }
+      }
+    }
+    // Set connection_id to peer's in memory representation as this data packet
+    // is created by peer_framer.
+    if (peer_framer_.perspective() == Perspective::IS_SERVER) {
+      header.source_connection_id = connection_id_;
+      header.source_connection_id_included = connection_id_included_;
+      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+    } else {
+      header.destination_connection_id = connection_id_;
+      header.destination_connection_id_included = connection_id_included_;
+    }
+    if (peer_framer_.version().HasIetfInvariantHeader() &&
+        peer_framer_.perspective() == Perspective::IS_SERVER) {
+      if (!connection_.client_connection_id().IsEmpty()) {
+        header.destination_connection_id = connection_.client_connection_id();
+        header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+      } else {
+        header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+      }
+      if (header.version_flag) {
+        header.source_connection_id = connection_id_;
+        header.source_connection_id_included = CONNECTION_ID_PRESENT;
+        if (GetParam().version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
+            header.long_packet_type == ZERO_RTT_PROTECTED) {
+          header.nonce = &kTestDiversificationNonce;
+        }
+      }
+    }
+    header.packet_number_length = packet_number_length_;
+    header.packet_number = QuicPacketNumber(number);
+    return header;
+  }
+
+  std::unique_ptr<QuicPacket> ConstructDataPacket(uint64_t number,
+                                                  bool has_stop_waiting,
+                                                  EncryptionLevel level) {
+    QuicPacketHeader header = ConstructPacketHeader(number, level);
+    QuicFrames frames;
+    if (VersionHasIetfQuicFrames(version().transport_version) &&
+        (level == ENCRYPTION_INITIAL || level == ENCRYPTION_HANDSHAKE)) {
+      frames.push_back(QuicFrame(QuicPingFrame()));
+      frames.push_back(QuicFrame(QuicPaddingFrame(100)));
+    } else {
+      frames.push_back(QuicFrame(frame1_));
+      if (has_stop_waiting) {
+        frames.push_back(QuicFrame(stop_waiting_));
+      }
+    }
+    return ConstructPacket(header, frames);
+  }
+
+  std::unique_ptr<SerializedPacket> ConstructProbingPacket() {
+    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+    if (VersionHasIetfQuicFrames(version().transport_version)) {
+      QuicPathFrameBuffer payload = {
+          {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
+      return QuicPacketCreatorPeer::
+          SerializePathChallengeConnectivityProbingPacket(&peer_creator_,
+                                                          payload);
+    }
+    return QuicPacketCreatorPeer::SerializeConnectivityProbingPacket(
+        &peer_creator_);
+  }
+
+  std::unique_ptr<QuicPacket> ConstructClosePacket(uint64_t number) {
+    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+    QuicPacketHeader header;
+    // Set connection_id to peer's in memory representation as this connection
+    // close packet is created by peer_framer.
+    if (peer_framer_.perspective() == Perspective::IS_SERVER) {
+      header.source_connection_id = connection_id_;
+      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+      if (!peer_framer_.version().HasIetfInvariantHeader()) {
+        header.source_connection_id_included = CONNECTION_ID_PRESENT;
+      }
+    } else {
+      header.destination_connection_id = connection_id_;
+      if (peer_framer_.version().HasIetfInvariantHeader()) {
+        header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+      }
+    }
+
+    header.packet_number = QuicPacketNumber(number);
+
+    QuicErrorCode kQuicErrorCode = QUIC_PEER_GOING_AWAY;
+    QuicConnectionCloseFrame qccf(peer_framer_.transport_version(),
+                                  kQuicErrorCode, NO_IETF_QUIC_ERROR, "",
+                                  /*transport_close_frame_type=*/0);
+    QuicFrames frames;
+    frames.push_back(QuicFrame(&qccf));
+    return ConstructPacket(header, frames);
+  }
+
+  QuicTime::Delta DefaultRetransmissionTime() {
+    return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
+  }
+
+  QuicTime::Delta DefaultDelayedAckTime() {
+    return QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  }
+
+  const QuicStopWaitingFrame InitStopWaitingFrame(uint64_t least_unacked) {
+    QuicStopWaitingFrame frame;
+    frame.least_unacked = QuicPacketNumber(least_unacked);
+    return frame;
+  }
+
+  // Construct a ack_frame that acks all packet numbers between 1 and
+  // |largest_acked|, except |missing|.
+  // REQUIRES: 1 <= |missing| < |largest_acked|
+  QuicAckFrame ConstructAckFrame(uint64_t largest_acked, uint64_t missing) {
+    return ConstructAckFrame(QuicPacketNumber(largest_acked),
+                             QuicPacketNumber(missing));
+  }
+
+  QuicAckFrame ConstructAckFrame(QuicPacketNumber largest_acked,
+                                 QuicPacketNumber missing) {
+    if (missing == QuicPacketNumber(1)) {
+      return InitAckFrame({{missing + 1, largest_acked + 1}});
+    }
+    return InitAckFrame(
+        {{QuicPacketNumber(1), missing}, {missing + 1, largest_acked + 1}});
+  }
+
+  // Undo nacking a packet within the frame.
+  void AckPacket(QuicPacketNumber arrived, QuicAckFrame* frame) {
+    EXPECT_FALSE(frame->packets.Contains(arrived));
+    frame->packets.Add(arrived);
+  }
+
+  void TriggerConnectionClose() {
+    // Send an erroneous packet to close the connection.
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+
+    EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+    // Triggers a connection by receiving ACK of unsent packet.
+    QuicAckFrame frame = InitAckFrame(10000);
+    ProcessAckPacket(1, &frame);
+    EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
+                 nullptr);
+    EXPECT_EQ(1, connection_close_frame_count_);
+    EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+                IsError(QUIC_INVALID_ACK_DATA));
+  }
+
+  void BlockOnNextWrite() {
+    writer_->BlockOnNextWrite();
+    EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  }
+
+  void SimulateNextPacketTooLarge() { writer_->SimulateNextPacketTooLarge(); }
+
+  void AlwaysGetPacketTooLarge() { writer_->AlwaysGetPacketTooLarge(); }
+
+  void SetWritePauseTimeDelta(QuicTime::Delta delta) {
+    writer_->SetWritePauseTimeDelta(delta);
+  }
+
+  void CongestionBlockWrites() {
+    EXPECT_CALL(*send_algorithm_, CanSend(_))
+        .WillRepeatedly(testing::Return(false));
+  }
+
+  void CongestionUnblockWrites() {
+    EXPECT_CALL(*send_algorithm_, CanSend(_))
+        .WillRepeatedly(testing::Return(true));
+  }
+
+  void set_perspective(Perspective perspective) {
+    connection_.set_perspective(perspective);
+    if (perspective == Perspective::IS_SERVER) {
+      QuicConfig config;
+      if (!GetQuicReloadableFlag(
+              quic_remove_connection_migration_connection_option)) {
+        QuicTagVector connection_options;
+        connection_options.push_back(kRVCM);
+        config.SetInitialReceivedConnectionOptions(connection_options);
+      }
+      EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+      connection_.SetFromConfig(config);
+
+      connection_.set_can_truncate_connection_ids(true);
+      QuicConnectionPeer::SetNegotiatedVersion(&connection_);
+      connection_.OnSuccessfulVersionNegotiation();
+    }
+    QuicFramerPeer::SetPerspective(&peer_framer_,
+                                   QuicUtils::InvertPerspective(perspective));
+    peer_framer_.SetInitialObfuscators(TestConnectionId());
+    for (EncryptionLevel level : {ENCRYPTION_ZERO_RTT, ENCRYPTION_HANDSHAKE,
+                                  ENCRYPTION_FORWARD_SECURE}) {
+      if (peer_framer_.HasEncrypterOfEncryptionLevel(level)) {
+        peer_creator_.SetEncrypter(
+            level, std::make_unique<NullEncrypter>(peer_framer_.perspective()));
+      }
+    }
+  }
+
+  void set_packets_between_probes_base(
+      const QuicPacketCount packets_between_probes_base) {
+    QuicConnectionPeer::ReInitializeMtuDiscoverer(
+        &connection_, packets_between_probes_base,
+        QuicPacketNumber(packets_between_probes_base));
+  }
+
+  bool IsDefaultTestConfiguration() {
+    TestParams p = GetParam();
+    return p.ack_response == AckResponse::kImmediate &&
+           p.version == AllSupportedVersions()[0] && p.no_stop_waiting;
+  }
+
+  void TestConnectionCloseQuicErrorCode(QuicErrorCode expected_code) {
+    // Not strictly needed for this test, but is commonly done.
+    EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
+                 nullptr);
+    const std::vector<QuicConnectionCloseFrame>& connection_close_frames =
+        writer_->connection_close_frames();
+    ASSERT_EQ(1u, connection_close_frames.size());
+
+    EXPECT_THAT(connection_close_frames[0].quic_error_code,
+                IsError(expected_code));
+
+    if (!VersionHasIetfQuicFrames(version().transport_version)) {
+      EXPECT_THAT(connection_close_frames[0].wire_error_code,
+                  IsError(expected_code));
+      EXPECT_EQ(GOOGLE_QUIC_CONNECTION_CLOSE,
+                connection_close_frames[0].close_type);
+      return;
+    }
+
+    QuicErrorCodeToIetfMapping mapping =
+        QuicErrorCodeToTransportErrorCode(expected_code);
+
+    if (mapping.is_transport_close) {
+      // This Google QUIC Error Code maps to a transport close,
+      EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE,
+                connection_close_frames[0].close_type);
+    } else {
+      // This maps to an application close.
+      EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
+                connection_close_frames[0].close_type);
+    }
+    EXPECT_EQ(mapping.error_code, connection_close_frames[0].wire_error_code);
+  }
+
+  void MtuDiscoveryTestInit() {
+    set_perspective(Perspective::IS_SERVER);
+    QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+    if (version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(&connection_);
+    }
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+    // QuicFramer::GetMaxPlaintextSize uses the smallest max plaintext size
+    // across all encrypters. The initial encrypter used with IETF QUIC has a
+    // 16-byte overhead, while the NullEncrypter used throughout this test has a
+    // 12-byte overhead. This test tests behavior that relies on computing the
+    // packet size correctly, so by unsetting the initial encrypter, we avoid
+    // having a mismatch between the overheads for the encrypters used. In
+    // non-test scenarios all encrypters used for a given connection have the
+    // same overhead, either 12 bytes for ones using Google QUIC crypto, or 16
+    // bytes for ones using TLS.
+    connection_.SetEncrypter(ENCRYPTION_INITIAL, nullptr);
+    // Prevent packets from being coalesced.
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+    EXPECT_TRUE(connection_.connected());
+  }
+
+  void PathProbeTestInit(Perspective perspective,
+                         bool receive_new_server_connection_id = true) {
+    set_perspective(perspective);
+    connection_.CreateConnectionIdManager();
+    EXPECT_EQ(connection_.perspective(), perspective);
+    if (perspective == Perspective::IS_SERVER) {
+      QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+    }
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+    // Discard INITIAL key.
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+    // Prevent packets from being coalesced.
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+    if (version().SupportsAntiAmplificationLimit() &&
+        perspective == Perspective::IS_SERVER) {
+      QuicConnectionPeer::SetAddressValidated(&connection_);
+    }
+    // Clear direct_peer_address.
+    QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+    // Clear effective_peer_address, it is the same as direct_peer_address for
+    // this test.
+    QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                                QuicSocketAddress());
+    EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+    } else {
+      EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+    }
+    QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
+    ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                    kPeerAddress, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(kPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+    if (perspective == Perspective::IS_CLIENT &&
+        receive_new_server_connection_id && version().HasIetfQuicFrames()) {
+      QuicNewConnectionIdFrame frame;
+      frame.connection_id = TestConnectionId(1234);
+      ASSERT_NE(frame.connection_id, connection_.connection_id());
+      frame.stateless_reset_token =
+          QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+      frame.retire_prior_to = 0u;
+      frame.sequence_number = 1u;
+      connection_.OnNewConnectionIdFrame(frame);
+    }
+  }
+
+  void TestClientRetryHandling(bool invalid_retry_tag,
+                               bool missing_original_id_in_config,
+                               bool wrong_original_id_in_config,
+                               bool missing_retry_id_in_config,
+                               bool wrong_retry_id_in_config);
+
+  void TestReplaceConnectionIdFromInitial();
+
+  QuicConnectionId connection_id_;
+  QuicFramer framer_;
+
+  MockSendAlgorithm* send_algorithm_;
+  std::unique_ptr<MockLossAlgorithm> loss_algorithm_;
+  MockClock clock_;
+  MockRandom random_generator_;
+  quiche::SimpleBufferAllocator buffer_allocator_;
+  std::unique_ptr<TestConnectionHelper> helper_;
+  std::unique_ptr<TestAlarmFactory> alarm_factory_;
+  QuicFramer peer_framer_;
+  QuicPacketCreator peer_creator_;
+  std::unique_ptr<TestPacketWriter> writer_;
+  TestConnection connection_;
+  QuicPacketCreator* creator_;
+  QuicSentPacketManager* manager_;
+  StrictMock<MockQuicConnectionVisitor> visitor_;
+
+  QuicStreamFrame frame1_;
+  QuicStreamFrame frame2_;
+  QuicCryptoFrame crypto_frame_;
+  QuicAckFrame ack_;
+  QuicStopWaitingFrame stop_waiting_;
+  QuicPacketNumberLength packet_number_length_;
+  QuicConnectionIdIncluded connection_id_included_;
+
+  SimpleSessionNotifier notifier_;
+
+  QuicConnectionCloseFrame saved_connection_close_frame_;
+  int connection_close_frame_count_;
+};
+
+// Run all end to end tests with all supported versions.
+INSTANTIATE_TEST_SUITE_P(QuicConnectionTests, QuicConnectionTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+// These two tests ensure that the QuicErrorCode mapping works correctly.
+// Both tests expect to see a Google QUIC close if not running IETF QUIC.
+// If running IETF QUIC, the first will generate a transport connection
+// close, the second an application connection close.
+// The connection close codes for the two tests are manually chosen;
+// they are expected to always map to transport- and application-
+// closes, respectively. If that changes, new codes should be chosen.
+TEST_P(QuicConnectionTest, CloseErrorCodeTestTransport) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.CloseConnection(
+      IETF_QUIC_PROTOCOL_VIOLATION, "Should be transport close",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+}
+
+// Test that the IETF QUIC Error code mapping function works
+// properly for application connection close codes.
+TEST_P(QuicConnectionTest, CloseErrorCodeTestApplication) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.CloseConnection(
+      QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
+      "Should be application close",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE);
+}
+
+TEST_P(QuicConnectionTest, SelfAddressChangeAtClient) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  EXPECT_TRUE(connection_.connected());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_));
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_));
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  // Cause change in self_address.
+  QuicIpAddress host;
+  host.FromString("1.1.1.1");
+  QuicSocketAddress self_address(host, 123);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_));
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_));
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, SelfAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  EXPECT_TRUE(connection_.connected());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_));
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_));
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  // Cause change in self_address.
+  QuicIpAddress host;
+  host.FromString("1.1.1.1");
+  QuicSocketAddress self_address(host, 123);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  EXPECT_CALL(visitor_, AllowSelfAddressChange()).WillOnce(Return(false));
+  if (GetQuicReloadableFlag(quic_drop_packets_with_changed_server_address)) {
+    ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address,
+                                    kPeerAddress, ENCRYPTION_INITIAL);
+    EXPECT_TRUE(connection_.connected());
+    EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
+    return;
+  }
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  EXPECT_QUIC_PEER_BUG(
+      ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address,
+                                      kPeerAddress, ENCRYPTION_INITIAL),
+      "Self address migration is not supported at the server");
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_ERROR_MIGRATING_ADDRESS);
+  EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
+}
+
+TEST_P(QuicConnectionTest, AllowSelfAddressChangeToMappedIpv4AddressAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  EXPECT_TRUE(connection_.connected());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(3);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
+  }
+  QuicIpAddress host;
+  host.FromString("1.1.1.1");
+  QuicSocketAddress self_address1(host, 443);
+  connection_.SetSelfAddress(self_address1);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1,
+                                  kPeerAddress, ENCRYPTION_INITIAL);
+  // Cause self_address change to mapped Ipv4 address.
+  QuicIpAddress host2;
+  host2.FromString(
+      absl::StrCat("::ffff:", connection_.self_address().host().ToString()));
+  QuicSocketAddress self_address2(host2, connection_.self_address().port());
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address2,
+                                  kPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.connected());
+  // self_address change back to Ipv4 address.
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1,
+                                  kPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, ClientAddressChangeAndPacketReordered) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(),
+                        /*port=*/23456);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+
+  // Decrease packet number to simulate out-of-order packets.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
+  // This is an old packet, do not migrate.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, PeerPortChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Prevent packets from being coalesced.
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(manager_, 1);
+  EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(manager_, 2);
+  EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  // PORT_CHANGE shouldn't state change in sent packet manager.
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
+  EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+  EXPECT_EQ(manager_->GetSendAlgorithm(), send_algorithm_);
+  if (connection_.validate_client_address()) {
+    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+    EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+  }
+}
+
+TEST_P(QuicConnectionTest, PeerIpAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.validate_client_address()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  // Prevent packets from being coalesced.
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  connection_.OnHandshakeComplete();
+
+  // Enable 5 RTO
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k5RTO);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
+                                                  connection_.connection_id());
+  QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
+                                                       QuicConnectionId());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Send some data to make connection has packets in flight.
+  connection_.SendStreamData3();
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(0);
+  // Do not propagate OnCanWrite() to session notifier.
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(AtLeast(1u));
+
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+  EXPECT_FALSE(writer_->path_challenge_frames().empty());
+  QuicPathFrameBuffer payload =
+      writer_->path_challenge_frames().front().data_buffer;
+  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+  // Switch to use the mock send algorithm.
+  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
+  connection_.SetSendAlgorithm(send_algorithm_);
+
+  // PATH_CHALLENGE is expanded upto the max packet size which may exceeds the
+  // anti-amplification limit.
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(1u,
+            connection_.GetStats().num_reverse_path_validtion_upon_migration);
+
+  // Verify server is throttled by anti-amplification limit.
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receiving an ACK to the packet sent after changing peer address doesn't
+  // finish migration validation.
+  QuicAckFrame ack_frame = InitAckFrame(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+
+  // Receiving PATH_RESPONSE should lift the anti-amplification limit.
+  QuicFrames frames3;
+  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+  EXPECT_CALL(visitor_, MaybeSendAddressToken());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(testing::AtLeast(1u));
+  ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+
+  // Verify the anti-amplification limit is lifted by sending a packet larger
+  // than the anti-amplification limit.
+  connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
+  EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+}
+
+TEST_P(QuicConnectionTest, PeerIpAddressChangeAtServerWithMissingConnectionId) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+
+  QuicConnectionId client_cid0 = TestConnectionId(1);
+  QuicConnectionId client_cid1 = TestConnectionId(3);
+  QuicConnectionId server_cid1;
+  SetClientConnectionId(client_cid0);
+  connection_.CreateConnectionIdManager();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Prevent packets from being coalesced.
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+
+  // Sends new server CID to client.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(
+          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.OnHandshakeComplete();
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Send some data to make connection has packets in flight.
+  connection_.SendStreamData3();
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  peer_creator_.SetServerConnectionId(server_cid1);
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // Do not propagate OnCanWrite() to session notifier.
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(AtLeast(1u));
+
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+
+  // Writing path response & reverse path challenge is blocked due to missing
+  // client connection ID, i.e., packets_write_attempts is unchanged.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Receives new client CID from client would unblock write.
+  QuicNewConnectionIdFrame new_cid_frame;
+  new_cid_frame.connection_id = client_cid1;
+  new_cid_frame.sequence_number = 1u;
+  new_cid_frame.retire_prior_to = 0u;
+  connection_.OnNewConnectionIdFrame(new_cid_frame);
+  connection_.SendStreamData3();
+
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is different from direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  const QuicSocketAddress kEffectivePeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/43210);
+  connection_.ReturnEffectivePeerAddressForNextPacket(kEffectivePeerAddress);
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kEffectivePeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with the same direct peer address and different
+  // effective peer address on server side will start connection migration.
+  const QuicSocketAddress kNewEffectivePeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/54321);
+  connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
+  if (connection_.validate_client_address()) {
+    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+    EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+  }
+
+  // Process another packet with a different direct peer address and the same
+  // effective peer address on server side will not start connection migration.
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+
+  if (!connection_.validate_client_address()) {
+    // ack_frame is used to complete the migration started by the last packet,
+    // we need to make sure a new migration does not start after the previous
+    // one is completed.
+    QuicAckFrame ack_frame = InitAckFrame(1);
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+    ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
+                                    kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
+    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+  }
+
+  // Process another packet with different direct peer address and different
+  // effective peer address on server side will start connection migration.
+  const QuicSocketAddress kNewerEffectivePeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/65432);
+  const QuicSocketAddress kFinalPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/34567);
+  connection_.ReturnEffectivePeerAddressForNextPacket(
+      kNewerEffectivePeerAddress);
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kFinalPeerAddress, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewerEffectivePeerAddress, connection_.effective_peer_address());
+  if (connection_.validate_client_address()) {
+    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+    EXPECT_EQ(send_algorithm_,
+              connection_.sent_packet_manager().GetSendAlgorithm());
+    EXPECT_EQ(2u, connection_.GetStats().num_validated_peer_migration);
+  }
+
+  // While the previous migration is ongoing, process another packet with the
+  // same direct peer address and different effective peer address on server
+  // side will start a new connection migration.
+  const QuicSocketAddress kNewestEffectivePeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/65430);
+  connection_.ReturnEffectivePeerAddressForNextPacket(
+      kNewestEffectivePeerAddress);
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  if (!connection_.validate_client_address()) {
+    EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(1);
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kFinalPeerAddress, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewestEffectivePeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  if (connection_.validate_client_address()) {
+    EXPECT_NE(send_algorithm_,
+              connection_.sent_packet_manager().GetSendAlgorithm());
+    EXPECT_EQ(kFinalPeerAddress, writer_->last_write_peer_address());
+    EXPECT_FALSE(writer_->path_challenge_frames().empty());
+    EXPECT_EQ(0u, connection_.GetStats()
+                      .num_peer_migration_while_validating_default_path);
+    EXPECT_TRUE(connection_.HasPendingPathValidation());
+  }
+}
+
+// Regression test for b/200020764.
+TEST_P(QuicConnectionTest, ConnectionMigrationWithPendingPaddingBytes) {
+  // TODO(haoyuewang) Move these test setup code to a common member function.
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  connection_.CreateConnectionIdManager();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicConnectionPeer::SetPeerAddress(&connection_, kPeerAddress);
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_, kPeerAddress);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+
+  // Sends new server CID to client.
+  QuicConnectionId new_cid;
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(Invoke([&](const QuicConnectionId& cid) { new_cid = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  packet_creator->FlushCurrentPacket();
+  packet_creator->AddPendingPadding(50u);
+  const QuicSocketAddress kPeerAddress3 =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/56789);
+  auto ack_frame = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  ProcessFramesPacketWithAddresses({QuicFrame(&ack_frame)}, kSelfAddress,
+                                   kPeerAddress3, ENCRYPTION_FORWARD_SECURE);
+  if (GetQuicReloadableFlag(
+          quic_flush_pending_frames_and_padding_bytes_on_migration)) {
+    // Any pending frames/padding should be flushed before default_path_ is
+    // temporarily reset.
+    ASSERT_EQ(connection_.self_address_on_default_path_while_sending_packet()
+                  .host()
+                  .address_family(),
+              IpAddressFamily::IP_V6);
+  } else {
+    ASSERT_EQ(connection_.self_address_on_default_path_while_sending_packet()
+                  .host()
+                  .address_family(),
+              IpAddressFamily::IP_UNSPEC);
+  }
+}
+
+// Regression test for b/196208556.
+TEST_P(QuicConnectionTest,
+       ReversePathValidationResponseReceivedFromUnexpectedPeerAddress) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  connection_.CreateConnectionIdManager();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicConnectionPeer::SetPeerAddress(&connection_, kPeerAddress);
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_, kPeerAddress);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Sends new server CID to client.
+  QuicConnectionId new_cid;
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(Invoke([&](const QuicConnectionId& cid) { new_cid = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  // Process a non-probing packet to migrate to path 2 and kick off reverse path
+  // validation.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  const QuicSocketAddress kPeerAddress2 =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  peer_creator_.SetServerConnectionId(new_cid);
+  ProcessFramesPacketWithAddresses({QuicFrame(QuicPingFrame())}, kSelfAddress,
+                                   kPeerAddress2, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(writer_->path_challenge_frames().empty());
+  QuicPathFrameBuffer reverse_path_challenge_payload =
+      writer_->path_challenge_frames().front().data_buffer;
+
+  // Receiveds a packet from path 3 with PATH_RESPONSE frame intended to
+  // validate path 2 and a non-probing frame.
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    const QuicSocketAddress kPeerAddress3 =
+        QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/56789);
+    auto ack_frame = InitAckFrame(1);
+    EXPECT_CALL(visitor_, OnConnectionMigration(IPV4_TO_IPV6_CHANGE)).Times(1);
+    EXPECT_CALL(visitor_, MaybeSendAddressToken()).WillOnce(Invoke([this]() {
+      connection_.SendControlFrame(
+          QuicFrame(new QuicNewTokenFrame(1, "new_token")));
+      return true;
+    }));
+    ProcessFramesPacketWithAddresses({QuicFrame(new QuicPathResponseFrame(
+                                          0, reverse_path_challenge_payload)),
+                                      QuicFrame(&ack_frame)},
+                                     kSelfAddress, kPeerAddress3,
+                                     ENCRYPTION_FORWARD_SECURE);
+  }
+}
+
+TEST_P(QuicConnectionTest, ReversePathValidationFailureAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  SetClientConnectionId(TestConnectionId(1));
+  connection_.CreateConnectionIdManager();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  // Prevent packets from being coalesced.
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+
+  QuicConnectionId client_cid0 = connection_.client_connection_id();
+  QuicConnectionId client_cid1 = TestConnectionId(2);
+  QuicConnectionId server_cid0 = connection_.connection_id();
+  QuicConnectionId server_cid1;
+  // Sends new server CID to client.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(
+          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.OnHandshakeComplete();
+  // Receives new client CID from client.
+  QuicNewConnectionIdFrame new_cid_frame;
+  new_cid_frame.connection_id = client_cid1;
+  new_cid_frame.sequence_number = 1u;
+  new_cid_frame.retire_prior_to = 0u;
+  connection_.OnNewConnectionIdFrame(new_cid_frame);
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+  ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(0);
+
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  QuicPaddingFrame padding;
+  frames2.push_back(QuicFrame(padding));
+  peer_creator_.SetServerConnectionId(server_cid1);
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  EXPECT_LT(0u, writer_->packets_write_attempts());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_EQ(default_path->client_connection_id, client_cid1);
+  EXPECT_EQ(default_path->server_connection_id, server_cid1);
+  EXPECT_EQ(alternative_path->client_connection_id, client_cid0);
+  EXPECT_EQ(alternative_path->server_connection_id, server_cid0);
+  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid1);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
+
+  for (size_t i = 0; i < QuicPathValidator::kMaxRetryTimes; ++i) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+    static_cast<TestAlarmFactory::TestAlarm*>(
+        QuicPathValidatorPeer::retry_timer(
+            QuicConnectionPeer::path_validator(&connection_)))
+        ->Fire();
+  }
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+
+  // Make sure anti-amplification limit is not reached.
+  ProcessFramesPacketWithAddresses(
+      {QuicFrame(QuicPingFrame()), QuicFrame(QuicPaddingFrame())}, kSelfAddress,
+      kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Advance the time so that the reverse path validation times out.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  static_cast<TestAlarmFactory::TestAlarm*>(
+      QuicPathValidatorPeer::retry_timer(
+          QuicConnectionPeer::path_validator(&connection_)))
+      ->Fire();
+  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Verify that default_path_ is reverted and alternative_path_ is cleared.
+  EXPECT_EQ(default_path->client_connection_id, client_cid0);
+  EXPECT_EQ(default_path->server_connection_id, server_cid0);
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/1u));
+  retire_peer_issued_cid_alarm->Fire();
+  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+}
+
+TEST_P(QuicConnectionTest, ReceivePathProbeWithNoAddressChangeAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  EXPECT_CALL(visitor_, OnPacketReceived(_, _, false)).Times(0);
+
+  // Process a padded PING packet with no peer address change on server side
+  // will be ignored. But a PATH CHALLENGE packet with no peer address change
+  // will be considered as path probing.
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
+
+  EXPECT_EQ(
+      num_probing_received + (GetParam().version.HasIetfQuicFrames() ? 1u : 0u),
+      connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+// Regression test for b/150161358.
+TEST_P(QuicConnectionTest, BufferedMtuPacketTooBig) {
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+  writer_->SetWriteBlocked();
+
+  // Send a MTU packet while blocked. It should be buffered.
+  connection_.SendMtuDiscoveryPacket(kMaxOutgoingPacketSize);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+
+  writer_->AlwaysGetPacketTooLarge();
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+}
+
+TEST_P(QuicConnectionTest, WriteOutOfOrderQueuedPackets) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  set_perspective(Perspective::IS_CLIENT);
+
+  BlockOnNextWrite();
+
+  QuicStreamId stream_id = 2;
+  connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
+
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  writer_->SetWritable();
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  connection_.OnCanWrite();
+}
+
+TEST_P(QuicConnectionTest, DiscardQueuedPacketsAfterConnectionClose) {
+  // Regression test for b/74073386.
+  {
+    InSequence seq;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AtLeast(1));
+    EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(AtLeast(1));
+  }
+
+  set_perspective(Perspective::IS_CLIENT);
+
+  writer_->SimulateNextPacketTooLarge();
+
+  // This packet write should fail, which should cause the connection to close
+  // after sending a connection close packet, then the failed packet should be
+  // queued.
+  connection_.SendStreamDataWithString(/*id=*/2, "foo", 0, NO_FIN);
+
+  EXPECT_FALSE(connection_.connected());
+  // No need to buffer packets.
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+
+  EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
+}
+
+class TestQuicPathValidationContext : public QuicPathValidationContext {
+ public:
+  TestQuicPathValidationContext(const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address,
+
+                                QuicPacketWriter* writer)
+      : QuicPathValidationContext(self_address, peer_address),
+        writer_(writer) {}
+
+  QuicPacketWriter* WriterToUse() override { return writer_; }
+
+ private:
+  QuicPacketWriter* writer_;
+};
+
+class TestValidationResultDelegate : public QuicPathValidator::ResultDelegate {
+ public:
+  TestValidationResultDelegate(QuicConnection* connection,
+                               const QuicSocketAddress& expected_self_address,
+                               const QuicSocketAddress& expected_peer_address,
+                               bool* success)
+      : QuicPathValidator::ResultDelegate(),
+        connection_(connection),
+        expected_self_address_(expected_self_address),
+        expected_peer_address_(expected_peer_address),
+        success_(success) {}
+  void OnPathValidationSuccess(
+      std::unique_ptr<QuicPathValidationContext> context) override {
+    EXPECT_EQ(expected_self_address_, context->self_address());
+    EXPECT_EQ(expected_peer_address_, context->peer_address());
+    *success_ = true;
+  }
+
+  void OnPathValidationFailure(
+      std::unique_ptr<QuicPathValidationContext> context) override {
+    EXPECT_EQ(expected_self_address_, context->self_address());
+    EXPECT_EQ(expected_peer_address_, context->peer_address());
+    if (connection_->perspective() == Perspective::IS_CLIENT) {
+      connection_->OnPathValidationFailureAtClient();
+    }
+    *success_ = false;
+  }
+
+ private:
+  QuicConnection* connection_;
+  QuicSocketAddress expected_self_address_;
+  QuicSocketAddress expected_peer_address_;
+  bool* success_;
+};
+
+// Receive a path probe request at the server side, i.e.,
+// in non-IETF version: receive a padded PING packet with a peer addess change;
+// in IETF version: receive a packet contains PATH CHALLENGE with peer address
+// change.
+TEST_P(QuicConnectionTest, ReceivePathProbingAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  QuicPathFrameBuffer payload;
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+    if (connection_.validate_client_address()) {
+      EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+          .Times(AtLeast(1u))
+          .WillOnce(Invoke([&]() {
+            EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+            EXPECT_EQ(1u, writer_->path_response_frames().size());
+            payload = writer_->path_challenge_frames().front().data_buffer;
+          }));
+    }
+  }
+  // Process a probing packet from a new peer address on server side
+  // is effectively receiving a connectivity probing.
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
+
+  EXPECT_EQ(num_probing_received + 1,
+            connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  if (GetParam().version.HasIetfQuicFrames() &&
+      connection_.use_path_validator() &&
+      GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately)) {
+    QuicByteCount bytes_sent =
+        QuicConnectionPeer::BytesSentOnAlternativePath(&connection_);
+    EXPECT_LT(0u, bytes_sent);
+    EXPECT_EQ(received->length(),
+              QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
+
+    // Receiving one more probing packet should update the bytes count.
+    probing_packet = ConstructProbingPacket();
+    received.reset(ConstructReceivedPacket(
+        QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                            probing_packet->encrypted_length),
+        clock_.Now()));
+    ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
+
+    EXPECT_EQ(num_probing_received + 2,
+              connection_.GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(2 * bytes_sent,
+              QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
+    EXPECT_EQ(2 * received->length(),
+              QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
+
+    bool success = false;
+    if (!connection_.validate_client_address()) {
+      EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+          .Times(AtLeast(1u))
+          .WillOnce(Invoke([&]() {
+            EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+            payload = writer_->path_challenge_frames().front().data_buffer;
+          }));
+
+      connection_.ValidatePath(
+          std::make_unique<TestQuicPathValidationContext>(
+              connection_.self_address(), kNewPeerAddress, writer_.get()),
+          std::make_unique<TestValidationResultDelegate>(
+              &connection_, connection_.self_address(), kNewPeerAddress,
+              &success));
+    }
+    EXPECT_EQ((connection_.validate_client_address() ? 2 : 3) * bytes_sent,
+              QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
+    QuicFrames frames;
+    frames.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+    ProcessFramesPacketWithAddresses(frames, connection_.self_address(),
+                                     kNewPeerAddress,
+                                     ENCRYPTION_FORWARD_SECURE);
+    EXPECT_LT(2 * received->length(),
+              QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
+    if (connection_.validate_client_address()) {
+      EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
+    }
+    // Receiving another probing packet from a newer address with a different
+    // port shouldn't trigger another reverse path validation.
+    QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
+                                        /*port=*/34567);
+    probing_packet = ConstructProbingPacket();
+    received.reset(ConstructReceivedPacket(
+        QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                            probing_packet->encrypted_length),
+        clock_.Now()));
+    ProcessReceivedPacket(kSelfAddress, kNewerPeerAddress, *received);
+    EXPECT_FALSE(connection_.HasPendingPathValidation());
+    EXPECT_EQ(connection_.validate_client_address(),
+              QuicConnectionPeer::IsAlternativePathValidated(&connection_));
+  }
+
+  // Process another packet with the old peer address on server side will not
+  // start peer migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+// Receive a padded PING packet with a port change on server side.
+TEST_P(QuicConnectionTest, ReceivePaddedPingWithPortChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  if (GetParam().version.UsesCryptoFrames()) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  if (GetParam().version.HasIetfQuicFrames()) {
+    // In IETF version, a padded PING packet with port change is not taken as
+    // connectivity probe.
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+    EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+  } else {
+    // In non-IETF version, process a padded PING packet from a new peer
+    // address on server side is effectively receiving a connectivity probing.
+    EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  }
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+  QuicFrames frames;
+  // Write a PING frame, which has no data payload.
+  QuicPingFrame ping_frame;
+  frames.push_back(QuicFrame(ping_frame));
+
+  // Add padding to the rest of the packet.
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(padding_frame));
+
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_INITIAL);
+
+  if (GetParam().version.HasIetfQuicFrames()) {
+    // Padded PING with port changen is not considered as connectivity probe but
+    // a PORT CHANGE.
+    EXPECT_EQ(num_probing_received,
+              connection_.GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  } else {
+    EXPECT_EQ(num_probing_received + 1,
+              connection_.GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(kPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  }
+
+  if (GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  }
+  // Process another packet with the old peer address on server side. gQUIC
+  // shouldn't regard this as a peer migration.
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, ReceiveReorderedPathProbingAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  // Decrease packet number to simulate out-of-order packets.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+  }
+
+  // Process a padded PING packet from a new peer address on server side
+  // is effectively receiving a connectivity probing, even if a newer packet has
+  // been received before this one.
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
+
+  EXPECT_EQ(num_probing_received + 1,
+            connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+  }
+
+  // Process a padded PING packet from a new peer address on server side
+  // is effectively receiving a connectivity probing.
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another non-probing packet with the new peer address on server
+  // side will start peer migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, ReceiveConnectivityProbingPacketAtClient) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  // Client takes all padded PING packet as speculative connectivity
+  // probing packet, and reports to visitor.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
+
+  EXPECT_EQ(
+      num_probing_received + (GetParam().version.HasIetfQuicFrames() ? 1u : 0u),
+      connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, ReceiveConnectivityProbingResponseAtClient) {
+  // TODO(b/150095484): add test coverage for IETF to verify that client takes
+  // PATH RESPONSE with peer address change as correct validation on the new
+  // path.
+  if (GetParam().version.HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  // Process a padded PING packet with a different self address on client side
+  // is effectively receiving a connectivity probing.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+  }
+
+  const QuicSocketAddress kNewSelfAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
+
+  EXPECT_EQ(num_probing_received + 1,
+            connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, PeerAddressChangeAtClient) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  set_perspective(Perspective::IS_CLIENT);
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with a different peer address on client side will
+  // only update peer address.
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_INITIAL);
+  if (connection_.version().HasIetfQuicFrames()) {
+    // IETF QUIC disallows server initiated address change.
+    EXPECT_EQ(kPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  } else {
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  }
+}
+
+TEST_P(QuicConnectionTest, MaxPacketSize) {
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  EXPECT_EQ(1250u, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, PeerLowersMaxPacketSize) {
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  constexpr uint32_t kTestMaxPacketSize = 1233u;
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMaxPacketSize(&config, kTestMaxPacketSize);
+  connection_.SetFromConfig(config);
+
+  EXPECT_EQ(kTestMaxPacketSize, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, PeerCannotRaiseMaxPacketSize) {
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  constexpr uint32_t kTestMaxPacketSize = 1450u;
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMaxPacketSize(&config, kTestMaxPacketSize);
+  connection_.SetFromConfig(config);
+
+  EXPECT_EQ(kDefaultMaxPacketSize, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, SmallerServerMaxPacketSize) {
+  TestConnection connection(TestConnectionId(), kSelfAddress, kPeerAddress,
+                            helper_.get(), alarm_factory_.get(), writer_.get(),
+                            Perspective::IS_SERVER, version());
+  EXPECT_EQ(Perspective::IS_SERVER, connection.perspective());
+  EXPECT_EQ(1000u, connection.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, LowerServerResponseMtuTest) {
+  set_perspective(Perspective::IS_SERVER);
+  connection_.SetMaxPacketLength(1000);
+  EXPECT_EQ(1000u, connection_.max_packet_length());
+
+  SetQuicFlag(FLAGS_quic_use_lower_server_response_mtu_for_test, true);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(::testing::AtMost(1));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(::testing::AtMost(1));
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_EQ(1250u, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSize) {
+  set_perspective(Perspective::IS_SERVER);
+  connection_.SetMaxPacketLength(1000);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = connection_id_;
+  header.version_flag = true;
+  header.packet_number = QuicPacketNumber(12);
+
+  if (QuicVersionHasLongHeaderLengths(
+          peer_framer_.version().transport_version)) {
+    header.long_packet_type = INITIAL;
+    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicFrames frames;
+  QuicPaddingFrame padding;
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    frames.push_back(QuicFrame(&crypto_frame_));
+  } else {
+    frames.push_back(QuicFrame(frame1_));
+  }
+  frames.push_back(QuicFrame(padding));
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(12),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
+
+  framer_.set_version(version());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.ApproximateNow(),
+                         false));
+
+  EXPECT_EQ(kMaxOutgoingPacketSize, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSizeWhileWriterLimited) {
+  const QuicByteCount lower_max_packet_size = 1240;
+  writer_->set_max_packet_size(lower_max_packet_size);
+  set_perspective(Perspective::IS_SERVER);
+  connection_.SetMaxPacketLength(1000);
+  EXPECT_EQ(1000u, connection_.max_packet_length());
+
+  QuicPacketHeader header;
+  header.destination_connection_id = connection_id_;
+  header.version_flag = true;
+  header.packet_number = QuicPacketNumber(12);
+
+  if (QuicVersionHasLongHeaderLengths(
+          peer_framer_.version().transport_version)) {
+    header.long_packet_type = INITIAL;
+    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicFrames frames;
+  QuicPaddingFrame padding;
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    frames.push_back(QuicFrame(&crypto_frame_));
+  } else {
+    frames.push_back(QuicFrame(frame1_));
+  }
+  frames.push_back(QuicFrame(padding));
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(12),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
+
+  framer_.set_version(version());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.ApproximateNow(),
+                         false));
+
+  // Here, the limit imposed by the writer is lower than the size of the packet
+  // received, so the writer max packet size is used.
+  EXPECT_EQ(lower_max_packet_size, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriter) {
+  const QuicByteCount lower_max_packet_size = 1240;
+  writer_->set_max_packet_size(lower_max_packet_size);
+
+  static_assert(lower_max_packet_size < kDefaultMaxPacketSize,
+                "Default maximum packet size is too low");
+  connection_.SetMaxPacketLength(kDefaultMaxPacketSize);
+
+  EXPECT_EQ(lower_max_packet_size, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriterForNewConnection) {
+  const QuicConnectionId connection_id = TestConnectionId(17);
+  const QuicByteCount lower_max_packet_size = 1240;
+  writer_->set_max_packet_size(lower_max_packet_size);
+  TestConnection connection(connection_id, kSelfAddress, kPeerAddress,
+                            helper_.get(), alarm_factory_.get(), writer_.get(),
+                            Perspective::IS_CLIENT, version());
+  EXPECT_EQ(Perspective::IS_CLIENT, connection.perspective());
+  EXPECT_EQ(lower_max_packet_size, connection.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, PacketsInOrder) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(1);
+  EXPECT_EQ(QuicPacketNumber(1u), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+
+  ProcessPacket(2);
+  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+
+  ProcessPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+}
+
+TEST_P(QuicConnectionTest, PacketsOutOfOrder) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+
+  ProcessPacket(2);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_FALSE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+
+  ProcessPacket(1);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_FALSE(IsMissing(2));
+  EXPECT_FALSE(IsMissing(1));
+}
+
+TEST_P(QuicConnectionTest, DuplicatePacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+
+  // Send packet 3 again, but do not set the expectation that
+  // the visitor OnStreamFrame() will be called.
+  ProcessDataPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+}
+
+TEST_P(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+
+  ProcessPacket(2);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(1));
+
+  ProcessPacket(5);
+  EXPECT_EQ(QuicPacketNumber(5u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(1));
+  EXPECT_TRUE(IsMissing(4));
+
+  // Pretend at this point the client has gotten acks for 2 and 3 and 1 is a
+  // packet the peer will not retransmit.  It indicates this by sending 'least
+  // awaiting' is 4.  The connection should then realize 1 will not be
+  // retransmitted, and will remove it from the missing list.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessAckPacket(6, &frame);
+
+  // Force an ack to be sent.
+  SendAckPacketToPeer();
+  EXPECT_TRUE(IsMissing(4));
+}
+
+TEST_P(QuicConnectionTest, RejectUnencryptedStreamData) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration() ||
+      VersionHasIetfQuicFrames(version().transport_version)) {
+    return;
+  }
+
+  // Process an unencrypted packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_QUIC_PEER_BUG(ProcessDataPacketAtLevel(1, false, ENCRYPTION_INITIAL),
+                       "");
+  TestConnectionCloseQuicErrorCode(QUIC_UNENCRYPTED_STREAM_DATA);
+}
+
+TEST_P(QuicConnectionTest, OutOfOrderReceiptCausesAckSend) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(3);
+  // Should not cause an ack.
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+  ProcessPacket(2);
+  // Should ack immediately, since this fills the last hole.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  ProcessPacket(1);
+  // Should ack immediately, since this fills the last hole.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+
+  ProcessPacket(4);
+  // Should not cause an ack.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, OutOfOrderAckReceiptCausesNoAck) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+
+  QuicAckFrame ack1 = InitAckFrame(1);
+  QuicAckFrame ack2 = InitAckFrame(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged()).Times(1);
+  }
+  ProcessAckPacket(2, &ack2);
+  // Should ack immediately since we have missing packets.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged()).Times(0);
+  }
+  ProcessAckPacket(1, &ack1);
+  // Should not ack an ack filling a missing packet.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  QuicPacketNumber original, second;
+
+  QuicByteCount packet_size =
+      SendStreamDataToPeer(3, "foo", 0, NO_FIN, &original);  // 1st packet.
+  SendStreamDataToPeer(3, "bar", 3, NO_FIN, &second);        // 2nd packet.
+
+  QuicAckFrame frame = InitAckFrame({{second, second + 1}});
+  // First nack triggers early retransmit.
+  LostPacketVector lost_packets;
+  lost_packets.push_back(LostPacket(original, kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicPacketNumber retransmission;
+  // Packet 1 is short header for IETF QUIC because the encryption level
+  // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _,
+                           GetParam().version.HasIetfInvariantHeader()
+                               ? packet_size
+                               : packet_size - kQuicVersionSize,
+                           _))
+      .WillOnce(SaveArg<2>(&retransmission));
+
+  ProcessAckPacket(&frame);
+
+  QuicAckFrame frame2 = ConstructAckFrame(retransmission, original);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  ProcessAckPacket(&frame2);
+
+  // Now if the peer sends an ack which still reports the retransmitted packet
+  // as missing, that will bundle an ack with data after two acks in a row
+  // indicate the high water mark needs to be raised.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
+  connection_.SendStreamDataWithString(3, "foo", 6, NO_FIN);
+  // No ack sent.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+
+  // No more packet loss for the rest of the test.
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&frame2);
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
+  connection_.SendStreamDataWithString(3, "foofoofoo", 9, NO_FIN);
+  // Ack bundled.
+  if (GetParam().no_stop_waiting) {
+    // Do not ACK acks.
+    EXPECT_EQ(1u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+  }
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_TRUE(writer_->ack_frames().empty());
+  } else {
+    EXPECT_FALSE(writer_->ack_frames().empty());
+  }
+
+  // But an ack with no missing packets will not send an ack.
+  AckPacket(original, &frame2);
+  ProcessAckPacket(&frame2);
+  ProcessAckPacket(&frame2);
+}
+
+TEST_P(QuicConnectionTest, AckFrequencyUpdatedFromAckFrequencyFrame) {
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    return;
+  }
+  connection_.set_can_receive_ack_frequency_frame();
+
+  // Expect 13 acks, every 3rd packet including the first packet with
+  // AckFrequencyFrame.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(13);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicAckFrequencyFrame ack_frequency_frame;
+  ack_frequency_frame.packet_tolerance = 3;
+  ProcessFramePacketAtLevel(1, QuicFrame(&ack_frequency_frame),
+                            ENCRYPTION_FORWARD_SECURE);
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(38);
+  // Receives packets 2 - 39.
+  for (size_t i = 2; i <= 39; ++i) {
+    ProcessDataPacket(i);
+  }
+}
+
+TEST_P(QuicConnectionTest, AckDecimationReducesAcks) {
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
+
+  // Start ack decimation from 10th packet.
+  connection_.set_min_received_before_ack_decimation(10);
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(30);
+
+  // Expect 6 acks: 5 acks between packets 1-10, and ack at 20.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
+  // Receives packets 1 - 29.
+  for (size_t i = 1; i <= 29; ++i) {
+    ProcessDataPacket(i);
+  }
+
+  // We now receive the 30th packet, and so we send an ack.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessDataPacket(30);
+}
+
+TEST_P(QuicConnectionTest, AckNeedsRetransmittableFrames) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(99);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(19);
+  // Receives packets 1 - 39.
+  for (size_t i = 1; i <= 39; ++i) {
+    ProcessDataPacket(i);
+  }
+  // Receiving Packet 40 causes 20th ack to send. Session is informed and adds
+  // WINDOW_UPDATE.
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
+      .WillOnce(Invoke([this]() {
+        connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_EQ(0u, writer_->window_update_frames().size());
+  ProcessDataPacket(40);
+  EXPECT_EQ(1u, writer_->window_update_frames().size());
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(9);
+  // Receives packets 41 - 59.
+  for (size_t i = 41; i <= 59; ++i) {
+    ProcessDataPacket(i);
+  }
+  // Send a packet containing stream frame.
+  SendStreamDataToPeer(
+      QuicUtils::GetFirstBidirectionalStreamId(
+          connection_.version().transport_version, Perspective::IS_CLIENT),
+      "bar", 0, NO_FIN, nullptr);
+
+  // Session will not be informed until receiving another 20 packets.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(19);
+  for (size_t i = 60; i <= 98; ++i) {
+    ProcessDataPacket(i);
+    EXPECT_EQ(0u, writer_->window_update_frames().size());
+  }
+  // Session does not add a retransmittable frame.
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
+      .WillOnce(Invoke([this]() {
+        connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_EQ(0u, writer_->ping_frames().size());
+  ProcessDataPacket(99);
+  EXPECT_EQ(0u, writer_->window_update_frames().size());
+  // A ping frame will be added.
+  EXPECT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, AckNeedsRetransmittableFramesAfterPto) {
+  // Disable TLP so the RTO fires immediately.
+  connection_.SetMaxTailLossProbes(0);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kEACK);
+  config.SetConnectionOptionsToSend(connection_options);
+  connection_.SetFromConfig(config);
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.OnHandshakeComplete();
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(10);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(4);
+  // Receive packets 1 - 9.
+  for (size_t i = 1; i <= 9; ++i) {
+    ProcessDataPacket(i);
+  }
+
+  // Send a ping and fire the retransmission alarm.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  SendPing();
+  QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  connection_.GetRetransmissionAlarm()->Fire();
+  ASSERT_TRUE(manager_->GetConsecutiveRtoCount() > 0 ||
+              manager_->GetConsecutivePtoCount() > 0);
+
+  // Process a packet, which requests a retransmittable frame be bundled
+  // with the ACK.
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
+      .WillOnce(Invoke([this]() {
+        connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessDataPacket(11);
+  EXPECT_EQ(1u, writer_->window_update_frames().size());
+}
+
+TEST_P(QuicConnectionTest, LeastUnackedLower) {
+  if (GetParam().version.HasIetfInvariantHeader()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "eep", 6, NO_FIN, nullptr);
+
+  // Start out saying the least unacked is 2.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
+  ProcessStopWaitingPacket(InitStopWaitingFrame(2));
+
+  // Change it to 1, but lower the packet number to fake out-of-order packets.
+  // This should be fine.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
+  // The scheduler will not process out of order acks, but all packet processing
+  // causes the connection to try to write.
+  if (!GetParam().no_stop_waiting) {
+    EXPECT_CALL(visitor_, OnCanWrite());
+  }
+  ProcessStopWaitingPacket(InitStopWaitingFrame(1));
+
+  // Now claim it's one, but set the ordering so it was sent "after" the first
+  // one.  This should cause a connection error.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 7);
+  if (!GetParam().no_stop_waiting) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AtLeast(1));
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .Times(AtLeast(1));
+  }
+  ProcessStopWaitingPacket(InitStopWaitingFrame(1));
+  if (!GetParam().no_stop_waiting) {
+    TestConnectionCloseQuicErrorCode(QUIC_INVALID_STOP_WAITING_DATA);
+  }
+}
+
+TEST_P(QuicConnectionTest, TooManySentPackets) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicPacketCount max_tracked_packets = 50;
+  QuicConnectionPeer::SetMaxTrackedPackets(&connection_, max_tracked_packets);
+
+  const int num_packets = max_tracked_packets + 5;
+
+  for (int i = 0; i < num_packets; ++i) {
+    SendStreamDataToPeer(1, "foo", 3 * i, NO_FIN, nullptr);
+  }
+
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+
+  ProcessFramePacket(QuicFrame(QuicPingFrame()));
+
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS);
+}
+
+TEST_P(QuicConnectionTest, LargestObservedLower) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "eep", 6, NO_FIN, nullptr);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+
+  // Start out saying the largest observed is 2.
+  QuicAckFrame frame1 = InitAckFrame(1);
+  QuicAckFrame frame2 = InitAckFrame(2);
+  ProcessAckPacket(&frame2);
+
+  EXPECT_CALL(visitor_, OnCanWrite());
+  ProcessAckPacket(&frame1);
+}
+
+TEST_P(QuicConnectionTest, AckUnsentData) {
+  // Ack a packet which has not been sent.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(0);
+  ProcessAckPacket(&frame);
+  TestConnectionCloseQuicErrorCode(QUIC_INVALID_ACK_DATA);
+}
+
+TEST_P(QuicConnectionTest, BasicSending) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  const QuicConnectionStats& stats = connection_.GetStats();
+  EXPECT_FALSE(stats.first_decrypted_packet.IsInitialized());
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);  // Packet 1
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+  SendAckPacketToPeer();  // Packet 2
+
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
+  }
+
+  SendAckPacketToPeer();  // Packet 3
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
+  }
+
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, &last_packet);  // Packet 4
+  EXPECT_EQ(QuicPacketNumber(4u), last_packet);
+  SendAckPacketToPeer();  // Packet 5
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
+  }
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+
+  // Peer acks up to packet 3.
+  QuicAckFrame frame = InitAckFrame(3);
+  ProcessAckPacket(&frame);
+  SendAckPacketToPeer();  // Packet 6
+
+  // As soon as we've acked one, we skip ack packets 2 and 3 and note lack of
+  // ack for 4.
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
+  }
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+
+  // Peer acks up to packet 4, the last packet.
+  QuicAckFrame frame2 = InitAckFrame(6);
+  ProcessAckPacket(&frame2);  // Acks don't instigate acks.
+
+  // Verify that we did not send an ack.
+  EXPECT_EQ(QuicPacketNumber(6u), writer_->header().packet_number);
+
+  // So the last ack has not changed.
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
+  }
+
+  // If we force an ack, we shouldn't change our retransmit state.
+  SendAckPacketToPeer();  // Packet 7
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
+  }
+
+  // But if we send more data it should.
+  SendStreamDataToPeer(1, "eep", 6, NO_FIN, &last_packet);  // Packet 8
+  EXPECT_EQ(QuicPacketNumber(8u), last_packet);
+  SendAckPacketToPeer();  // Packet 9
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
+  }
+  EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
+}
+
+// QuicConnection should record the packet sent-time prior to sending the
+// packet.
+TEST_P(QuicConnectionTest, RecordSentTimeBeforePacketSent) {
+  // We're using a MockClock for the tests, so we have complete control over the
+  // time.
+  // Our recorded timestamp for the last packet sent time will be passed in to
+  // the send_algorithm.  Make sure that it is set to the correct value.
+  QuicTime actual_recorded_send_time = QuicTime::Zero();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<0>(&actual_recorded_send_time));
+
+  // First send without any pause and check the result.
+  QuicTime expected_recorded_send_time = clock_.Now();
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
+      << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
+      << ".  Actual time = " << actual_recorded_send_time.ToDebuggingValue();
+
+  // Now pause during the write, and check the results.
+  actual_recorded_send_time = QuicTime::Zero();
+  const QuicTime::Delta write_pause_time_delta =
+      QuicTime::Delta::FromMilliseconds(5000);
+  SetWritePauseTimeDelta(write_pause_time_delta);
+  expected_recorded_send_time = clock_.Now();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<0>(&actual_recorded_send_time));
+  connection_.SendStreamDataWithString(2, "baz", 0, NO_FIN);
+  EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
+      << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
+      << ".  Actual time = " << actual_recorded_send_time.ToDebuggingValue();
+}
+
+TEST_P(QuicConnectionTest, FramePacking) {
+  // Send two stream frames in 1 packet by queueing them.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendStreamData3();
+    connection_.SendStreamData5();
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  }
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it's an ack and two stream frames from
+  // two different streams.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  }
+
+  EXPECT_TRUE(writer_->ack_frames().empty());
+
+  ASSERT_EQ(2u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+  EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
+            writer_->stream_frames()[1]->stream_id);
+}
+
+TEST_P(QuicConnectionTest, FramePackingNonCryptoThenCrypto) {
+  // Send two stream frames (one non-crypto, then one crypto) in 2 packets by
+  // queueing them.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendStreamData3();
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoStreamData();
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  }
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it contains a crypto stream frame.
+  EXPECT_LE(2u, writer_->frame_count());
+  ASSERT_LE(1u, writer_->padding_frames().size());
+  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    ASSERT_EQ(1u, writer_->stream_frames().size());
+    EXPECT_EQ(QuicUtils::GetCryptoStreamId(connection_.transport_version()),
+              writer_->stream_frames()[0]->stream_id);
+  } else {
+    EXPECT_LE(1u, writer_->crypto_frames().size());
+  }
+}
+
+TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) {
+  // Send two stream frames (one crypto, then one non-crypto) in 2 packets by
+  // queueing them.
+  {
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendCryptoStreamData();
+    connection_.SendStreamData3();
+  }
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it's the stream frame from stream 3.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+}
+
+TEST_P(QuicConnectionTest, FramePackingAckResponse) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  // Process a data packet to queue up a pending ack.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  QuicPacketNumber last_packet;
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    connection_.SendCryptoDataWithString("foo", 0);
+  } else {
+    SendStreamDataToPeer(
+        QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
+        NO_FIN, &last_packet);
+  }
+  // Verify ack is bundled with outging packet.
+  EXPECT_FALSE(writer_->ack_frames().empty());
+
+  EXPECT_CALL(visitor_, OnCanWrite())
+      .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
+                          &connection_, &TestConnection::SendStreamData3)),
+                      IgnoreResult(InvokeWithoutArgs(
+                          &connection_, &TestConnection::SendStreamData5))));
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+
+  // Process a data packet to cause the visitor's OnCanWrite to be invoked.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  ProcessDataPacket(2);
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it's an ack and two stream frames from
+  // two different streams.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  ASSERT_EQ(2u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+  EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
+            writer_->stream_frames()[1]->stream_id);
+}
+
+TEST_P(QuicConnectionTest, FramePackingSendv) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.transport_version(), Perspective::IS_CLIENT);
+  connection_.SaveAndSendStreamData(stream_id, "ABCDEF", 0, NO_FIN);
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure multiple iovector blocks have
+  // been packed into a single stream frame from one stream.
+  EXPECT_EQ(1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(0u, writer_->padding_frames().size());
+  QuicStreamFrame* frame = writer_->stream_frames()[0].get();
+  EXPECT_EQ(stream_id, frame->stream_id);
+  EXPECT_EQ("ABCDEF",
+            absl::string_view(frame->data_buffer, frame->data_length));
+}
+
+TEST_P(QuicConnectionTest, FramePackingSendvQueued) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+
+  BlockOnNextWrite();
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.transport_version(), Perspective::IS_CLIENT);
+  connection_.SaveAndSendStreamData(stream_id, "ABCDEF", 0, NO_FIN);
+
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  EXPECT_TRUE(connection_.HasQueuedData());
+
+  // Unblock the writes and actually send.
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+
+  // Parse the last packet and ensure it's one stream frame from one stream.
+  EXPECT_EQ(1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(0u, writer_->padding_frames().size());
+  QuicStreamFrame* frame = writer_->stream_frames()[0].get();
+  EXPECT_EQ(stream_id, frame->stream_id);
+  EXPECT_EQ("ABCDEF",
+            absl::string_view(frame->data_buffer, frame->data_length));
+}
+
+TEST_P(QuicConnectionTest, SendingZeroBytes) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Send a zero byte write with a fin using writev.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.transport_version(), Perspective::IS_CLIENT);
+  connection_.SaveAndSendStreamData(stream_id, {}, 0, FIN);
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Padding frames are added by v99 to ensure a minimum packet size.
+  size_t extra_padding_frames = 0;
+  if (GetParam().version.HasHeaderProtection()) {
+    extra_padding_frames = 1;
+  }
+
+  // Parse the last packet and ensure it's one stream frame from one stream.
+  EXPECT_EQ(1u + extra_padding_frames, writer_->frame_count());
+  EXPECT_EQ(extra_padding_frames, writer_->padding_frames().size());
+  ASSERT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(stream_id, writer_->stream_frames()[0]->stream_id);
+  EXPECT_TRUE(writer_->stream_frames()[0]->fin);
+}
+
+TEST_P(QuicConnectionTest, LargeSendWithPendingAck) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  // Set the ack alarm by processing a ping frame.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Processs a PING frame.
+  ProcessFramePacket(QuicFrame(QuicPingFrame()));
+  // Ensure that this has caused the ACK alarm to be set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  // Send data and ensure the ack is bundled.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(9);
+  const std::string data(10000, '?');
+  QuicConsumedData consumed = connection_.SaveAndSendStreamData(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()), data,
+      0, FIN);
+  EXPECT_EQ(data.length(), consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it's one stream frame with a fin.
+  EXPECT_EQ(1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+  EXPECT_TRUE(writer_->stream_frames()[0]->fin);
+  // Ensure the ack alarm was cancelled when the ack was sent.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, OnCanWrite) {
+  // Visitor's OnCanWrite will send data, but will have more pending writes.
+  EXPECT_CALL(visitor_, OnCanWrite())
+      .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
+                          &connection_, &TestConnection::SendStreamData3)),
+                      IgnoreResult(InvokeWithoutArgs(
+                          &connection_, &TestConnection::SendStreamData5))));
+  {
+    InSequence seq;
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillOnce(Return(true));
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+        .WillRepeatedly(Return(false));
+  }
+
+  EXPECT_CALL(*send_algorithm_, CanSend(_))
+      .WillRepeatedly(testing::Return(true));
+
+  connection_.OnCanWrite();
+
+  // Parse the last packet and ensure it's the two stream frames from
+  // two different streams.
+  EXPECT_EQ(2u, writer_->frame_count());
+  EXPECT_EQ(2u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+  EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
+            writer_->stream_frames()[1]->stream_id);
+}
+
+TEST_P(QuicConnectionTest, RetransmitOnNack) {
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(3, "foos", 3, NO_FIN, &last_packet);
+  SendStreamDataToPeer(3, "fooos", 7, NO_FIN, &last_packet);
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Don't lose a packet on an ack, and nothing is retransmitted.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame ack_one = InitAckFrame(1);
+  ProcessAckPacket(&ack_one);
+
+  // Lose a packet and ensure it triggers retransmission.
+  QuicAckFrame nack_two = ConstructAckFrame(3, 2);
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_FALSE(QuicPacketCreatorPeer::SendVersionInPacket(creator_));
+  ProcessAckPacket(&nack_two);
+}
+
+TEST_P(QuicConnectionTest, DoNotSendQueuedPacketForResetStream) {
+  // Block the connection to queue the packet.
+  BlockOnNextWrite();
+
+  QuicStreamId stream_id = 2;
+  connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
+
+  // Now that there is a queued packet, reset the stream.
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Unblock the connection and verify that only the RST_STREAM is sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+}
+
+TEST_P(QuicConnectionTest, SendQueuedPacketForQuicRstStreamNoError) {
+  // Block the connection to queue the packet.
+  BlockOnNextWrite();
+
+  QuicStreamId stream_id = 2;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
+
+  // Now that there is a queued packet, reset the stream.
+  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 3);
+
+  // Unblock the connection and verify that the RST_STREAM is sent and the data
+  // packet is sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+}
+
+TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnNack) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "fooos", 7, NO_FIN, &last_packet);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 12);
+
+  // Lose a packet and ensure it does not trigger retransmission.
+  QuicAckFrame nack_two = ConstructAckFrame(last_packet, last_packet - 1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessAckPacket(&nack_two);
+}
+
+TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnNack) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "fooos", 7, NO_FIN, &last_packet);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 12);
+
+  // Lose a packet, ensure it triggers retransmission.
+  QuicAckFrame nack_two = ConstructAckFrame(last_packet, last_packet - 1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  LostPacketVector lost_packets;
+  lost_packets.push_back(LostPacket(last_packet - 1, kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ProcessAckPacket(&nack_two);
+}
+
+TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnRTO) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Fire the RTO and verify that the RST_STREAM is resent, not stream data.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  connection_.GetRetransmissionAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+  EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
+}
+
+// Ensure that if the only data in flight is non-retransmittable, the
+// retransmission alarm is not set.
+TEST_P(QuicConnectionTest, CancelRetransmissionAlarmAfterResetStream) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_data_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
+
+  // Cancel the stream.
+  const QuicPacketNumber rst_packet = last_data_packet + 1;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, rst_packet, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Ack the RST_STREAM frame (since it's retransmittable), but not the data
+  // packet, which is no longer retransmittable since the stream was cancelled.
+  QuicAckFrame nack_stream_data =
+      ConstructAckFrame(rst_packet, last_data_packet);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessAckPacket(&nack_stream_data);
+
+  // Ensure that the data is still in flight, but the retransmission alarm is no
+  // longer set.
+  EXPECT_GT(manager_->GetBytesInFlight(), 0u);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnRTO) {
+  connection_.SetMaxTailLossProbes(0);
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 3);
+
+  // Fire the RTO and verify that the RST_STREAM is resent, the stream data
+  // is sent.
+  const size_t num_retransmissions = connection_.PtoEnabled() ? 1 : 2;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(num_retransmissions));
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  connection_.GetRetransmissionAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  if (num_retransmissions == 2) {
+    ASSERT_EQ(1u, writer_->rst_stream_frames().size());
+    EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
+  }
+}
+
+TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(stream_id, "fooos", 7, NO_FIN);
+
+  // Lose a packet which will trigger a pending retransmission.
+  QuicAckFrame ack = ConstructAckFrame(last_packet, last_packet - 1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessAckPacket(&ack);
+
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 12);
+
+  // Unblock the connection and verify that the RST_STREAM is sent but not the
+  // second data packet nor a retransmit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->rst_stream_frames().size());
+  EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
+}
+
+TEST_P(QuicConnectionTest, SendPendingRetransmissionForQuicRstStreamNoError) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(stream_id, "fooos", 7, NO_FIN);
+
+  // Lose a packet which will trigger a pending retransmission.
+  QuicAckFrame ack = ConstructAckFrame(last_packet, last_packet - 1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  LostPacketVector lost_packets;
+  lost_packets.push_back(LostPacket(last_packet - 1, kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessAckPacket(&ack);
+
+  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 12);
+
+  // Unblock the connection and verify that the RST_STREAM is sent and the
+  // second data packet or a retransmit is sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(2));
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  // The RST_STREAM_FRAME is sent after queued packets and pending
+  // retransmission.
+  connection_.SendControlFrame(QuicFrame(
+      new QuicRstStreamFrame(1, stream_id, QUIC_STREAM_NO_ERROR, 14)));
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+}
+
+TEST_P(QuicConnectionTest, RetransmitAckedPacket) {
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);    // Packet 1
+  SendStreamDataToPeer(1, "foos", 3, NO_FIN, &last_packet);   // Packet 2
+  SendStreamDataToPeer(1, "fooos", 7, NO_FIN, &last_packet);  // Packet 3
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Instigate a loss with an ack.
+  QuicAckFrame nack_two = ConstructAckFrame(3, 2);
+  // The first nack should trigger a fast retransmission, but we'll be
+  // write blocked, so the packet will be queued.
+  BlockOnNextWrite();
+
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
+      .Times(1);
+  ProcessAckPacket(&nack_two);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Now, ack the previous transmission.
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(false, _, _, _, _));
+  QuicAckFrame ack_all = InitAckFrame(3);
+  ProcessAckPacket(&ack_all);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
+      .Times(0);
+
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  // We do not store retransmittable frames of this retransmission.
+  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, 4));
+}
+
+TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  QuicPacketNumber original, second;
+
+  QuicByteCount packet_size =
+      SendStreamDataToPeer(3, "foo", 0, NO_FIN, &original);  // 1st packet.
+  SendStreamDataToPeer(3, "bar", 3, NO_FIN, &second);        // 2nd packet.
+
+  QuicAckFrame frame = InitAckFrame({{second, second + 1}});
+  // The first nack should retransmit the largest observed packet.
+  LostPacketVector lost_packets;
+  lost_packets.push_back(LostPacket(original, kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  // Packet 1 is short header for IETF QUIC because the encryption level
+  // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _,
+                           GetParam().version.HasIetfInvariantHeader()
+                               ? packet_size
+                               : packet_size - kQuicVersionSize,
+                           _));
+  ProcessAckPacket(&frame);
+}
+
+TEST_P(QuicConnectionTest, QueueAfterTwoRTOs) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  for (int i = 0; i < 10; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendStreamDataWithString(3, "foo", i * 3, NO_FIN);
+  }
+
+  // Block the writer and ensure they're queued.
+  BlockOnNextWrite();
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_TRUE(connection_.HasQueuedData());
+
+  // Unblock the writer.
+  writer_->SetWritable();
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(
+      2 * DefaultRetransmissionTime().ToMicroseconds()));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.GetRetransmissionAlarm()->Fire();
+  connection_.OnCanWrite();
+}
+
+TEST_P(QuicConnectionTest, WriteBlockedBufferedThenSent) {
+  BlockOnNextWrite();
+  writer_->set_is_write_blocked_data_buffered(true);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, WriteBlockedThenSent) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  BlockOnNextWrite();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // The second packet should also be queued, in order to ensure packets are
+  // never sent out of order.
+  writer_->SetWritable();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(2u, connection_.NumQueuedPackets());
+
+  // Now both are sent in order when we unblock.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.OnCanWrite();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  BlockOnNextWrite();
+  writer_->set_is_write_blocked_data_buffered(true);
+  // Simulate the retransmission alarm firing.
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // Ack the sent packet before the callback returns, which happens in
+  // rare circumstances with write blocked sockets.
+  QuicAckFrame ack = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  uint64_t retransmission = connection_.PtoEnabled() ? 3 : 2;
+  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_,
+                                                            retransmission));
+}
+
+TEST_P(QuicConnectionTest, AlarmsWhenWriteBlocked) {
+  // Block the connection.
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+
+  // Set the send alarm. Fire the alarm and ensure it doesn't attempt to write.
+  connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
+  connection_.GetSendAlarm()->Fire();
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, NoSendAlarmAfterProcessPacketWhenWriteBlocked) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Block the connection.
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  // Process packet number 1. Can not call ProcessPacket or ProcessDataPacket
+  // here, because they will fire the alarm after QuicConnection::ProcessPacket
+  // is returned.
+  const uint64_t received_packet_num = 1;
+  const bool has_stop_waiting = false;
+  const EncryptionLevel level = ENCRYPTION_FORWARD_SECURE;
+  std::unique_ptr<QuicPacket> packet(
+      ConstructDataPacket(received_packet_num, has_stop_waiting, level));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(level, QuicPacketNumber(received_packet_num),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, AddToWriteBlockedListIfWriterBlockedWhenProcessing) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+
+  // Simulate the case where a shared writer gets blocked by another connection.
+  writer_->SetWriteBlocked();
+
+  // Process an ACK, make sure the connection calls visitor_->OnWriteBlocked().
+  QuicAckFrame ack1 = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+  ProcessAckPacket(1, &ack1);
+}
+
+TEST_P(QuicConnectionTest, DoNotAddToWriteBlockedListAfterDisconnect) {
+  writer_->SetBatchMode(true);
+  EXPECT_TRUE(connection_.connected());
+  // Have to explicitly grab the OnConnectionClosed frame and check
+  // its parameters because this is a silent connection close and the
+  // frame is not also transmitted to the peer.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
+                                ConnectionCloseBehavior::SILENT_CLOSE);
+
+    EXPECT_FALSE(connection_.connected());
+    writer_->SetWriteBlocked();
+  }
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PEER_GOING_AWAY));
+}
+
+TEST_P(QuicConnectionTest, AddToWriteBlockedListIfBlockedOnFlushPackets) {
+  writer_->SetBatchMode(true);
+  writer_->BlockOnNextFlush();
+
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // flusher's destructor will call connection_.FlushPackets, which should add
+    // the connection to the write blocked list.
+  }
+}
+
+TEST_P(QuicConnectionTest, NoLimitPacketsPerNack) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  int offset = 0;
+  // Send packets 1 to 15.
+  for (int i = 0; i < 15; ++i) {
+    SendStreamDataToPeer(1, "foo", offset, NO_FIN, nullptr);
+    offset += 3;
+  }
+
+  // Ack 15, nack 1-14.
+
+  QuicAckFrame nack =
+      InitAckFrame({{QuicPacketNumber(15), QuicPacketNumber(16)}});
+
+  // 14 packets have been NACK'd and lost.
+  LostPacketVector lost_packets;
+  for (int i = 1; i < 15; ++i) {
+    lost_packets.push_back(
+        LostPacket(QuicPacketNumber(i), kMaxOutgoingPacketSize));
+  }
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessAckPacket(&nack);
+}
+
+// Test sending multiple acks from the connection to the session.
+TEST_P(QuicConnectionTest, MultipleAcks) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);  // Packet 1
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);  // Packet 2
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
+  SendAckPacketToPeer();                                    // Packet 3
+  SendStreamDataToPeer(5, "foo", 0, NO_FIN, &last_packet);  // Packet 4
+  EXPECT_EQ(QuicPacketNumber(4u), last_packet);
+  SendStreamDataToPeer(1, "foo", 3, NO_FIN, &last_packet);  // Packet 5
+  EXPECT_EQ(QuicPacketNumber(5u), last_packet);
+  SendStreamDataToPeer(3, "foo", 3, NO_FIN, &last_packet);  // Packet 6
+  EXPECT_EQ(QuicPacketNumber(6u), last_packet);
+
+  // Client will ack packets 1, 2, [!3], 4, 5.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame1 = ConstructAckFrame(5, 3);
+  ProcessAckPacket(&frame1);
+
+  // Now the client implicitly acks 3, and explicitly acks 6.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame2 = InitAckFrame(6);
+  ProcessAckPacket(&frame2);
+}
+
+TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);  // Packet 1;
+  // From now on, we send acks, so the send algorithm won't mark them pending.
+  SendAckPacketToPeer();  // Packet 2
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame = InitAckFrame(1);
+  ProcessAckPacket(&frame);
+
+  // Verify that our internal state has least-unacked as 2, because we're still
+  // waiting for a potential ack for 2.
+
+  EXPECT_EQ(QuicPacketNumber(2u), stop_waiting()->least_unacked);
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame(2);
+  ProcessAckPacket(&frame);
+  EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
+
+  // When we send an ack, we make sure our least-unacked makes sense.  In this
+  // case since we're not waiting on an ack for 2 and all packets are acked, we
+  // set it to 3.
+  SendAckPacketToPeer();  // Packet 3
+  // Least_unacked remains at 3 until another ack is received.
+  EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    // Check that the outgoing ack had its packet number as least_unacked.
+    EXPECT_EQ(QuicPacketNumber(3u), least_unacked());
+  }
+
+  // Ack the ack, which updates the rtt and raises the least unacked.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame(3);
+  ProcessAckPacket(&frame);
+
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);  // Packet 4
+  EXPECT_EQ(QuicPacketNumber(4u), stop_waiting()->least_unacked);
+  SendAckPacketToPeer();  // Packet 5
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
+  }
+
+  // Send two data packets at the end, and ensure if the last one is acked,
+  // the least unacked is raised above the ack packets.
+  SendStreamDataToPeer(1, "bar", 6, NO_FIN, nullptr);  // Packet 6
+  SendStreamDataToPeer(1, "bar", 9, NO_FIN, nullptr);  // Packet 7
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
+                        {QuicPacketNumber(7), QuicPacketNumber(8)}});
+  ProcessAckPacket(&frame);
+
+  EXPECT_EQ(QuicPacketNumber(6u), stop_waiting()->least_unacked);
+}
+
+TEST_P(QuicConnectionTest, TLP) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(1);
+
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
+  QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+
+  EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
+  // Simulate the retransmission alarm firing and sending a tlp,
+  // so send algorithm's OnRetransmissionTimeout is not called.
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  const QuicPacketNumber retransmission(
+      connection_.SupportsMultiplePacketNumberSpaces() ? 3 : 2);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, retransmission, _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(retransmission, writer_->header().packet_number);
+  // We do not raise the high water mark yet.
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
+}
+
+TEST_P(QuicConnectionTest, RTO) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  QuicTime default_retransmission_time =
+      clock_.ApproximateNow() + DefaultRetransmissionTime();
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
+
+  EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
+  EXPECT_EQ(default_retransmission_time,
+            connection_.GetRetransmissionAlarm()->deadline());
+  // Simulate the retransmission alarm firing.
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(QuicPacketNumber(2u), writer_->header().packet_number);
+  // We do not raise the high water mark yet.
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
+}
+
+// Regression test of b/133771183.
+TEST_P(QuicConnectionTest, RtoWithNoDataToRetransmit) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SetMaxTailLossProbes(0);
+
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
+  // Connection is cwnd limited.
+  CongestionBlockWrites();
+  // Stream gets reset.
+  SendRstStream(3, QUIC_ERROR_PROCESSING_STREAM, 3);
+  // Simulate the retransmission alarm firing.
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  // RTO fires, but there is no packet to be RTOed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(40);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(20);
+  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(false));
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(1);
+  // Receives packets 1 - 40.
+  for (size_t i = 1; i <= 40; ++i) {
+    ProcessDataPacket(i);
+  }
+}
+
+TEST_P(QuicConnectionTest, SendHandshakeMessages) {
+  use_tagging_decrypter();
+  // A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
+  // the end of the packet. We can test this to check which encrypter was used.
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+
+  // Attempt to send a handshake message and have the socket block.
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  BlockOnNextWrite();
+  connection_.SendCryptoDataWithString("foo", 0);
+  // The packet should be serialized, but not queued.
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Switch to the new encrypter.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+
+  // Now become writeable and flush the packets.
+  writer_->SetWritable();
+  EXPECT_CALL(visitor_, OnCanWrite());
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+
+  // Verify that the handshake packet went out at the null encryption.
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+}
+
+TEST_P(QuicConnectionTest,
+       DropRetransmitsForNullEncryptedPacketAfterForwardSecure) {
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SendCryptoStreamData();
+
+  // Simulate the retransmission alarm firing and the socket blocking.
+  BlockOnNextWrite();
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Go forward secure.
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+
+  EXPECT_EQ(QuicTime::Zero(), connection_.GetRetransmissionAlarm()->deadline());
+  // Unblock the socket and ensure that no packets are sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+}
+
+TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) {
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+
+  connection_.SendCryptoDataWithString("foo", 0);
+
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+
+  SendStreamDataToPeer(2, "bar", 0, NO_FIN, nullptr);
+  EXPECT_FALSE(notifier_.HasLostStreamData());
+  connection_.MarkZeroRttPacketsForRetransmission(0);
+  EXPECT_TRUE(notifier_.HasLostStreamData());
+}
+
+TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  use_tagging_decrypter();
+
+  const uint8_t tag = 0x07;
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+
+  // Process an encrypted packet which can not yet be decrypted which should
+  // result in the packet being buffered.
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Transition to the new encryption state and process another encrypted packet
+  // which should result in the original packet being processed.
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Finally, process a third packet and note that we do not reprocess the
+  // buffered packet.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+}
+
+TEST_P(QuicConnectionTest, TestRetransmitOrder) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  QuicByteCount first_packet_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&first_packet_size));
+
+  connection_.SendStreamDataWithString(3, "first_packet", 0, NO_FIN);
+  QuicByteCount second_packet_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&second_packet_size));
+  connection_.SendStreamDataWithString(3, "second_packet", 12, NO_FIN);
+  EXPECT_NE(first_packet_size, second_packet_size);
+  // Advance the clock by huge time to make sure packets will be retransmitted.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
+  {
+    InSequence s;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
+  }
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // Advance again and expect the packets to be sent again in the same order.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
+  {
+    InSequence s;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
+  }
+  connection_.GetRetransmissionAlarm()->Fire();
+}
+
+TEST_P(QuicConnectionTest, Buffer100NonDecryptablePacketsThenKeyChange) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(100);
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  use_tagging_decrypter();
+
+  const uint8_t tag = 0x07;
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+
+  // Process an encrypted packet which can not yet be decrypted which should
+  // result in the packet being buffered.
+  for (uint64_t i = 1; i <= 100; ++i) {
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  }
+
+  // Transition to the new encryption state and process another encrypted packet
+  // which should result in the original packets being processed.
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(100);
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+
+  // Finally, process a third packet and note that we do not reprocess the
+  // buffered packet.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(102, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+}
+
+TEST_P(QuicConnectionTest, SetRTOAfterWritingToSocket) {
+  BlockOnNextWrite();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Test that RTO is started once we write to the socket.
+  writer_->SetWritable();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.OnCanWrite();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, DelayRTOWithAckReceipt) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  connection_.SendStreamDataWithString(3, "bar", 0, NO_FIN);
+  QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+  EXPECT_EQ(DefaultRetransmissionTime(),
+            retransmission_alarm->deadline() - clock_.Now());
+
+  // Advance the time right before the RTO, then receive an ack for the first
+  // packet to delay the RTO.
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame ack = InitAckFrame(1);
+  ProcessAckPacket(&ack);
+  // Now we have an RTT sample of DefaultRetransmissionTime(500ms),
+  // so the RTO has increased to 2 * SRTT.
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+  EXPECT_EQ(retransmission_alarm->deadline() - clock_.Now(),
+            2 * DefaultRetransmissionTime());
+
+  // Move forward past the original RTO and ensure the RTO is still pending.
+  clock_.AdvanceTime(2 * DefaultRetransmissionTime());
+
+  // Ensure the second packet gets retransmitted when it finally fires.
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+  EXPECT_EQ(retransmission_alarm->deadline(), clock_.ApproximateNow());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  // Manually cancel the alarm to simulate a real test.
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // The new retransmitted packet number should set the RTO to a larger value
+  // than previously.
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+  QuicTime next_rto_time = retransmission_alarm->deadline();
+  QuicTime expected_rto_time =
+      connection_.sent_packet_manager().GetRetransmissionTime();
+  EXPECT_EQ(next_rto_time, expected_rto_time);
+}
+
+TEST_P(QuicConnectionTest, TestQueued) {
+  connection_.SetMaxTailLossProbes(0);
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Unblock the writes and actually send.
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, InitialTimeout) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+
+  // SetFromConfig sets the initial timeouts before negotiation.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  // Subtract a second from the idle timeout on the client side.
+  QuicTime default_timeout =
+      clock_.ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  // Simulate the timeout alarm firing.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1));
+  connection_.GetTimeoutAlarm()->Fire();
+
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, IdleTimeoutAfterFirstSentPacket) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  QuicTime initial_ddl =
+      clock_.ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  EXPECT_EQ(initial_ddl, connection_.GetTimeoutAlarm()->deadline());
+  EXPECT_TRUE(connection_.connected());
+
+  // Advance the time and send the first packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+  // This will be the updated deadline for the connection to idle time out.
+  QuicTime new_ddl = clock_.ApproximateNow() +
+                     QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+
+  // Simulate the timeout alarm firing, the connection should not be closed as
+  // a new packet has been sent.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  QuicTime::Delta delay = initial_ddl - clock_.ApproximateNow();
+  clock_.AdvanceTime(delay);
+  // Verify the timeout alarm deadline is updated.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_EQ(new_ddl, connection_.GetTimeoutAlarm()->deadline());
+
+  // Simulate the timeout alarm firing again, the connection now should be
+  // closed.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  clock_.AdvanceTime(new_ddl - clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, IdleTimeoutAfterSendTwoPackets) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  QuicTime initial_ddl =
+      clock_.ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  EXPECT_EQ(initial_ddl, connection_.GetTimeoutAlarm()->deadline());
+  EXPECT_TRUE(connection_.connected());
+
+  // Immediately send the first packet, this is a rare case but test code will
+  // hit this issue often as MockClock used for tests doesn't move with code
+  // execution until manually adjusted.
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+
+  // Advance the time and send the second packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
+
+  // Simulate the timeout alarm firing, the connection will be closed.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  clock_.AdvanceTime(initial_ddl - clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, HandshakeTimeout) {
+  // Use a shorter handshake timeout than idle timeout for this test.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  connection_.SetNetworkTimeouts(timeout, timeout);
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+
+  QuicTime handshake_timeout =
+      clock_.ApproximateNow() + timeout - QuicTime::Delta::FromSeconds(1);
+  EXPECT_EQ(handshake_timeout, connection_.GetTimeoutAlarm()->deadline());
+  EXPECT_TRUE(connection_.connected());
+
+  // Send and ack new data 3 seconds later to lengthen the idle timeout.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+      "GET /", 0, FIN, nullptr);
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(3));
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&frame);
+
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_TRUE(connection_.connected());
+
+  clock_.AdvanceTime(timeout - QuicTime::Delta::FromSeconds(2));
+
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  // Simulate the timeout alarm firing.
+  connection_.GetTimeoutAlarm()->Fire();
+
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_HANDSHAKE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, PingAfterSend) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+
+  // Advance to 5ms, and send a packet to the peer, which will set
+  // the ping alarm.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+      "GET /", 0, FIN, nullptr);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(15),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now recevie an ACK of the previous packet, which will move the
+  // ping alarm forward.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  // The ping timer is set slightly less than 15 seconds in the future, because
+  // of the 1s ping timer alarm granularity.
+  EXPECT_EQ(
+      QuicTime::Delta::FromSeconds(15) - QuicTime::Delta::FromMilliseconds(5),
+      connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  writer_->Reset();
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  connection_.GetPingAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->ping_frames().size());
+  writer_->Reset();
+
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(false));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  SendAckPacketToPeer();
+
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, ReducedPingTimeout) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+
+  // Use a reduced ping timeout for this connection.
+  connection_.set_ping_timeout(QuicTime::Delta::FromSeconds(10));
+
+  // Advance to 5ms, and send a packet to the peer, which will set
+  // the ping alarm.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+      "GET /", 0, FIN, nullptr);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(10),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now recevie an ACK of the previous packet, which will move the
+  // ping alarm forward.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  // The ping timer is set slightly less than 10 seconds in the future, because
+  // of the 1s ping timer alarm granularity.
+  EXPECT_EQ(
+      QuicTime::Delta::FromSeconds(10) - QuicTime::Delta::FromMilliseconds(5),
+      connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  writer_->Reset();
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
+  connection_.GetPingAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->ping_frames().size());
+  writer_->Reset();
+
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(false));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  SendAckPacketToPeer();
+
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+}
+
+// Tests whether sending an MTU discovery packet to peer successfully causes the
+// maximum packet size to increase.
+TEST_P(QuicConnectionTest, SendMtuDiscoveryPacket) {
+  MtuDiscoveryTestInit();
+
+  // Send an MTU probe.
+  const size_t new_mtu = kDefaultMaxPacketSize + 100;
+  QuicByteCount mtu_probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&mtu_probe_size));
+  connection_.SendMtuDiscoveryPacket(new_mtu);
+  EXPECT_EQ(new_mtu, mtu_probe_size);
+  EXPECT_EQ(QuicPacketNumber(1u), creator_->packet_number());
+
+  // Send more than MTU worth of data.  No acknowledgement was received so far,
+  // so the MTU should be at its old value.
+  const std::string data(kDefaultMaxPacketSize + 1, '.');
+  QuicByteCount size_before_mtu_change;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(2)
+      .WillOnce(SaveArg<3>(&size_before_mtu_change))
+      .WillOnce(Return());
+  connection_.SendStreamDataWithString(3, data, 0, FIN);
+  EXPECT_EQ(QuicPacketNumber(3u), creator_->packet_number());
+  EXPECT_EQ(kDefaultMaxPacketSize, size_before_mtu_change);
+
+  // Acknowledge all packets so far.
+  QuicAckFrame probe_ack = InitAckFrame(3);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(new_mtu, connection_.max_packet_length());
+
+  // Send the same data again.  Check that it fits into a single packet now.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(3, data, 0, FIN);
+  EXPECT_EQ(QuicPacketNumber(4u), creator_->packet_number());
+}
+
+// Verifies that when a MTU probe packet is sent and buffered in a batch writer,
+// the writer is flushed immediately.
+TEST_P(QuicConnectionTest, BatchWriterFlushedAfterMtuDiscoveryPacket) {
+  writer_->SetBatchMode(true);
+  MtuDiscoveryTestInit();
+
+  // Send an MTU probe.
+  const size_t target_mtu = kDefaultMaxPacketSize + 100;
+  QuicByteCount mtu_probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&mtu_probe_size));
+  const uint32_t prior_flush_attempts = writer_->flush_attempts();
+  connection_.SendMtuDiscoveryPacket(target_mtu);
+  EXPECT_EQ(target_mtu, mtu_probe_size);
+  EXPECT_EQ(writer_->flush_attempts(), prior_flush_attempts + 1);
+}
+
+// Tests whether MTU discovery does not happen when it is not explicitly enabled
+// by the connection options.
+TEST_P(QuicConnectionTest, MtuDiscoveryDisabled) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 10;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  const QuicPacketCount number_of_packets = packets_between_probes_base * 2;
+  for (QuicPacketCount i = 0; i < number_of_packets; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    EXPECT_EQ(0u, connection_.mtu_probe_count());
+  }
+}
+
+// Tests whether MTU discovery works when all probes are acknowledged on the
+// first try.
+TEST_P(QuicConnectionTest, MtuDiscoveryEnabled) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+
+  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
+                                  kMtuDiscoveryTargetPacketSizeHigh));
+
+  const QuicPacketNumber probe_packet_number =
+      FirstSendingPacketNumber() + packets_between_probes_base;
+  ASSERT_EQ(probe_packet_number, creator_->packet_number());
+
+  // Acknowledge all packets sent so far.
+  QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+  EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+
+  QuicStreamOffset stream_offset = packets_between_probes_base;
+  QuicByteCount last_probe_size = 0;
+  for (size_t num_probes = 1; num_probes < kMtuDiscoveryAttempts;
+       ++num_probes) {
+    // Send just enough packets without triggering the next probe.
+    for (QuicPacketCount i = 0;
+         i < (packets_between_probes_base << num_probes) - 1; ++i) {
+      SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
+      ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    }
+
+    // Trigger the next probe.
+    SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
+    ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    QuicByteCount new_probe_size;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .WillOnce(SaveArg<3>(&new_probe_size));
+    connection_.GetMtuDiscoveryAlarm()->Fire();
+    EXPECT_THAT(new_probe_size,
+                InRange(probe_size, kMtuDiscoveryTargetPacketSizeHigh));
+    EXPECT_EQ(num_probes + 1, connection_.mtu_probe_count());
+
+    // Acknowledge all packets sent so far.
+    QuicAckFrame probe_ack = InitAckFrame(creator_->packet_number());
+    ProcessAckPacket(&probe_ack);
+    EXPECT_EQ(new_probe_size, connection_.max_packet_length());
+    EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+    last_probe_size = probe_size;
+    probe_size = new_probe_size;
+  }
+
+  // The last probe size should be equal to the target.
+  EXPECT_EQ(probe_size, kMtuDiscoveryTargetPacketSizeHigh);
+
+  writer_->SetShouldWriteFail();
+
+  // Ignore PACKET_WRITE_ERROR once.
+  SendStreamDataToPeer(3, "(", stream_offset++, NO_FIN, nullptr);
+  EXPECT_EQ(last_probe_size, connection_.max_packet_length());
+  EXPECT_TRUE(connection_.connected());
+
+  // Close connection on another PACKET_WRITE_ERROR.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  SendStreamDataToPeer(3, ")", stream_offset++, NO_FIN, nullptr);
+  EXPECT_EQ(last_probe_size, connection_.max_packet_length());
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PACKET_WRITE_ERROR));
+}
+
+// After a successful MTU probe, one and only one write error should be ignored
+// if it happened in QuicConnection::FlushPacket.
+TEST_P(QuicConnectionTest,
+       MtuDiscoveryIgnoreOneWriteErrorInFlushAfterSuccessfulProbes) {
+  MtuDiscoveryTestInit();
+  writer_->SetBatchMode(true);
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  const QuicByteCount original_max_packet_length =
+      connection_.max_packet_length();
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+
+  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
+                                  kMtuDiscoveryTargetPacketSizeHigh));
+
+  const QuicPacketNumber probe_packet_number =
+      FirstSendingPacketNumber() + packets_between_probes_base;
+  ASSERT_EQ(probe_packet_number, creator_->packet_number());
+
+  // Acknowledge all packets sent so far.
+  QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+  EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+
+  writer_->SetShouldWriteFail();
+
+  // Ignore PACKET_WRITE_ERROR once.
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // flusher's destructor will call connection_.FlushPackets, which should
+    // get a WRITE_STATUS_ERROR from the writer and ignore it.
+  }
+  EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
+  EXPECT_TRUE(connection_.connected());
+
+  // Close connection on another PACKET_WRITE_ERROR.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // flusher's destructor will call connection_.FlushPackets, which should
+    // get a WRITE_STATUS_ERROR from the writer and ignore it.
+  }
+  EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PACKET_WRITE_ERROR));
+}
+
+// Simulate the case where the first attempt to send a probe is write blocked,
+// and after unblock, the second attempt returns a MSG_TOO_BIG error.
+TEST_P(QuicConnectionTest, MtuDiscoveryWriteBlocked) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  QuicByteCount original_max_packet_length = connection_.max_packet_length();
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  BlockOnNextWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  ASSERT_TRUE(connection_.connected());
+
+  writer_->SetWritable();
+  SimulateNextPacketTooLarge();
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
+  EXPECT_TRUE(connection_.connected());
+}
+
+// Tests whether MTU discovery works correctly when the probes never get
+// acknowledged.
+TEST_P(QuicConnectionTest, MtuDiscoveryFailed) {
+  MtuDiscoveryTestInit();
+
+  // Lower the number of probes between packets in order to make the test go
+  // much faster.
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  const QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(100);
+
+  EXPECT_EQ(packets_between_probes_base,
+            QuicConnectionPeer::GetPacketsBetweenMtuProbes(&connection_));
+
+  // This tests sends more packets than strictly necessary to make sure that if
+  // the connection was to send more discovery packets than needed, those would
+  // get caught as well.
+  const QuicPacketCount number_of_packets =
+      packets_between_probes_base * (1 << (kMtuDiscoveryAttempts + 1));
+  std::vector<QuicPacketNumber> mtu_discovery_packets;
+  // Called on many acks.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  for (QuicPacketCount i = 0; i < number_of_packets; i++) {
+    SendStreamDataToPeer(3, "!", i, NO_FIN, nullptr);
+    clock_.AdvanceTime(rtt);
+
+    // Receive an ACK, which marks all data packets as received, and all MTU
+    // discovery packets as missing.
+
+    QuicAckFrame ack;
+
+    if (!mtu_discovery_packets.empty()) {
+      QuicPacketNumber min_packet = *min_element(mtu_discovery_packets.begin(),
+                                                 mtu_discovery_packets.end());
+      QuicPacketNumber max_packet = *max_element(mtu_discovery_packets.begin(),
+                                                 mtu_discovery_packets.end());
+      ack.packets.AddRange(QuicPacketNumber(1), min_packet);
+      ack.packets.AddRange(QuicPacketNumber(max_packet + 1),
+                           creator_->packet_number() + 1);
+      ack.largest_acked = creator_->packet_number();
+
+    } else {
+      ack.packets.AddRange(QuicPacketNumber(1), creator_->packet_number() + 1);
+      ack.largest_acked = creator_->packet_number();
+    }
+
+    ProcessAckPacket(&ack);
+
+    // Trigger MTU probe if it would be scheduled now.
+    if (!connection_.GetMtuDiscoveryAlarm()->IsSet()) {
+      continue;
+    }
+
+    // Fire the alarm.  The alarm should cause a packet to be sent.
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    connection_.GetMtuDiscoveryAlarm()->Fire();
+    // Record the packet number of the MTU discovery packet in order to
+    // mark it as NACK'd.
+    mtu_discovery_packets.push_back(creator_->packet_number());
+  }
+
+  // Ensure the number of packets between probes grows exponentially by checking
+  // it against the closed-form expression for the packet number.
+  ASSERT_EQ(kMtuDiscoveryAttempts, mtu_discovery_packets.size());
+  for (uint64_t i = 0; i < kMtuDiscoveryAttempts; i++) {
+    // 2^0 + 2^1 + 2^2 + ... + 2^n = 2^(n + 1) - 1
+    const QuicPacketCount packets_between_probes =
+        packets_between_probes_base * ((1 << (i + 1)) - 1);
+    EXPECT_EQ(QuicPacketNumber(packets_between_probes + (i + 1)),
+              mtu_discovery_packets[i]);
+  }
+
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  EXPECT_EQ(kDefaultMaxPacketSize, connection_.max_packet_length());
+  EXPECT_EQ(kMtuDiscoveryAttempts, connection_.mtu_probe_count());
+}
+
+// Probe 3 times, the first one succeeds, then fails, then succeeds again.
+TEST_P(QuicConnectionTest, MtuDiscoverySecondProbeFailed) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  QuicStreamOffset stream_offset = 0;
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
+                                  kMtuDiscoveryTargetPacketSizeHigh));
+
+  const QuicPacketNumber probe_packet_number =
+      FirstSendingPacketNumber() + packets_between_probes_base;
+  ASSERT_EQ(probe_packet_number, creator_->packet_number());
+
+  // Acknowledge all packets sent so far.
+  QuicAckFrame first_ack = InitAckFrame(probe_packet_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&first_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+  EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+
+  // Send just enough packets without triggering the second probe.
+  for (QuicPacketCount i = 0; i < (packets_between_probes_base << 1) - 1; ++i) {
+    SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the second probe.
+  SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount second_probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&second_probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  EXPECT_THAT(second_probe_size,
+              InRange(probe_size, kMtuDiscoveryTargetPacketSizeHigh));
+  EXPECT_EQ(2u, connection_.mtu_probe_count());
+
+  // Acknowledge all packets sent so far, except the second probe.
+  QuicPacketNumber second_probe_packet_number = creator_->packet_number();
+  QuicAckFrame second_ack = InitAckFrame(second_probe_packet_number - 1);
+  ProcessAckPacket(&first_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+
+  // Send just enough packets without triggering the third probe.
+  for (QuicPacketCount i = 0; i < (packets_between_probes_base << 2) - 1; ++i) {
+    SendStreamDataToPeer(3, "@", stream_offset++, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the third probe.
+  SendStreamDataToPeer(3, "#", stream_offset++, NO_FIN, nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount third_probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&third_probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  EXPECT_THAT(third_probe_size, InRange(probe_size, second_probe_size));
+  EXPECT_EQ(3u, connection_.mtu_probe_count());
+
+  // Acknowledge all packets sent so far, except the second probe.
+  QuicAckFrame third_ack =
+      ConstructAckFrame(creator_->packet_number(), second_probe_packet_number);
+  ProcessAckPacket(&third_ack);
+  EXPECT_EQ(third_probe_size, connection_.max_packet_length());
+
+  SendStreamDataToPeer(3, "$", stream_offset++, NO_FIN, nullptr);
+  EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
+
+  if (connection_.PathDegradingDetectionInProgress() &&
+      QuicConnectionPeer::GetPathDegradingDeadline(&connection_) <
+          QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(
+              &connection_)) {
+    // Fire path degrading alarm first.
+    connection_.PathDegradingTimeout();
+  }
+
+  // Verify the max packet size has not reduced.
+  EXPECT_EQ(third_probe_size, connection_.max_packet_length());
+
+  // Fire alarm to get path mtu reduction callback called.
+  EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+
+  // Verify the max packet size has reduced to the previous value.
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+}
+
+// Tests whether MTU discovery works when the writer has a limit on how large a
+// packet can be.
+TEST_P(QuicConnectionTest, MtuDiscoveryWriterLimited) {
+  MtuDiscoveryTestInit();
+
+  const QuicByteCount mtu_limit = kMtuDiscoveryTargetPacketSizeHigh - 1;
+  writer_->set_max_packet_size(mtu_limit);
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+
+  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(), mtu_limit));
+
+  const QuicPacketNumber probe_sequence_number =
+      FirstSendingPacketNumber() + packets_between_probes_base;
+  ASSERT_EQ(probe_sequence_number, creator_->packet_number());
+
+  // Acknowledge all packets sent so far.
+  QuicAckFrame probe_ack = InitAckFrame(probe_sequence_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+  EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+
+  QuicStreamOffset stream_offset = packets_between_probes_base;
+  for (size_t num_probes = 1; num_probes < kMtuDiscoveryAttempts;
+       ++num_probes) {
+    // Send just enough packets without triggering the next probe.
+    for (QuicPacketCount i = 0;
+         i < (packets_between_probes_base << num_probes) - 1; ++i) {
+      SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
+      ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    }
+
+    // Trigger the next probe.
+    SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
+    ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    QuicByteCount new_probe_size;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .WillOnce(SaveArg<3>(&new_probe_size));
+    connection_.GetMtuDiscoveryAlarm()->Fire();
+    EXPECT_THAT(new_probe_size, InRange(probe_size, mtu_limit));
+    EXPECT_EQ(num_probes + 1, connection_.mtu_probe_count());
+
+    // Acknowledge all packets sent so far.
+    QuicAckFrame probe_ack = InitAckFrame(creator_->packet_number());
+    ProcessAckPacket(&probe_ack);
+    EXPECT_EQ(new_probe_size, connection_.max_packet_length());
+    EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+    probe_size = new_probe_size;
+  }
+
+  // The last probe size should be equal to the target.
+  EXPECT_EQ(probe_size, mtu_limit);
+}
+
+// Tests whether MTU discovery works when the writer returns an error despite
+// advertising higher packet length.
+TEST_P(QuicConnectionTest, MtuDiscoveryWriterFailed) {
+  MtuDiscoveryTestInit();
+
+  const QuicByteCount mtu_limit = kMtuDiscoveryTargetPacketSizeHigh - 1;
+  const QuicByteCount initial_mtu = connection_.max_packet_length();
+  EXPECT_LT(initial_mtu, mtu_limit);
+  writer_->set_max_packet_size(mtu_limit);
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  writer_->SimulateNextPacketTooLarge();
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  ASSERT_TRUE(connection_.connected());
+
+  // Send more data.
+  QuicPacketNumber probe_number = creator_->packet_number();
+  QuicPacketCount extra_packets = packets_between_probes_base * 3;
+  for (QuicPacketCount i = 0; i < extra_packets; i++) {
+    connection_.EnsureWritableAndSendStreamData5();
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Acknowledge all packets sent so far, except for the lost probe.
+  QuicAckFrame probe_ack =
+      ConstructAckFrame(creator_->packet_number(), probe_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(initial_mtu, connection_.max_packet_length());
+
+  // Send more packets, and ensure that none of them sets the alarm.
+  for (QuicPacketCount i = 0; i < 4 * packets_between_probes_base; i++) {
+    connection_.EnsureWritableAndSendStreamData5();
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  EXPECT_EQ(initial_mtu, connection_.max_packet_length());
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+}
+
+TEST_P(QuicConnectionTest, NoMtuDiscoveryAfterConnectionClosed) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 10;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  EXPECT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterSendDuringHandshake) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta initial_idle_timeout =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
+
+  // When we send a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Now send more data. This will not move the timeout because
+  // no data has been received since the previous write.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // The original alarm will fire.  We should not time out because we had a
+  // network event at t=5ms.  The alarm will reregister.
+  clock_.AdvanceTime(initial_idle_timeout - five_ms - five_ms);
+  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // This time, we should time out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(five_ms);
+  EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterRetransmission) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  const QuicTime start_time = clock_.Now();
+  const QuicTime::Delta initial_idle_timeout =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  QuicTime default_timeout = clock_.Now() + initial_idle_timeout;
+
+  connection_.SetMaxTailLossProbes(0);
+  const QuicTime default_retransmission_time =
+      start_time + DefaultRetransmissionTime();
+
+  ASSERT_LT(default_retransmission_time, default_timeout);
+
+  // When we send a packet, the timeout will change to 5 ms +
+  // kInitialIdleTimeoutSecs (but it will not reschedule the alarm).
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  const QuicTime send_time = start_time + five_ms;
+  clock_.AdvanceTime(five_ms);
+  ASSERT_EQ(send_time, clock_.Now());
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Move forward 5 ms and receive a packet, which will move the timeout
+  // forward 5 ms more (but will not reschedule the alarm).
+  const QuicTime receive_time = send_time + five_ms;
+  clock_.AdvanceTime(receive_time - clock_.Now());
+  ASSERT_EQ(receive_time, clock_.Now());
+  ProcessPacket(1);
+
+  // Now move forward to the retransmission time and retransmit the
+  // packet, which should move the timeout forward again (but will not
+  // reschedule the alarm).
+  EXPECT_EQ(default_retransmission_time + five_ms,
+            connection_.GetRetransmissionAlarm()->deadline());
+  // Simulate the retransmission alarm firing.
+  const QuicTime rto_time = send_time + DefaultRetransmissionTime();
+  const QuicTime final_timeout = rto_time + initial_idle_timeout;
+  clock_.AdvanceTime(rto_time - clock_.Now());
+  ASSERT_EQ(rto_time, clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // Advance to the original timeout and fire the alarm. The connection should
+  // timeout, and the alarm should be registered based on the time of the
+  // retransmission.
+  clock_.AdvanceTime(default_timeout - clock_.Now());
+  ASSERT_EQ(default_timeout.ToDebuggingValue(),
+            clock_.Now().ToDebuggingValue());
+  EXPECT_EQ(default_timeout, clock_.Now());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_TRUE(connection_.connected());
+  ASSERT_EQ(final_timeout.ToDebuggingValue(),
+            connection_.GetTimeoutAlarm()->deadline().ToDebuggingValue());
+
+  // This time, we should time out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(final_timeout - clock_.Now());
+  EXPECT_EQ(connection_.GetTimeoutAlarm()->deadline(), clock_.Now());
+  EXPECT_EQ(final_timeout, clock_.Now());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterSendAfterHandshake) {
+  // When the idle timeout fires, verify that by default we do not send any
+  // connection close packets.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+
+  // Create a handshake message that also enables silent close.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  QuicConfig client_config;
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  client_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
+  const QuicErrorCode error =
+      config.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta default_idle_timeout =
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
+
+  // When we send a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Now send more data. This will not move the timeout because
+  // no data has been received since the previous write.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // The original alarm will fire.  We should not time out because we had a
+  // network event at t=5ms.  The alarm will reregister.
+  clock_.AdvanceTime(default_idle_timeout - five_ms - five_ms);
+  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // This time, we should time out.
+  // This results in a SILENT_CLOSE, so the writer will not be invoked
+  // and will not save the frame. Grab the frame from OnConnectionClosed
+  // directly.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+
+  clock_.AdvanceTime(five_ms);
+  EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_NETWORK_IDLE_TIMEOUT));
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseAndTLP) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  // Same test as above, but sending TLPs causes a connection close to be sent.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+
+  // Create a handshake message that also enables silent close.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  QuicConfig client_config;
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  client_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
+  const QuicErrorCode error =
+      config.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta default_idle_timeout =
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
+
+  // When we send a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Retransmit the packet via tail loss probe.
+  clock_.AdvanceTime(connection_.GetRetransmissionAlarm()->deadline() -
+                     clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // This time, we should time out and send a connection close due to the TLP.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(connection_.GetTimeoutAlarm()->deadline() -
+                     clock_.ApproximateNow() + five_ms);
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseWithOpenStreams) {
+  // Same test as above, but having open streams causes a connection close
+  // to be sent.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+
+  // Create a handshake message that also enables silent close.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  QuicConfig client_config;
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  client_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
+  const QuicErrorCode error =
+      config.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta default_idle_timeout =
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
+
+  // When we send a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Indicate streams are still open.
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  if (GetQuicReloadableFlag(quic_add_stream_info_to_idle_close_detail)) {
+    EXPECT_CALL(visitor_, GetStreamsInfoForLogging()).WillOnce(Return(""));
+  }
+
+  // This time, we should time out and send a connection close due to the TLP.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(connection_.GetTimeoutAlarm()->deadline() -
+                     clock_.ApproximateNow() + five_ms);
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterReceive) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta initial_idle_timeout =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
+
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, NO_FIN);
+
+  EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+  clock_.AdvanceTime(five_ms);
+
+  // When we receive a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  QuicAckFrame ack = InitAckFrame(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+
+  // The original alarm will fire.  We should not time out because we had a
+  // network event at t=5ms.  The alarm will reregister.
+  clock_.AdvanceTime(initial_idle_timeout - five_ms);
+  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // This time, we should time out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(five_ms);
+  EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta initial_idle_timeout =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  connection_.SetNetworkTimeouts(
+      QuicTime::Delta::Infinite(),
+      initial_idle_timeout + QuicTime::Delta::FromSeconds(1));
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, NO_FIN);
+
+  EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+  clock_.AdvanceTime(five_ms);
+
+  // When we receive a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  QuicAckFrame ack = InitAckFrame(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+
+  // The original alarm will fire.  We should not time out because we had a
+  // network event at t=5ms.  The alarm will reregister.
+  clock_.AdvanceTime(initial_idle_timeout - five_ms);
+  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Now, send packets while advancing the time and verify that the connection
+  // eventually times out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  for (int i = 0; i < 100 && connection_.connected(); ++i) {
+    QUIC_LOG(INFO) << "sending data packet";
+    connection_.SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+        "foo", 0, NO_FIN);
+    connection_.GetTimeoutAlarm()->Fire();
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfter5ClientRTOs) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(2);
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k5RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  }
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  connection_.SetFromConfig(config);
+
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+
+  // Fire the retransmission alarm 6 times, twice for TLP and 4 times for RTO.
+  for (int i = 0; i < 6; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    connection_.GetRetransmissionAlarm()->Fire();
+    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+    EXPECT_TRUE(connection_.connected());
+  }
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.PathDegradingTimeout();
+
+  EXPECT_EQ(2u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
+  EXPECT_EQ(4u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
+  // This time, we should time out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
+}
+
+TEST_P(QuicConnectionTest, SendScheduler) {
+  // Test that if we send a packet without delay, it is not queued.
+  QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> packet =
+      ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
+                         HAS_RETRANSMITTABLE_DATA, false, false);
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, FailToSendFirstPacket) {
+  // Test that the connection does not crash when it fails to send the first
+  // packet at which point self_address_ might be uninitialized.
+  QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
+  std::unique_ptr<QuicPacket> packet =
+      ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
+  writer_->SetShouldWriteFail();
+  connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
+                         HAS_RETRANSMITTABLE_DATA, false, false);
+}
+
+TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
+  QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> packet =
+      ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
+  BlockOnNextWrite();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _))
+      .Times(0);
+  connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
+                         HAS_RETRANSMITTABLE_DATA, false, false);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
+  // Queue the first packet.
+  size_t payload_length = connection_.max_packet_length();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(testing::Return(false));
+  const std::string payload(payload_length, 'a');
+  QuicStreamId first_bidi_stream_id(QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.version().transport_version, Perspective::IS_CLIENT));
+  EXPECT_EQ(0u, connection_
+                    .SendStreamDataWithString(first_bidi_stream_id, payload, 0,
+                                              NO_FIN)
+                    .bytes_consumed);
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, SendingThreePackets) {
+  // Make the payload twice the size of the packet, so 3 packets are written.
+  size_t total_payload_length = 2 * connection_.max_packet_length();
+  const std::string payload(total_payload_length, 'a');
+  QuicStreamId first_bidi_stream_id(QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.version().transport_version, Perspective::IS_CLIENT));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
+  EXPECT_EQ(payload.size(), connection_
+                                .SendStreamDataWithString(first_bidi_stream_id,
+                                                          payload, 0, NO_FIN)
+                                .bytes_consumed);
+}
+
+TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!GetParam().version.HasIetfInvariantHeader()) {
+    // For IETF QUIC, encryption level will be switched to FORWARD_SECURE in
+    // SendStreamDataWithString.
+    QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  }
+  // Set up a larger payload than will fit in one packet.
+  const std::string payload(connection_.max_packet_length(), 'a');
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+
+  // Now send some packets with no truncation.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  EXPECT_EQ(payload.size(),
+            connection_.SendStreamDataWithString(3, payload, 0, NO_FIN)
+                .bytes_consumed);
+  // Track the size of the second packet here.  The overhead will be the largest
+  // we see in this test, due to the non-truncated connection id.
+  size_t non_truncated_packet_size = writer_->last_packet_size();
+
+  // Change to a 0 byte connection id.
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedBytesForConnectionId(&config, 0);
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  EXPECT_EQ(payload.size(),
+            connection_.SendStreamDataWithString(3, payload, 1350, NO_FIN)
+                .bytes_consumed);
+  if (connection_.version().HasIetfInvariantHeader()) {
+    // Short header packets sent from server omit connection ID already, and
+    // stream offset size increases from 0 to 2.
+    EXPECT_EQ(non_truncated_packet_size, writer_->last_packet_size() - 2);
+  } else {
+    // Just like above, we save 8 bytes on payload, and 8 on truncation. -2
+    // because stream offset size is 2 instead of 0.
+    EXPECT_EQ(non_truncated_packet_size,
+              writer_->last_packet_size() + 8 * 2 - 2);
+  }
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAck) {
+  QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  const uint8_t tag = 0x07;
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+  // Process a packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+
+  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
+  // instead of ENCRYPTION_INITIAL.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Check if delayed ack timer is running for the expected interval.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+  // Simulate delayed ack alarm firing.
+  clock_.AdvanceTime(DefaultDelayedAckTime());
+  connection_.GetAckAlarm()->Fire();
+  // Check that ack is sent and that delayed ack alarm is reset.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
+
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // The ack time should be based on min_rtt/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() +
+                      QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  const uint8_t tag = 0x07;
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+  // Process a packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  }
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
+  // instead of ENCRYPTION_INITIAL.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_ZERO_RTT);
+
+  // Check if delayed ack timer is running for the expected interval.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // The 10th received packet causes an ack to be sent.
+  for (int i = 0; i < 9; ++i) {
+    EXPECT_TRUE(connection_.HasPendingAcks());
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_ZERO_RTT);
+  }
+  // Check that ack is sent and that delayed ack alarm is reset.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckDecimationUnlimitedAggregation) {
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  // No limit on the number of packets received before sending an ack.
+  connection_options.push_back(kAKDU);
+  config.SetConnectionOptionsToSend(connection_options);
+  connection_.SetFromConfig(config);
+
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // The ack time should be based on min_rtt/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() +
+                      QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  const uint8_t tag = 0x07;
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+  // Process a packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  }
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
+  // instead of ENCRYPTION_INITIAL.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_ZERO_RTT);
+
+  // Check if delayed ack timer is running for the expected interval.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // 18 packets will not cause an ack to be sent.  19 will because when
+  // stop waiting frames are in use, we ack every 20 packets no matter what.
+  for (int i = 0; i < 18; ++i) {
+    EXPECT_TRUE(connection_.HasPendingAcks());
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_ZERO_RTT);
+  }
+  // The delayed ack timer should still be set to the expected deadline.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckDecimationEighthRtt) {
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
+  QuicConnectionPeer::SetAckDecimationDelay(&connection_, 0.125);
+
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // The ack time should be based on min_rtt/8, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() +
+                      QuicTime::Delta::FromMilliseconds(kMinRttMs / 8);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  const uint8_t tag = 0x07;
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+  // Process a packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  }
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
+  // instead of ENCRYPTION_INITIAL.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_ZERO_RTT);
+
+  // Check if delayed ack timer is running for the expected interval.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // The 10th received packet causes an ack to be sent.
+  for (int i = 0; i < 9; ++i) {
+    EXPECT_TRUE(connection_.HasPendingAcks());
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_ZERO_RTT);
+  }
+  // Check that ack is sent and that delayed ack alarm is reset.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessPacket(1);
+  // Check that ack is sent and that delayed ack alarm is set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // Completing the handshake as the server does nothing.
+  QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_SERVER);
+  connection_.OnHandshakeComplete();
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // Complete the handshake as the client decreases the delayed ack time to 0ms.
+  QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_CLIENT);
+  connection_.OnHandshakeComplete();
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
+              connection_.GetAckAlarm()->deadline());
+  } else {
+    EXPECT_EQ(clock_.ApproximateNow(), connection_.GetAckAlarm()->deadline());
+  }
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckOnSecondPacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessPacket(1);
+  ProcessPacket(2);
+  // Check that ack is sent and that delayed ack alarm is reset.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, NoAckOnOldNacks) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessPacket(2);
+  size_t frames_per_ack = GetParam().no_stop_waiting ? 1 : 2;
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(3);
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + frames_per_ack, writer_->frame_count());
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  writer_->Reset();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessPacket(4);
+  EXPECT_EQ(0u, writer_->frame_count());
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(5);
+  padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + frames_per_ack, writer_->frame_count());
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  writer_->Reset();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  // Now only set the timer on the 6th packet, instead of sending another ack.
+  ProcessPacket(6);
+  padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count, writer_->frame_count());
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingPacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_));
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  ProcessDataPacket(1);
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  // Check that ack is bundled with outgoing data and that delayed ack
+  // alarm is reset.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingCryptoPacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  connection_.SendCryptoDataWithString("foo", 0);
+  // Check that ack is bundled with outgoing crypto data.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, BlockAndBufferOnFirstCHLOPacketOfTwo) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessPacket(1);
+  BlockOnNextWrite();
+  writer_->set_is_write_blocked_data_buffered(true);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  } else {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  }
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_FALSE(connection_.HasQueuedData());
+  connection_.SendCryptoDataWithString("bar", 3);
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    // CRYPTO frames are not flushed when writer is blocked.
+    EXPECT_FALSE(connection_.HasQueuedData());
+  } else {
+    EXPECT_TRUE(connection_.HasQueuedData());
+  }
+}
+
+TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_CALL(visitor_, OnCanWrite())
+      .WillOnce(IgnoreResult(InvokeWithoutArgs(
+          &connection_, &TestConnection::SendCryptoStreamData)));
+  // Process a packet from the crypto stream, which is frame1_'s default.
+  // Receiving the CHLO as packet 2 first will cause the connection to
+  // immediately send an ack, due to the packet gap.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  // Check that ack is sent and that delayed ack alarm is reset.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_EQ(1u, writer_->stream_frames().size());
+  } else {
+    EXPECT_EQ(1u, writer_->crypto_frames().size());
+  }
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, BundleAckForSecondCHLOTwoPacketReject) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+
+  // Process two packets from the crypto stream, which is frame1_'s default,
+  // simulating a 2 packet reject.
+  {
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+    } else {
+      EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    }
+    ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+    // Send the new CHLO when the REJ is processed.
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      EXPECT_CALL(visitor_, OnCryptoFrame(_))
+          .WillOnce(IgnoreResult(InvokeWithoutArgs(
+              &connection_, &TestConnection::SendCryptoStreamData)));
+    } else {
+      EXPECT_CALL(visitor_, OnStreamFrame(_))
+          .WillOnce(IgnoreResult(InvokeWithoutArgs(
+              &connection_, &TestConnection::SendCryptoStreamData)));
+    }
+    ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  }
+  // Check that ack is sent and that delayed ack alarm is reset.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_EQ(1u, writer_->stream_frames().size());
+  } else {
+    EXPECT_EQ(1u, writer_->crypto_frames().size());
+  }
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, NO_FIN);
+  // Ack the second packet, which will retransmit the first packet.
+  QuicAckFrame ack = ConstructAckFrame(2, 1);
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  writer_->Reset();
+
+  // Now ack the retransmission, which will both raise the high water mark
+  // and see if there is more data to send.
+  ack = ConstructAckFrame(3, 1);
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+
+  // Check that no packet is sent and the ack alarm isn't set.
+  EXPECT_EQ(0u, writer_->frame_count());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  writer_->Reset();
+
+  // Send the same ack, but send both data and an ack together.
+  ack = ConstructAckFrame(3, 1);
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(visitor_, OnCanWrite())
+      .WillOnce(IgnoreResult(InvokeWithoutArgs(
+          &connection_, &TestConnection::EnsureWritableAndSendStreamData5)));
+  ProcessAckPacket(&ack);
+
+  // Check that ack is bundled with outgoing data and the delayed ack
+  // alarm is reset.
+  if (GetParam().no_stop_waiting) {
+    // Do not ACK acks.
+    EXPECT_EQ(1u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  if (GetParam().no_stop_waiting) {
+    EXPECT_TRUE(writer_->ack_frames().empty());
+  } else {
+    EXPECT_FALSE(writer_->ack_frames().empty());
+    EXPECT_EQ(QuicPacketNumber(3u),
+              LargestAcked(writer_->ack_frames().front()));
+  }
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, NoAckSentForClose) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessPacket(1);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessClosePacket(2);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PEER_GOING_AWAY));
+}
+
+TEST_P(QuicConnectionTest, SendWhenDisconnected) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+  EXPECT_EQ(DISCARD, connection_.GetSerializedPacketFate(
+                         /*is_mtu_discovery=*/false, ENCRYPTION_INITIAL));
+}
+
+TEST_P(QuicConnectionTest, SendConnectivityProbingWhenDisconnected) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
+
+  EXPECT_QUIC_BUG(connection_.SendConnectivityProbingPacket(
+                      writer_.get(), connection_.peer_address()),
+                  "Not sending connectivity probing packet as connection is "
+                  "disconnected.");
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PEER_GOING_AWAY));
+}
+
+TEST_P(QuicConnectionTest, WriteBlockedAfterClientSendsConnectivityProbe) {
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
+  // Block next write so that sending connectivity probe will encounter a
+  // blocked write when send a connectivity probe to the peer.
+  probing_writer.BlockOnNextWrite();
+  // Connection will not be marked as write blocked as connectivity probe only
+  // affects the probing_writer which is not the default.
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(1);
+  connection_.SendConnectivityProbingPacket(&probing_writer,
+                                            connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, WriterBlockedAfterServerSendsConnectivityProbe) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  // Block next write so that sending connectivity probe will encounter a
+  // blocked write when send a connectivity probe to the peer.
+  writer_->BlockOnNextWrite();
+  // Connection will be marked as write blocked as server uses the default
+  // writer to send connectivity probes.
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(1);
+  if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) {
+    QuicPathFrameBuffer payload{
+        {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendPathChallenge(
+        payload, connection_.self_address(), connection_.peer_address(),
+        connection_.effective_peer_address(), writer_.get());
+  } else {
+    connection_.SendConnectivityProbingPacket(writer_.get(),
+                                              connection_.peer_address());
+  }
+}
+
+TEST_P(QuicConnectionTest, WriterErrorWhenClientSendsConnectivityProbe) {
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
+  probing_writer.SetShouldWriteFail();
+
+  // Connection should not be closed if a connectivity probe is failed to be
+  // sent.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
+  connection_.SendConnectivityProbingPacket(&probing_writer,
+                                            connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, WriterErrorWhenServerSendsConnectivityProbe) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  writer_->SetShouldWriteFail();
+  // Connection should not be closed if a connectivity probe is failed to be
+  // sent.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, PublicReset) {
+  if (GetParam().version.HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicPublicResetPacket header;
+  // Public reset packet in only built by server.
+  header.connection_id = connection_id_;
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      framer_.BuildPublicResetPacket(header));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PUBLIC_RESET));
+}
+
+TEST_P(QuicConnectionTest, IetfStatelessReset) {
+  if (!GetParam().version.HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedStatelessResetToken(&config,
+                                                 kTestStatelessResetToken);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildIetfStatelessResetPacket(connection_id_,
+                                                /*received_packet_length=*/100,
+                                                kTestStatelessResetToken));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  if (!connection_.use_path_validator()) {
+    EXPECT_CALL(visitor_, ValidateStatelessReset(_, _)).WillOnce(Return(true));
+  }
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PUBLIC_RESET));
+}
+
+TEST_P(QuicConnectionTest, GoAway) {
+  if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) {
+    // GoAway is not available in version 99.
+    return;
+  }
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicGoAwayFrame* goaway = new QuicGoAwayFrame();
+  goaway->last_good_stream_id = 1;
+  goaway->error_code = QUIC_PEER_GOING_AWAY;
+  goaway->reason_phrase = "Going away.";
+  EXPECT_CALL(visitor_, OnGoAway(_));
+  ProcessGoAwayPacket(goaway);
+}
+
+TEST_P(QuicConnectionTest, WindowUpdate) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicWindowUpdateFrame window_update;
+  window_update.stream_id = 3;
+  window_update.max_data = 1234;
+  EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
+  ProcessFramePacket(QuicFrame(window_update));
+}
+
+TEST_P(QuicConnectionTest, Blocked) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicBlockedFrame blocked;
+  blocked.stream_id = 3;
+  EXPECT_CALL(visitor_, OnBlockedFrame(_));
+  ProcessFramePacket(QuicFrame(blocked));
+  EXPECT_EQ(1u, connection_.GetStats().blocked_frames_received);
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+}
+
+TEST_P(QuicConnectionTest, ZeroBytePacket) {
+  // Don't close the connection for zero byte packets.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  QuicReceivedPacket encrypted(nullptr, 0, QuicTime::Zero());
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, encrypted);
+}
+
+TEST_P(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) {
+  if (GetParam().version.HasIetfInvariantHeader()) {
+    return;
+  }
+  // Set the packet number of the ack packet to be least unacked (4).
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 3);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessStopWaitingPacket(InitStopWaitingFrame(4));
+  EXPECT_FALSE(connection_.ack_frame().packets.Empty());
+}
+
+TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) {
+  // All supported versions except the one the connection supports.
+  ParsedQuicVersionVector versions;
+  for (auto version : AllSupportedVersions()) {
+    if (version != connection_.version()) {
+      versions.push_back(version);
+    }
+  }
+
+  // Send a version negotiation packet.
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(),
+          connection_.version().HasIetfInvariantHeader(),
+          connection_.version().HasLengthPrefixedConnectionIds(), versions));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  // Verify no connection close packet gets sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_INVALID_VERSION));
+}
+
+TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiationWithConnectionClose) {
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kINVC);
+  config.SetClientConnectionOptions(connection_options);
+  connection_.SetFromConfig(config);
+
+  // All supported versions except the one the connection supports.
+  ParsedQuicVersionVector versions;
+  for (auto version : AllSupportedVersions()) {
+    if (version != connection_.version()) {
+      versions.push_back(version);
+    }
+  }
+
+  // Send a version negotiation packet.
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(),
+          connection_.version().HasIetfInvariantHeader(),
+          connection_.version().HasLengthPrefixedConnectionIds(), versions));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  // Verify connection close packet gets sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1u));
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_INVALID_VERSION));
+}
+
+TEST_P(QuicConnectionTest, BadVersionNegotiation) {
+  // Send a version negotiation packet with the version the client started with.
+  // It should be rejected.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(),
+          connection_.version().HasIetfInvariantHeader(),
+          connection_.version().HasLengthPrefixedConnectionIds(),
+          AllSupportedVersions()));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET));
+}
+
+TEST_P(QuicConnectionTest, CheckSendStats) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendStreamDataWithString(3, "first", 0, NO_FIN);
+  size_t first_packet_size = writer_->last_packet_size();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendStreamDataWithString(5, "second", 0, NO_FIN);
+  size_t second_packet_size = writer_->last_packet_size();
+
+  // 2 retransmissions due to rto, 1 due to explicit nack.
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
+
+  // Retransmit due to RTO.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // Retransmit due to explicit nacks.
+  QuicAckFrame nack_three =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
+                    {QuicPacketNumber(4), QuicPacketNumber(5)}});
+
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(3), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessAckPacket(&nack_three);
+
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .WillOnce(Return(QuicBandwidth::Zero()));
+
+  const QuicConnectionStats& stats = connection_.GetStats();
+  // For IETF QUIC, version is not included as the encryption level switches to
+  // FORWARD_SECURE in SendStreamDataWithString.
+  size_t save_on_version =
+      GetParam().version.HasIetfInvariantHeader() ? 0 : kQuicVersionSize;
+  EXPECT_EQ(3 * first_packet_size + 2 * second_packet_size - save_on_version,
+            stats.bytes_sent);
+  EXPECT_EQ(5u, stats.packets_sent);
+  EXPECT_EQ(2 * first_packet_size + second_packet_size - save_on_version,
+            stats.bytes_retransmitted);
+  EXPECT_EQ(3u, stats.packets_retransmitted);
+  EXPECT_EQ(1u, stats.rto_count);
+  EXPECT_EQ(kDefaultMaxPacketSize, stats.egress_mtu);
+}
+
+TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) {
+  // Construct a packet with stream frame and connection close frame.
+  QuicPacketHeader header;
+  if (peer_framer_.perspective() == Perspective::IS_SERVER) {
+    header.source_connection_id = connection_id_;
+    header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+    if (!peer_framer_.version().HasIetfInvariantHeader()) {
+      header.source_connection_id_included = CONNECTION_ID_PRESENT;
+    }
+  } else {
+    header.destination_connection_id = connection_id_;
+    if (peer_framer_.version().HasIetfInvariantHeader()) {
+      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+    }
+  }
+  header.packet_number = QuicPacketNumber(1);
+  header.version_flag = false;
+
+  QuicErrorCode kQuicErrorCode = QUIC_PEER_GOING_AWAY;
+  // This QuicConnectionCloseFrame will default to being for a Google QUIC
+  // close. If doing IETF QUIC then set fields appropriately for CC/T or CC/A,
+  // depending on the mapping.
+  QuicConnectionCloseFrame qccf(peer_framer_.transport_version(),
+                                kQuicErrorCode, NO_IETF_QUIC_ERROR, "",
+                                /*transport_close_frame_type=*/0);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  frames.push_back(QuicFrame(&qccf));
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+  EXPECT_TRUE(nullptr != packet);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
+      kMaxOutgoingPacketSize);
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PEER_GOING_AWAY));
+}
+
+TEST_P(QuicConnectionTest, SelectMutualVersion) {
+  connection_.SetSupportedVersions(AllSupportedVersions());
+  // Set the connection to speak the lowest quic version.
+  connection_.set_version(QuicVersionMin());
+  EXPECT_EQ(QuicVersionMin(), connection_.version());
+
+  // Pass in available versions which includes a higher mutually supported
+  // version.  The higher mutually supported version should be selected.
+  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  EXPECT_TRUE(connection_.SelectMutualVersion(supported_versions));
+  EXPECT_EQ(QuicVersionMax(), connection_.version());
+
+  // Expect that the lowest version is selected.
+  // Ensure the lowest supported version is less than the max, unless they're
+  // the same.
+  ParsedQuicVersionVector lowest_version_vector;
+  lowest_version_vector.push_back(QuicVersionMin());
+  EXPECT_TRUE(connection_.SelectMutualVersion(lowest_version_vector));
+  EXPECT_EQ(QuicVersionMin(), connection_.version());
+
+  // Shouldn't be able to find a mutually supported version.
+  ParsedQuicVersionVector unsupported_version;
+  unsupported_version.push_back(UnsupportedQuicVersion());
+  EXPECT_FALSE(connection_.SelectMutualVersion(unsupported_version));
+}
+
+TEST_P(QuicConnectionTest, ConnectionCloseWhenWritable) {
+  EXPECT_FALSE(writer_->IsWriteBlocked());
+
+  // Send a packet.
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  TriggerConnectionClose();
+  EXPECT_LE(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, ConnectionCloseGettingWriteBlocked) {
+  BlockOnNextWrite();
+  TriggerConnectionClose();
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+}
+
+TEST_P(QuicConnectionTest, ConnectionCloseWhenWriteBlocked) {
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  TriggerConnectionClose();
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, OnPacketSentDebugVisitor) {
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
+  QuicPacketHeader header;
+  header.packet_number = QuicPacketNumber(1);
+  if (GetParam().version.HasIetfInvariantHeader()) {
+    header.form = IETF_QUIC_LONG_HEADER_PACKET;
+  }
+
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPacketHeader(Ref(header), _, _)).Times(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(1);
+  EXPECT_CALL(debug_visitor, OnSuccessfulVersionNegotiation(_)).Times(1);
+  connection_.OnPacketHeader(header);
+}
+
+TEST_P(QuicConnectionTest, Pacing) {
+  TestConnection server(connection_id_, kPeerAddress, kSelfAddress,
+                        helper_.get(), alarm_factory_.get(), writer_.get(),
+                        Perspective::IS_SERVER, version());
+  TestConnection client(connection_id_, kSelfAddress, kPeerAddress,
+                        helper_.get(), alarm_factory_.get(), writer_.get(),
+                        Perspective::IS_CLIENT, version());
+  EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing(
+      static_cast<const QuicSentPacketManager*>(
+          &client.sent_packet_manager())));
+  EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing(
+      static_cast<const QuicSentPacketManager*>(
+          &server.sent_packet_manager())));
+}
+
+TEST_P(QuicConnectionTest, WindowUpdateInstigateAcks) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Send a WINDOW_UPDATE frame.
+  QuicWindowUpdateFrame window_update;
+  window_update.stream_id = 3;
+  window_update.max_data = 1234;
+  EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
+  ProcessFramePacket(QuicFrame(window_update));
+
+  // Ensure that this has caused the ACK alarm to be set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, BlockedFrameInstigateAcks) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Send a BLOCKED frame.
+  QuicBlockedFrame blocked;
+  blocked.stream_id = 3;
+  EXPECT_CALL(visitor_, OnBlockedFrame(_));
+  ProcessFramePacket(QuicFrame(blocked));
+
+  // Ensure that this has caused the ACK alarm to be set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, ReevaluateTimeUntilSendOnAck) {
+  // Enable pacing.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  // Send two packets.  One packet is not sufficient because if it gets acked,
+  // there will be no packets in flight after that and the pacer will always
+  // allow the next packet in that situation.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "bar",
+      3, NO_FIN);
+  connection_.OnCanWrite();
+
+  // Schedule the next packet for a few milliseconds in future.
+  QuicSentPacketManagerPeer::DisablePacerBursts(manager_);
+  QuicTime scheduled_pacing_time =
+      clock_.Now() + QuicTime::Delta::FromMilliseconds(5);
+  QuicSentPacketManagerPeer::SetNextPacedPacketTime(manager_,
+                                                    scheduled_pacing_time);
+
+  // Send a packet and have it be blocked by congestion control.
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(false));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "baz",
+      6, NO_FIN);
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+
+  // Process an ack and the send alarm will be set to the new 5ms delay.
+  QuicAckFrame ack = InitAckFrame(1);
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  ProcessAckPacket(&ack);
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_TRUE(connection_.GetSendAlarm()->IsSet());
+  EXPECT_EQ(scheduled_pacing_time, connection_.GetSendAlarm()->deadline());
+  writer_->Reset();
+}
+
+TEST_P(QuicConnectionTest, SendAcksImmediately) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  CongestionBlockWrites();
+  SendAckPacketToPeer();
+}
+
+TEST_P(QuicConnectionTest, SendPingImmediately) {
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  CongestionBlockWrites();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+  EXPECT_CALL(debug_visitor, OnPingSent()).Times(1);
+  connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+  EXPECT_FALSE(connection_.HasQueuedData());
+}
+
+TEST_P(QuicConnectionTest, SendBlockedImmediately) {
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+  connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
+  EXPECT_EQ(1u, connection_.GetStats().blocked_frames_sent);
+  EXPECT_FALSE(connection_.HasQueuedData());
+}
+
+TEST_P(QuicConnectionTest, FailedToSendBlockedFrames) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  QuicBlockedFrame blocked(1, 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(0);
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+  connection_.SendControlFrame(QuicFrame(blocked));
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+  EXPECT_FALSE(connection_.HasQueuedData());
+}
+
+TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  EXPECT_QUIC_BUG(connection_.SaveAndSendStreamData(3, {}, 0, FIN),
+                  "Cannot send stream data with level: ENCRYPTION_INITIAL");
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA));
+}
+
+TEST_P(QuicConnectionTest, SetRetransmissionAlarmForCryptoPacket) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendCryptoStreamData();
+
+  // Verify retransmission timer is correctly set after crypto packet has been
+  // sent.
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  QuicTime retransmission_time =
+      QuicConnectionPeer::GetSentPacketManager(&connection_)
+          ->GetRetransmissionTime();
+  EXPECT_NE(retransmission_time, clock_.ApproximateNow());
+  EXPECT_EQ(retransmission_time,
+            connection_.GetRetransmissionAlarm()->deadline());
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+}
+
+// Includes regression test for b/69979024.
+TEST_P(QuicConnectionTest, PathDegradingDetectionForNonCryptoPackets) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  for (int i = 0; i < 2; ++i) {
+    // Send a packet. Now there's a retransmittable packet on the wire, so the
+    // path degrading detection should be set.
+    connection_.SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
+        offset, NO_FIN);
+    offset += data_size;
+    EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+    // Check the deadline of the path degrading detection.
+    QuicTime::Delta delay =
+        QuicConnectionPeer::GetSentPacketManager(&connection_)
+            ->GetPathDegradingDelay();
+    EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                         clock_.ApproximateNow());
+
+    // Send a second packet. The path degrading detection's deadline should
+    // remain the same.
+    // Regression test for b/69979024.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    QuicTime prev_deadline =
+        connection_.GetBlackholeDetectorAlarm()->deadline();
+    connection_.SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
+        offset, NO_FIN);
+    offset += data_size;
+    EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+    EXPECT_EQ(prev_deadline,
+              connection_.GetBlackholeDetectorAlarm()->deadline());
+
+    // Now receive an ACK of the first packet. This should advance the path
+    // degrading detection's deadline since forward progress has been made.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    if (i == 0) {
+      EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+    }
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(1u + 2u * i), QuicPacketNumber(2u + 2u * i)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+    // Check the deadline of the path degrading detection.
+    delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+                ->GetPathDegradingDelay();
+    EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                         clock_.ApproximateNow());
+
+    if (i == 0) {
+      // Now receive an ACK of the second packet. Since there are no more
+      // retransmittable packets on the wire, this should cancel the path
+      // degrading detection.
+      clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+      EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+      frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+      ProcessAckPacket(&frame);
+      EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+    } else {
+      // Advance time to the path degrading alarm's deadline and simulate
+      // firing the alarm.
+      clock_.AdvanceTime(delay);
+      EXPECT_CALL(visitor_, OnPathDegrading());
+      connection_.PathDegradingTimeout();
+      EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+    }
+  }
+  EXPECT_TRUE(connection_.IsPathDegrading());
+}
+
+TEST_P(QuicConnectionTest, RetransmittableOnWireSetsPingAlarm) {
+  const QuicTime::Delta retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(50);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Send a packet.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  // Now there's a retransmittable packet on the wire, so the path degrading
+  // alarm should be set.
+  // The retransmittable-on-wire alarm should not be set.
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+                              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+  ASSERT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now receive an ACK of the packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(&frame);
+  // No more retransmittable packets on the wire, so the path degrading alarm
+  // should be cancelled, and the ping alarm should be set to the
+  // retransmittable_on_wire_timeout.
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Simulate firing the ping alarm and sending a PING.
+  clock_.AdvanceTime(retransmittable_on_wire_timeout);
+  connection_.GetPingAlarm()->Fire();
+
+  // Now there's a retransmittable packet (PING) on the wire, so the path
+  // degrading alarm should be set.
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+}
+
+TEST_P(QuicConnectionTest, ServerRetransmittableOnWire) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  SetQuicReloadableFlag(quic_enable_server_on_wire_ping, true);
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kSRWP);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  connection_.SetFromConfig(config);
+
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  ProcessPacket(1);
+
+  ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
+  QuicTime::Delta ping_delay = QuicTime::Delta::FromMilliseconds(200);
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  // Verify PING alarm gets cancelled.
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+
+  // Now receive an ACK of the packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(2, &frame);
+  // Verify PING alarm gets scheduled.
+  ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+// This test verifies that the connection marks path as degrading and does not
+// spin timer to detect path degrading when a new packet is sent on the
+// degraded path.
+TEST_P(QuicConnectionTest, NoPathDegradingDetectionIfPathIsDegrading) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Send the first packet. Now there's a retransmittable packet on the wire, so
+  // the path degrading alarm should be set.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  // Check the deadline of the path degrading detection.
+  QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+                              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+
+  // Send a second packet. The path degrading detection's deadline should remain
+  // the same.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicTime prev_deadline = connection_.GetBlackholeDetectorAlarm()->deadline();
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_EQ(prev_deadline, connection_.GetBlackholeDetectorAlarm()->deadline());
+
+  // Now receive an ACK of the first packet. This should advance the path
+  // degrading detection's deadline since forward progress has been made.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  // Check the deadline of the path degrading alarm.
+  delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+
+  // Advance time to the path degrading detection's deadline and simulate
+  // firing the path degrading detection. This path will be considered as
+  // degrading.
+  clock_.AdvanceTime(delay);
+  EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
+  connection_.PathDegradingTimeout();
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.IsPathDegrading());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  // Send a third packet. The path degrading detection is no longer set but path
+  // should still be marked as degrading.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.IsPathDegrading());
+}
+
+// This test verifies that the connection unmarks path as degrarding and spins
+// the timer to detect future path degrading when forward progress is made
+// after path has been marked degrading.
+TEST_P(QuicConnectionTest, UnmarkPathDegradingOnForwardProgress) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Send the first packet. Now there's a retransmittable packet on the wire, so
+  // the path degrading alarm should be set.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  // Check the deadline of the path degrading alarm.
+  QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+                              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+
+  // Send a second packet. The path degrading alarm's deadline should remain
+  // the same.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicTime prev_deadline = connection_.GetBlackholeDetectorAlarm()->deadline();
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_EQ(prev_deadline, connection_.GetBlackholeDetectorAlarm()->deadline());
+
+  // Now receive an ACK of the first packet. This should advance the path
+  // degrading alarm's deadline since forward progress has been made.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  // Check the deadline of the path degrading alarm.
+  delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+
+  // Advance time to the path degrading alarm's deadline and simulate
+  // firing the alarm.
+  clock_.AdvanceTime(delay);
+  EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
+  connection_.PathDegradingTimeout();
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.IsPathDegrading());
+
+  // Send a third packet. The path degrading alarm is no longer set but path
+  // should still be marked as degrading.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.IsPathDegrading());
+
+  // Now receive an ACK of the second packet. This should unmark the path as
+  // degrading. And will set a timer to detect new path degrading.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  ProcessAckPacket(&frame);
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, NoPathDegradingOnServer) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+  // Send data.
+  const char data[] = "data";
+  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+  // Ack data.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
+  ProcessAckPacket(&frame);
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, NoPathDegradingAfterSendingAck) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  SendAckPacketToPeer();
+  EXPECT_FALSE(connection_.sent_packet_manager().unacked_packets().empty());
+  EXPECT_FALSE(connection_.sent_packet_manager().HasInFlightPackets());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, MultipleCallsToCloseConnection) {
+  // Verifies that multiple calls to CloseConnection do not
+  // result in multiple attempts to close the connection - it will be marked as
+  // disconnected after the first call.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
+  connection_.CloseConnection(QUIC_NO_ERROR, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+  connection_.CloseConnection(QUIC_NO_ERROR, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+TEST_P(QuicConnectionTest, ServerReceivesChloOnNonCryptoStream) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  CryptoHandshakeMessage message;
+  CryptoFramer framer;
+  message.set_tag(kCHLO);
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  frame1_.stream_id = 10;
+  frame1_.data_buffer = data->data();
+  frame1_.data_length = data->length();
+
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  ForceProcessFramePacket(QuicFrame(frame1_));
+  if (VersionHasIetfQuicFrames(version().transport_version)) {
+    // INITIAL packet should not contain STREAM frame.
+    TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+  } else {
+    TestConnectionCloseQuicErrorCode(QUIC_MAYBE_CORRUPTED_MEMORY);
+  }
+}
+
+TEST_P(QuicConnectionTest, ClientReceivesRejOnNonCryptoStream) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  CryptoHandshakeMessage message;
+  CryptoFramer framer;
+  message.set_tag(kREJ);
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  frame1_.stream_id = 10;
+  frame1_.data_buffer = data->data();
+  frame1_.data_length = data->length();
+
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  ForceProcessFramePacket(QuicFrame(frame1_));
+  if (VersionHasIetfQuicFrames(version().transport_version)) {
+    // INITIAL packet should not contain STREAM frame.
+    TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+  } else {
+    TestConnectionCloseQuicErrorCode(QUIC_MAYBE_CORRUPTED_MEMORY);
+  }
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnPacketTooLarge) {
+  SimulateNextPacketTooLarge();
+  // A connection close packet is sent
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+TEST_P(QuicConnectionTest, AlwaysGetPacketTooLarge) {
+  // Test even we always get packet too large, we do not infinitely try to send
+  // close packet.
+  AlwaysGetPacketTooLarge();
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnQueuedWriteError) {
+  // Regression test for crbug.com/979507.
+  //
+  // If we get a write error when writing queued packets, we should attempt to
+  // send a connection close packet, but if sending that fails, it shouldn't get
+  // queued.
+
+  // Queue a packet to write.
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Configure writer to always fail.
+  AlwaysGetPacketTooLarge();
+
+  // Expect that we attempt to close the connection exactly once.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+
+  // Unblock the writes and actually send.
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+// Verify that if connection has no outstanding data, it notifies the send
+// algorithm after the write.
+TEST_P(QuicConnectionTest, SendDataAndBecomeApplicationLimited) {
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
+  {
+    InSequence seq;
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+        .WillRepeatedly(Return(false));
+  }
+
+  connection_.SendStreamData3();
+}
+
+// Verify that the connection does not become app-limited if there is
+// outstanding data to send after the write.
+TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedIfMoreDataAvailable) {
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
+  {
+    InSequence seq;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
+  }
+
+  connection_.SendStreamData3();
+}
+
+// Verify that the connection does not become app-limited after blocked write
+// even if there is outstanding data to send after the write.
+TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedDueToWriteBlock) {
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
+  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
+  BlockOnNextWrite();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamData3();
+
+  // Now unblock the writer, become congestion control blocked,
+  // and ensure we become app-limited after writing.
+  writer_->SetWritable();
+  CongestionBlockWrites();
+  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
+  connection_.OnCanWrite();
+}
+
+// Test the mode in which the link is filled up with probing retransmissions if
+// the connection becomes application-limited.
+TEST_P(QuicConnectionTest, SendDataWhenApplicationLimited) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
+      .WillRepeatedly(Return(true));
+  {
+    InSequence seq;
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+        .WillRepeatedly(Return(false));
+  }
+  EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
+    return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
+        PROBING_RETRANSMISSION);
+  });
+  // Fix congestion window to be 20,000 bytes.
+  EXPECT_CALL(*send_algorithm_, CanSend(Ge(20000u)))
+      .WillRepeatedly(Return(false));
+  EXPECT_CALL(*send_algorithm_, CanSend(Lt(20000u)))
+      .WillRepeatedly(Return(true));
+
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
+  ASSERT_EQ(0u, connection_.GetStats().packets_sent);
+  connection_.set_fill_up_link_during_probing(true);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+  connection_.SendStreamData3();
+
+  // We expect a lot of packets from a 20 kbyte window.
+  EXPECT_GT(connection_.GetStats().packets_sent, 10u);
+  // Ensure that the packets are padded.
+  QuicByteCount average_packet_size =
+      connection_.GetStats().bytes_sent / connection_.GetStats().packets_sent;
+  EXPECT_GT(average_packet_size, 1000u);
+
+  // Acknowledge all packets sent, except for the last one.
+  QuicAckFrame ack = InitAckFrame(
+      connection_.sent_packet_manager().GetLargestSentPacket() - 1);
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+
+  // Ensure that since we no longer have retransmittable bytes in flight, this
+  // will not cause any responses to be sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
+  ProcessAckPacket(&ack);
+}
+
+TEST_P(QuicConnectionTest, DoNotForceSendingAckOnPacketTooLarge) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  // Send an ack by simulating delayed ack alarm firing.
+  ProcessPacket(1);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  connection_.GetAckAlarm()->Fire();
+  // Simulate data packet causes write error.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  SimulateNextPacketTooLarge();
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  // Ack frame is not bundled in connection close packet.
+  EXPECT_TRUE(writer_->ack_frames().empty());
+  if (writer_->padding_frames().empty()) {
+    EXPECT_EQ(1u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+  }
+
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionAllLevels) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    // Each connection close packet should be sent in distinct UDP packets.
+    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+              writer_->connection_close_packets());
+    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+              writer_->packets_write_attempts());
+    return;
+  }
+
+  // A single UDP packet should be sent with multiple connection close packets
+  // coalesced together.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Only the first packet has been processed yet.
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+
+  // ProcessPacket resets the visitor and frees the coalesced packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOneLevel) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
+TEST_P(QuicConnectionTest, DoNotPadServerInitialConnectionClose) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  EXPECT_TRUE(writer_->padding_frames().empty());
+  EXPECT_EQ(ENCRYPTION_INITIAL, writer_->framer()->last_decrypted_level());
+}
+
+// Regression test for b/63620844.
+TEST_P(QuicConnectionTest, FailedToWriteHandshakePacket) {
+  SimulateNextPacketTooLarge();
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+
+  connection_.SendCryptoStreamData();
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+TEST_P(QuicConnectionTest, MaxPacingRate) {
+  EXPECT_EQ(0, connection_.MaxPacingRate().ToBytesPerSecond());
+  connection_.SetMaxPacingRate(QuicBandwidth::FromBytesPerSecond(100));
+  EXPECT_EQ(100, connection_.MaxPacingRate().ToBytesPerSecond());
+}
+
+TEST_P(QuicConnectionTest, ClientAlwaysSendConnectionId) {
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_EQ(CONNECTION_ID_PRESENT,
+            writer_->last_packet_header().destination_connection_id_included);
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedBytesForConnectionId(&config, 0);
+  connection_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(3, "bar", 3, NO_FIN);
+  // Verify connection id is still sent in the packet.
+  EXPECT_EQ(CONNECTION_ID_PRESENT,
+            writer_->last_packet_header().destination_connection_id_included);
+}
+
+TEST_P(QuicConnectionTest, SendProbingRetransmissions) {
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  const QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "bar", 3, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "test", 6, NO_FIN, &last_packet);
+
+  const QuicByteCount old_bytes_in_flight =
+      connection_.sent_packet_manager().GetBytesInFlight();
+
+  // Allow 9 probing retransmissions to be sent.
+  {
+    InSequence seq;
+    EXPECT_CALL(*send_algorithm_, CanSend(_))
+        .Times(9 * 2)
+        .WillRepeatedly(Return(true));
+    EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  }
+  // Expect them retransmitted in cyclic order (foo, bar, test, foo, bar...).
+  QuicPacketCount sent_count = 0;
+
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _))
+      .WillRepeatedly(Invoke(
+          [this, &sent_count](QuicPacketNumber, QuicPacketLength, bool,
+                              TransmissionType, EncryptionLevel,
+                              const QuicFrames&, const QuicFrames&, QuicTime) {
+            ASSERT_EQ(1u, writer_->stream_frames().size());
+            if (connection_.version().CanSendCoalescedPackets()) {
+              // There is a delay of sending coalesced packet, so (6, 0, 3, 6,
+              // 0...).
+              EXPECT_EQ(3 * ((sent_count + 2) % 3),
+                        writer_->stream_frames()[0]->offset);
+            } else {
+              // Identify the frames by stream offset (0, 3, 6, 0, 3...).
+              EXPECT_EQ(3 * (sent_count % 3),
+                        writer_->stream_frames()[0]->offset);
+            }
+            sent_count++;
+          }));
+
+  EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
+    return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
+        PROBING_RETRANSMISSION);
+  });
+
+  connection_.SendProbingRetransmissions();
+
+  // Ensure that the in-flight has increased.
+  const QuicByteCount new_bytes_in_flight =
+      connection_.sent_packet_manager().GetBytesInFlight();
+  EXPECT_GT(new_bytes_in_flight, old_bytes_in_flight);
+}
+
+// Ensure that SendProbingRetransmissions() does not retransmit anything when
+// there are no outstanding packets.
+TEST_P(QuicConnectionTest,
+       SendProbingRetransmissionsFailsWhenNothingToRetransmit) {
+  ASSERT_TRUE(connection_.sent_packet_manager().unacked_packets().empty());
+
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
+    return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
+        PROBING_RETRANSMISSION);
+  });
+
+  connection_.SendProbingRetransmissions();
+}
+
+TEST_P(QuicConnectionTest, PingAfterLastRetransmittablePacketAcked) {
+  const QuicTime::Delta retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(50);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Advance 5ms, send a retransmittable packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Advance 5ms, send a second retransmittable packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+
+  // Now receive an ACK of the first packet. This should not set the
+  // retransmittable-on-wire alarm since packet 2 is still on the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  // The ping alarm has a 1 second granularity, and the clock has been advanced
+  // 10ms since it was originally set.
+  EXPECT_EQ(ping_delay - QuicTime::Delta::FromMilliseconds(10),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now receive an ACK of the second packet. This should set the
+  // retransmittable-on-wire alarm now that no retransmittable packets are on
+  // the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now receive a duplicate ACK of the second packet. This should not update
+  // the ping alarm.
+  QuicTime prev_deadline = connection_.GetPingAlarm()->deadline();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
+
+  // Now receive a non-ACK packet.  This should not update the ping alarm.
+  prev_deadline = connection_.GetPingAlarm()->deadline();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  ProcessPacket(4);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
+
+  // Simulate the alarm firing and check that a PING is sent.
+  connection_.GetPingAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(padding_frame_count + 3u, writer_->frame_count());
+  }
+  ASSERT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, NoPingIfRetransmittablePacketSent) {
+  const QuicTime::Delta retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(50);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Advance 5ms, send a retransmittable packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now receive an ACK of the first packet. This should set the
+  // retransmittable-on-wire alarm now that no retransmittable packets are on
+  // the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Before the alarm fires, send another retransmittable packet. This should
+  // cancel the retransmittable-on-wire alarm since now there's a
+  // retransmittable packet on the wire.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+
+  // Now receive an ACK of the second packet. This should set the
+  // retransmittable-on-wire alarm now that no retransmittable packets are on
+  // the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Simulate the alarm firing and check that a PING is sent.
+  writer_->Reset();
+  connection_.GetPingAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    // Do not ACK acks.
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(padding_frame_count + 3u, writer_->frame_count());
+  }
+  ASSERT_EQ(1u, writer_->ping_frames().size());
+}
+
+// When there is no stream data received but are open streams, send the
+// first few consecutive pings with aggressive retransmittable-on-wire
+// timeout. Exponentially back off the retransmittable-on-wire ping timeout
+// afterwards until it exceeds the default ping timeout.
+TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) {
+  int max_aggressive_retransmittable_on_wire_ping_count = 5;
+  SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count,
+              max_aggressive_retransmittable_on_wire_ping_count);
+  const QuicTime::Delta initial_retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(200);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      initial_retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  const char data[] = "data";
+  // Advance 5ms, send a retransmittable data packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+
+  // Verify that the first few consecutive retransmittable on wire pings are
+  // sent with aggressive timeout.
+  for (int i = 0; i <= max_aggressive_retransmittable_on_wire_ping_count; i++) {
+    // Receive an ACK of the previous packet. This should set the ping alarm
+    // with the initial retransmittable-on-wire timeout.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    QuicPacketNumber ack_num = creator_->packet_number();
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+    EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+    // Simulate the alarm firing and check that a PING is sent.
+    writer_->Reset();
+    clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+    connection_.GetPingAlarm()->Fire();
+  }
+
+  QuicTime::Delta retransmittable_on_wire_timeout =
+      initial_retransmittable_on_wire_timeout;
+
+  // Verify subsequent pings are sent with timeout that is exponentially backed
+  // off.
+  while (retransmittable_on_wire_timeout * 2 < connection_.ping_timeout()) {
+    // Receive an ACK for the previous PING. This should set the
+    // ping alarm with backed off retransmittable-on-wire timeout.
+    retransmittable_on_wire_timeout = retransmittable_on_wire_timeout * 2;
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    QuicPacketNumber ack_num = creator_->packet_number();
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+    EXPECT_EQ(retransmittable_on_wire_timeout,
+              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+    // Simulate the alarm firing and check that a PING is sent.
+    writer_->Reset();
+    clock_.AdvanceTime(retransmittable_on_wire_timeout);
+    connection_.GetPingAlarm()->Fire();
+  }
+
+  // The ping alarm is set with default ping timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Receive an ACK for the previous PING. The ping alarm is set with an
+  // earlier deadline.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicPacketNumber ack_num = creator_->packet_number();
+  QuicAckFrame frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout() - QuicTime::Delta::FromMilliseconds(5),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+// This test verify that the count of consecutive aggressive pings is reset
+// when new data is received. And it also verifies the connection resets
+// the exponential back-off of the retransmittable-on-wire ping timeout
+// after receiving new stream data.
+TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) {
+  int max_aggressive_retransmittable_on_wire_ping_count = 3;
+  SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count, 3);
+  const QuicTime::Delta initial_retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(200);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      initial_retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+
+  const char data[] = "data";
+  // Advance 5ms, send a retransmittable data packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Receive an ACK of the first packet. This should set the ping alarm with
+  // initial retransmittable-on-wire timeout since there is no retransmittable
+  // packet on the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Simulate the alarm firing and check that a PING is sent.
+  writer_->Reset();
+  clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+  connection_.GetPingAlarm()->Fire();
+
+  // Receive an ACK for the previous PING. Ping alarm will be set with
+  // aggressive timeout.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicPacketNumber ack_num = creator_->packet_number();
+  frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Process a data packet.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(peer_creator_.packet_number() + 1);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_,
+                                         peer_creator_.packet_number() + 1);
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Verify the count of consecutive aggressive pings is reset.
+  for (int i = 0; i < max_aggressive_retransmittable_on_wire_ping_count; i++) {
+    // Receive an ACK of the previous packet. This should set the ping alarm
+    // with the initial retransmittable-on-wire timeout.
+    QuicPacketNumber ack_num = creator_->packet_number();
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+    EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+    // Simulate the alarm firing and check that a PING is sent.
+    writer_->Reset();
+    clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+    connection_.GetPingAlarm()->Fire();
+    // Advance 5ms to receive next packet.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  }
+
+  // Receive another ACK for the previous PING. This should set the
+  // ping alarm with backed off retransmittable-on-wire timeout.
+  ack_num = creator_->packet_number();
+  frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout * 2,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  writer_->Reset();
+  clock_.AdvanceTime(2 * initial_retransmittable_on_wire_timeout);
+  connection_.GetPingAlarm()->Fire();
+
+  // Process another data packet and a new ACK packet. The ping alarm is set
+  // with aggressive ping timeout again.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  ProcessDataPacket(peer_creator_.packet_number() + 1);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_,
+                                         peer_creator_.packet_number() + 1);
+  ack_num = creator_->packet_number();
+  frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+// Make sure that we never send more retransmissible on the wire pings than
+// the limit in FLAGS_quic_max_retransmittable_on_wire_ping_count.
+TEST_P(QuicConnectionTest, RetransmittableOnWirePingLimit) {
+  static constexpr int kMaxRetransmittableOnWirePingCount = 3;
+  SetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count,
+              kMaxRetransmittableOnWirePingCount);
+  static constexpr QuicTime::Delta initial_retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(200);
+  static constexpr QuicTime::Delta short_delay =
+      QuicTime::Delta::FromMilliseconds(5);
+  ASSERT_LT(short_delay * 10, initial_retransmittable_on_wire_timeout);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      initial_retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  const char data[] = "data";
+  // Advance 5ms, send a retransmittable data packet to the peer.
+  clock_.AdvanceTime(short_delay);
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+
+  // Verify that the first few consecutive retransmittable on wire pings are
+  // sent with aggressive timeout.
+  for (int i = 0; i <= kMaxRetransmittableOnWirePingCount; i++) {
+    // Receive an ACK of the previous packet. This should set the ping alarm
+    // with the initial retransmittable-on-wire timeout.
+    clock_.AdvanceTime(short_delay);
+    QuicPacketNumber ack_num = creator_->packet_number();
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+    EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+    // Simulate the alarm firing and check that a PING is sent.
+    writer_->Reset();
+    clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+    connection_.GetPingAlarm()->Fire();
+  }
+
+  // Receive an ACK of the previous packet. This should set the ping alarm
+  // but this time with the default ping timeout.
+  QuicPacketNumber ack_num = creator_->packet_number();
+  QuicAckFrame frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+TEST_P(QuicConnectionTest, ValidStatelessResetToken) {
+  const StatelessResetToken kTestToken{0, 1, 0, 1, 0, 1, 0, 1,
+                                       0, 1, 0, 1, 0, 1, 0, 1};
+  const StatelessResetToken kWrongTestToken{0, 1, 0, 1, 0, 1, 0, 1,
+                                            0, 1, 0, 1, 0, 1, 0, 2};
+  QuicConfig config;
+  // No token has been received.
+  EXPECT_FALSE(connection_.IsValidStatelessResetToken(kTestToken));
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(2);
+  // Token is different from received token.
+  QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
+  connection_.SetFromConfig(config);
+  EXPECT_FALSE(connection_.IsValidStatelessResetToken(kWrongTestToken));
+
+  QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
+  connection_.SetFromConfig(config);
+  EXPECT_TRUE(connection_.IsValidStatelessResetToken(kTestToken));
+}
+
+TEST_P(QuicConnectionTest, WriteBlockedWithInvalidAck) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  BlockOnNextWrite();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(5, "foo", 0, FIN);
+  // This causes connection to be closed because packet 1 has not been sent yet.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessAckPacket(1, &frame);
+  EXPECT_EQ(0, connection_close_frame_count_);
+}
+
+TEST_P(QuicConnectionTest, SendMessage) {
+  if (!VersionSupportsMessageFrames(connection_.transport_version())) {
+    return;
+  }
+  if (connection_.version().UsesTls()) {
+    QuicConfig config;
+    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
+        &config, kMaxAcceptedDatagramFrameSize);
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  std::string message(connection_.GetCurrentLargestMessagePayload() * 2, 'a');
+  quiche::QuicheMemSlice slice;
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendStreamData3();
+    // Send a message which cannot fit into current open packet, and 2 packets
+    // get sent, one contains stream frame, and the other only contains the
+    // message frame.
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+    slice = MemSliceFromString(absl::string_view(
+        message.data(), connection_.GetCurrentLargestMessagePayload()));
+    EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
+              connection_.SendMessage(1, absl::MakeSpan(&slice, 1), false));
+  }
+  // Fail to send a message if connection is congestion control blocked.
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  slice = MemSliceFromString("message");
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
+            connection_.SendMessage(2, absl::MakeSpan(&slice, 1), false));
+
+  // Always fail to send a message which cannot fit into one packet.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  slice = MemSliceFromString(absl::string_view(
+      message.data(), connection_.GetCurrentLargestMessagePayload() + 1));
+  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
+            connection_.SendMessage(3, absl::MakeSpan(&slice, 1), false));
+}
+
+TEST_P(QuicConnectionTest, GetCurrentLargestMessagePayload) {
+  if (!connection_.version().SupportsMessageFrames()) {
+    return;
+  }
+  // Force use of this encrypter to simplify test expectations by making sure
+  // that the encryption overhead is constant across versions.
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x00));
+  QuicPacketLength expected_largest_payload = 1219;
+  if (connection_.version().SendsVariableLengthPacketNumberInLongHeader()) {
+    expected_largest_payload += 3;
+  }
+  if (connection_.version().HasLongHeaderLengths()) {
+    expected_largest_payload -= 2;
+  }
+  if (connection_.version().HasLengthPrefixedConnectionIds()) {
+    expected_largest_payload -= 1;
+  }
+  if (connection_.version().UsesTls()) {
+    // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
+    EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), 0);
+    QuicConfig config;
+    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
+        &config, kMaxAcceptedDatagramFrameSize);
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+    // Verify the value post-handshake.
+    EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(),
+              expected_largest_payload);
+  } else {
+    EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(),
+              expected_largest_payload);
+  }
+}
+
+TEST_P(QuicConnectionTest, GetGuaranteedLargestMessagePayload) {
+  if (!connection_.version().SupportsMessageFrames()) {
+    return;
+  }
+  // Force use of this encrypter to simplify test expectations by making sure
+  // that the encryption overhead is constant across versions.
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x00));
+  QuicPacketLength expected_largest_payload = 1219;
+  if (connection_.version().HasLongHeaderLengths()) {
+    expected_largest_payload -= 2;
+  }
+  if (connection_.version().HasLengthPrefixedConnectionIds()) {
+    expected_largest_payload -= 1;
+  }
+  if (connection_.version().UsesTls()) {
+    // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
+    EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(), 0);
+    QuicConfig config;
+    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
+        &config, kMaxAcceptedDatagramFrameSize);
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+    // Verify the value post-handshake.
+    EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
+              expected_largest_payload);
+  } else {
+    EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
+              expected_largest_payload);
+  }
+}
+
+TEST_P(QuicConnectionTest, LimitedLargestMessagePayload) {
+  if (!connection_.version().SupportsMessageFrames() ||
+      !connection_.version().UsesTls()) {
+    return;
+  }
+  constexpr QuicPacketLength kFrameSizeLimit = 1000;
+  constexpr QuicPacketLength kPayloadSizeLimit =
+      kFrameSizeLimit - kQuicFrameTypeSize;
+  // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
+  EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), 0);
+  EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(), 0);
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMaxDatagramFrameSize(&config, kFrameSizeLimit);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  // Verify the value post-handshake.
+  EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), kPayloadSizeLimit);
+  EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
+            kPayloadSizeLimit);
+}
+
+// Test to check that the path challenge/path response logic works
+// correctly. This test is only for version-99
+TEST_P(QuicConnectionTest, ServerResponseToPathChallenge) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  // First check if the server can send probing packet.
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  // Create and send the probe request (PATH_CHALLENGE frame).
+  // SendConnectivityProbingPacket ends up calling
+  // TestPacketWriter::WritePacket() which in turns receives and parses the
+  // packet by calling framer_.ProcessPacket() -- which in turn calls
+  // SimpleQuicFramer::OnPathChallengeFrame(). SimpleQuicFramer saves
+  // the packet in writer_->path_challenge_frames()
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+  // Save the random contents of the challenge for later comparison to the
+  // response.
+  ASSERT_GE(writer_->path_challenge_frames().size(), 1u);
+  QuicPathFrameBuffer challenge_data =
+      writer_->path_challenge_frames().front().data_buffer;
+
+  // Normally, QuicConnection::OnPathChallengeFrame and OnPaddingFrame would be
+  // called and it will perform actions to ensure that the rest of the protocol
+  // is performed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_TRUE(connection_.OnPathChallengeFrame(
+      writer_->path_challenge_frames().front()));
+  EXPECT_TRUE(connection_.OnPaddingFrame(writer_->padding_frames().front()));
+  creator_->FlushCurrentPacket();
+
+  // The final check is to ensure that the random data in the response matches
+  // the random data from the challenge.
+  EXPECT_EQ(1u, writer_->path_response_frames().size());
+  EXPECT_EQ(0, memcmp(&challenge_data,
+                      &(writer_->path_response_frames().front().data_buffer),
+                      sizeof(challenge_data)));
+}
+
+TEST_P(QuicConnectionTest, ClientResponseToPathChallengeOnDefaulSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  // First check if the client can send probing packet.
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  // Create and send the probe request (PATH_CHALLENGE frame).
+  // SendConnectivityProbingPacket ends up calling
+  // TestPacketWriter::WritePacket() which in turns receives and parses the
+  // packet by calling framer_.ProcessPacket() -- which in turn calls
+  // SimpleQuicFramer::OnPathChallengeFrame(). SimpleQuicFramer saves
+  // the packet in writer_->path_challenge_frames()
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+  // Save the random contents of the challenge for later validation against the
+  // response.
+  ASSERT_GE(writer_->path_challenge_frames().size(), 1u);
+  QuicPathFrameBuffer challenge_data =
+      writer_->path_challenge_frames().front().data_buffer;
+
+  // Normally, QuicConnection::OnPathChallengeFrame would be
+  // called and it will perform actions to ensure that the rest of the protocol
+  // is performed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_TRUE(connection_.OnPathChallengeFrame(
+      writer_->path_challenge_frames().front()));
+  EXPECT_TRUE(connection_.OnPaddingFrame(writer_->padding_frames().front()));
+  creator_->FlushCurrentPacket();
+
+  // The final check is to ensure that the random data in the response matches
+  // the random data from the challenge.
+  EXPECT_EQ(1u, writer_->path_response_frames().size());
+  EXPECT_EQ(0, memcmp(&challenge_data,
+                      &(writer_->path_response_frames().front().data_buffer),
+                      sizeof(challenge_data)));
+}
+
+TEST_P(QuicConnectionTest, ClientResponseToPathChallengeOnAlternativeSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+
+  // Receiving a PATH_CHALLENGE on the alternative path. Response to this
+  // PATH_CHALLENGE should be sent via the alternative writer.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(2u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_response_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
+
+  QuicSocketAddress kNewerSelfAddress(QuicIpAddress::Loopback6(),
+                                      /*port=*/34567);
+  // Receiving a PATH_CHALLENGE on an unknown socket should be ignored.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
+  ProcessReceivedPacket(kNewerSelfAddress, kPeerAddress, *received);
+}
+
+TEST_P(QuicConnectionTest,
+       RestartPathDegradingDetectionAfterMigrationWithProbe) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  // Send data and verify the path degrading detection is set.
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+
+  // Verify the path degrading detection is in progress.
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  QuicTime ddl = connection_.GetBlackholeDetectorAlarm()->deadline();
+
+  // Simulate the firing of path degrading.
+  clock_.AdvanceTime(ddl - clock_.ApproximateNow());
+  EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
+  connection_.PathDegradingTimeout();
+  EXPECT_TRUE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    // Simulate path degrading handling by sending a probe on an alternet path.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
+    connection_.SendConnectivityProbingPacket(&probing_writer,
+                                              connection_.peer_address());
+    // Verify that path degrading detection is not reset.
+    EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+    // Simulate successful path degrading handling by receiving probe response.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+    const QuicSocketAddress kNewSelfAddress =
+        QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+    std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+    std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+        QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                            probing_packet->encrypted_length),
+        clock_.Now()));
+    uint64_t num_probing_received =
+        connection_.GetStats().num_connectivity_probing_received;
+    ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
+
+    EXPECT_EQ(num_probing_received + 1,
+              connection_.GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(kPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+    EXPECT_TRUE(connection_.IsPathDegrading());
+  }
+
+  // Verify new path degrading detection is activated.
+  EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
+  connection_.OnSuccessfulMigration(/*is_port_change*/ true);
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, ClientsResetCwndAfterConnectionMigration) {
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  EXPECT_EQ(kSelfAddress, connection_.self_address());
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(manager_, 1);
+  EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(manager_, 2);
+  EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+  const SendAlgorithmInterface* send_algorithm = manager_->GetSendAlgorithm();
+
+  // Migrate to a new address with different IP.
+  const QuicSocketAddress kNewSelfAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
+                          &new_writer, false);
+  EXPECT_EQ(default_init_rtt, manager_->GetRttStats()->initial_rtt());
+  EXPECT_EQ(0u, manager_->GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_->GetConsecutiveTlpCount());
+  EXPECT_NE(send_algorithm, manager_->GetSendAlgorithm());
+}
+
+// Regression test for b/110259444
+TEST_P(QuicConnectionTest, DoNotScheduleSpuriousAckAlarm) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  writer_->SetWriteBlocked();
+
+  ProcessPacket(1);
+  // Verify ack alarm is set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Fire the ack alarm, verify no packet is sent because the writer is blocked.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.GetAckAlarm()->Fire();
+
+  writer_->SetWritable();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(2);
+  // Verify ack alarm is not set.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, DisablePacingOffloadConnectionOptions) {
+  EXPECT_FALSE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
+  writer_->set_supports_release_time(true);
+  QuicConfig config;
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_TRUE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
+
+  QuicTagVector connection_options;
+  connection_options.push_back(kNPCO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  // Verify pacing offload is disabled.
+  EXPECT_FALSE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
+}
+
+// Regression test for b/110259444
+// Get a path response without having issued a path challenge...
+TEST_P(QuicConnectionTest, OrphanPathResponse) {
+  QuicPathFrameBuffer data = {{0, 1, 2, 3, 4, 5, 6, 7}};
+
+  QuicPathResponseFrame frame(99, data);
+  EXPECT_TRUE(connection_.OnPathResponseFrame(frame));
+  // If PATH_RESPONSE was accepted (payload matches the payload saved
+  // in QuicConnection::transmitted_connectivity_probe_payload_) then
+  // current_packet_content_ would be set to FIRST_FRAME_IS_PING.
+  // Since this PATH_RESPONSE does not match, current_packet_content_
+  // must not be FIRST_FRAME_IS_PING.
+  EXPECT_NE(QuicConnection::FIRST_FRAME_IS_PING,
+            QuicConnectionPeer::GetCurrentPacketContent(&connection_));
+}
+
+// Regression test for b/120791670
+TEST_P(QuicConnectionTest, StopProcessingGQuicPacketInIetfQuicConnection) {
+  // This test mimics a problematic scenario where a QUIC connection using a
+  // modern version received a Q043 packet and processed it incorrectly.
+  // We can remove this test once Q043 is deprecated.
+  if (!version().HasIetfInvariantHeader()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+
+  // Let connection process a Google QUIC packet.
+  peer_framer_.set_version_for_tests(ParsedQuicVersion::Q043());
+  std::unique_ptr<QuicPacket> packet(
+      ConstructDataPacket(2, !kHasStopWaiting, ENCRYPTION_INITIAL));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(2),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  // Make sure no stream frame is processed.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(0);
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+
+  EXPECT_EQ(2u, connection_.GetStats().packets_received);
+  EXPECT_EQ(1u, connection_.GetStats().packets_processed);
+}
+
+TEST_P(QuicConnectionTest, AcceptPacketNumberZero) {
+  if (!VersionHasIetfQuicFrames(version().transport_version)) {
+    return;
+  }
+  // Set first_sending_packet_number to be 0 to allow successfully processing
+  // acks which ack packet number 0.
+  QuicFramerPeer::SetFirstSendingPacketNumber(writer_->framer()->framer(), 0);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(0);
+  EXPECT_EQ(QuicPacketNumber(0), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+
+  ProcessPacket(1);
+  EXPECT_EQ(QuicPacketNumber(1), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+
+  ProcessPacket(2);
+  EXPECT_EQ(QuicPacketNumber(2), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+}
+
+TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicSending) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+
+  connection_.SendCryptoStreamData();
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  QuicAckFrame frame1 = InitAckFrame(1);
+  // Received ACK for packet 1.
+  ProcessFramePacketAtLevel(30, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(4);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 0,
+                                         NO_FIN);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 4,
+                                         NO_FIN);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         8, NO_FIN);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         12, FIN);
+  // Received ACK for packets 2, 4, 5.
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  QuicAckFrame frame2 =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
+                    {QuicPacketNumber(4), QuicPacketNumber(6)}});
+  // Make sure although the same packet number is used, but they are in
+  // different packet number spaces.
+  ProcessFramePacketAtLevel(30, QuicFrame(&frame2), ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest, PeerAcksPacketsInWrongPacketNumberSpace) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+
+  connection_.SendCryptoStreamData();
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  QuicAckFrame frame1 = InitAckFrame(1);
+  // Received ACK for packet 1.
+  ProcessFramePacketAtLevel(30, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 0,
+                                         NO_FIN);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 4,
+                                         NO_FIN);
+
+  // Received ACK for packets 2 and 3 in wrong packet number space.
+  QuicAckFrame invalid_ack =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(4)}});
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ProcessFramePacketAtLevel(300, QuicFrame(&invalid_ack), ENCRYPTION_INITIAL);
+  TestConnectionCloseQuicErrorCode(QUIC_INVALID_ACK_DATA);
+}
+
+TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicReceiving) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  // Receives packet 1000 in application data.
+  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         0, NO_FIN);
+  // Verify application data ACK gets bundled with outgoing data.
+  EXPECT_EQ(2u, writer_->frame_count());
+  // Make sure ACK alarm is still set because initial data is not ACKed.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Receive packet 1001 in application data.
+  ProcessDataPacketAtLevel(1001, false, ENCRYPTION_FORWARD_SECURE);
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  // Simulates ACK alarm fires and verify two ACKs are flushed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.GetAckAlarm()->Fire();
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  // Receives more packets in application data.
+  ProcessDataPacketAtLevel(1002, false, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  // Verify zero rtt and forward secure packets get acked in the same packet.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessDataPacket(1003);
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, CancelAckAlarmOnWriteBlocked) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  // Receives packet 1000 in application data.
+  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  writer_->SetWriteBlocked();
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AnyNumber());
+  // Simulates ACK alarm fires and verify no ACK is flushed because of write
+  // blocked.
+  clock_.AdvanceTime(DefaultDelayedAckTime());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.GetAckAlarm()->Fire();
+  // Verify ACK alarm is not set.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+
+  writer_->SetWritable();
+  // Verify 2 ACKs are sent when connection gets unblocked.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.OnCanWrite();
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+// Make sure a packet received with the right client connection ID is processed.
+TEST_P(QuicConnectionTest, ValidClientConnectionId) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  SetClientConnectionId(TestConnectionId(0x33));
+  QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_FORWARD_SECURE);
+  header.destination_connection_id = TestConnectionId(0x33);
+  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+  header.source_connection_id_included = CONNECTION_ID_ABSENT;
+  QuicFrames frames;
+  QuicPingFrame ping_frame;
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(ping_frame));
+  frames.push_back(QuicFrame(padding_frame));
+  std::unique_ptr<QuicPacket> packet =
+      BuildUnsizedDataPacket(&peer_framer_, header, frames);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
+      kMaxOutgoingPacketSize);
+  QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                     false);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+}
+
+// Make sure a packet received with a different client connection ID is dropped.
+TEST_P(QuicConnectionTest, InvalidClientConnectionId) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  SetClientConnectionId(TestConnectionId(0x33));
+  QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_FORWARD_SECURE);
+  header.destination_connection_id = TestConnectionId(0xbad);
+  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+  header.source_connection_id_included = CONNECTION_ID_ABSENT;
+  QuicFrames frames;
+  QuicPingFrame ping_frame;
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(ping_frame));
+  frames.push_back(QuicFrame(padding_frame));
+  std::unique_ptr<QuicPacket> packet =
+      BuildUnsizedDataPacket(&peer_framer_, header, frames);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
+      kMaxOutgoingPacketSize);
+  QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                     false);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
+}
+
+// Make sure the first packet received with a different client connection ID on
+// the server is processed and it changes the client connection ID.
+TEST_P(QuicConnectionTest, UpdateClientConnectionIdFromFirstPacket) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_INITIAL);
+  header.source_connection_id = TestConnectionId(0x33);
+  header.source_connection_id_included = CONNECTION_ID_PRESENT;
+  QuicFrames frames;
+  QuicPingFrame ping_frame;
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(ping_frame));
+  frames.push_back(QuicFrame(padding_frame));
+  std::unique_ptr<QuicPacket> packet =
+      BuildUnsizedDataPacket(&peer_framer_, header, frames);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(1),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                     false);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  EXPECT_EQ(TestConnectionId(0x33), connection_.client_connection_id());
+}
+void QuicConnectionTest::TestReplaceConnectionIdFromInitial() {
+  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
+    return;
+  }
+  // We start with a known connection ID.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  EXPECT_NE(TestConnectionId(0x33), connection_.connection_id());
+  // Receiving an initial can replace the connection ID once.
+  {
+    QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_INITIAL);
+    header.source_connection_id = TestConnectionId(0x33);
+    header.source_connection_id_included = CONNECTION_ID_PRESENT;
+    QuicFrames frames;
+    QuicPingFrame ping_frame;
+    QuicPaddingFrame padding_frame;
+    frames.push_back(QuicFrame(ping_frame));
+    frames.push_back(QuicFrame(padding_frame));
+    std::unique_ptr<QuicPacket> packet =
+        BuildUnsizedDataPacket(&peer_framer_, header, frames);
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(1),
+                                    *packet, buffer, kMaxOutgoingPacketSize);
+    QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                       false);
+    ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  }
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  EXPECT_EQ(TestConnectionId(0x33), connection_.connection_id());
+  // Trying to replace the connection ID a second time drops the packet.
+  {
+    QuicPacketHeader header = ConstructPacketHeader(2, ENCRYPTION_INITIAL);
+    header.source_connection_id = TestConnectionId(0x66);
+    header.source_connection_id_included = CONNECTION_ID_PRESENT;
+    QuicFrames frames;
+    QuicPingFrame ping_frame;
+    QuicPaddingFrame padding_frame;
+    frames.push_back(QuicFrame(ping_frame));
+    frames.push_back(QuicFrame(padding_frame));
+    std::unique_ptr<QuicPacket> packet =
+        BuildUnsizedDataPacket(&peer_framer_, header, frames);
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(2),
+                                    *packet, buffer, kMaxOutgoingPacketSize);
+    QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                       false);
+    ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  }
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
+  EXPECT_EQ(TestConnectionId(0x33), connection_.connection_id());
+}
+
+TEST_P(QuicConnectionTest, ReplaceServerConnectionIdFromInitial) {
+  TestReplaceConnectionIdFromInitial();
+}
+
+TEST_P(QuicConnectionTest, ReplaceServerConnectionIdFromRetryAndInitial) {
+  // First make the connection process a RETRY and replace the server connection
+  // ID a first time.
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+  // Reset the test framer to use the right connection ID.
+  peer_framer_.SetInitialObfuscators(connection_.connection_id());
+  // Now process an INITIAL and replace the server connection ID a second time.
+  TestReplaceConnectionIdFromInitial();
+}
+
+// Regression test for b/134416344.
+TEST_P(QuicConnectionTest, CheckConnectedBeforeFlush) {
+  // This test mimics a scenario where a connection processes 2 packets and the
+  // 2nd packet contains connection close frame. When the 2nd flusher goes out
+  // of scope, a delayed ACK is pending, and ACK alarm should not be scheduled
+  // because connection is disconnected.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  const QuicErrorCode kErrorCode = QUIC_INTERNAL_ERROR;
+  std::unique_ptr<QuicConnectionCloseFrame> connection_close_frame(
+      new QuicConnectionCloseFrame(connection_.transport_version(), kErrorCode,
+                                   NO_IETF_QUIC_ERROR, "",
+                                   /*transport_close_frame_type=*/0));
+
+  // Received 2 packets.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  ProcessFramePacketWithAddresses(QuicFrame(connection_close_frame.release()),
+                                  kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  // Verify ack alarm is not set.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+// Verify that a packet containing three coalesced packets is parsed correctly.
+TEST_P(QuicConnectionTest, CoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(connection_.transport_version())) {
+    // Coalesced packets can only be encoded using long header lengths.
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(3);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
+  }
+
+  uint64_t packet_numbers[3] = {1, 2, 3};
+  EncryptionLevel encryption_levels[3] = {
+      ENCRYPTION_INITIAL, ENCRYPTION_INITIAL, ENCRYPTION_FORWARD_SECURE};
+  char buffer[kMaxOutgoingPacketSize] = {};
+  size_t total_encrypted_length = 0;
+  for (int i = 0; i < 3; i++) {
+    QuicPacketHeader header =
+        ConstructPacketHeader(packet_numbers[i], encryption_levels[i]);
+    QuicFrames frames;
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      frames.push_back(QuicFrame(&crypto_frame_));
+    } else {
+      frames.push_back(QuicFrame(frame1_));
+    }
+    std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
+    peer_creator_.set_encryption_level(encryption_levels[i]);
+    size_t encrypted_length = peer_framer_.EncryptPayload(
+        encryption_levels[i], QuicPacketNumber(packet_numbers[i]), *packet,
+        buffer + total_encrypted_length,
+        sizeof(buffer) - total_encrypted_length);
+    EXPECT_GT(encrypted_length, 0u);
+    total_encrypted_length += encrypted_length;
+  }
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, total_encrypted_length, clock_.Now(), false));
+  if (connection_.GetSendAlarm()->IsSet()) {
+    connection_.GetSendAlarm()->Fire();
+  }
+
+  EXPECT_TRUE(connection_.connected());
+}
+
+// Regression test for crbug.com/992831.
+TEST_P(QuicConnectionTest, CoalescedPacketThatSavesFrames) {
+  if (!QuicVersionHasLongHeaderLengths(connection_.transport_version())) {
+    // Coalesced packets can only be encoded using long header lengths.
+    return;
+  }
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    // TODO(b/129151114) Enable this test with multiple packet number spaces.
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_))
+        .Times(3)
+        .WillRepeatedly([this](const QuicCryptoFrame& /*frame*/) {
+          // QuicFrame takes ownership of the QuicBlockedFrame.
+          connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
+        });
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_))
+        .Times(3)
+        .WillRepeatedly([this](const QuicStreamFrame& /*frame*/) {
+          // QuicFrame takes ownership of the QuicBlockedFrame.
+          connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
+        });
+  }
+
+  uint64_t packet_numbers[3] = {1, 2, 3};
+  EncryptionLevel encryption_levels[3] = {
+      ENCRYPTION_INITIAL, ENCRYPTION_INITIAL, ENCRYPTION_FORWARD_SECURE};
+  char buffer[kMaxOutgoingPacketSize] = {};
+  size_t total_encrypted_length = 0;
+  for (int i = 0; i < 3; i++) {
+    QuicPacketHeader header =
+        ConstructPacketHeader(packet_numbers[i], encryption_levels[i]);
+    QuicFrames frames;
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      frames.push_back(QuicFrame(&crypto_frame_));
+    } else {
+      frames.push_back(QuicFrame(frame1_));
+    }
+    std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
+    peer_creator_.set_encryption_level(encryption_levels[i]);
+    size_t encrypted_length = peer_framer_.EncryptPayload(
+        encryption_levels[i], QuicPacketNumber(packet_numbers[i]), *packet,
+        buffer + total_encrypted_length,
+        sizeof(buffer) - total_encrypted_length);
+    EXPECT_GT(encrypted_length, 0u);
+    total_encrypted_length += encrypted_length;
+  }
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, total_encrypted_length, clock_.Now(), false));
+  if (connection_.GetSendAlarm()->IsSet()) {
+    connection_.GetSendAlarm()->Fire();
+  }
+
+  EXPECT_TRUE(connection_.connected());
+
+  SendAckPacketToPeer();
+}
+
+// Regresstion test for b/138962304.
+TEST_P(QuicConnectionTest, RtoAndWriteBlocked) {
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_data_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Writer gets blocked.
+  writer_->SetWriteBlocked();
+
+  // Cancel the stream.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+      .WillRepeatedly(
+          Invoke(&notifier_, &SimpleSessionNotifier::WillingToWrite));
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Retransmission timer fires in RTO mode.
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify no packets get flushed when writer is blocked.
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+// Regresstion test for b/138962304.
+TEST_P(QuicConnectionTest, TlpAndWriteBlocked) {
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  connection_.SetMaxTailLossProbes(1);
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_data_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
+  SendStreamDataToPeer(4, "foo", 0, NO_FIN, &last_data_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Writer gets blocked.
+  writer_->SetWriteBlocked();
+
+  // Cancel stream 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  // Retransmission timer fires in TLP mode.
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify one packets is forced flushed when writer is blocked.
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+}
+
+// Regresstion test for b/139375344.
+TEST_P(QuicConnectionTest, RtoForcesSendingPing) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SetMaxTailLossProbes(2);
+  EXPECT_EQ(0u, connection_.GetStats().tlp_count);
+  EXPECT_EQ(0u, connection_.GetStats().rto_count);
+
+  SendStreamDataToPeer(2, "foo", 0, NO_FIN, nullptr);
+  QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+  // TLP fires.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.GetStats().tlp_count);
+  EXPECT_EQ(0u, connection_.GetStats().rto_count);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Packet 1 gets acked.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessAckPacket(1, &frame);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
+
+  // RTO fires, verify a PING packet gets sent because there is no data to send.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.GetStats().tlp_count);
+  EXPECT_EQ(1u, connection_.GetStats().rto_count);
+  EXPECT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, ProbeTimeout) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k2PTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foooooo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foooooo", 7, NO_FIN, &last_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Reset stream.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Fire the PTO and verify only the RST_STREAM is resent, not stream data.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(0u, writer_->stream_frames().size());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionAfter6ClientPTOs) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k1PTO);
+  connection_options.push_back(k6PTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  }
+  connection_.OnHandshakeComplete();
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+
+  // Fire the retransmission alarm 5 times.
+  for (int i = 0; i < 5; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.GetRetransmissionAlarm()->Fire();
+    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+    EXPECT_TRUE(connection_.connected());
+  }
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.PathDegradingTimeout();
+
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
+  EXPECT_EQ(5u, connection_.sent_packet_manager().GetConsecutivePtoCount());
+  // Closes connection on 6th PTO.
+  // May send multiple connecction close packets with multiple PN spaces.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionAfter7ClientPTOs) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k2PTO);
+  connection_options.push_back(k7PTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  }
+  connection_.OnHandshakeComplete();
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+
+  // Fire the retransmission alarm 6 times.
+  for (int i = 0; i < 6; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    connection_.GetRetransmissionAlarm()->Fire();
+    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+    EXPECT_TRUE(connection_.connected());
+  }
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.PathDegradingTimeout();
+
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
+  EXPECT_EQ(6u, connection_.sent_packet_manager().GetConsecutivePtoCount());
+  // Closes connection on 7th PTO.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionAfter8ClientPTOs) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k2PTO);
+  connection_options.push_back(k8PTO);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  }
+  connection_.OnHandshakeComplete();
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+
+  // Fire the retransmission alarm 7 times.
+  for (int i = 0; i < 7; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    connection_.GetRetransmissionAlarm()->Fire();
+    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+    EXPECT_TRUE(connection_.connected());
+  }
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.PathDegradingTimeout();
+
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
+  EXPECT_EQ(7u, connection_.sent_packet_manager().GetConsecutivePtoCount());
+  // Closes connection on 8th PTO.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
+}
+
+TEST_P(QuicConnectionTest, DeprecateHandshakeMode) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  QuicAckFrame frame1 = InitAckFrame(1);
+  // Received ACK for packet 1.
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+
+  // Verify retransmission alarm is still set because handshake is not
+  // confirmed although there is nothing in flight.
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_EQ(0u, connection_.GetStats().pto_count);
+  EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count);
+
+  // PTO fires, verify a PING packet gets sent because there is no data to send.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.GetStats().pto_count);
+  EXPECT_EQ(1u, connection_.GetStats().crypto_retransmit_count);
+  EXPECT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, AntiAmplificationLimit) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+
+  set_perspective(Perspective::IS_SERVER);
+  // Verify no data can be sent at the beginning because bytes received is 0.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receives packet 1.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  const size_t anti_amplification_factor =
+      GetQuicFlag(FLAGS_quic_anti_amplification_factor);
+  // Verify now packets can be sent.
+  for (size_t i = 1; i < anti_amplification_factor; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+    // Verify retransmission alarm is not set if throttled by anti-amplification
+    // limit.
+    EXPECT_EQ(i != anti_amplification_factor - 1,
+              connection_.GetRetransmissionAlarm()->IsSet());
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
+
+  // Receives packet 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  // Verify more packets can be sent.
+  for (size_t i = anti_amplification_factor + 1;
+       i < anti_amplification_factor * 2; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo",
+                                       2 * anti_amplification_factor * 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(3);
+  // Verify anti-amplification limit is gone after address validation.
+  for (size_t i = 0; i < 100; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
+  }
+}
+
+TEST_P(QuicConnectionTest, 3AntiAmplificationLimit) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+
+  set_perspective(Perspective::IS_SERVER);
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k3AFF);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
+                                                         QuicConnectionId());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  // Verify no data can be sent at the beginning because bytes received is 0.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receives packet 1.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  const size_t anti_amplification_factor = 3;
+  // Verify now packets can be sent.
+  for (size_t i = 1; i < anti_amplification_factor; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+    // Verify retransmission alarm is not set if throttled by anti-amplification
+    // limit.
+    EXPECT_EQ(i != anti_amplification_factor - 1,
+              connection_.GetRetransmissionAlarm()->IsSet());
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
+
+  // Receives packet 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  // Verify more packets can be sent.
+  for (size_t i = anti_amplification_factor + 1;
+       i < anti_amplification_factor * 2; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo",
+                                       2 * anti_amplification_factor * 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(3);
+  // Verify anti-amplification limit is gone after address validation.
+  for (size_t i = 0; i < 100; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
+  }
+}
+
+TEST_P(QuicConnectionTest, 10AntiAmplificationLimit) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+
+  set_perspective(Perspective::IS_SERVER);
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k10AF);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
+                                                         QuicConnectionId());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  // Verify no data can be sent at the beginning because bytes received is 0.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receives packet 1.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  const size_t anti_amplification_factor = 10;
+  // Verify now packets can be sent.
+  for (size_t i = 1; i < anti_amplification_factor; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+    // Verify retransmission alarm is not set if throttled by anti-amplification
+    // limit.
+    EXPECT_EQ(i != anti_amplification_factor - 1,
+              connection_.GetRetransmissionAlarm()->IsSet());
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
+
+  // Receives packet 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  // Verify more packets can be sent.
+  for (size_t i = anti_amplification_factor + 1;
+       i < anti_amplification_factor * 2; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo",
+                                       2 * anti_amplification_factor * 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(3);
+  // Verify anti-amplification limit is gone after address validation.
+  for (size_t i = 0; i < 100; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
+  }
+}
+
+TEST_P(QuicConnectionTest, AckPendingWithAmplificationLimited) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
+  set_perspective(Perspective::IS_SERVER);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Receives packet 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Send response in different encryption level and cause amplification factor
+  // throttled.
+  size_t i = 0;
+  while (connection_.CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+    connection_.SendCryptoDataWithString(std::string(1024, 'a'), i * 1024,
+                                         ENCRYPTION_HANDSHAKE);
+    ++i;
+  }
+  // Verify ACK is still pending.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  // Fire ACK alarm and verify ACK cannot be sent due to amplification factor.
+  clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.GetAckAlarm()->Fire();
+  // Verify ACK alarm is cancelled.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+
+  // Receives packet 2 and verify ACK gets flushed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  EXPECT_FALSE(writer_->ack_frames().empty());
+}
+
+TEST_P(QuicConnectionTest, ConnectionCloseFrameType) {
+  if (!VersionHasIetfQuicFrames(version().transport_version)) {
+    // Test relevent only for IETF QUIC.
+    return;
+  }
+  const QuicErrorCode kQuicErrorCode = IETF_QUIC_PROTOCOL_VIOLATION;
+  // Use the (unknown) frame type of 9999 to avoid triggering any logic
+  // which might be associated with the processing of a known frame type.
+  const uint64_t kTransportCloseFrameType = 9999u;
+  QuicFramerPeer::set_current_received_frame_type(
+      QuicConnectionPeer::GetFramer(&connection_), kTransportCloseFrameType);
+  // Do a transport connection close
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  const std::vector<QuicConnectionCloseFrame>& connection_close_frames =
+      writer_->connection_close_frames();
+  ASSERT_EQ(1u, connection_close_frames.size());
+  EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE,
+            connection_close_frames[0].close_type);
+  EXPECT_EQ(kQuicErrorCode, connection_close_frames[0].quic_error_code);
+  EXPECT_EQ(kTransportCloseFrameType,
+            connection_close_frames[0].transport_close_frame_type);
+}
+
+// Regression test for b/137401387 and b/138962304.
+TEST_P(QuicConnectionTest, RtoPacketAsTwo) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(1);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  std::string stream_data(3000, 's');
+  // Send packets 1 - 66 and exhaust cwnd.
+  for (size_t i = 0; i < 22; ++i) {
+    // 3 packets for each stream, the first 2 are guaranteed to be full packets.
+    SendStreamDataToPeer(i + 2, stream_data, 0, FIN, nullptr);
+  }
+  CongestionBlockWrites();
+
+  // Fires TLP. Please note, this tail loss probe has 1 byte less stream data
+  // compared to packet 1 because packet number length increases.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(67), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Fires RTO. Please note, although packets 2 and 3 *should* be RTOed, but
+  // packet 2 gets RTOed to two packets because packet number length increases.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(68), _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(69), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  // Resets all streams except 2 and ack packets 1 and 2. Now, packet 3 is the
+  // only one containing retransmittable frames.
+  for (size_t i = 1; i < 22; ++i) {
+    notifier_.OnStreamReset(i + 2, QUIC_STREAM_CANCELLED);
+  }
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(3)}});
+  ProcessAckPacket(1, &frame);
+  CongestionUnblockWrites();
+
+  // Fires TLP, verify a PING gets sent because packet 3 is marked
+  // RTO_RETRANSMITTED.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(70), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+}
+
+TEST_P(QuicConnectionTest, PtoSkipsPacketNumber) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k1PTO);
+  connection_options.push_back(kPTOS);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foooooo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foooooo", 7, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(2), last_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Fire PTO and verify the PTO retransmission skips one packet number.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(QuicPacketNumber(4), writer_->last_packet_header().packet_number);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, SendCoalescedPackets) {
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(3);
+  EXPECT_CALL(debug_visitor, OnCoalescedPacketSent(_, _)).Times(1);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    use_tagging_decrypter();
+    connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                             std::make_unique<TaggingEncrypter>(0x01));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0);
+    // Verify this packet is on hold.
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                             std::make_unique<TaggingEncrypter>(0x02));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString("bar", 3);
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+    connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                             std::make_unique<TaggingEncrypter>(0x03));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    SendStreamDataToPeer(2, "baz", 3, NO_FIN, nullptr);
+  }
+  // Verify all 3 packets are coalesced in the same UDP datagram.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+  // Verify the packet is padded to full.
+  EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
+
+  // Verify packet process.
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+  EXPECT_EQ(0u, writer_->stream_frames().size());
+  // Verify there is coalesced packet.
+  EXPECT_NE(nullptr, writer_->coalesced_packet());
+}
+
+TEST_P(QuicConnectionTest, FailToCoalescePacket) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration() ||
+      !connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+
+  set_perspective(Perspective::IS_SERVER);
+  use_tagging_decrypter();
+
+  EXPECT_CALL(visitor_, OnHandshakePacketSent());
+
+  if (GetQuicReloadableFlag(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  }
+
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  auto test_body = [&] {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                             std::make_unique<TaggingEncrypter>(0x01));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0);
+    // Verify this packet is on hold.
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                             std::make_unique<TaggingEncrypter>(0x02));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString("bar", 3);
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+    connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                             std::make_unique<TaggingEncrypter>(0x03));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    SendStreamDataToPeer(2, "baz", 3, NO_FIN, nullptr);
+
+    creator_->Flush();
+
+    auto& coalesced_packet =
+        QuicConnectionPeer::GetCoalescedPacket(&connection_);
+    QuicPacketLength coalesced_packet_max_length =
+        coalesced_packet.max_packet_length();
+    QuicCoalescedPacketPeer::SetMaxPacketLength(coalesced_packet,
+                                                coalesced_packet.length());
+
+    // Make the coalescer's FORWARD_SECURE packet longer.
+    *QuicCoalescedPacketPeer::GetMutableEncryptedBuffer(
+        coalesced_packet, ENCRYPTION_FORWARD_SECURE) += "!!! TEST !!!";
+
+    QUIC_LOG(INFO) << "Reduced coalesced_packet_max_length from "
+                   << coalesced_packet_max_length << " to "
+                   << coalesced_packet.max_packet_length()
+                   << ", coalesced_packet.length:" << coalesced_packet.length()
+                   << ", coalesced_packet.packet_lengths:"
+                   << absl::StrJoin(coalesced_packet.packet_lengths(), ":");
+  };
+
+  EXPECT_QUIC_BUG(test_body(), "SerializeCoalescedPacket failed.");
+
+  if (GetQuicReloadableFlag(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
+    EXPECT_FALSE(connection_.connected());
+    EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+                IsError(QUIC_FAILED_TO_SERIALIZE_PACKET));
+    EXPECT_EQ(saved_connection_close_frame_.error_details,
+              "Failed to serialize coalesced packet.");
+  } else {
+    EXPECT_TRUE(connection_.connected());
+  }
+}
+
+TEST_P(QuicConnectionTest, LegacyVersionEncapsulation) {
+  connection_.EnableLegacyVersionEncapsulation("test.example.org");
+
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+
+  // Our TestPacketWriter normally parses the sent packet using the version
+  // from the connection, so here we need to tell it to use the encapsulation
+  // version, and reset the initial decrypter for that version.
+  writer_->framer()->SetSupportedVersions(
+      SupportedVersions(LegacyVersionForEncapsulation()));
+  writer_->framer()->framer()->SetInitialObfuscators(
+      connection_.connection_id());
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendCryptoDataWithString("TEST_CRYPTO_DATA", /*offset=*/0);
+  }
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  // Verify that the packet is fully padded.
+  EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
+
+  // Check that the connection stats show Legacy Version Encapsulation was used.
+  EXPECT_GT(connection_.GetStats().sent_legacy_version_encapsulated_packets,
+            0u);
+
+  // Verify that the sent packet was in fact encapsulated, and check header.
+  const QuicPacketHeader& encapsulated_header = writer_->last_packet_header();
+  EXPECT_TRUE(encapsulated_header.version_flag);
+  EXPECT_EQ(encapsulated_header.version, LegacyVersionForEncapsulation());
+  EXPECT_EQ(encapsulated_header.destination_connection_id,
+            connection_.connection_id());
+
+  // Encapsulated packet should contain a stream frame for the crypto stream,
+  // optionally padding, and nothing else.
+  EXPECT_EQ(0u, writer_->crypto_frames().size());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(writer_->frame_count(), writer_->framer()->padding_frames().size() +
+                                        writer_->stream_frames().size());
+}
+
+TEST_P(QuicConnectionTest, ClientReceivedHandshakeDone) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnHandshakeDoneReceived());
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest, ServerReceivedHandshakeDone) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnHandshakeDoneReceived()).Times(0);
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest, MultiplePacketNumberSpacePto) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  // Send handshake packet.
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
+
+  // Send application data.
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         0, NO_FIN);
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+  QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+
+  // Retransmit handshake data.
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify 1-RTT packet gets coalesced with handshake retransmission.
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+
+  // Send application data.
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         4, NO_FIN);
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+  retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+
+  // Retransmit handshake data again.
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(9), _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(8), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify 1-RTT packet gets coalesced with handshake retransmission.
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+
+  // Discard handshake key.
+  connection_.OnHandshakeComplete();
+  retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+
+  // Retransmit application data.
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(11), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+}
+
+void QuicConnectionTest::TestClientRetryHandling(
+    bool invalid_retry_tag, bool missing_original_id_in_config,
+    bool wrong_original_id_in_config, bool missing_retry_id_in_config,
+    bool wrong_retry_id_in_config) {
+  if (invalid_retry_tag) {
+    ASSERT_FALSE(missing_original_id_in_config);
+    ASSERT_FALSE(wrong_original_id_in_config);
+    ASSERT_FALSE(missing_retry_id_in_config);
+    ASSERT_FALSE(wrong_retry_id_in_config);
+  } else {
+    ASSERT_FALSE(missing_original_id_in_config && wrong_original_id_in_config);
+    ASSERT_FALSE(missing_retry_id_in_config && wrong_retry_id_in_config);
+  }
+  if (!version().UsesTls()) {
+    return;
+  }
+
+  // These values come from draft-ietf-quic-v2 Appendix A.4.
+  uint8_t retry_packet_rfcv2[] = {
+      0xcf, 0x70, 0x9a, 0x50, 0xc4, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1d, 0xc7, 0x11, 0x30,
+      0xcd, 0x1e, 0xd3, 0x9d, 0x6e, 0xfc, 0xee, 0x5c, 0x85, 0x80, 0x65, 0x01};
+  // These values come from RFC9001 Appendix A.4.
+  uint8_t retry_packet_rfcv1[] = {
+      0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x04, 0xa2, 0x65, 0xba,
+      0x2e, 0xff, 0x4d, 0x82, 0x90, 0x58, 0xfb, 0x3f, 0x0f, 0x24, 0x96, 0xba};
+  uint8_t retry_packet29[] = {
+      0xff, 0xff, 0x00, 0x00, 0x1d, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xd1, 0x69, 0x26, 0xd8,
+      0x1f, 0x6f, 0x9c, 0xa2, 0x95, 0x3a, 0x8a, 0xa4, 0x57, 0x5e, 0x1e, 0x49};
+
+  uint8_t* retry_packet;
+  size_t retry_packet_length;
+  if (version() == ParsedQuicVersion::V2Draft01()) {
+    retry_packet = retry_packet_rfcv2;
+    retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv2);
+  } else if (version() == ParsedQuicVersion::RFCv1()) {
+    retry_packet = retry_packet_rfcv1;
+    retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv1);
+  } else if (version() == ParsedQuicVersion::Draft29()) {
+    retry_packet = retry_packet29;
+    retry_packet_length = ABSL_ARRAYSIZE(retry_packet29);
+  } else {
+    // TODO(dschinazi) generate retry packets for all versions once we have
+    // server-side support for generating these programmatically.
+    return;
+  }
+
+  uint8_t original_connection_id_bytes[] = {0x83, 0x94, 0xc8, 0xf0,
+                                            0x3e, 0x51, 0x57, 0x08};
+  uint8_t new_connection_id_bytes[] = {0xf0, 0x67, 0xa5, 0x50,
+                                       0x2a, 0x42, 0x62, 0xb5};
+  uint8_t retry_token_bytes[] = {0x74, 0x6f, 0x6b, 0x65, 0x6e};
+
+  QuicConnectionId original_connection_id(
+      reinterpret_cast<char*>(original_connection_id_bytes),
+      ABSL_ARRAYSIZE(original_connection_id_bytes));
+  QuicConnectionId new_connection_id(
+      reinterpret_cast<char*>(new_connection_id_bytes),
+      ABSL_ARRAYSIZE(new_connection_id_bytes));
+
+  std::string retry_token(reinterpret_cast<char*>(retry_token_bytes),
+                          ABSL_ARRAYSIZE(retry_token_bytes));
+
+  if (invalid_retry_tag) {
+    // Flip the last bit of the retry packet to prevent the integrity tag
+    // from validating correctly.
+    retry_packet[retry_packet_length - 1] ^= 1;
+  }
+
+  QuicConnectionId config_original_connection_id = original_connection_id;
+  if (wrong_original_id_in_config) {
+    // Flip the first bit of the connection ID.
+    ASSERT_FALSE(config_original_connection_id.IsEmpty());
+    config_original_connection_id.mutable_data()[0] ^= 0x80;
+  }
+  QuicConnectionId config_retry_source_connection_id = new_connection_id;
+  if (wrong_retry_id_in_config) {
+    // Flip the first bit of the connection ID.
+    ASSERT_FALSE(config_retry_source_connection_id.IsEmpty());
+    config_retry_source_connection_id.mutable_data()[0] ^= 0x80;
+  }
+
+  // Make sure the connection uses the connection ID from the test vectors,
+  QuicConnectionPeer::SetServerConnectionId(&connection_,
+                                            original_connection_id);
+  // Make sure our fake framer has the new post-retry INITIAL keys so that any
+  // retransmission triggered by retry can be decrypted.
+  writer_->framer()->framer()->SetInitialObfuscators(new_connection_id);
+
+  // Process the RETRY packet.
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(reinterpret_cast<char*>(retry_packet),
+                         retry_packet_length, clock_.Now()));
+
+  if (invalid_retry_tag) {
+    // Make sure we refuse to process a RETRY with invalid tag.
+    EXPECT_FALSE(connection_.GetStats().retry_packet_processed);
+    EXPECT_EQ(connection_.connection_id(), original_connection_id);
+    EXPECT_TRUE(QuicPacketCreatorPeer::GetRetryToken(
+                    QuicConnectionPeer::GetPacketCreator(&connection_))
+                    .empty());
+    return;
+  }
+
+  // Make sure we correctly parsed the RETRY.
+  EXPECT_TRUE(connection_.GetStats().retry_packet_processed);
+  EXPECT_EQ(connection_.connection_id(), new_connection_id);
+  EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
+                QuicConnectionPeer::GetPacketCreator(&connection_)),
+            retry_token);
+
+  // Test validating the original_connection_id from the config.
+  QuicConfig received_config;
+  QuicConfigPeer::SetNegotiated(&received_config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &received_config, connection_.connection_id());
+    if (!missing_retry_id_in_config) {
+      QuicConfigPeer::SetReceivedRetrySourceConnectionId(
+          &received_config, config_retry_source_connection_id);
+    }
+  }
+  if (!missing_original_id_in_config) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &received_config, config_original_connection_id);
+  }
+
+  if (missing_original_id_in_config || wrong_original_id_in_config ||
+      missing_retry_id_in_config || wrong_retry_id_in_config) {
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .Times(0);
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+  connection_.SetFromConfig(received_config);
+  if (missing_original_id_in_config || wrong_original_id_in_config ||
+      missing_retry_id_in_config || wrong_retry_id_in_config) {
+    ASSERT_FALSE(connection_.connected());
+    TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+  } else {
+    EXPECT_TRUE(connection_.connected());
+  }
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetry) {
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryInvalidTag) {
+  TestClientRetryHandling(/*invalid_retry_tag=*/true,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryMissingOriginalId) {
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/true,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryWrongOriginalId) {
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/true,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryMissingRetryId) {
+  if (!connection_.version().UsesTls()) {
+    // Versions that do not authenticate connection IDs never send the
+    // retry_source_connection_id transport parameter.
+    return;
+  }
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/true,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryWrongRetryId) {
+  if (!connection_.version().UsesTls()) {
+    // Versions that do not authenticate connection IDs never send the
+    // retry_source_connection_id transport parameter.
+    return;
+  }
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/true);
+}
+
+TEST_P(QuicConnectionTest, ClientRetransmitsInitialPacketsOnRetry) {
+  if (!connection_.version().HasIetfQuicFrames()) {
+    // TestClientRetryHandling() currently only supports IETF draft versions.
+    return;
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+
+  connection_.SendCryptoStreamData();
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+
+  // Verify that initial data is retransmitted immediately after receiving
+  // RETRY.
+  if (GetParam().ack_response == AckResponse::kImmediate) {
+    EXPECT_EQ(2u, writer_->packets_write_attempts());
+    EXPECT_EQ(1u, writer_->framer()->crypto_frames().size());
+  }
+}
+
+TEST_P(QuicConnectionTest, NoInitialPacketsRetransmissionOnInvalidRetry) {
+  if (!connection_.version().HasIetfQuicFrames()) {
+    return;
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+
+  connection_.SendCryptoStreamData();
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  TestClientRetryHandling(/*invalid_retry_tag=*/true,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, ClientReceivesOriginalConnectionIdWithoutRetry) {
+  if (!connection_.version().UsesTls()) {
+    // QUIC+TLS is required to transmit connection ID transport parameters.
+    return;
+  }
+  if (connection_.version().UsesTls()) {
+    // Versions that authenticate connection IDs always send the
+    // original_destination_connection_id transport parameter.
+    return;
+  }
+  // Make sure that receiving the original_destination_connection_id transport
+  // parameter fails the handshake when no RETRY packet was received before it.
+  QuicConfig received_config;
+  QuicConfigPeer::SetNegotiated(&received_config, true);
+  QuicConfigPeer::SetReceivedOriginalConnectionId(&received_config,
+                                                  TestConnectionId(0x12345));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+  connection_.SetFromConfig(received_config);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+}
+
+TEST_P(QuicConnectionTest, ClientReceivesRetrySourceConnectionIdWithoutRetry) {
+  if (!connection_.version().UsesTls()) {
+    // Versions that do not authenticate connection IDs never send the
+    // retry_source_connection_id transport parameter.
+    return;
+  }
+  // Make sure that receiving the retry_source_connection_id transport parameter
+  // fails the handshake when no RETRY packet was received before it.
+  QuicConfig received_config;
+  QuicConfigPeer::SetNegotiated(&received_config, true);
+  QuicConfigPeer::SetReceivedRetrySourceConnectionId(&received_config,
+                                                     TestConnectionId(0x12345));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+  connection_.SetFromConfig(received_config);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+}
+
+// Regression test for http://crbug/1047977
+TEST_P(QuicConnectionTest, MaxStreamsFrameCausesConnectionClose) {
+  if (!VersionHasIetfQuicFrames(connection_.transport_version())) {
+    return;
+  }
+  // Received frame causes connection close.
+  EXPECT_CALL(visitor_, OnMaxStreamsFrame(_))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+        connection_.CloseConnection(
+            QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, "error",
+            ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return true;
+      }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicMaxStreamsFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest, StreamsBlockedFrameCausesConnectionClose) {
+  if (!VersionHasIetfQuicFrames(connection_.transport_version())) {
+    return;
+  }
+  // Received frame causes connection close.
+  EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+        connection_.CloseConnection(
+            QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, "error",
+            ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return true;
+      }));
+  QuicFrames frames;
+  frames.push_back(
+      QuicFrame(QuicStreamsBlockedFrame(kInvalidControlFrameId, 10, false)));
+  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest,
+       BundleAckWithConnectionCloseMultiplePacketNumberSpace) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  // Receives packet 2000 in application data.
+  ProcessDataPacketAtLevel(2000, false, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  // Verify ack is bundled.
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    // Each connection close packet should be sent in distinct UDP packets.
+    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+              writer_->connection_close_packets());
+    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+              writer_->packets_write_attempts());
+    return;
+  }
+
+  // A single UDP packet should be sent with multiple connection close packets
+  // coalesced together.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Only the first packet has been processed yet.
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+
+  // ProcessPacket resets the visitor and frees the coalesced packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  // Verify ack is bundled.
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
+// Regression test for b/151220135.
+TEST_P(QuicConnectionTest, SendPingWhenSkipPacketNumberForPto) {
+  if (!VersionSupportsMessageFrames(connection_.transport_version())) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kPTOS);
+  connection_options.push_back(k1PTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
+        &config, kMaxAcceptedDatagramFrameSize);
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  connection_.OnHandshakeComplete();
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS, SendMessage("message"));
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // PTO fires, verify a PING packet gets sent because there is no data to
+  // send.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.GetStats().pto_count);
+  EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count);
+  EXPECT_EQ(1u, writer_->ping_frames().size());
+}
+
+// Regression test for b/155757133
+TEST_P(QuicConnectionTest, DonotChangeQueuedAcks) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  ProcessPacket(2);
+  ProcessPacket(3);
+  ProcessPacket(4);
+  // Process a packet containing stream frame followed by ACK of packets 1.
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicStreamFrame(
+      QuicUtils::GetFirstBidirectionalStreamId(
+          connection_.version().transport_version, Perspective::IS_CLIENT),
+      false, 0u, absl::string_view())));
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  frames.push_back(QuicFrame(&ack_frame));
+  // Receiving stream frame causes something to send.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
+    connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
+    // Verify now the queued ACK contains packet number 2.
+    EXPECT_TRUE(QuicPacketCreatorPeer::QueuedFrames(
+                    QuicConnectionPeer::GetPacketCreator(&connection_))[0]
+                    .ack_frame->packets.Contains(QuicPacketNumber(2)));
+  }));
+  ProcessFramesPacketAtLevel(9, frames, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(writer_->ack_frames()[0].packets.Contains(QuicPacketNumber(2)));
+}
+
+TEST_P(QuicConnectionTest, DonotExtendIdleTimeOnUndecryptablePackets) {
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  // Subtract a second from the idle timeout on the client side.
+  QuicTime initial_deadline =
+      clock_.ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
+
+  // Received an undecryptable packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  const uint8_t tag = 0x07;
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(tag));
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  // Verify deadline does not get extended.
+  EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
+  QuicTime::Delta delay = initial_deadline - clock_.ApproximateNow();
+  clock_.AdvanceTime(delay);
+  connection_.GetTimeoutAlarm()->Fire();
+  // Verify connection gets closed.
+  EXPECT_FALSE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, BundleAckWithImmediateResponse) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
+    notifier_.WriteOrBufferWindowUpate(0, 0);
+  }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessDataPacket(1);
+  // Verify ACK is bundled with WINDOW_UPDATE.
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, AckAlarmFiresEarly) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  // Receives packet 1000 in application data.
+  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Verify ACK deadline does not change.
+  EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
+            connection_.GetAckAlarm()->deadline());
+
+  // Ack alarm fires early.
+  // Verify the earliest ACK is flushed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetAckAlarm()->Fire();
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
+            connection_.GetAckAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionClient) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kCBHD);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole detection is in progress.
+  EXPECT_TRUE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionServer) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kCBHD);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole detection is disabled.
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, 2RtoBlackholeDetection) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k2RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole delay is expected.
+  EXPECT_EQ(clock_.Now() +
+                connection_.sent_packet_manager().GetNetworkBlackholeDelay(2),
+            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+TEST_P(QuicConnectionTest, 3RtoBlackholeDetection) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k3RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole delay is expected.
+  EXPECT_EQ(clock_.Now() +
+                connection_.sent_packet_manager().GetNetworkBlackholeDelay(3),
+            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+TEST_P(QuicConnectionTest, 4RtoBlackholeDetection) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k4RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole delay is expected.
+  EXPECT_EQ(clock_.Now() +
+                connection_.sent_packet_manager().GetNetworkBlackholeDelay(4),
+            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+TEST_P(QuicConnectionTest, 6RtoBlackholeDetection) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k6RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole delay is expected.
+  EXPECT_EQ(clock_.Now() +
+                connection_.sent_packet_manager().GetNetworkBlackholeDelay(6),
+            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+// Regresstion test for b/158491591.
+TEST_P(QuicConnectionTest, MadeForwardProgressOnDiscardingKeys) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  // Send handshake packet.
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k5RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  }
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+  // Discard handshake keys.
+  connection_.OnHandshakeComplete();
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    // Verify blackhole detection stops.
+    EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
+  } else {
+    // Problematic: although there is nothing in flight, blackhole detection is
+    // still in progress.
+    EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+  }
+}
+
+TEST_P(QuicConnectionTest, ProcessUndecryptablePacketsBasedOnEncryptionLevel) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+  use_tagging_decrypter();
+
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  for (uint64_t i = 1; i <= 3; ++i) {
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+  }
+  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  for (uint64_t j = 5; j <= 7; ++j) {
+    ProcessDataPacketAtLevel(j, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+  }
+  EXPECT_EQ(7u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  // Verify all ENCRYPTION_HANDSHAKE packets get processed.
+  if (!VersionHasIetfQuicFrames(version().transport_version)) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(6);
+  }
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  EXPECT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  // Verify the 1-RTT packet gets processed.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+}
+
+TEST_P(QuicConnectionTest, ServerBundlesInitialDataWithInitialAck) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+  QuicTime expected_pto_time =
+      connection_.sent_packet_manager().GetRetransmissionTime();
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+  // Verify PTO time does not change.
+  EXPECT_EQ(expected_pto_time,
+            connection_.sent_packet_manager().GetRetransmissionTime());
+
+  // Receives packet 1001 in initial data.
+  ProcessCryptoPacketAtLevel(1001, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Receives packet 1002 in initial data.
+  ProcessCryptoPacketAtLevel(1002, ENCRYPTION_INITIAL);
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  // Verify CRYPTO frame is bundled with INITIAL ACK.
+  EXPECT_FALSE(writer_->crypto_frames().empty());
+  // Verify PTO time changes.
+  EXPECT_NE(expected_pto_time,
+            connection_.sent_packet_manager().GetRetransmissionTime());
+}
+
+TEST_P(QuicConnectionTest, ClientBundlesHandshakeDataWithHandshakeAck) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  // Receives packet 1000 in handshake data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_HANDSHAKE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+
+  // Receives packet 1001 in handshake data.
+  ProcessCryptoPacketAtLevel(1001, ENCRYPTION_HANDSHAKE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Receives packet 1002 in handshake data.
+  ProcessCryptoPacketAtLevel(1002, ENCRYPTION_HANDSHAKE);
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  // Verify CRYPTO frame is bundled with HANDSHAKE ACK.
+  EXPECT_FALSE(writer_->crypto_frames().empty());
+}
+
+// Regresstion test for b/156232673.
+TEST_P(QuicConnectionTest, CoalescePacketOfLowerEncryptionLevel) {
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    use_tagging_decrypter();
+    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                             std::make_unique<TaggingEncrypter>(0x01));
+    connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                             std::make_unique<TaggingEncrypter>(0x02));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    SendStreamDataToPeer(2, std::string(1286, 'a'), 0, NO_FIN, nullptr);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    // Try to coalesce a HANDSHAKE packet after 1-RTT packet.
+    // Verify soft max packet length gets resumed and handshake packet gets
+    // successfully sent.
+    connection_.SendCryptoDataWithString("a", 0, ENCRYPTION_HANDSHAKE);
+  }
+}
+
+// Regression test for b/160790422.
+TEST_P(QuicConnectionTest, ServerRetransmitsHandshakeDataEarly) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+  QuicTime expected_pto_time =
+      connection_.sent_packet_manager().GetRetransmissionTime();
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  // Send HANDSHAKE 2 and 3.
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+  connection_.SendCryptoDataWithString("bar", 3, ENCRYPTION_HANDSHAKE);
+  // Verify PTO time does not change.
+  EXPECT_EQ(expected_pto_time,
+            connection_.sent_packet_manager().GetRetransmissionTime());
+
+  // Receives ACK for HANDSHAKE 2.
+  QuicFrames frames;
+  auto ack_frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  frames.push_back(QuicFrame(&ack_frame));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramesPacketAtLevel(30, frames, ENCRYPTION_HANDSHAKE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  // Receives PING from peer.
+  frames.clear();
+  frames.push_back(QuicFrame(QuicPingFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(3)));
+  ProcessFramesPacketAtLevel(31, frames, ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(clock_.Now() + kAlarmGranularity,
+            connection_.GetAckAlarm()->deadline());
+  // Fire ACK alarm.
+  clock_.AdvanceTime(kAlarmGranularity);
+  connection_.GetAckAlarm()->Fire();
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  // Verify handshake data gets retransmitted early.
+  EXPECT_FALSE(writer_->crypto_frames().empty());
+}
+
+// Regression test for b/161228202
+TEST_P(QuicConnectionTest, InflatedRttSample) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // 30ms RTT.
+  const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(30);
+  set_perspective(Perspective::IS_SERVER);
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  std::string initial_crypto_data(512, 'a');
+  connection_.SendCryptoDataWithString(initial_crypto_data, 0,
+                                       ENCRYPTION_INITIAL);
+  ASSERT_TRUE(connection_.sent_packet_manager()
+                  .GetRetransmissionTime()
+                  .IsInitialized());
+  QuicTime::Delta pto_timeout =
+      connection_.sent_packet_manager().GetRetransmissionTime() - clock_.Now();
+  // Send Handshake 2.
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  std::string handshake_crypto_data(1024, 'a');
+  connection_.SendCryptoDataWithString(handshake_crypto_data, 0,
+                                       ENCRYPTION_HANDSHAKE);
+
+  // INITIAL 1 gets lost and PTO fires.
+  clock_.AdvanceTime(pto_timeout);
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  clock_.AdvanceTime(kTestRTT);
+  // Assume retransmitted INITIAL gets received.
+  QuicFrames frames;
+  auto ack_frame = InitAckFrame({{QuicPacketNumber(4), QuicPacketNumber(5)}});
+  frames.push_back(QuicFrame(&ack_frame));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessFramesPacketAtLevel(1001, frames, ENCRYPTION_INITIAL);
+  EXPECT_EQ(kTestRTT, rtt_stats->latest_rtt());
+  // Because retransmitted INITIAL gets received so HANDSHAKE 2 gets processed.
+  frames.clear();
+  // HANDSHAKE 5 is also processed.
+  QuicAckFrame ack_frame2 =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
+                    {QuicPacketNumber(5), QuicPacketNumber(6)}});
+  ack_frame2.ack_delay_time = QuicTime::Delta::Zero();
+  frames.push_back(QuicFrame(&ack_frame2));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_HANDSHAKE);
+  // Verify RTT inflation gets mitigated.
+  EXPECT_EQ(rtt_stats->latest_rtt(), kTestRTT);
+}
+
+// Regression test for b/161228202
+TEST_P(QuicConnectionTest, CoalscingPacketCausesInfiniteLoop) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+
+  // Set anti amplification factor to 2, such that RetransmitDataOfSpaceIfAny
+  // makes no forward progress and causes infinite loop.
+  SetQuicFlag(FLAGS_quic_anti_amplification_factor, 2);
+
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  std::string initial_crypto_data(512, 'a');
+  connection_.SendCryptoDataWithString(initial_crypto_data, 0,
+                                       ENCRYPTION_INITIAL);
+  ASSERT_TRUE(connection_.sent_packet_manager()
+                  .GetRetransmissionTime()
+                  .IsInitialized());
+  QuicTime::Delta pto_timeout =
+      connection_.sent_packet_manager().GetRetransmissionTime() - clock_.Now();
+  // Send Handshake 2.
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  // Verify HANDSHAKE packet is coalesced with INITIAL retransmission.
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  std::string handshake_crypto_data(1024, 'a');
+  connection_.SendCryptoDataWithString(handshake_crypto_data, 0,
+                                       ENCRYPTION_HANDSHAKE);
+
+  // INITIAL 1 gets lost and PTO fires.
+  clock_.AdvanceTime(pto_timeout);
+  connection_.GetRetransmissionAlarm()->Fire();
+}
+
+TEST_P(QuicConnectionTest, ClientAckDelayForAsyncPacketProcessing) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+  }));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+
+  // Received undecryptable HANDSHAKE 2.
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+  ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  // Received INITIAL 4 (which is retransmission of INITIAL 1) after 100ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  // Generate HANDSHAKE key.
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  // Verify HANDSHAKE packet gets processed.
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  } else {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  }
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Verify immediate ACK has been sent out when flush went out of scope.
+    ASSERT_FALSE(connection_.HasPendingAcks());
+  } else {
+    ASSERT_TRUE(connection_.HasPendingAcks());
+    // Send ACKs.
+    clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
+    connection_.GetAckAlarm()->Fire();
+  }
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Verify the ack_delay_time in the sent HANDSHAKE ACK frame is 100ms.
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
+              writer_->ack_frames()[0].ack_delay_time);
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+    return;
+  }
+  // Verify the ack_delay_time in the INITIAL ACK frame is 1ms.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
+            writer_->ack_frames()[0].ack_delay_time);
+  // Process the coalesced HANDSHAKE packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  // Verify the ack_delay_time in the HANDSHAKE ACK frame includes the
+  // buffering time.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(101),
+            writer_->ack_frames()[0].ack_delay_time);
+  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
+TEST_P(QuicConnectionTest, TestingLiveness) {
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  QuicConfig client_config;
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  client_config.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(30));
+  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
+  const QuicErrorCode error =
+      config.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+
+  connection_.SetFromConfig(config);
+  connection_.OnHandshakeComplete();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.MaybeTestLiveness());
+
+  QuicTime deadline = connection_.GetTimeoutAlarm()->deadline();
+  QuicTime::Delta timeout = deadline - clock_.ApproximateNow();
+  // Advance time to near the idle timeout.
+  clock_.AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_TRUE(connection_.MaybeTestLiveness());
+  // Verify idle deadline does not change.
+  EXPECT_EQ(deadline, connection_.GetTimeoutAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, SilentIdleTimeout) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  QuicConfig config;
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
+                                                         QuicConnectionId());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.GetTimeoutAlarm()->Fire();
+  // Verify the connection close packets get serialized and added to
+  // termination packets list.
+  EXPECT_NE(nullptr,
+            QuicConnectionPeer::GetConnectionClosePacket(&connection_));
+}
+
+TEST_P(QuicConnectionTest, DonotSendPing) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.OnHandshakeComplete();
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+      "GET /", 0, FIN, nullptr);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(15),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now recevie an ACK and response of the previous packet, which will move the
+  // ping alarm forward.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicFrames frames;
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  frames.push_back(QuicFrame(&ack_frame));
+  frames.push_back(QuicFrame(QuicStreamFrame(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()), true,
+      0u, absl::string_view())));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  // The ping timer is set slightly less than 15 seconds in the future, because
+  // of the 1s ping timer alarm granularity.
+  EXPECT_EQ(
+      QuicTime::Delta::FromSeconds(15) - QuicTime::Delta::FromMilliseconds(5),
+      connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  // Suppose now ShouldKeepConnectionAlive returns false.
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(false));
+  // Verify PING does not get sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.GetPingAlarm()->Fire();
+}
+
+// Regression test for b/159698337
+TEST_P(QuicConnectionTest, DuplicateAckCausesLostPackets) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  // Finish handshake.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  std::string data(1200, 'a');
+  // Send data packets 1 - 5.
+  for (size_t i = 0; i < 5; ++i) {
+    SendStreamDataToPeer(
+        GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
+        i * 1200, i == 4 ? FIN : NO_FIN, nullptr);
+  }
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(3);
+
+  // ACK packet 5 and 1 and 2 are detected lost.
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(5), QuicPacketNumber(6)}});
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .Times(AnyNumber())
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  ProcessAckPacket(1, &frame);
+  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+  QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+
+  // ACK packet 1 - 5 and 7.
+  QuicAckFrame frame2 =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(6)},
+                    {QuicPacketNumber(7), QuicPacketNumber(8)}});
+  ProcessAckPacket(2, &frame2);
+  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+
+  // ACK packet 7 again and assume packet 6 is detected lost.
+  QuicAckFrame frame3 =
+      InitAckFrame({{QuicPacketNumber(7), QuicPacketNumber(8)}});
+  lost_packets.clear();
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(6), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .Times(AnyNumber())
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  ProcessAckPacket(3, &frame3);
+  // Make sure loss detection is cancelled even there is no new acked packets.
+  EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, ShorterIdleTimeoutOnSentPackets) {
+  EXPECT_TRUE(connection_.connected());
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.SetClientConnectionOptions(QuicTagVector{kFIDT});
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  }
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  connection_.SetFromConfig(config);
+
+  ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  // Send a packet close to timeout.
+  QuicTime::Delta timeout =
+      connection_.GetTimeoutAlarm()->deadline() - clock_.Now();
+  clock_.AdvanceTime(timeout - QuicTime::Delta::FromSeconds(1));
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify this sent packet does not extend idle timeout since 1s is > PTO
+  // delay.
+  ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
+            connection_.GetTimeoutAlarm()->deadline() - clock_.Now());
+
+  // Received an ACK 100ms later.
+  clock_.AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(100));
+  QuicAckFrame ack = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(1, &ack);
+  // Verify idle timeout gets extended.
+  EXPECT_EQ(clock_.Now() + timeout, connection_.GetTimeoutAlarm()->deadline());
+}
+
+// Regression test for b/166255274
+TEST_P(QuicConnectionTest,
+       ReserializeInitialPacketInCoalescerAfterDiscardingInitialKey) {
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+  }));
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+    // Verify the packet is on hold.
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+    // Flush pending ACKs.
+    connection_.GetAckAlarm()->Fire();
+  }
+  EXPECT_FALSE(connection_.packet_creator().HasPendingFrames());
+  // The ACK frame is deleted along with initial_packet_ in coalescer. Sending
+  // connection close would cause this (released) ACK frame be serialized (and
+  // crashes).
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, PathValidationOnNewSocketSuccess) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(new QuicPathResponseFrame(
+      99, new_writer.path_challenge_frames().front().data_buffer)));
+  ProcessFramesPacketWithAddresses(frames, kNewSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(success);
+}
+
+TEST_P(QuicConnectionTest, NewPathValidationCancelsPreviousOne) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = true;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+  // Start another path validation request.
+  const QuicSocketAddress kNewSelfAddress2(QuicIpAddress::Any4(), 12346);
+  EXPECT_NE(kNewSelfAddress2, connection_.self_address());
+  TestPacketWriter new_writer2(version(), &clock_, Perspective::IS_CLIENT);
+  if (!connection_.connection_migration_use_new_cid()) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AtLeast(1u))
+        .WillOnce(Invoke([&]() {
+          EXPECT_EQ(1u, new_writer2.packets_write_attempts());
+          EXPECT_EQ(1u, new_writer2.path_challenge_frames().size());
+          EXPECT_EQ(1u, new_writer2.padding_frames().size());
+          EXPECT_EQ(kNewSelfAddress2.host(),
+                    new_writer2.last_write_source_address());
+        }));
+  }
+  bool success2 = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress2, connection_.peer_address(), &new_writer2),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress2, connection_.peer_address(),
+          &success2));
+  EXPECT_FALSE(success);
+  if (connection_.connection_migration_use_new_cid()) {
+    // There is no pening path validation as there is no available connection
+    // ID.
+    EXPECT_FALSE(connection_.HasPendingPathValidation());
+  } else {
+    EXPECT_TRUE(connection_.HasPendingPathValidation());
+  }
+}
+
+// Regression test for b/182571515.
+TEST_P(QuicConnectionTest, PathValidationRetry) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(2u)
+      .WillRepeatedly(Invoke([&]() {
+        EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+      }));
+  bool success = true;
+  connection_.ValidatePath(std::make_unique<TestQuicPathValidationContext>(
+                               connection_.self_address(),
+                               connection_.peer_address(), writer_.get()),
+                           std::make_unique<TestValidationResultDelegate>(
+                               &connection_, connection_.self_address(),
+                               connection_.peer_address(), &success));
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+
+  // Retry after time out.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
+  static_cast<TestAlarmFactory::TestAlarm*>(
+      QuicPathValidatorPeer::retry_timer(
+          QuicConnectionPeer::path_validator(&connection_)))
+      ->Fire();
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, PathValidationReceivesStatelessReset) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedStatelessResetToken(&config,
+                                                 kTestStatelessResetToken);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = true;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildIetfStatelessResetPacket(connection_id_,
+                                                /*received_packet_length=*/100,
+                                                kTestStatelessResetToken));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  connection_.ProcessUdpPacket(kNewSelfAddress, kPeerAddress, *received);
+  EXPECT_FALSE(connection_.HasPendingPathValidation());
+  EXPECT_FALSE(success);
+}
+
+// Tests that PATH_CHALLENGE is dropped if it is sent via a blocked alternative
+// writer.
+TEST_P(QuicConnectionTest, SendPathChallengeUsingBlockedNewSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  new_writer.BlockOnNextWrite();
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1))
+      .WillOnce(Invoke([&]() {
+        // Even though the socket is blocked, the PATH_CHALLENGE should still be
+        // treated as sent.
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+  new_writer.SetWritable();
+  // Write event on the default socket shouldn't make any difference.
+  connection_.OnCanWrite();
+  // A NEW_CONNECTION_ID frame is received in PathProbeTestInit and OnCanWrite
+  // will write a acking packet.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_EQ(1u, new_writer.packets_write_attempts());
+}
+
+//  Tests that PATH_CHALLENGE is dropped if it is sent via the default writer
+//  and the writer is blocked.
+TEST_P(QuicConnectionTest, SendPathChallengeUsingBlockedDefaultSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
+  writer_->BlockOnNextWrite();
+  // 1st time is after writer returns WRITE_STATUS_BLOCKED. 2nd time is in
+  // ShouldGeneratePacket().
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(2));
+  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        // This packet isn't sent actually, instead it is buffered in the
+        // connection.
+        EXPECT_EQ(1u, writer_->packets_write_attempts());
+        if (connection_.validate_client_address()) {
+          EXPECT_EQ(1u, writer_->path_response_frames().size());
+          EXPECT_EQ(0,
+                    memcmp(&path_challenge_payload,
+                           &writer_->path_response_frames().front().data_buffer,
+                           sizeof(path_challenge_payload)));
+        }
+        EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+      }))
+      .WillRepeatedly(Invoke([&]() {
+        // Only one PATH_CHALLENGE should be sent out.
+        EXPECT_EQ(0u, writer_->path_challenge_frames().size());
+      }));
+  bool success = false;
+  if (connection_.validate_client_address()) {
+    // Receiving a PATH_CHALLENGE from the new peer address should trigger
+    // address validation.
+    QuicFrames frames;
+    frames.push_back(
+        QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+    ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                     ENCRYPTION_FORWARD_SECURE);
+  } else {
+    // Manually start to validate the new peer address.
+    connection_.ValidatePath(
+        std::make_unique<TestQuicPathValidationContext>(
+            connection_.self_address(), kNewPeerAddress, writer_.get()),
+        std::make_unique<TestValidationResultDelegate>(
+            &connection_, connection_.self_address(), kNewPeerAddress,
+            &success));
+  }
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Try again with the new socket blocked from the beginning. The 2nd
+  // PATH_CHALLENGE shouldn't be serialized, but be dropped.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
+  static_cast<TestAlarmFactory::TestAlarm*>(
+      QuicPathValidatorPeer::retry_timer(
+          QuicConnectionPeer::path_validator(&connection_)))
+      ->Fire();
+
+  // No more write attempt should be made.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  writer_->SetWritable();
+  // OnCanWrite() should actually write out the 1st PATH_CHALLENGE packet
+  // buffered earlier, thus incrementing the write counter. It may also send
+  // ACKs to previously received packets.
+  connection_.OnCanWrite();
+  EXPECT_LE(2u, writer_->packets_write_attempts());
+}
+
+// Tests that write error on the alternate socket should be ignored.
+TEST_P(QuicConnectionTest, SendPathChallengeFailOnNewSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  new_writer.SetShouldWriteFail();
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
+
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(1u, new_writer.packets_write_attempts());
+  EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+  EXPECT_EQ(1u, new_writer.padding_frames().size());
+  EXPECT_EQ(kNewSelfAddress.host(), new_writer.last_write_source_address());
+
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+  //  Regardless of the write error, the connection should still be connected.
+  EXPECT_TRUE(connection_.connected());
+}
+
+// Tests that write error while sending PATH_CHALLANGE from the default socket
+// should close the connection.
+TEST_P(QuicConnectionTest, SendPathChallengeFailOnDefaultPath) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  writer_->SetShouldWriteFail();
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(
+          Invoke([](QuicConnectionCloseFrame frame, ConnectionCloseSource) {
+            EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, frame.quic_error_code);
+          }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
+  {
+    // Add a flusher to force flush, otherwise the frames will remain in the
+    // packet creator.
+    bool success = false;
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.ValidatePath(std::make_unique<TestQuicPathValidationContext>(
+                                 connection_.self_address(),
+                                 connection_.peer_address(), writer_.get()),
+                             std::make_unique<TestValidationResultDelegate>(
+                                 &connection_, connection_.self_address(),
+                                 connection_.peer_address(), &success));
+  }
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  EXPECT_EQ(connection_.peer_address(), writer_->last_write_peer_address());
+  EXPECT_FALSE(connection_.connected());
+  // Closing connection should abandon ongoing path validation.
+  EXPECT_FALSE(connection_.HasPendingPathValidation());
+}
+
+TEST_P(QuicConnectionTest, SendPathChallengeFailOnAlternativePeerAddress) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  writer_->SetShouldWriteFail();
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(
+          Invoke([](QuicConnectionCloseFrame frame, ConnectionCloseSource) {
+            EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, frame.quic_error_code);
+          }));
+  // Sending PATH_CHALLENGE to trigger a flush write which will fail and close
+  // the connection.
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          connection_.self_address(), kNewPeerAddress, writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, connection_.self_address(), kNewPeerAddress, &success));
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_FALSE(connection_.HasPendingPathValidation());
+  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+  EXPECT_FALSE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest,
+       SendPathChallengeFailPacketTooBigOnAlternativePeerAddress) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  // Make sure there is no outstanding ACK_FRAME to write.
+  connection_.OnCanWrite();
+  uint32_t num_packets_write_attempts = writer_->packets_write_attempts();
+
+  writer_->SetShouldWriteFail();
+  writer_->SetWriteError(*writer_->MessageTooBigErrorCode());
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(0u);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
+  // Sending PATH_CHALLENGE to trigger a flush write which will fail with
+  // MSG_TOO_BIG.
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          connection_.self_address(), kNewPeerAddress, writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, connection_.self_address(), kNewPeerAddress, &success));
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  // Connection shouldn't be closed.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(++num_packets_write_attempts, writer_->packets_write_attempts());
+  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+}
+
+// Check that if there are two PATH_CHALLENGE frames in the packet, the latter
+// one is ignored.
+TEST_P(QuicConnectionTest, ReceiveMultiplePathChallenge) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicPathFrameBuffer path_frame_buffer1{0, 1, 2, 3, 4, 5, 6, 7};
+  QuicPathFrameBuffer path_frame_buffer2{8, 9, 10, 11, 12, 13, 14, 15};
+  QuicFrames frames;
+  frames.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer1)));
+  frames.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer2)));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
+                                          /*port=*/23456);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+
+  // Expect 2 packets to be sent: the first are padded PATH_RESPONSE(s) to the
+  // alternative peer address. The 2nd is a ACK-only packet to the original
+  // peer address.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(2)
+      .WillOnce(Invoke([=]() {
+        EXPECT_EQ(1u, writer_->path_response_frames().size());
+        // The final check is to ensure that the random data in the response
+        // matches the random data from the challenge.
+        EXPECT_EQ(0,
+                  memcmp(path_frame_buffer1.data(),
+                         &(writer_->path_response_frames().front().data_buffer),
+                         sizeof(path_frame_buffer1)));
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+      }))
+      .WillOnce(Invoke([=]() {
+        // The last write of ACK-only packet should still use the old peer
+        // address.
+        EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
+      }));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest, ReceiveStreamFrameBeforePathChallenge) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE));
+  EXPECT_CALL(*send_algorithm_, OnConnectionMigration())
+      .Times(connection_.validate_client_address() ? 0u : 1u);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke([=](const QuicStreamFrame& frame) {
+        // Send some data on the stream. The STREAM_FRAME should be built into
+        // one packet together with the latter PATH_RESPONSE and PATH_CHALLENGE.
+        const std::string data{"response body"};
+        connection_.producer()->SaveStreamData(frame.stream_id, data);
+        return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
+                                           NO_FIN);
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(connection_.validate_client_address() ? 0u : 1u);
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+
+  // Verify that this packet contains a STREAM_FRAME and a
+  // PATH_RESPONSE_FRAME.
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(1u, writer_->path_response_frames().size());
+  EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
+            writer_->path_challenge_frames().size());
+  // The final check is to ensure that the random data in the response
+  // matches the random data from the challenge.
+  EXPECT_EQ(0, memcmp(path_frame_buffer.data(),
+                      &(writer_->path_response_frames().front().data_buffer),
+                      sizeof(path_frame_buffer)));
+  EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
+            writer_->path_challenge_frames().size());
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+  if (connection_.validate_client_address()) {
+    EXPECT_TRUE(connection_.HasPendingPathValidation());
+  }
+}
+
+TEST_P(QuicConnectionTest, ReceiveStreamFrameFollowingPathChallenge) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicFrames frames;
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  // PATH_RESPONSE should be flushed out before the rest packet is parsed.
+  frames.push_back(QuicFrame(frame1_));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+  QuicByteCount received_packet_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([=, &received_packet_size]() {
+        // Verify that this packet contains a PATH_RESPONSE_FRAME.
+        EXPECT_EQ(0u, writer_->stream_frames().size());
+        EXPECT_EQ(1u, writer_->path_response_frames().size());
+        // The final check is to ensure that the random data in the response
+        // matches the random data from the challenge.
+        EXPECT_EQ(0,
+                  memcmp(path_frame_buffer.data(),
+                         &(writer_->path_response_frames().front().data_buffer),
+                         sizeof(path_frame_buffer)));
+        EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
+                  writer_->path_challenge_frames().size());
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+        received_packet_size =
+            QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_);
+      }));
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE));
+  EXPECT_CALL(*send_algorithm_, OnConnectionMigration())
+      .Times(connection_.validate_client_address() ? 0u : 1u);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke([=](const QuicStreamFrame& frame) {
+        // Send some data on the stream. The STREAM_FRAME should be built into a
+        // new packet but throttled by anti-amplifciation limit.
+        const std::string data{"response body"};
+        connection_.producer()->SaveStreamData(frame.stream_id, data);
+        return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
+                                           NO_FIN);
+      }));
+
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  if (!connection_.validate_client_address()) {
+    return;
+  }
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_EQ(0u,
+            QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
+  EXPECT_EQ(
+      received_packet_size,
+      QuicConnectionPeer::BytesReceivedBeforeAddressValidation(&connection_));
+}
+
+// Tests that a PATH_CHALLENGE is received in between other frames in an out of
+// order packet.
+TEST_P(QuicConnectionTest, PathChallengeWithDataInOutOfOrderPacket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  frames.push_back(QuicFrame(frame2_));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
+                                          /*port=*/23456);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .Times(2)
+      .WillRepeatedly(Invoke([=](const QuicStreamFrame& frame) {
+        // Send some data on the stream. The STREAM_FRAME should be built into
+        // one packet together with the latter PATH_RESPONSE.
+        const std::string data{"response body"};
+        connection_.producer()->SaveStreamData(frame.stream_id, data);
+        return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
+                                           NO_FIN);
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(Invoke([=]() {
+        // Verify that this packet contains a STREAM_FRAME and is sent to the
+        // original peer address.
+        EXPECT_EQ(1u, writer_->stream_frames().size());
+        // No connection migration should happen because the packet is received
+        // out of order.
+        EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
+      }))
+      .WillOnce(Invoke([=]() {
+        EXPECT_EQ(1u, writer_->path_response_frames().size());
+        // The final check is to ensure that the random data in the response
+        // matches the random data from the challenge.
+        EXPECT_EQ(0,
+                  memcmp(path_frame_buffer.data(),
+                         &(writer_->path_response_frames().front().data_buffer),
+                         sizeof(path_frame_buffer)));
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+        // PATH_RESPONSE should be sent in another packet to a different peer
+        // address.
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+      }))
+      .WillOnce(Invoke([=]() {
+        // Verify that this packet contains a STREAM_FRAME and is sent to the
+        // original peer address.
+        EXPECT_EQ(1u, writer_->stream_frames().size());
+        // No connection migration should happen because the packet is received
+        // out of order.
+        EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
+      }));
+  // Lower the packet number so that receiving this packet shouldn't trigger
+  // peer migration.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+}
+
+// Tests that a PATH_CHALLENGE is cached if its PATH_RESPONSE can't be sent.
+TEST_P(QuicConnectionTest, FailToWritePathResponse) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicFrames frames;
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
+                                          /*port=*/23456);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
+  // Lower the packet number so that receiving this packet shouldn't trigger
+  // peer migration.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  writer_->SetWriteBlocked();
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+}
+
+// Regression test for b/168101557.
+TEST_P(QuicConnectionTest, HandshakeDataDoesNotGetPtoed) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  // Send HANDSHAKE packets.
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Send half RTT packet.
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+
+  // Receives HANDSHAKE 1.
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_HANDSHAKE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  // Verify there is pending ACK.
+  ASSERT_TRUE(connection_.HasPendingAcks());
+  // Set the send alarm.
+  connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
+
+  // Fire ACK alarm.
+  connection_.GetAckAlarm()->Fire();
+  // Verify 1-RTT packet is coalesced with handshake packet.
+  EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+  connection_.GetSendAlarm()->Fire();
+
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify a handshake packet gets PTOed and 1-RTT packet gets coalesced.
+  EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+}
+
+// Regression test for b/168294218.
+TEST_P(QuicConnectionTest, CoalescerHandlesInitialKeyDiscard) {
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_discard_initial_packet_with_key_dropped, true);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+  }));
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+
+  EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    use_tagging_decrypter();
+    ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+    connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                             std::make_unique<TaggingEncrypter>(0x01));
+    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                             std::make_unique<TaggingEncrypter>(0x02));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
+    // Verify this packet is on hold.
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+  }
+  EXPECT_TRUE(connection_.connected());
+}
+
+// Regresstion test for b/168294218
+TEST_P(QuicConnectionTest, ZeroRttRejectionAndMissingInitialKeys) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // Not defer send in response to packet.
+  connection_.set_defer_send_in_response_to_packets(false);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+  }));
+  EXPECT_CALL(visitor_, OnCryptoFrame(_))
+      .WillRepeatedly(Invoke([=](const QuicCryptoFrame& frame) {
+        if (frame.level == ENCRYPTION_HANDSHAKE) {
+          // 0-RTT gets rejected.
+          connection_.MarkZeroRttPacketsForRetransmission(0);
+          // Send Crypto data.
+          connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                                   std::make_unique<TaggingEncrypter>(0x03));
+          connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+          connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+          connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                                   std::make_unique<TaggingEncrypter>(0x04));
+          connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+          // Advance INITIAL ack delay to trigger initial ACK to be sent AFTER
+          // the retransmission of rejected 0-RTT packets while the HANDSHAKE
+          // packet is still in the coalescer, such that the INITIAL key gets
+          // dropped between SendAllPendingAcks and actually send the ack frame,
+          // bummer.
+          clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+        }
+      }));
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+
+  QuicAckFrame frame1 = InitAckFrame(1);
+  // Received ACK for packet 1.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Fire retransmission alarm.
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  QuicFrames frames1;
+  frames1.push_back(QuicFrame(&crypto_frame_));
+  QuicFrames frames2;
+  QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0,
+                               absl::string_view(data1));
+  frames2.push_back(QuicFrame(&crypto_frame));
+  ProcessCoalescedPacket(
+      {{2, frames1, ENCRYPTION_INITIAL}, {3, frames2, ENCRYPTION_HANDSHAKE}});
+}
+
+TEST_P(QuicConnectionTest, OnZeroRttPacketAcked) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SendCryptoStreamData();
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  connection_.SendStreamDataWithString(4, "bar", 0, NO_FIN);
+  // Received ACK for packet 1, HANDSHAKE packet and 1-RTT ACK.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  QuicFrames frames1;
+  QuicAckFrame ack_frame1 = InitAckFrame(1);
+  frames1.push_back(QuicFrame(&ack_frame1));
+
+  QuicFrames frames2;
+  QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0,
+                               absl::string_view(data1));
+  frames2.push_back(QuicFrame(&crypto_frame));
+  EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  ProcessCoalescedPacket(
+      {{1, frames1, ENCRYPTION_INITIAL}, {2, frames2, ENCRYPTION_HANDSHAKE}});
+
+  QuicFrames frames3;
+  QuicAckFrame ack_frame2 =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  frames3.push_back(QuicFrame(&ack_frame2));
+  EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(1);
+  ProcessCoalescedPacket({{3, frames3, ENCRYPTION_FORWARD_SECURE}});
+
+  QuicFrames frames4;
+  QuicAckFrame ack_frame3 =
+      InitAckFrame({{QuicPacketNumber(3), QuicPacketNumber(4)}});
+  frames4.push_back(QuicFrame(&ack_frame3));
+  EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
+  ProcessCoalescedPacket({{4, frames4, ENCRYPTION_FORWARD_SECURE}});
+}
+
+TEST_P(QuicConnectionTest, InitiateKeyUpdate) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  TransportParameters params;
+  QuicConfig config;
+  std::string error_details;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+
+  MockFramerVisitor peer_framer_visitor_;
+  peer_framer_.set_visitor(&peer_framer_visitor_);
+
+  use_tagging_decrypter();
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+
+  // Key update should still not be allowed, since no packet has been acked
+  // from the current key phase.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Send packet 1.
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+
+  // Key update should still not be allowed, even though a packet was sent in
+  // the current key phase it hasn't been acked yet.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  // Receive ack for packet 1.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  ProcessAckPacket(&frame1);
+
+  // OnDecryptedFirstPacketInKeyPhase is called even on the first key phase,
+  // so discard_previous_keys_alarm_ should be set now.
+  EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Key update should now be allowed.
+  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
+  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
+    return std::make_unique<TaggingEncrypter>(0x02);
+  });
+  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+  // discard_previous_keys_alarm_ should not be set until a packet from the new
+  // key phase has been received. (The alarm that was set above should be
+  // cleared if it hasn't fired before the next key update happened.)
+  EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Pretend that peer accepts the key update.
+  EXPECT_CALL(peer_framer_visitor_,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
+  EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
+      .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); });
+  peer_framer_.SetKeyUpdateSupportForConnection(true);
+  peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
+
+  // Another key update should not be allowed yet.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+
+  // Send packet 2.
+  SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
+  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+  // Receive ack for packet 2.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame2 = InitAckFrame(2);
+  ProcessAckPacket(&frame2);
+  EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Key update should be allowed again now that a packet has been acked from
+  // the current key phase.
+  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x03); });
+  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
+    return std::make_unique<TaggingEncrypter>(0x03);
+  });
+  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+
+  // Pretend that peer accepts the key update.
+  EXPECT_CALL(peer_framer_visitor_,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x03); });
+  EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
+      .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x03); });
+  peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
+
+  // Another key update should not be allowed yet.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+
+  // Send packet 3.
+  SendStreamDataToPeer(3, "baz", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(3u), last_packet);
+
+  // Another key update should not be allowed yet.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Receive ack for packet 3.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame3 = InitAckFrame(3);
+  ProcessAckPacket(&frame3);
+  EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Key update should be allowed now.
+  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x04); });
+  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
+    return std::make_unique<TaggingEncrypter>(0x04);
+  });
+  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+}
+
+TEST_P(QuicConnectionTest, InitiateKeyUpdateApproachingConfidentialityLimit) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 3U);
+
+  std::string error_details;
+  TransportParameters params;
+  // Key update is enabled.
+  QuicConfig config;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  MockFramerVisitor peer_framer_visitor_;
+  peer_framer_.set_visitor(&peer_framer_visitor_);
+
+  use_tagging_decrypter();
+
+  uint8_t current_tag = 0x01;
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(current_tag));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(current_tag));
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+
+  peer_framer_.SetKeyUpdateSupportForConnection(true);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(current_tag));
+
+  const QuicConnectionStats& stats = connection_.GetStats();
+
+  for (int packet_num = 1; packet_num <= 8; ++packet_num) {
+    if (packet_num == 3 || packet_num == 6) {
+      current_tag++;
+      EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+          .WillOnce([current_tag]() {
+            return std::make_unique<StrictTaggingDecrypter>(current_tag);
+          });
+      EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter())
+          .WillOnce([current_tag]() {
+            return std::make_unique<TaggingEncrypter>(current_tag);
+          });
+      EXPECT_CALL(visitor_,
+                  OnKeyUpdate(KeyUpdateReason::kLocalKeyUpdateLimitOverride));
+    }
+    // Send packet.
+    QuicPacketNumber last_packet;
+    SendStreamDataToPeer(packet_num, "foo", 0, NO_FIN, &last_packet);
+    EXPECT_EQ(QuicPacketNumber(packet_num), last_packet);
+    if (packet_num >= 6) {
+      EXPECT_EQ(2U, stats.key_update_count);
+    } else if (packet_num >= 3) {
+      EXPECT_EQ(1U, stats.key_update_count);
+    } else {
+      EXPECT_EQ(0U, stats.key_update_count);
+    }
+
+    if (packet_num == 4 || packet_num == 7) {
+      // Pretend that peer accepts the key update.
+      EXPECT_CALL(peer_framer_visitor_,
+                  AdvanceKeysAndCreateCurrentOneRttDecrypter())
+          .WillOnce([current_tag]() {
+            return std::make_unique<StrictTaggingDecrypter>(current_tag);
+          });
+      EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
+          .WillOnce([current_tag]() {
+            return std::make_unique<TaggingEncrypter>(current_tag);
+          });
+      peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
+    }
+    // Receive ack for packet.
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+    QuicAckFrame frame1 = InitAckFrame(packet_num);
+    ProcessAckPacket(&frame1);
+  }
+}
+
+TEST_P(QuicConnectionTest,
+       CloseConnectionOnConfidentialityLimitKeyUpdateNotAllowed) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  // Set key update confidentiality limit to 1 packet.
+  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 1U);
+  // Use confidentiality limit for connection close of 3 packets.
+  constexpr size_t kConfidentialityLimit = 3U;
+
+  std::string error_details;
+  TransportParameters params;
+  // Key update is enabled.
+  QuicConfig config;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::make_unique<NullEncrypterWithConfidentialityLimit>(
+          Perspective::IS_CLIENT, kConfidentialityLimit));
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+
+  QuicPacketNumber last_packet;
+  // Send 3 packets without receiving acks for any of them. Key update will not
+  // be allowed, so the confidentiality limit should be reached, forcing the
+  // connection to be closed.
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_TRUE(connection_.connected());
+  SendStreamDataToPeer(2, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_FALSE(connection_.connected());
+  const QuicConnectionStats& stats = connection_.GetStats();
+  EXPECT_EQ(0U, stats.key_update_count);
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitDuringHandshake) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr uint8_t correct_tag = 0x01;
+  constexpr uint8_t wrong_tag = 0xFE;
+  constexpr QuicPacketCount kIntegrityLimit = 3;
+
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 1; i <= kIntegrityLimit; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    if (i == kIntegrityLimit) {
+      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+      EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
+    }
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAfterHandshake) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr uint8_t correct_tag = 0x01;
+  constexpr uint8_t wrong_tag = 0xFE;
+  constexpr QuicPacketCount kIntegrityLimit = 3;
+
+  use_tagging_decrypter();
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 1; i <= kIntegrityLimit; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    if (i == kIntegrityLimit) {
+      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+    }
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest,
+       CloseConnectionOnIntegrityLimitAcrossEncryptionLevels) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr uint8_t correct_tag = 0x01;
+  constexpr uint8_t wrong_tag = 0xFE;
+  constexpr QuicPacketCount kIntegrityLimit = 4;
+
+  use_tagging_decrypter();
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 1; i <= 2; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.RemoveEncrypter(ENCRYPTION_HANDSHAKE);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 3; i <= kIntegrityLimit; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    if (i == kIntegrityLimit) {
+      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+    }
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest, IntegrityLimitDoesNotApplyWithoutDecryptionKey) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr uint8_t correct_tag = 0x01;
+  constexpr uint8_t wrong_tag = 0xFE;
+  constexpr QuicPacketCount kIntegrityLimit = 3;
+
+  use_tagging_decrypter();
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 1; i <= kIntegrityLimit * 2; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        0u, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAcrossKeyPhases) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr QuicPacketCount kIntegrityLimit = 4;
+
+  TransportParameters params;
+  QuicConfig config;
+  std::string error_details;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  MockFramerVisitor peer_framer_visitor_;
+  peer_framer_.set_visitor(&peer_framer_visitor_);
+
+  use_tagging_decrypter();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   0x01, kIntegrityLimit));
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0xFF));
+  for (uint64_t i = 1; i <= 2; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  // Send packet 1.
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+  // Receive ack for packet 1.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  ProcessAckPacket(&frame1);
+  // Key update should now be allowed, initiate it.
+  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce([kIntegrityLimit]() {
+        return std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+            0x02, kIntegrityLimit);
+      });
+  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
+    return std::make_unique<TaggingEncrypter>(0x02);
+  });
+  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+
+  // Pretend that peer accepts the key update.
+  EXPECT_CALL(peer_framer_visitor_,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
+  EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
+      .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); });
+  peer_framer_.SetKeyUpdateSupportForConnection(true);
+  peer_framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests);
+
+  // Send packet 2.
+  SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
+  // Receive ack for packet 2.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame2 = InitAckFrame(2);
+  ProcessAckPacket(&frame2);
+
+  EXPECT_EQ(2u,
+            connection_.GetStats().num_failed_authentication_packets_received);
+
+  // Do two more undecryptable packets. Integrity limit should be reached.
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0xFF));
+  for (uint64_t i = 3; i <= kIntegrityLimit; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    if (i == kIntegrityLimit) {
+      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+    }
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest, SendAckFrequencyFrame) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  connection_.OnHandshakeComplete();
+
+  writer_->SetWritable();
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 99);
+  // Send packet 100
+  SendStreamDataToPeer(/*id=*/1, "foo", /*offset=*/0, NO_FIN, nullptr);
+
+  QuicAckFrequencyFrame captured_frame;
+  EXPECT_CALL(visitor_, SendAckFrequency(_))
+      .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) {
+        captured_frame = frame;
+      }));
+  // Send packet 101.
+  SendStreamDataToPeer(/*id=*/1, "bar", /*offset=*/3, NO_FIN, nullptr);
+
+  EXPECT_EQ(captured_frame.packet_tolerance, 10u);
+  EXPECT_EQ(captured_frame.max_ack_delay,
+            QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
+
+  // Sending packet 102 does not trigger sending another AckFrequencyFrame.
+  SendStreamDataToPeer(/*id=*/1, "baz", /*offset=*/6, NO_FIN, nullptr);
+}
+
+TEST_P(QuicConnectionTest, SendAckFrequencyFrameUponHandshakeCompletion) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  QuicTagVector quic_tag_vector;
+  // Enable sending AckFrequency upon handshake completion.
+  quic_tag_vector.push_back(kAFF2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  QuicAckFrequencyFrame captured_frame;
+  EXPECT_CALL(visitor_, SendAckFrequency(_))
+      .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) {
+        captured_frame = frame;
+      }));
+
+  connection_.OnHandshakeComplete();
+
+  EXPECT_EQ(captured_frame.packet_tolerance, 2u);
+  EXPECT_EQ(captured_frame.max_ack_delay,
+            QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
+}
+
+TEST_P(QuicConnectionTest, FastRecoveryOfLostServerHello) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.SendCryptoStreamData();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+
+  // Assume ServerHello gets lost.
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE);
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  // Shorten PTO for fast recovery from lost ServerHello.
+  EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
+            connection_.GetRetransmissionAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, ServerHelloGetsReordered) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_))
+      .WillRepeatedly(Invoke([=](const QuicCryptoFrame& frame) {
+        if (frame.level == ENCRYPTION_INITIAL) {
+          // Install handshake read keys.
+          SetDecrypter(ENCRYPTION_HANDSHAKE,
+                       std::make_unique<StrictTaggingDecrypter>(0x02));
+          connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                                   std::make_unique<TaggingEncrypter>(0x02));
+          connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+        }
+      }));
+
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.SendCryptoStreamData();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+
+  // Assume ServerHello gets reordered.
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  // Verify fast recovery is not enabled.
+  EXPECT_EQ(connection_.sent_packet_manager().GetRetransmissionTime(),
+            connection_.GetRetransmissionAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, MigratePath) {
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.OnPathDegradingDetected();
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+
+  // Buffer a packet.
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+  writer_->SetWriteBlocked();
+  connection_.SendMtuDiscoveryPacket(kMaxOutgoingPacketSize);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading());
+  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
+                          &new_writer, /*owns_writer=*/false);
+
+  EXPECT_EQ(kNewSelfAddress, connection_.self_address());
+  EXPECT_EQ(&new_writer, QuicConnectionPeer::GetWriter(&connection_));
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  // Buffered packet on the old path should be discarded.
+  if (connection_.connection_migration_use_new_cid()) {
+    EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  } else {
+    EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  }
+}
+
+TEST_P(QuicConnectionTest, MigrateToNewPathDuringProbing) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_TRUE(QuicConnectionPeer::IsAlternativePath(
+      &connection_, kNewSelfAddress, connection_.peer_address()));
+
+  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
+                          &new_writer, /*owns_writer=*/false);
+  EXPECT_EQ(kNewSelfAddress, connection_.self_address());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_FALSE(QuicConnectionPeer::IsAlternativePath(
+      &connection_, kNewSelfAddress, connection_.peer_address()));
+}
+
+TEST_P(QuicConnectionTest, SingleAckInPacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
+    connection_.SendStreamData3();
+    connection_.CloseConnection(
+        QUIC_INTERNAL_ERROR, "error",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+}
+
+TEST_P(QuicConnectionTest,
+       ServerReceivedZeroRttPacketAfterOneRttPacketWithRetainedKey) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  set_perspective(Perspective::IS_SERVER);
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Finish handshake.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
+
+  // 0-RTT packet received out of order should be decoded since the decrypter
+  // is temporarily retained.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(
+      0u,
+      connection_.GetStats()
+          .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter);
+
+  // Simulate the timeout for discarding 0-RTT keys passing.
+  connection_.GetDiscardZeroRttDecryptionKeysAlarm()->Fire();
+
+  // Another 0-RTT packet received now should not be decoded.
+  EXPECT_FALSE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(0);
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(
+      1u,
+      connection_.GetStats()
+          .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter);
+
+  // The |discard_zero_rtt_decryption_keys_alarm_| should only be set on the
+  // first 1-RTT packet received.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(5, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, NewTokenFrameInstigateAcks) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
+  EXPECT_CALL(visitor_, OnNewTokenReceived(_));
+  ProcessFramePacket(QuicFrame(new_token));
+
+  // Ensure that this has caused the ACK alarm to be set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, ServerClosesConnectionOnNewTokenFrame) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
+  EXPECT_CALL(visitor_, OnNewTokenReceived(_)).Times(0);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  ProcessFramePacket(QuicFrame(new_token));
+  EXPECT_FALSE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, OverrideRetryTokenWithRetryPacket) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  std::string address_token = "TestAddressToken";
+  connection_.SetSourceAddressTokenToSend(address_token);
+  EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
+                QuicConnectionPeer::GetPacketCreator(&connection_)),
+            address_token);
+  // Passes valid retry and verify token gets overridden.
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, DonotOverrideRetryTokenWithAddressToken) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  // Passes valid retry and verify token gets overridden.
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+  std::string retry_token = QuicPacketCreatorPeer::GetRetryToken(
+      QuicConnectionPeer::GetPacketCreator(&connection_));
+
+  std::string address_token = "TestAddressToken";
+  connection_.SetSourceAddressTokenToSend(address_token);
+  EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
+                QuicConnectionPeer::GetPacketCreator(&connection_)),
+            retry_token);
+}
+
+TEST_P(QuicConnectionTest,
+       ServerReceivedZeroRttWithHigherPacketNumberThanOneRtt) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  // The code that checks for this error piggybacks on some book-keeping state
+  // kept for key update, so enable key update for the test.
+  std::string error_details;
+  TransportParameters params;
+  QuicConfig config;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
+                                                  connection_.connection_id());
+  QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+      &config, connection_.connection_id());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  set_perspective(Perspective::IS_SERVER);
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Finish handshake.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  // Decrypt a 1-RTT packet.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
+
+  // 0-RTT packet with higher packet number than a 1-RTT packet is invalid and
+  // should cause the connection to be closed.
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(
+      QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
+}
+
+// Regression test for b/177312785
+TEST_P(QuicConnectionTest, PeerMigrateBeforeHandshakeConfirm) {
+  if (!VersionHasIetfQuicFrames(version().transport_version)) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_START));
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with a different peer address on server side will
+  // close connection.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(0);
+  ProcessFramePacketWithAddresses(QuicFrame(&frame), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_FALSE(connection_.connected());
+}
+
+// Regresstion test for b/175685916
+TEST_P(QuicConnectionTest, TryToFlushAckWithAckQueued) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  set_perspective(Perspective::IS_SERVER);
+
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.OnHandshakeComplete();
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 200);
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  // Sending ACK_FREQUENCY bundles ACK. QuicConnectionPeer::SendPing
+  // will try to bundle ACK but there is no pending ACK.
+  EXPECT_CALL(visitor_, SendAckFrequency(_))
+      .WillOnce(Invoke(&notifier_,
+                       &SimpleSessionNotifier::WriteOrBufferAckFrequency));
+  QuicConnectionPeer::SendPing(&connection_);
+}
+
+TEST_P(QuicConnectionTest, PathChallengeBeforePeerIpAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  SetClientConnectionId(TestConnectionId(1));
+  connection_.CreateConnectionIdManager();
+
+  QuicConnectionId server_cid0 = connection_.connection_id();
+  QuicConnectionId client_cid0 = connection_.client_connection_id();
+  QuicConnectionId client_cid1 = TestConnectionId(2);
+  QuicConnectionId server_cid1;
+  // Sends new server CID to client.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(
+          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.MaybeSendConnectionIdToClient();
+  // Receives new client CID from client.
+  QuicNewConnectionIdFrame new_cid_frame;
+  new_cid_frame.connection_id = client_cid1;
+  new_cid_frame.sequence_number = 1u;
+  new_cid_frame.retire_prior_to = 0u;
+  connection_.OnNewConnectionIdFrame(new_cid_frame);
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+  ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  peer_creator_.SetServerConnectionId(server_cid1);
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
+  QuicFrames frames1;
+  frames1.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+  QuicPathFrameBuffer payload;
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(AtLeast(1))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+        EXPECT_EQ(kPeerAddress, connection_.peer_address());
+        EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+        EXPECT_FALSE(writer_->path_response_frames().empty());
+        EXPECT_FALSE(writer_->path_challenge_frames().empty());
+        payload = writer_->path_challenge_frames().front().data_buffer;
+      }));
+  ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_EQ(default_path->client_connection_id, client_cid0);
+  EXPECT_EQ(default_path->server_connection_id, server_cid0);
+  EXPECT_EQ(alternative_path->client_connection_id, client_cid1);
+  EXPECT_EQ(alternative_path->server_connection_id, server_cid1);
+  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  }));
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(0);
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  EXPECT_TRUE(writer_->path_challenge_frames().empty());
+  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+  // Switch to use the mock send algorithm.
+  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
+  connection_.SetSendAlgorithm(send_algorithm_);
+  EXPECT_EQ(default_path->client_connection_id, client_cid1);
+  EXPECT_EQ(default_path->server_connection_id, server_cid1);
+  // The previous default path is kept as alternative path before reverse path
+  // validation finishes.
+  EXPECT_EQ(alternative_path->client_connection_id, client_cid0);
+  EXPECT_EQ(alternative_path->server_connection_id, server_cid0);
+  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid1);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
+
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  EXPECT_EQ(1u, connection_.GetStats()
+                    .num_peer_migration_to_proactively_validated_address);
+
+  // The PATH_CHALLENGE and PATH_RESPONSE is expanded upto the max packet size
+  // which may exceeds the anti-amplification limit. Verify server is throttled
+  // by anti-amplification limit.
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receiving PATH_RESPONSE should lift the anti-amplification limit.
+  QuicFrames frames3;
+  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+  EXPECT_CALL(visitor_, MaybeSendAddressToken());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(testing::AtLeast(1u));
+  ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+  // Verify that alternative_path_ is cleared and the peer CID is retired.
+  EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+
+  // Verify the anti-amplification limit is lifted by sending a packet larger
+  // than the anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
+  EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+}
+
+TEST_P(QuicConnectionTest,
+       PathValidationSucceedsBeforePeerIpAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+
+  QuicConnectionId server_cid0 = connection_.connection_id();
+  QuicConnectionId server_cid1;
+  // Sends new server CID to client.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(
+          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.MaybeSendConnectionIdToClient();
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  // Receive probing packet with new peer address.
+  peer_creator_.SetServerConnectionId(server_cid1);
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+  QuicPathFrameBuffer payload;
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+        EXPECT_EQ(kPeerAddress, connection_.peer_address());
+        EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+        EXPECT_FALSE(writer_->path_response_frames().empty());
+        EXPECT_FALSE(writer_->path_challenge_frames().empty());
+        payload = writer_->path_challenge_frames().front().data_buffer;
+      }))
+      .WillRepeatedly(Invoke([&]() {
+        // Only start reverse path validation once.
+        EXPECT_TRUE(writer_->path_challenge_frames().empty());
+      }));
+  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
+  QuicFrames frames1;
+  frames1.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+  ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_EQ(default_path->server_connection_id, server_cid0);
+  EXPECT_EQ(alternative_path->server_connection_id, server_cid1);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  // Receive PATH_RESPONSE should mark the new peer address validated.
+  QuicFrames frames3;
+  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+  ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+
+  // Process another packet with a newer peer address with the same port will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(0);
+  const QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
+                                            /*port=*/34567);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
+    EXPECT_EQ(kNewerPeerAddress, connection_.peer_address());
+  }));
+  EXPECT_CALL(visitor_, MaybeSendAddressToken());
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewerPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewerPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewerPeerAddress, connection_.effective_peer_address());
+  // Since the newer address has the same IP as the previously validated probing
+  // address. The peer migration becomes validated immediately.
+  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+  EXPECT_EQ(kNewerPeerAddress, writer_->last_write_peer_address());
+  EXPECT_EQ(1u, connection_.GetStats()
+                    .num_peer_migration_to_proactively_validated_address);
+  EXPECT_FALSE(connection_.HasPendingPathValidation());
+  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+
+  EXPECT_EQ(default_path->server_connection_id, server_cid1);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
+  // Verify that alternative_path_ is cleared.
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+
+  // Switch to use the mock send algorithm.
+  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
+  connection_.SetSendAlgorithm(send_algorithm_);
+
+  // Verify the server is not throttled by the anti-amplification limit by
+  // sending a packet larger than the anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
+  EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+}
+
+TEST_P(QuicConnectionTest,
+       ProbedOnAnotherPathAfterPeerIpAddressChangeAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+  if (!connection_.validate_client_address()) {
+    return;
+  }
+
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+
+  // Process a packet with a new peer address will start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(0);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  }));
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+
+  // Switch to use the mock send algorithm.
+  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
+  connection_.SetSendAlgorithm(send_algorithm_);
+
+  // Receive probing packet with a newer peer address shouldn't override the
+  // on-going path validation.
+  const QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
+                                            /*port=*/34567);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(kNewerPeerAddress, writer_->last_write_peer_address());
+        EXPECT_FALSE(writer_->path_response_frames().empty());
+        EXPECT_TRUE(writer_->path_challenge_frames().empty());
+      }));
+  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
+  QuicFrames frames1;
+  frames1.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+  ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewerPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+}
+
+TEST_P(QuicConnectionTest,
+       PathValidationFailedOnClientDueToLackOfServerConnectionId) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+    config.SetConnectionOptionsToSend({kRVCM});
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT,
+                    /*receive_new_server_connection_id=*/false);
+
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/34567);
+
+  bool success;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+
+  EXPECT_FALSE(success);
+}
+
+TEST_P(QuicConnectionTest,
+       PathValidationFailedOnClientDueToLackOfClientConnectionIdTheSecondTime) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT,
+                    /*receive_new_server_connection_id=*/false);
+  SetClientConnectionId(TestConnectionId(1));
+
+  // Make sure server connection ID is available for the 1st validation.
+  QuicConnectionId server_cid0 = connection_.connection_id();
+  QuicConnectionId server_cid1 = TestConnectionId(2);
+  QuicConnectionId server_cid2 = TestConnectionId(4);
+  QuicConnectionId client_cid1;
+  QuicNewConnectionIdFrame frame1;
+  frame1.connection_id = server_cid1;
+  frame1.sequence_number = 1u;
+  frame1.retire_prior_to = 0u;
+  frame1.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame1.connection_id);
+  connection_.OnNewConnectionIdFrame(frame1);
+  const auto* packet_creator =
+      QuicConnectionPeer::GetPacketCreator(&connection_);
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), server_cid0);
+
+  // Client will issue a new client connection ID to server.
+  EXPECT_CALL(visitor_, SendNewConnectionId(_))
+      .WillOnce(Invoke([&](const QuicNewConnectionIdFrame& frame) {
+        client_cid1 = frame.connection_id;
+      }));
+
+  const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
+  ASSERT_NE(kSelfAddress1, connection_.self_address());
+  bool success1;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kSelfAddress1, connection_.peer_address(), writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kSelfAddress1, connection_.peer_address(), &success1));
+
+  // Migrate upon 1st validation success.
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  ASSERT_TRUE(connection_.MigratePath(kSelfAddress1, connection_.peer_address(),
+                                      &new_writer, /*owns_writer=*/false));
+  QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  EXPECT_EQ(default_path->client_connection_id, client_cid1);
+  EXPECT_EQ(default_path->server_connection_id, server_cid1);
+  EXPECT_EQ(default_path->stateless_reset_token, frame1.stateless_reset_token);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), server_cid1);
+
+  // Client will retire server connection ID on old default_path.
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+
+  // Another server connection ID is available to client.
+  QuicNewConnectionIdFrame frame2;
+  frame2.connection_id = server_cid2;
+  frame2.sequence_number = 2u;
+  frame2.retire_prior_to = 1u;
+  frame2.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame2.connection_id);
+  connection_.OnNewConnectionIdFrame(frame2);
+
+  const QuicSocketAddress kSelfAddress2(QuicIpAddress::Loopback4(),
+                                        /*port=*/45678);
+  bool success2;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kSelfAddress2, connection_.peer_address(), writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kSelfAddress2, connection_.peer_address(), &success2));
+  // Since server does not retire any client connection ID yet, 2nd validation
+  // would fail due to lack of client connection ID.
+  EXPECT_FALSE(success2);
+}
+
+TEST_P(QuicConnectionTest, ServerConnectionIdRetiredUponPathValidationFailure) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  // Make sure server connection ID is available for validation.
+  QuicNewConnectionIdFrame frame;
+  frame.connection_id = TestConnectionId(2);
+  frame.sequence_number = 1u;
+  frame.retire_prior_to = 0u;
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  connection_.OnNewConnectionIdFrame(frame);
+
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/34567);
+  bool success;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+
+  auto* path_validator = QuicConnectionPeer::path_validator(&connection_);
+  path_validator->CancelPathValidation();
+  QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
+  EXPECT_FALSE(success);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+
+  // Client will retire server connection ID on alternative_path.
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/1u));
+  retire_peer_issued_cid_alarm->Fire();
+}
+
+TEST_P(QuicConnectionTest,
+       MigratePathDirectlyFailedDueToLackOfServerConnectionId) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT,
+                    /*receive_new_server_connection_id=*/false);
+  const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
+  ASSERT_NE(kSelfAddress1, connection_.self_address());
+
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  ASSERT_FALSE(connection_.MigratePath(kSelfAddress1,
+                                       connection_.peer_address(), &new_writer,
+                                       /*owns_writer=*/false));
+}
+
+TEST_P(QuicConnectionTest,
+       MigratePathDirectlyFailedDueToLackOfClientConnectionIdTheSecondTime) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT,
+                    /*receive_new_server_connection_id=*/false);
+  SetClientConnectionId(TestConnectionId(1));
+
+  // Make sure server connection ID is available for the 1st migration.
+  QuicNewConnectionIdFrame frame1;
+  frame1.connection_id = TestConnectionId(2);
+  frame1.sequence_number = 1u;
+  frame1.retire_prior_to = 0u;
+  frame1.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame1.connection_id);
+  connection_.OnNewConnectionIdFrame(frame1);
+
+  // Client will issue a new client connection ID to server.
+  QuicConnectionId new_client_connection_id;
+  EXPECT_CALL(visitor_, SendNewConnectionId(_))
+      .WillOnce(Invoke([&](const QuicNewConnectionIdFrame& frame) {
+        new_client_connection_id = frame.connection_id;
+      }));
+
+  // 1st migration is successful.
+  const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
+  ASSERT_NE(kSelfAddress1, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  ASSERT_TRUE(connection_.MigratePath(kSelfAddress1, connection_.peer_address(),
+                                      &new_writer,
+                                      /*owns_writer=*/false));
+  QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  EXPECT_EQ(default_path->client_connection_id, new_client_connection_id);
+  EXPECT_EQ(default_path->server_connection_id, frame1.connection_id);
+  EXPECT_EQ(default_path->stateless_reset_token, frame1.stateless_reset_token);
+
+  // Client will retire server connection ID on old default_path.
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+
+  // Another server connection ID is available to client.
+  QuicNewConnectionIdFrame frame2;
+  frame2.connection_id = TestConnectionId(4);
+  frame2.sequence_number = 2u;
+  frame2.retire_prior_to = 1u;
+  frame2.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame2.connection_id);
+  connection_.OnNewConnectionIdFrame(frame2);
+
+  // Since server does not retire any client connection ID yet, 2nd migration
+  // would fail due to lack of client connection ID.
+  const QuicSocketAddress kSelfAddress2(QuicIpAddress::Loopback4(),
+                                        /*port=*/45678);
+  auto new_writer2 = std::make_unique<TestPacketWriter>(version(), &clock_,
+                                                        Perspective::IS_CLIENT);
+  ASSERT_FALSE(connection_.MigratePath(
+      kSelfAddress2, connection_.peer_address(), new_writer2.release(),
+      /*owns_writer=*/true));
+}
+
+TEST_P(QuicConnectionTest,
+       CloseConnectionAfterReceiveNewConnectionIdFromPeerUsingEmptyCID) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  ASSERT_TRUE(connection_.client_connection_id().IsEmpty());
+
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(1);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_FALSE(connection_.OnNewConnectionIdFrame(frame));
+
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest, NewConnectionIdFrameResultsInError) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  connection_.CreateConnectionIdManager();
+  ASSERT_FALSE(connection_.connection_id().IsEmpty());
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = connection_id_;  // Reuses connection ID casuing error.
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_FALSE(connection_.OnNewConnectionIdFrame(frame));
+
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest,
+       ClientRetirePeerIssuedConnectionIdTriggeredByNewConnectionIdFrame) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  connection_.CreateConnectionIdManager();
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(1);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
+
+  frame.sequence_number = 2u;
+  frame.connection_id = TestConnectionId(2);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 1u;  // CID associated with #1 will be retired.
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_EQ(connection_.connection_id(), connection_id_);
+
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+  EXPECT_EQ(connection_.connection_id(), TestConnectionId(2));
+  EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
+            TestConnectionId(2));
+}
+
+TEST_P(QuicConnectionTest,
+       ServerRetirePeerIssuedConnectionIdTriggeredByNewConnectionIdFrame) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  SetClientConnectionId(TestConnectionId(0));
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(1);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
+
+  frame.sequence_number = 2u;
+  frame.connection_id = TestConnectionId(2);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 1u;  // CID associated with #1 will be retired.
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(0));
+
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(2));
+  EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
+            TestConnectionId(2));
+}
+
+TEST_P(
+    QuicConnectionTest,
+    ReplacePeerIssuedConnectionIdOnBothPathsTriggeredByNewConnectionIdFrame) {
+  if (!version().HasIetfQuicFrames() || !connection_.use_path_validator() ||
+      !connection_.count_bytes_on_alternative_path_separately()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  SetClientConnectionId(TestConnectionId(0));
+
+  // Populate alternative_path_ with probing packet.
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  QuicIpAddress new_host;
+  new_host.FromString("1.1.1.1");
+  ProcessReceivedPacket(kSelfAddress,
+                        QuicSocketAddress(new_host, /*port=*/23456), *received);
+
+  EXPECT_EQ(
+      TestConnectionId(0),
+      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(&connection_));
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(1);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
+
+  frame.sequence_number = 2u;
+  frame.connection_id = TestConnectionId(2);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 1u;  // CID associated with #1 will be retired.
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(0));
+
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(2));
+  EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
+            TestConnectionId(2));
+  // Clean up alternative path connection ID.
+  EXPECT_EQ(
+      TestConnectionId(2),
+      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(&connection_));
+}
+
+TEST_P(QuicConnectionTest,
+       CloseConnectionAfterReceiveRetireConnectionIdWhenNoCIDIssued) {
+  if (!version().HasIetfQuicFrames() ||
+      !connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicRetireConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+
+  EXPECT_FALSE(connection_.OnRetireConnectionIdFrame(frame));
+
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest, RetireConnectionIdFrameResultsInError) {
+  if (!version().HasIetfQuicFrames() ||
+      !connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.MaybeSendConnectionIdToClient();
+
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicRetireConnectionIdFrame frame;
+  frame.sequence_number = 2u;  // The corresponding ID is never issued.
+
+  EXPECT_FALSE(connection_.OnRetireConnectionIdFrame(frame));
+
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest,
+       ServerRetireSelfIssuedConnectionIdWithoutSendingNewConnectionIdBefore) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+
+  auto* retire_self_issued_cid_alarm =
+      connection_.GetRetireSelfIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_self_issued_cid_alarm->IsSet());
+
+  QuicConnectionId cid0 = connection_id_;
+  QuicRetireConnectionIdFrame frame;
+  frame.sequence_number = 0u;
+  if (connection_.connection_migration_use_new_cid()) {
+    EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_)).Times(2);
+    EXPECT_CALL(visitor_, SendNewConnectionId(_)).Times(2);
+  }
+  EXPECT_TRUE(connection_.OnRetireConnectionIdFrame(frame));
+}
+
+TEST_P(QuicConnectionTest, ServerRetireSelfIssuedConnectionId) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+  QuicConnectionId recorded_cid;
+  auto cid_recorder = [&recorded_cid](const QuicConnectionId& cid) {
+    recorded_cid = cid;
+  };
+  QuicConnectionId cid0 = connection_id_;
+  QuicConnectionId cid1;
+  QuicConnectionId cid2;
+  EXPECT_EQ(connection_.connection_id(), cid0);
+  EXPECT_EQ(connection_.GetOneActiveServerConnectionId(), cid0);
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(Invoke(cid_recorder));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.MaybeSendConnectionIdToClient();
+  cid1 = recorded_cid;
+
+  auto* retire_self_issued_cid_alarm =
+      connection_.GetRetireSelfIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_self_issued_cid_alarm->IsSet());
+
+  // Generate three packets with different connection IDs that will arrive out
+  // of order (2, 1, 3) later.
+  char buffers[3][kMaxOutgoingPacketSize];
+  // Destination connection ID of packet1 is cid0.
+  auto packet1 =
+      ConstructPacket({QuicFrame(QuicPingFrame())}, ENCRYPTION_FORWARD_SECURE,
+                      buffers[0], kMaxOutgoingPacketSize);
+  peer_creator_.SetServerConnectionId(cid1);
+  auto retire_cid_frame = std::make_unique<QuicRetireConnectionIdFrame>();
+  retire_cid_frame->sequence_number = 0u;
+  // Destination connection ID of packet2 is cid1.
+  auto packet2 = ConstructPacket({QuicFrame(retire_cid_frame.release())},
+                                 ENCRYPTION_FORWARD_SECURE, buffers[1],
+                                 kMaxOutgoingPacketSize);
+  // Destination connection ID of packet3 is cid1.
+  auto packet3 =
+      ConstructPacket({QuicFrame(QuicPingFrame())}, ENCRYPTION_FORWARD_SECURE,
+                      buffers[2], kMaxOutgoingPacketSize);
+
+  // Packet2 with RetireConnectionId frame trigers sending NewConnectionId
+  // immediately.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(Invoke(cid_recorder));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  peer_creator_.SetServerConnectionId(cid1);
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet2);
+  cid2 = recorded_cid;
+  // cid0 is not retired immediately.
+  EXPECT_THAT(connection_.GetActiveServerConnectionIds(),
+              ElementsAre(cid0, cid1, cid2));
+  ASSERT_TRUE(retire_self_issued_cid_alarm->IsSet());
+  EXPECT_EQ(connection_.connection_id(), cid1);
+  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid0 ||
+              connection_.GetOneActiveServerConnectionId() == cid1 ||
+              connection_.GetOneActiveServerConnectionId() == cid2);
+
+  // Packet1 updates the connection ID on the default path but not the active
+  // connection ID.
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet1);
+  EXPECT_EQ(connection_.connection_id(), cid0);
+  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid0 ||
+              connection_.GetOneActiveServerConnectionId() == cid1 ||
+              connection_.GetOneActiveServerConnectionId() == cid2);
+
+  // cid0 is retired when the retire CID alarm fires.
+  EXPECT_CALL(visitor_, OnServerConnectionIdRetired(cid0));
+  retire_self_issued_cid_alarm->Fire();
+  EXPECT_THAT(connection_.GetActiveServerConnectionIds(),
+              ElementsAre(cid1, cid2));
+  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid1 ||
+              connection_.GetOneActiveServerConnectionId() == cid2);
+
+  // Packet3 updates the connection ID on the default path.
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet3);
+  EXPECT_EQ(connection_.connection_id(), cid1);
+  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid1 ||
+              connection_.GetOneActiveServerConnectionId() == cid2);
+}
+
+TEST_P(QuicConnectionTest, PatchMissingClientConnectionIdOntoAlternativePath) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+  connection_.set_client_connection_id(TestConnectionId(1));
+
+  // Set up the state after path probing.
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  auto* alternative_path = QuicConnectionPeer::GetAlternativePath(&connection_);
+  QuicIpAddress new_host;
+  new_host.FromString("12.12.12.12");
+  alternative_path->self_address = default_path->self_address;
+  alternative_path->peer_address = QuicSocketAddress(new_host, 12345);
+  alternative_path->server_connection_id = TestConnectionId(3);
+  ASSERT_TRUE(alternative_path->client_connection_id.IsEmpty());
+  ASSERT_FALSE(alternative_path->stateless_reset_token.has_value());
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(5);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+  // New ID is patched onto the alternative path when the needed
+  // NEW_CONNECTION_ID frame is received after PATH_CHALLENGE frame.
+  connection_.OnNewConnectionIdFrame(frame);
+
+  ASSERT_EQ(alternative_path->client_connection_id, frame.connection_id);
+  ASSERT_EQ(alternative_path->stateless_reset_token,
+            frame.stateless_reset_token);
+}
+
+TEST_P(QuicConnectionTest, PatchMissingClientConnectionIdOntoDefaultPath) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+  connection_.set_client_connection_id(TestConnectionId(1));
+
+  // Set up the state after peer migration without probing.
+  auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  auto* alternative_path = QuicConnectionPeer::GetAlternativePath(&connection_);
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  *alternative_path = std::move(*default_path);
+  QuicIpAddress new_host;
+  new_host.FromString("12.12.12.12");
+  default_path->self_address = default_path->self_address;
+  default_path->peer_address = QuicSocketAddress(new_host, 12345);
+  default_path->server_connection_id = TestConnectionId(3);
+  packet_creator->SetDefaultPeerAddress(default_path->peer_address);
+  packet_creator->SetServerConnectionId(default_path->server_connection_id);
+  packet_creator->SetClientConnectionId(default_path->client_connection_id);
+
+  ASSERT_FALSE(default_path->validated);
+  ASSERT_TRUE(default_path->client_connection_id.IsEmpty());
+  ASSERT_FALSE(default_path->stateless_reset_token.has_value());
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(5);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+  // New ID is patched onto the default path when the needed
+  // NEW_CONNECTION_ID frame is received after PATH_CHALLENGE frame.
+  connection_.OnNewConnectionIdFrame(frame);
+
+  ASSERT_EQ(default_path->client_connection_id, frame.connection_id);
+  ASSERT_EQ(default_path->stateless_reset_token, frame.stateless_reset_token);
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), frame.connection_id);
+}
+
+TEST_P(QuicConnectionTest, ShouldGeneratePacketBlockedByMissingConnectionId) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.set_client_connection_id(TestConnectionId(1));
+  connection_.CreateConnectionIdManager();
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  ASSERT_TRUE(
+      connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
+
+  QuicPacketCreator* packet_creator =
+      QuicConnectionPeer::GetPacketCreator(&connection_);
+  QuicIpAddress peer_host1;
+  peer_host1.FromString("12.12.12.12");
+  QuicSocketAddress peer_address1(peer_host1, 1235);
+
+  {
+    // No connection ID is available as context is created without any.
+    QuicPacketCreator::ScopedPeerAddressContext context(
+        packet_creator, peer_address1, EmptyQuicConnectionId(),
+        EmptyQuicConnectionId(),
+        /*update_connection_id=*/true);
+    ASSERT_FALSE(connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                                  NOT_HANDSHAKE));
+  }
+  ASSERT_TRUE(
+      connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
+}
+
+// Regression test for b/182571515
+TEST_P(QuicConnectionTest, LostDataThenGetAcknowledged) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.validate_client_address()) {
+    return;
+  }
+
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  QuicPacketNumber last_packet;
+  // Send packets 1 to 4.
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);  // Packet 1
+  SendStreamDataToPeer(3, "foo", 3, NO_FIN, &last_packet);  // Packet 2
+  SendStreamDataToPeer(3, "foo", 6, NO_FIN, &last_packet);  // Packet 3
+  SendStreamDataToPeer(3, "foo", 9, NO_FIN, &last_packet);  // Packet 4
+
+  // Process a PING packet to set peer address.
+  ProcessFramePacket(QuicFrame(QuicPingFrame()));
+
+  // Process a packet containing a STREAM_FRAME and an ACK with changed peer
+  // address.
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  QuicAckFrame ack = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)}});
+  frames.push_back(QuicFrame(&ack));
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(_)).Times(1);
+
+  // Invoke OnCanWrite.
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(
+          InvokeWithoutArgs(&notifier_, &SimpleSessionNotifier::OnCanWrite));
+  QuicIpAddress ip_address;
+  ASSERT_TRUE(ip_address.FromString("127.0.52.223"));
+  EXPECT_QUIC_BUG(ProcessFramesPacketWithAddresses(
+                      frames, kSelfAddress, QuicSocketAddress(ip_address, 1000),
+                      ENCRYPTION_FORWARD_SECURE),
+                  "Try to write mid packet processing");
+  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+  // Verify stream frame will not be retransmitted.
+  EXPECT_TRUE(writer_->stream_frames().empty());
+}
+
+TEST_P(QuicConnectionTest, PtoSendStreamData) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  // Send HANDSHAKE packets.
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // Send half RTT packet with congestion control blocked.
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(false));
+  connection_.SendStreamDataWithString(2, std::string(1500, 'a'), 0, NO_FIN);
+
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify INITIAL and HANDSHAKE get retransmitted.
+  EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
+}
+
+TEST_P(QuicConnectionTest, SendingZeroRttPacketsDoesNotPostponePTO) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  // Install 0-RTT keys.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+
+  // CHLO gets acknowledged after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+  // Verify PTO is still armed since address validation is not finished yet.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // Send 0-RTT packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  // PTO deadline should be unchanged.
+  EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, QueueingUndecryptablePacketsDoesntPostponePTO) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(3);
+  connection_.SetFromConfig(config);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+
+  // CHLO gets acknowledged after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+  // Verify PTO is still armed since address validation is not finished yet.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // Receive an undecryptable packets.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0xFF));
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO deadline is sooner.
+  EXPECT_GT(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
+  pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // PTO fires.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  clock_.AdvanceTime(pto_deadline - clock_.ApproximateNow());
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify PTO is still armed since address validation is not finished yet.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // Verify PTO deadline does not change.
+  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, QueueUndecryptableHandshakePackets) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(3);
+  connection_.SetFromConfig(config);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.RemoveDecrypter(ENCRYPTION_HANDSHAKE);
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+
+  // Receive an undecryptable handshake packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0xFF));
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+  // Verify this handshake packet gets queued.
+  EXPECT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+}
+
+TEST_P(QuicConnectionTest, PingNotSentAt0RTTLevelWhenInitialAvailable) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+
+  // CHLO gets acknowledged after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+  // Verify PTO is still armed since address validation is not finished yet.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // PTO fires.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  clock_.AdvanceTime(pto_deadline - clock_.ApproximateNow());
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify the PING gets sent in ENCRYPTION_INITIAL.
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+}
+
+TEST_P(QuicConnectionTest, AckElicitingFrames) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!version().HasIetfQuicFrames() ||
+      !connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, SendNewConnectionId(_)).Times(2);
+  EXPECT_CALL(visitor_, OnRstStream(_));
+  EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
+  EXPECT_CALL(visitor_, OnBlockedFrame(_));
+  EXPECT_CALL(visitor_, OnHandshakeDoneReceived());
+  EXPECT_CALL(visitor_, OnStreamFrame(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(visitor_, OnMaxStreamsFrame(_));
+  EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_));
+  EXPECT_CALL(visitor_, OnStopSendingFrame(_));
+  EXPECT_CALL(visitor_, OnMessageReceived(""));
+  EXPECT_CALL(visitor_, OnNewTokenReceived(""));
+
+  SetClientConnectionId(TestConnectionId(12));
+  connection_.CreateConnectionIdManager();
+  QuicConnectionPeer::GetSelfIssuedConnectionIdManager(&connection_)
+      ->MaybeSendNewConnectionIds();
+  connection_.set_can_receive_ack_frequency_frame();
+
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  QuicRstStreamFrame rst_stream_frame;
+  QuicWindowUpdateFrame window_update_frame;
+  QuicPathChallengeFrame path_challenge_frame;
+  QuicNewConnectionIdFrame new_connection_id_frame;
+  QuicRetireConnectionIdFrame retire_connection_id_frame;
+  retire_connection_id_frame.sequence_number = 1u;
+  QuicStopSendingFrame stop_sending_frame;
+  QuicPathResponseFrame path_response_frame;
+  QuicMessageFrame message_frame;
+  QuicNewTokenFrame new_token_frame;
+  QuicAckFrequencyFrame ack_frequency_frame;
+  QuicBlockedFrame blocked_frame;
+  size_t packet_number = 1;
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+  for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
+    QuicFrameType frame_type = static_cast<QuicFrameType>(i);
+    bool skipped = false;
+    QuicFrame frame;
+    QuicFrames frames;
+    // Add some padding to fullfill the min size requirement of header
+    // protection.
+    frames.push_back(QuicFrame(QuicPaddingFrame(10)));
+    switch (frame_type) {
+      case PADDING_FRAME:
+        frame = QuicFrame(QuicPaddingFrame(10));
+        break;
+      case MTU_DISCOVERY_FRAME:
+        frame = QuicFrame(QuicMtuDiscoveryFrame());
+        break;
+      case PING_FRAME:
+        frame = QuicFrame(QuicPingFrame());
+        break;
+      case MAX_STREAMS_FRAME:
+        frame = QuicFrame(QuicMaxStreamsFrame());
+        break;
+      case STOP_WAITING_FRAME:
+        // Not supported.
+        skipped = true;
+        break;
+      case STREAMS_BLOCKED_FRAME:
+        frame = QuicFrame(QuicStreamsBlockedFrame());
+        break;
+      case STREAM_FRAME:
+        frame = QuicFrame(QuicStreamFrame());
+        break;
+      case HANDSHAKE_DONE_FRAME:
+        frame = QuicFrame(QuicHandshakeDoneFrame());
+        break;
+      case ACK_FRAME:
+        frame = QuicFrame(&ack_frame);
+        break;
+      case RST_STREAM_FRAME:
+        frame = QuicFrame(&rst_stream_frame);
+        break;
+      case CONNECTION_CLOSE_FRAME:
+        // Do not test connection close.
+        skipped = true;
+        break;
+      case GOAWAY_FRAME:
+        // Does not exist in IETF QUIC.
+        skipped = true;
+        break;
+      case BLOCKED_FRAME:
+        frame = QuicFrame(blocked_frame);
+        break;
+      case WINDOW_UPDATE_FRAME:
+        frame = QuicFrame(window_update_frame);
+        break;
+      case PATH_CHALLENGE_FRAME:
+        frame = QuicFrame(&path_challenge_frame);
+        break;
+      case STOP_SENDING_FRAME:
+        frame = QuicFrame(stop_sending_frame);
+        break;
+      case NEW_CONNECTION_ID_FRAME:
+        frame = QuicFrame(&new_connection_id_frame);
+        break;
+      case RETIRE_CONNECTION_ID_FRAME:
+        frame = QuicFrame(&retire_connection_id_frame);
+        break;
+      case PATH_RESPONSE_FRAME:
+        frame = QuicFrame(&path_response_frame);
+        break;
+      case MESSAGE_FRAME:
+        frame = QuicFrame(&message_frame);
+        break;
+      case CRYPTO_FRAME:
+        // CRYPTO_FRAME is ack eliciting is covered by other tests.
+        skipped = true;
+        break;
+      case NEW_TOKEN_FRAME:
+        frame = QuicFrame(&new_token_frame);
+        break;
+      case ACK_FREQUENCY_FRAME:
+        frame = QuicFrame(&ack_frequency_frame);
+        break;
+      case NUM_FRAME_TYPES:
+        skipped = true;
+        break;
+    }
+    if (skipped) {
+      continue;
+    }
+    ASSERT_EQ(frame_type, frame.type);
+    frames.push_back(frame);
+    EXPECT_FALSE(connection_.HasPendingAcks());
+    // Process frame.
+    ProcessFramesPacketAtLevel(packet_number++, frames,
+                               ENCRYPTION_FORWARD_SECURE);
+    if (QuicUtils::IsAckElicitingFrame(frame_type)) {
+      ASSERT_TRUE(connection_.HasPendingAcks()) << frame;
+      // Flush ACK.
+      clock_.AdvanceTime(DefaultDelayedAckTime());
+      connection_.GetAckAlarm()->Fire();
+    }
+    EXPECT_FALSE(connection_.HasPendingAcks());
+    ASSERT_TRUE(connection_.connected());
+  }
+}
+
+TEST_P(QuicConnectionTest, ReceivedChloAndAck) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicFrames frames;
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  frames.push_back(MakeCryptoFrame());
+  frames.push_back(QuicFrame(&ack_frame));
+
+  EXPECT_CALL(visitor_, OnCryptoFrame(_))
+      .WillOnce(IgnoreResult(InvokeWithoutArgs(
+          &connection_, &TestConnection::SendCryptoStreamData)));
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_INITIAL);
+}
+
+// Regression test for b/201643321.
+TEST_P(QuicConnectionTest, FailedToRetransmitShlo) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+  // Received ENCRYPTION_ZERO_RTT 1.
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    // Send half RTT data to exhaust amplification credit.
+    connection_.SendStreamDataWithString(0, std::string(100 * 1024, 'a'), 0,
+                                         NO_FIN);
+  }
+  // Received INITIAL 2.
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  ASSERT_TRUE(connection_.HasPendingAcks());
+  // Verify ACK delay is 1ms.
+  EXPECT_EQ(clock_.Now() + kAlarmGranularity,
+            connection_.GetAckAlarm()->deadline());
+  // ACK is not throttled by amplification limit, and SHLO is bundled. Also
+  // HANDSHAKE + 1RTT packets get coalesced.
+  if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
+  } else {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  }
+  // ACK alarm fires.
+  clock_.AdvanceTime(kAlarmGranularity);
+  connection_.GetAckAlarm()->Fire();
+  if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
+    // Verify 1-RTT packet is coalesced.
+    EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
+  } else {
+    // Verify HANDSHAKE packet is coalesced with INITIAL ACK + SHLO.
+    EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+  }
+  // Only the first packet in the coalesced packet has been processed,
+  // verify SHLO is bundled with INITIAL ACK.
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+  // Process the coalesced HANDSHAKE packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(0u, writer_->ack_frames().size());
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+  if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
+    // Process the coalesced 1-RTT packet.
+    ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+    packet = writer_->coalesced_packet()->Clone();
+    writer_->framer()->ProcessPacket(*packet);
+    EXPECT_EQ(0u, writer_->crypto_frames().size());
+    EXPECT_EQ(1u, writer_->stream_frames().size());
+  } else {
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+  }
+
+  // Received INITIAL 3.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  ProcessCryptoPacketAtLevel(3, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+// Regression test for b/216133388.
+TEST_P(QuicConnectionTest, FailedToConsumeCryptoData) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x03));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+  // Received ENCRYPTION_ZERO_RTT 1.
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
+                                         ENCRYPTION_HANDSHAKE);
+    // Send 1-RTT 3.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(40, 'a'), 0, NO_FIN);
+  }
+  // Received HANDSHAKE Ping, hence discard INITIAL keys.
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x03));
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_HANDSHAKE);
+  clock_.AdvanceTime(kAlarmGranularity);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Sending this 1-RTT data would leave the coalescer only have space to
+    // accommodate the HANDSHAKE ACK. The crypto data cannot be bundled with the
+    // ACK.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(1395, 'a'), 40, NO_FIN);
+  }
+  // Verify retransmission alarm is armed.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  const QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted)) {
+    // Verify the retransmission is a coalesced packet with HANDSHAKE 2 and
+    // 1-RTT 3.
+    EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
+    // Only the first packet in the coalesced packet has been processed.
+    EXPECT_EQ(1u, writer_->crypto_frames().size());
+    // Process the coalesced 1-RTT packet.
+    ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+    auto packet = writer_->coalesced_packet()->Clone();
+    writer_->framer()->ProcessPacket(*packet);
+    EXPECT_EQ(1u, writer_->stream_frames().size());
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+  } else {
+    // Although packet 2 has not been retransmitted, it has been marked PTOed
+    // and a HANDHSAKE PING gets retransmitted.
+    EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+    EXPECT_EQ(1u, writer_->ping_frames().size());
+    EXPECT_TRUE(writer_->stream_frames().empty());
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+  }
+  // Verify retransmission alarm is still armed.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest,
+       RTTSampleDoesNotIncludeQueuingDelayWithPostponedAckProcessing) {
+  // An endpoint might postpone the processing of ACK when the corresponding
+  // decryption key is not available. This test makes sure the RTT sample does
+  // not include the queuing delay.
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(3);
+  connection_.SetFromConfig(config);
+
+  // 30ms RTT.
+  const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(30);
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(kTestRTT, QuicTime::Delta::Zero(), QuicTime::Zero());
+  use_tagging_decrypter();
+
+  // Send 0-RTT packet.
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(0, std::string(10, 'a'), 0, FIN);
+
+  // Receives 1-RTT ACK for 0-RTT packet after RTT + ack_delay.
+  clock_.AdvanceTime(
+      kTestRTT + QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  // Peer reported ACK delay.
+  ack_frame.ack_delay_time =
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(&ack_frame));
+  QuicPacketHeader header =
+      ConstructPacketHeader(30, ENCRYPTION_FORWARD_SECURE);
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(30), *packet, buffer,
+      kMaxOutgoingPacketSize);
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+  if (connection_.GetSendAlarm()->IsSet()) {
+    connection_.GetSendAlarm()->Fire();
+  }
+  ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+
+  // Assume 1-RTT decrypter is available after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  ASSERT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  // Verify RTT sample does not include queueing delay.
+  EXPECT_EQ(rtt_stats->latest_rtt(), kTestRTT);
+}
+
+// Regression test for b/112480134.
+TEST_P(QuicConnectionTest, NoExtraPaddingInReserializedInitial) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration() ||
+      !connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+
+  set_perspective(Perspective::IS_SERVER);
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  uint64_t debug_visitor_sent_count = 0;
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _))
+      .WillRepeatedly([&]() { debug_visitor_sent_count++; });
+
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x03));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+
+  // Received ENCRYPTION_ZERO_RTT 2.
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
+                                         ENCRYPTION_HANDSHAKE);
+    // Send 1-RTT 3.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(400, 'b'), 0, NO_FIN);
+  }
+
+  // Arrange the stream data to be sent in response to ENCRYPTION_INITIAL 3.
+  const std::string data4(1000, '4');  // Data to send in stream id 4
+  const std::string data8(3000, '8');  // Data to send in stream id 8
+  EXPECT_CALL(visitor_, OnCanWrite()).WillOnce([&]() {
+    connection_.producer()->SaveStreamData(4, data4);
+    connection_.producer()->SaveStreamData(8, data8);
+
+    notifier_.WriteOrBufferData(4, data4.size(), FIN_AND_PADDING);
+
+    // This should trigger FlushCoalescedPacket.
+    notifier_.WriteOrBufferData(8, data8.size(), FIN);
+  });
+
+  QuicByteCount pending_padding_after_serialize_2nd_1rtt_packet = 0;
+  QuicPacketCount num_1rtt_packets_serialized = 0;
+  EXPECT_CALL(connection_, OnSerializedPacket(_))
+      .WillRepeatedly([&](SerializedPacket packet) {
+        if (packet.encryption_level == ENCRYPTION_FORWARD_SECURE) {
+          num_1rtt_packets_serialized++;
+          if (num_1rtt_packets_serialized == 2) {
+            pending_padding_after_serialize_2nd_1rtt_packet =
+                connection_.packet_creator().pending_padding_bytes();
+          }
+        }
+        connection_.QuicConnection::OnSerializedPacket(std::move(packet));
+      });
+
+  // Server receives INITIAL 3, this will serialzie FS 7 (stream 4, stream 8),
+  // which will trigger a flush of a coalesced packet consists of INITIAL 4,
+  // HS 5 and FS 6 (stream 4).
+  if (GetQuicReloadableFlag(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
+    // Expect no QUIC_BUG.
+    ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL);
+    EXPECT_EQ(
+        debug_visitor_sent_count,
+        connection_.sent_packet_manager().GetLargestSentPacket().ToUint64());
+  } else {
+    // Expect QUIC_BUG due to extra padding.
+    EXPECT_QUIC_BUG(
+        { ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL); },
+        "Reserialize initial packet in coalescer has unexpected size");
+    EXPECT_EQ(
+        debug_visitor_sent_count + 1,
+        connection_.sent_packet_manager().GetLargestSentPacket().ToUint64());
+  }
+
+  // The error only happens if after serializing the second 1RTT packet(pkt #7),
+  // the pending padding bytes is non zero.
+  EXPECT_GT(pending_padding_after_serialize_2nd_1rtt_packet, 0u);
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, ReportedAckDelayIncludesQueuingDelay) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(3);
+  connection_.SetFromConfig(config);
+
+  // Receive 1-RTT ack-eliciting packet while keys are not available.
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicPingFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(100)));
+  QuicPacketHeader header =
+      ConstructPacketHeader(30, ENCRYPTION_FORWARD_SECURE);
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(30), *packet, buffer,
+      kMaxOutgoingPacketSize);
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  const QuicTime packet_receipt_time = clock_.Now();
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+  if (connection_.GetSendAlarm()->IsSet()) {
+    connection_.GetSendAlarm()->Fire();
+  }
+  ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  // 1-RTT keys become available after 10ms.
+  const QuicTime::Delta kQueuingDelay = QuicTime::Delta::FromMilliseconds(10);
+  clock_.AdvanceTime(kQueuingDelay);
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  ASSERT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  ASSERT_TRUE(connection_.HasPendingAcks());
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    EXPECT_EQ(packet_receipt_time + DefaultDelayedAckTime(),
+              connection_.GetAckAlarm()->deadline());
+    clock_.AdvanceTime(packet_receipt_time + DefaultDelayedAckTime() -
+                       clock_.Now());
+  } else {
+    EXPECT_EQ(clock_.Now() + DefaultDelayedAckTime(),
+              connection_.GetAckAlarm()->deadline());
+    clock_.AdvanceTime(DefaultDelayedAckTime());
+  }
+  // Fire ACK alarm.
+  connection_.GetAckAlarm()->Fire();
+  ASSERT_EQ(1u, writer_->ack_frames().size());
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Verify ACK delay time does not include queuing delay.
+    EXPECT_EQ(DefaultDelayedAckTime(), writer_->ack_frames()[0].ack_delay_time);
+  } else {
+    // Verify ACK delay time = queuing delay + ack delay
+    EXPECT_EQ(DefaultDelayedAckTime() + kQueuingDelay,
+              writer_->ack_frames()[0].ack_delay_time);
+  }
+}
+
+TEST_P(QuicConnectionTest, CoalesceOneRTTPacketWithInitialAndHandshakePackets) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x03));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+
+  // Received ENCRYPTION_ZERO_RTT 2.
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
+                                         ENCRYPTION_HANDSHAKE);
+    // Send 1-RTT data.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(2000, 'b'), 0, FIN);
+  }
+  // Verify coalesced packet [INITIAL 1 + HANDSHAKE 2 + part of 1-RTT data] +
+  // rest of 1-RTT data get sent.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+
+  // Received ENCRYPTION_INITIAL 3.
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL);
+
+  // Verify a coalesced packet gets sent.
+  EXPECT_EQ(3u, writer_->packets_write_attempts());
+
+  // Only the first INITIAL packet has been processed yet.
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+
+  // Process HANDSHAKE packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+  if (!GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+    return;
+  }
+  // Process 1-RTT packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+}
+
+// Regression test for b/180103273
+TEST_P(QuicConnectionTest, SendMultipleConnectionCloses) {
+  if (!version().HasIetfQuicFrames() ||
+      !GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  // Finish handshake.
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.RemoveEncrypter(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  // Verify BeforeConnectionCloseSent gets called twice while OnConnectionClosed
+  // is called once.
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent()).Times(2);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  // Send connection close w/o closing connection.
+  QuicConnectionPeer::SendConnectionClosePacket(
+      &connection_, INTERNAL_ERROR, QUIC_INTERNAL_ERROR, "internal error");
+  // Fire blackhole detection alarm.
+  EXPECT_QUIC_BUG(connection_.GetBlackholeDetectorAlarm()->Fire(),
+                  "Already sent connection close");
+}
+
+// Regression test for b/157895910.
+TEST_P(QuicConnectionTest, EarliestSentTimeNotInitializedWhenPtoFires) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x03));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
+                                         ENCRYPTION_HANDSHAKE);
+    // Send half RTT data.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(2000, 'b'), 0, FIN);
+  }
+
+  // Received ACKs for both INITIAL and HANDSHAKE packets.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  QuicFrames frames1;
+  QuicAckFrame ack_frame1 = InitAckFrame(1);
+  frames1.push_back(QuicFrame(&ack_frame1));
+
+  QuicFrames frames2;
+  QuicAckFrame ack_frame2 =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  frames2.push_back(QuicFrame(&ack_frame2));
+  ProcessCoalescedPacket(
+      {{2, frames1, ENCRYPTION_INITIAL}, {3, frames2, ENCRYPTION_HANDSHAKE}});
+  // Verify PTO is not armed given the only outstanding data is half RTT data.
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_constants.cc b/quiche/quic/core/quic_constants.cc
new file mode 100644
index 0000000..b9594fa
--- /dev/null
+++ b/quiche/quic/core/quic_constants.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_constants.h"
+
+namespace quic {
+
+const char* const kFinalOffsetHeaderKey = ":final-offset";
+
+const char* const kEPIDGoogleFrontEnd = "GFE";
+const char* const kEPIDGoogleFrontEnd0 = "GFE0";
+
+QuicPacketNumber MaxRandomInitialPacketNumber() {
+  static const QuicPacketNumber kMaxRandomInitialPacketNumber =
+      QuicPacketNumber(0x7fffffff);
+  return kMaxRandomInitialPacketNumber;
+}
+
+QuicPacketNumber FirstSendingPacketNumber() {
+  static const QuicPacketNumber kFirstSendingPacketNumber = QuicPacketNumber(1);
+  return kFirstSendingPacketNumber;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_constants.h b/quiche/quic/core/quic_constants.h
new file mode 100644
index 0000000..189179f
--- /dev/null
+++ b/quiche/quic/core/quic_constants.h
@@ -0,0 +1,316 @@
+// 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_CONSTANTS_H_
+#define QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <limits>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+// Definitions of constant values used throughout the QUIC code.
+
+namespace quic {
+
+// Simple time constants.
+const uint64_t kNumSecondsPerMinute = 60;
+const uint64_t kNumSecondsPerHour = kNumSecondsPerMinute * 60;
+const uint64_t kNumSecondsPerWeek = kNumSecondsPerHour * 24 * 7;
+const uint64_t kNumMillisPerSecond = 1000;
+const uint64_t kNumMicrosPerMilli = 1000;
+const uint64_t kNumMicrosPerSecond = kNumMicrosPerMilli * kNumMillisPerSecond;
+
+// Default number of connections for N-connection emulation.
+const uint32_t kDefaultNumConnections = 2;
+// Default initial maximum size in bytes of a QUIC packet.
+const QuicByteCount kDefaultMaxPacketSize = 1250;
+// Default initial maximum size in bytes of a QUIC packet for servers.
+const QuicByteCount kDefaultServerMaxPacketSize = 1000;
+// Maximum transmission unit on Ethernet.
+const QuicByteCount kEthernetMTU = 1500;
+// The maximum packet size of any QUIC packet over IPv6, based on ethernet's max
+// size, minus the IP and UDP headers. IPv6 has a 40 byte header, UDP adds an
+// additional 8 bytes.  This is a total overhead of 48 bytes.  Ethernet's
+// max packet size is 1500 bytes,  1500 - 48 = 1452.
+const QuicByteCount kMaxV6PacketSize = 1452;
+// The maximum packet size of any QUIC packet over IPv4.
+// 1500(Ethernet) - 20(IPv4 header) - 8(UDP header) = 1472.
+const QuicByteCount kMaxV4PacketSize = 1472;
+// The maximum incoming packet size allowed.
+const QuicByteCount kMaxIncomingPacketSize = kMaxV4PacketSize;
+// The maximum outgoing packet size allowed.
+const QuicByteCount kMaxOutgoingPacketSize = kMaxV6PacketSize;
+// ETH_MAX_MTU - MAX(sizeof(iphdr), sizeof(ip6_hdr)) - sizeof(udphdr).
+const QuicByteCount kMaxGsoPacketSize = 65535 - 40 - 8;
+// The maximal IETF DATAGRAM frame size we'll accept. Choosing 2^16 ensures
+// that it is greater than the biggest frame we could ever fit in a QUIC packet.
+const QuicByteCount kMaxAcceptedDatagramFrameSize = 65536;
+// Default value of the max_packet_size transport parameter if it is not
+// transmitted.
+const QuicByteCount kDefaultMaxPacketSizeTransportParam = 65527;
+// Default maximum packet size used in the Linux TCP implementation.
+// Used in QUIC for congestion window computations in bytes.
+const QuicByteCount kDefaultTCPMSS = 1460;
+const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
+// The minimum size of a packet which can elicit a version negotiation packet,
+// as per section 8.1 of the QUIC spec.
+const QuicByteCount kMinPacketSizeForVersionNegotiation = 1200;
+
+// We match SPDY's use of 32 (since we'd compete with SPDY).
+const QuicPacketCount kInitialCongestionWindow = 32;
+
+// Do not allow initial congestion window to be greater than 200 packets.
+const QuicPacketCount kMaxInitialCongestionWindow = 200;
+
+// Do not allow initial congestion window to be smaller than 10 packets.
+const QuicPacketCount kMinInitialCongestionWindow = 10;
+
+// Minimum size of initial flow control window, for both stream and session.
+// This is only enforced when version.AllowsLowFlowControlLimits() is false.
+const QuicByteCount kMinimumFlowControlSendWindow = 16 * 1024;  // 16 KB
+// Default size of initial flow control window, for both stream and session.
+const QuicByteCount kDefaultFlowControlSendWindow = 16 * 1024;  // 16 KB
+
+// Maximum flow control receive window limits for connection and stream.
+const QuicByteCount kStreamReceiveWindowLimit = 16 * 1024 * 1024;   // 16 MB
+const QuicByteCount kSessionReceiveWindowLimit = 24 * 1024 * 1024;  // 24 MB
+
+// Minimum size of the CWND, in packets, when doing bandwidth resumption.
+const QuicPacketCount kMinCongestionWindowForBandwidthResumption = 10;
+
+// Default size of the socket receive buffer in bytes.
+const QuicByteCount kDefaultSocketReceiveBuffer = 1024 * 1024;
+
+// The lower bound of an untrusted initial rtt value.
+const uint32_t kMinUntrustedInitialRoundTripTimeUs = 10 * kNumMicrosPerMilli;
+
+// The lower bound of a trusted initial rtt value.
+const uint32_t kMinTrustedInitialRoundTripTimeUs = 5 * kNumMicrosPerMilli;
+
+// Don't allow a client to suggest an RTT longer than 1 second.
+const uint32_t kMaxInitialRoundTripTimeUs = kNumMicrosPerSecond;
+
+// Maximum number of open streams per connection.
+const size_t kDefaultMaxStreamsPerConnection = 100;
+
+// Number of bytes reserved for public flags in the packet header.
+const size_t kPublicFlagsSize = 1;
+// Number of bytes reserved for version number in the packet header.
+const size_t kQuicVersionSize = 4;
+
+// Minimum number of active connection IDs that an end point can maintain.
+const uint32_t kMinNumOfActiveConnectionIds = 2;
+
+// Length of the retry integrity tag in bytes.
+// https://tools.ietf.org/html/draft-ietf-quic-transport-25#section-17.2.5
+const size_t kRetryIntegrityTagLength = 16;
+
+// By default, UnackedPacketsMap allocates buffer of 64 after the first packet
+// is added.
+const int kDefaultUnackedPacketsInitialCapacity = 64;
+
+// Signifies that the QuicPacket will contain version of the protocol.
+const bool kIncludeVersion = true;
+// Signifies that the QuicPacket will include a diversification nonce.
+const bool kIncludeDiversificationNonce = true;
+
+// Header key used to identify final offset on data stream when sending HTTP/2
+// trailing headers over QUIC.
+QUIC_EXPORT_PRIVATE extern const char* const kFinalOffsetHeaderKey;
+
+// Default maximum delayed ack time, in ms.
+// Uses a 25ms delayed ack timer. Helps with better signaling
+// in low-bandwidth (< ~384 kbps), where an ack is sent per packet.
+const int64_t kDefaultDelayedAckTimeMs = 25;
+
+// Default minimum delayed ack time, in ms (used only for sender control of ack
+// frequency).
+const uint32_t kDefaultMinAckDelayTimeMs = 5;
+
+// Default shift of the ACK delay in the IETF QUIC ACK frame.
+const uint32_t kDefaultAckDelayExponent = 3;
+
+// Minimum tail loss probe time in ms.
+static const int64_t kMinTailLossProbeTimeoutMs = 10;
+
+// The timeout before the handshake succeeds.
+const int64_t kInitialIdleTimeoutSecs = 5;
+// The maximum idle timeout that can be negotiated.
+const int64_t kMaximumIdleTimeoutSecs = 60 * 10;  // 10 minutes.
+// The default timeout for a connection until the crypto handshake succeeds.
+const int64_t kMaxTimeForCryptoHandshakeSecs = 10;  // 10 secs.
+
+// Default limit on the number of undecryptable packets the connection buffers
+// before the CHLO/SHLO arrive.
+const size_t kDefaultMaxUndecryptablePackets = 10;
+
+// Default ping timeout.
+const int64_t kPingTimeoutSecs = 15;  // 15 secs.
+
+// Minimum number of RTTs between Server Config Updates (SCUP) sent to client.
+const int kMinIntervalBetweenServerConfigUpdatesRTTs = 10;
+
+// Minimum time between Server Config Updates (SCUP) sent to client.
+const int kMinIntervalBetweenServerConfigUpdatesMs = 1000;
+
+// Minimum number of packets between Server Config Updates (SCUP).
+const int kMinPacketsBetweenServerConfigUpdates = 100;
+
+// The number of open streams that a server will accept is set to be slightly
+// larger than the negotiated limit. Immediately closing the connection if the
+// client opens slightly too many streams is not ideal: the client may have sent
+// a FIN that was lost, and simultaneously opened a new stream. The number of
+// streams a server accepts is a fixed increment over the negotiated limit, or a
+// percentage increase, whichever is larger.
+const float kMaxStreamsMultiplier = 1.1f;
+const int kMaxStreamsMinimumIncrement = 10;
+
+// Available streams are ones with IDs less than the highest stream that has
+// been opened which have neither been opened or reset. The limit on the number
+// of available streams is 10 times the limit on the number of open streams.
+const int kMaxAvailableStreamsMultiplier = 10;
+
+// Track the number of promises that are not yet claimed by a
+// corresponding get.  This must be smaller than
+// kMaxAvailableStreamsMultiplier, because RST on a promised stream my
+// create available streams entries.
+const int kMaxPromisedStreamsMultiplier = kMaxAvailableStreamsMultiplier - 1;
+
+// TCP RFC calls for 1 second RTO however Linux differs from this default and
+// define the minimum RTO to 200ms, we will use the same until we have data to
+// support a higher or lower value.
+static const int64_t kMinRetransmissionTimeMs = 200;
+// The delayed ack time must not be greater than half the min RTO.
+static_assert(kDefaultDelayedAckTimeMs <= kMinRetransmissionTimeMs / 2,
+              "Delayed ack time must be less than or equal half the MinRTO");
+
+// We define an unsigned 16-bit floating point value, inspired by IEEE floats
+// (http://en.wikipedia.org/wiki/Half_precision_floating-point_format),
+// with 5-bit exponent (bias 1), 11-bit mantissa (effective 12 with hidden
+// bit) and denormals, but without signs, transfinites or fractions. Wire format
+// 16 bits (little-endian byte order) are split into exponent (high 5) and
+// mantissa (low 11) and decoded as:
+//   uint64_t value;
+//   if (exponent == 0) value = mantissa;
+//   else value = (mantissa | 1 << 11) << (exponent - 1)
+const int kUFloat16ExponentBits = 5;
+const int kUFloat16MaxExponent = (1 << kUFloat16ExponentBits) - 2;     // 30
+const int kUFloat16MantissaBits = 16 - kUFloat16ExponentBits;          // 11
+const int kUFloat16MantissaEffectiveBits = kUFloat16MantissaBits + 1;  // 12
+const uint64_t kUFloat16MaxValue =  // 0x3FFC0000000
+    ((UINT64_C(1) << kUFloat16MantissaEffectiveBits) - 1)
+    << kUFloat16MaxExponent;
+
+// kDiversificationNonceSize is the size, in bytes, of the nonce that a server
+// may set in the packet header to ensure that its INITIAL keys are not
+// duplicated.
+const size_t kDiversificationNonceSize = 32;
+
+// The largest gap in packets we'll accept without closing the connection.
+// This will likely have to be tuned.
+const QuicPacketCount kMaxPacketGap = 5000;
+
+// The max number of sequence number intervals that
+// QuicPeerIssuedConnetionIdManager can maintain.
+const size_t kMaxNumConnectionIdSequenceNumberIntervals = 20;
+
+// The maximum number of random padding bytes to add.
+const QuicByteCount kMaxNumRandomPaddingBytes = 256;
+
+// The size of stream send buffer data slice size in bytes. A data slice is
+// piece of stream data stored in contiguous memory, and a stream frame can
+// contain data from multiple data slices.
+const QuicByteCount kQuicStreamSendBufferSliceSize = 4 * 1024;
+
+// For When using Random Initial Packet Numbers, they can start
+// anyplace in the range 1...((2^31)-1) or 0x7fffffff
+QUIC_EXPORT_PRIVATE QuicPacketNumber MaxRandomInitialPacketNumber();
+
+// Used to represent an invalid or no control frame id.
+const QuicControlFrameId kInvalidControlFrameId = 0;
+
+// The max length a stream can have.
+const QuicByteCount kMaxStreamLength = (UINT64_C(1) << 62) - 1;
+
+// The max value that can be encoded using IETF Var Ints.
+const uint64_t kMaxIetfVarInt = UINT64_C(0x3fffffffffffffff);
+
+// The maximum stream id value that is supported - (2^32)-1
+const QuicStreamId kMaxQuicStreamId = 0xffffffff;
+
+// The maximum value that can be stored in a 32-bit QuicStreamCount.
+const QuicStreamCount kMaxQuicStreamCount = 0xffffffff;
+
+// Number of bytes reserved for packet header type.
+const size_t kPacketHeaderTypeSize = 1;
+
+// Number of bytes reserved for connection ID length.
+const size_t kConnectionIdLengthSize = 1;
+
+// Minimum length of random bytes in IETF stateless reset packet.
+const size_t kMinRandomBytesLengthInStatelessReset = 24;
+
+// Maximum length allowed for the token in a NEW_TOKEN frame.
+const size_t kMaxNewTokenTokenLength = 0xffff;
+
+// The prefix used by a source address token in a NEW_TOKEN frame.
+const uint8_t kAddressTokenPrefix = 0;
+
+// Default initial rtt used before any samples are received.
+const int kInitialRttMs = 100;
+
+// Default threshold of packet reordering before a packet is declared lost.
+static const QuicPacketCount kDefaultPacketReorderingThreshold = 3;
+
+// Default fraction (1/4) of an RTT the algorithm waits before determining a
+// packet is lost due to early retransmission by time based loss detection.
+static const int kDefaultLossDelayShift = 2;
+
+// Default fraction (1/8) of an RTT when doing IETF loss detection.
+static const int kDefaultIetfLossDelayShift = 3;
+
+// Maximum number of retransmittable packets received before sending an ack.
+const QuicPacketCount kDefaultRetransmittablePacketsBeforeAck = 2;
+// Wait for up to 10 retransmittable packets before sending an ack.
+const QuicPacketCount kMaxRetransmittablePacketsBeforeAck = 10;
+// Minimum number of packets received before ack decimation is enabled.
+// This intends to avoid the beginning of slow start, when CWNDs may be
+// rapidly increasing.
+const QuicPacketCount kMinReceivedBeforeAckDecimation = 100;
+// One quarter RTT delay when doing ack decimation.
+const float kAckDecimationDelay = 0.25;
+
+// The default alarm granularity assumed by QUIC code.
+const QuicTime::Delta kAlarmGranularity = QuicTime::Delta::FromMilliseconds(1);
+
+// Maximum number of unretired connection IDs a connection can have.
+const size_t kMaxNumConnectonIdsInUse = 10u;
+
+// Packet number of first sending packet of a connection. Please note, this
+// cannot be used as first received packet because peer can choose its starting
+// packet number.
+QUIC_EXPORT_PRIVATE QuicPacketNumber FirstSendingPacketNumber();
+
+// Used by clients to tell if a public reset is sent from a Google frontend.
+QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd;
+QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd0;
+
+// HTTP/3 Datagrams.
+enum : QuicDatagramContextId {
+  kFirstDatagramContextIdClient = 0,
+  kFirstDatagramContextIdServer = 1,
+  kDatagramContextIdIncrement = 2,
+};
+
+enum : uint64_t {
+  kHttpDatagramStreamIdDivisor = 4,
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
diff --git a/quiche/quic/core/quic_control_frame_manager.cc b/quiche/quic/core/quic_control_frame_manager.cc
new file mode 100644
index 0000000..64e5eec
--- /dev/null
+++ b/quiche/quic/core/quic_control_frame_manager.cc
@@ -0,0 +1,363 @@
+// Copyright (c) 2017 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 "quiche/quic/core/quic_control_frame_manager.h"
+
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+namespace {
+
+// The maximum number of buffered control frames which are waiting to be ACKed
+// or sent for the first time.
+const size_t kMaxNumControlFrames = 1000;
+
+}  // namespace
+
+QuicControlFrameManager::QuicControlFrameManager(QuicSession* session)
+    : last_control_frame_id_(kInvalidControlFrameId),
+      least_unacked_(1),
+      least_unsent_(1),
+      delegate_(session) {}
+
+QuicControlFrameManager::~QuicControlFrameManager() {
+  while (!control_frames_.empty()) {
+    DeleteFrame(&control_frames_.front());
+    control_frames_.pop_front();
+  }
+}
+
+void QuicControlFrameManager::WriteOrBufferQuicFrame(QuicFrame frame) {
+  const bool had_buffered_frames = HasBufferedFrames();
+  control_frames_.emplace_back(frame);
+  if (control_frames_.size() > kMaxNumControlFrames) {
+    delegate_->OnControlFrameManagerError(
+        QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES,
+        absl::StrCat("More than ", kMaxNumControlFrames,
+                     "buffered control frames, least_unacked: ", least_unacked_,
+                     ", least_unsent_: ", least_unsent_));
+    return;
+  }
+  if (had_buffered_frames) {
+    return;
+  }
+  WriteBufferedFrames();
+}
+
+void QuicControlFrameManager::WriteOrBufferRstStream(
+    QuicStreamId id, QuicResetStreamError error,
+    QuicStreamOffset bytes_written) {
+  QUIC_DVLOG(1) << "Writing RST_STREAM_FRAME";
+  WriteOrBufferQuicFrame((QuicFrame(new QuicRstStreamFrame(
+      ++last_control_frame_id_, id, error, bytes_written))));
+}
+
+void QuicControlFrameManager::WriteOrBufferGoAway(
+    QuicErrorCode error, QuicStreamId last_good_stream_id,
+    const std::string& reason) {
+  QUIC_DVLOG(1) << "Writing GOAWAY_FRAME";
+  WriteOrBufferQuicFrame(QuicFrame(new QuicGoAwayFrame(
+      ++last_control_frame_id_, error, last_good_stream_id, reason)));
+}
+
+void QuicControlFrameManager::WriteOrBufferWindowUpdate(
+    QuicStreamId id, QuicStreamOffset byte_offset) {
+  QUIC_DVLOG(1) << "Writing WINDOW_UPDATE_FRAME";
+  WriteOrBufferQuicFrame(QuicFrame(
+      QuicWindowUpdateFrame(++last_control_frame_id_, id, byte_offset)));
+}
+
+void QuicControlFrameManager::WriteOrBufferBlocked(QuicStreamId id) {
+  QUIC_DVLOG(1) << "Writing BLOCKED_FRAME";
+  WriteOrBufferQuicFrame(
+      QuicFrame(QuicBlockedFrame(++last_control_frame_id_, id)));
+}
+
+void QuicControlFrameManager::WriteOrBufferStreamsBlocked(QuicStreamCount count,
+                                                          bool unidirectional) {
+  QUIC_DVLOG(1) << "Writing STREAMS_BLOCKED Frame";
+  QUIC_CODE_COUNT(quic_streams_blocked_transmits);
+  WriteOrBufferQuicFrame(QuicFrame(QuicStreamsBlockedFrame(
+      ++last_control_frame_id_, count, unidirectional)));
+}
+
+void QuicControlFrameManager::WriteOrBufferMaxStreams(QuicStreamCount count,
+                                                      bool unidirectional) {
+  QUIC_DVLOG(1) << "Writing MAX_STREAMS Frame";
+  QUIC_CODE_COUNT(quic_max_streams_transmits);
+  WriteOrBufferQuicFrame(QuicFrame(
+      QuicMaxStreamsFrame(++last_control_frame_id_, count, unidirectional)));
+}
+
+void QuicControlFrameManager::WriteOrBufferStopSending(
+    QuicResetStreamError error, QuicStreamId stream_id) {
+  QUIC_DVLOG(1) << "Writing STOP_SENDING_FRAME";
+  WriteOrBufferQuicFrame(QuicFrame(
+      QuicStopSendingFrame(++last_control_frame_id_, stream_id, error)));
+}
+
+void QuicControlFrameManager::WriteOrBufferHandshakeDone() {
+  QUIC_DVLOG(1) << "Writing HANDSHAKE_DONE";
+  WriteOrBufferQuicFrame(
+      QuicFrame(QuicHandshakeDoneFrame(++last_control_frame_id_)));
+}
+
+void QuicControlFrameManager::WriteOrBufferAckFrequency(
+    const QuicAckFrequencyFrame& ack_frequency_frame) {
+  QUIC_DVLOG(1) << "Writing ACK_FREQUENCY frame";
+  QuicControlFrameId control_frame_id = ++last_control_frame_id_;
+  // Using the control_frame_id for sequence_number here leaves gaps in
+  // sequence_number.
+  WriteOrBufferQuicFrame(
+      QuicFrame(new QuicAckFrequencyFrame(control_frame_id,
+                                          /*sequence_number=*/control_frame_id,
+                                          ack_frequency_frame.packet_tolerance,
+                                          ack_frequency_frame.max_ack_delay)));
+}
+
+void QuicControlFrameManager::WriteOrBufferNewConnectionId(
+    const QuicConnectionId& connection_id, uint64_t sequence_number,
+    uint64_t retire_prior_to,
+    const StatelessResetToken& stateless_reset_token) {
+  QUIC_DVLOG(1) << "Writing NEW_CONNECTION_ID frame";
+  WriteOrBufferQuicFrame(QuicFrame(new QuicNewConnectionIdFrame(
+      ++last_control_frame_id_, connection_id, sequence_number,
+      stateless_reset_token, retire_prior_to)));
+}
+
+void QuicControlFrameManager::WriteOrBufferRetireConnectionId(
+    uint64_t sequence_number) {
+  QUIC_DVLOG(1) << "Writing RETIRE_CONNECTION_ID frame";
+  WriteOrBufferQuicFrame(QuicFrame(new QuicRetireConnectionIdFrame(
+      ++last_control_frame_id_, sequence_number)));
+}
+
+void QuicControlFrameManager::WriteOrBufferNewToken(absl::string_view token) {
+  QUIC_DVLOG(1) << "Writing NEW_TOKEN frame";
+  WriteOrBufferQuicFrame(
+      QuicFrame(new QuicNewTokenFrame(++last_control_frame_id_, token)));
+}
+
+void QuicControlFrameManager::OnControlFrameSent(const QuicFrame& frame) {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    QUIC_BUG(quic_bug_12727_1)
+        << "Send or retransmit a control frame with invalid control frame id";
+    return;
+  }
+  if (frame.type == WINDOW_UPDATE_FRAME) {
+    QuicStreamId stream_id = frame.window_update_frame.stream_id;
+    if (window_update_frames_.contains(stream_id) &&
+        id > window_update_frames_[stream_id]) {
+      // Consider the older window update of the same stream as acked.
+      OnControlFrameIdAcked(window_update_frames_[stream_id]);
+    }
+    window_update_frames_[stream_id] = id;
+  }
+  if (pending_retransmissions_.contains(id)) {
+    // This is retransmitted control frame.
+    pending_retransmissions_.erase(id);
+    return;
+  }
+  if (id > least_unsent_) {
+    QUIC_BUG(quic_bug_10517_1)
+        << "Try to send control frames out of order, id: " << id
+        << " least_unsent: " << least_unsent_;
+    delegate_->OnControlFrameManagerError(
+        QUIC_INTERNAL_ERROR, "Try to send control frames out of order");
+    return;
+  }
+  ++least_unsent_;
+}
+
+bool QuicControlFrameManager::OnControlFrameAcked(const QuicFrame& frame) {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (!OnControlFrameIdAcked(id)) {
+    return false;
+  }
+  if (frame.type == WINDOW_UPDATE_FRAME) {
+    QuicStreamId stream_id = frame.window_update_frame.stream_id;
+    if (window_update_frames_.contains(stream_id) &&
+        window_update_frames_[stream_id] == id) {
+      window_update_frames_.erase(stream_id);
+    }
+  }
+  return true;
+}
+
+void QuicControlFrameManager::OnControlFrameLost(const QuicFrame& frame) {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    // Frame does not have a valid control frame ID, ignore it.
+    return;
+  }
+  if (id >= least_unsent_) {
+    QUIC_BUG(quic_bug_10517_2) << "Try to mark unsent control frame as lost";
+    delegate_->OnControlFrameManagerError(
+        QUIC_INTERNAL_ERROR, "Try to mark unsent control frame as lost");
+    return;
+  }
+  if (id < least_unacked_ ||
+      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
+          kInvalidControlFrameId) {
+    // This frame has already been acked.
+    return;
+  }
+  if (!pending_retransmissions_.contains(id)) {
+    pending_retransmissions_[id] = true;
+    QUIC_BUG_IF(quic_bug_12727_2,
+                pending_retransmissions_.size() > control_frames_.size())
+        << "least_unacked_: " << least_unacked_
+        << ", least_unsent_: " << least_unsent_;
+  }
+}
+
+bool QuicControlFrameManager::IsControlFrameOutstanding(
+    const QuicFrame& frame) const {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    // Frame without a control frame ID should not be retransmitted.
+    return false;
+  }
+  // Consider this frame is outstanding if it does not get acked.
+  return id < least_unacked_ + control_frames_.size() && id >= least_unacked_ &&
+         GetControlFrameId(control_frames_.at(id - least_unacked_)) !=
+             kInvalidControlFrameId;
+}
+
+bool QuicControlFrameManager::HasPendingRetransmission() const {
+  return !pending_retransmissions_.empty();
+}
+
+bool QuicControlFrameManager::WillingToWrite() const {
+  return HasPendingRetransmission() || HasBufferedFrames();
+}
+
+QuicFrame QuicControlFrameManager::NextPendingRetransmission() const {
+  QUIC_BUG_IF(quic_bug_12727_3, pending_retransmissions_.empty())
+      << "Unexpected call to NextPendingRetransmission() with empty pending "
+      << "retransmission list.";
+  QuicControlFrameId id = pending_retransmissions_.begin()->first;
+  return control_frames_.at(id - least_unacked_);
+}
+
+void QuicControlFrameManager::OnCanWrite() {
+  if (HasPendingRetransmission()) {
+    // Exit early to allow streams to write pending retransmissions if any.
+    WritePendingRetransmission();
+    return;
+  }
+  WriteBufferedFrames();
+}
+
+bool QuicControlFrameManager::RetransmitControlFrame(const QuicFrame& frame,
+                                                     TransmissionType type) {
+  QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
+                type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    // Frame does not have a valid control frame ID, ignore it. Returns true
+    // to allow writing following frames.
+    return true;
+  }
+  if (id >= least_unsent_) {
+    QUIC_BUG(quic_bug_10517_3) << "Try to retransmit unsent control frame";
+    delegate_->OnControlFrameManagerError(
+        QUIC_INTERNAL_ERROR, "Try to retransmit unsent control frame");
+    return false;
+  }
+  if (id < least_unacked_ ||
+      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
+          kInvalidControlFrameId) {
+    // This frame has already been acked.
+    return true;
+  }
+  QuicFrame copy = CopyRetransmittableControlFrame(frame);
+  QUIC_DVLOG(1) << "control frame manager is forced to retransmit frame: "
+                << frame;
+  if (delegate_->WriteControlFrame(copy, type)) {
+    return true;
+  }
+  DeleteFrame(&copy);
+  return false;
+}
+
+void QuicControlFrameManager::WriteBufferedFrames() {
+  while (HasBufferedFrames()) {
+    QuicFrame frame_to_send =
+        control_frames_.at(least_unsent_ - least_unacked_);
+    QuicFrame copy = CopyRetransmittableControlFrame(frame_to_send);
+    if (!delegate_->WriteControlFrame(copy, NOT_RETRANSMISSION)) {
+      // Connection is write blocked.
+      DeleteFrame(&copy);
+      break;
+    }
+    OnControlFrameSent(frame_to_send);
+  }
+}
+
+void QuicControlFrameManager::WritePendingRetransmission() {
+  while (HasPendingRetransmission()) {
+    QuicFrame pending = NextPendingRetransmission();
+    QuicFrame copy = CopyRetransmittableControlFrame(pending);
+    if (!delegate_->WriteControlFrame(copy, LOSS_RETRANSMISSION)) {
+      // Connection is write blocked.
+      DeleteFrame(&copy);
+      break;
+    }
+    OnControlFrameSent(pending);
+  }
+}
+
+bool QuicControlFrameManager::OnControlFrameIdAcked(QuicControlFrameId id) {
+  if (id == kInvalidControlFrameId) {
+    // Frame does not have a valid control frame ID, ignore it.
+    return false;
+  }
+  if (id >= least_unsent_) {
+    QUIC_BUG(quic_bug_10517_4) << "Try to ack unsent control frame";
+    delegate_->OnControlFrameManagerError(QUIC_INTERNAL_ERROR,
+                                          "Try to ack unsent control frame");
+    return false;
+  }
+  if (id < least_unacked_ ||
+      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
+          kInvalidControlFrameId) {
+    // This frame has already been acked.
+    return false;
+  }
+
+  // Set control frame ID of acked frames to 0.
+  SetControlFrameId(kInvalidControlFrameId,
+                    &control_frames_.at(id - least_unacked_));
+  // Remove acked control frames from pending retransmissions.
+  pending_retransmissions_.erase(id);
+  // Clean up control frames queue and increment least_unacked_.
+  while (!control_frames_.empty() &&
+         GetControlFrameId(control_frames_.front()) == kInvalidControlFrameId) {
+    DeleteFrame(&control_frames_.front());
+    control_frames_.pop_front();
+    ++least_unacked_;
+  }
+  return true;
+}
+
+bool QuicControlFrameManager::HasBufferedFrames() const {
+  return least_unsent_ < least_unacked_ + control_frames_.size();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_control_frame_manager.h b/quiche/quic/core/quic_control_frame_manager.h
new file mode 100644
index 0000000..b885301
--- /dev/null
+++ b/quiche/quic/core/quic_control_frame_manager.h
@@ -0,0 +1,192 @@
+// Copyright (c) 2017 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_CONTROL_FRAME_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+class QuicSession;
+
+namespace test {
+class QuicControlFrameManagerPeer;
+}  // namespace test
+
+// Control frame manager contains a list of sent control frames with valid
+// control frame IDs. Control frames without valid control frame IDs include:
+// (1) non-retransmittable frames (e.g., ACK_FRAME, PADDING_FRAME,
+// STOP_WAITING_FRAME, etc.), (2) CONNECTION_CLOSE and IETF Quic
+// APPLICATION_CLOSE frames.
+// New control frames are added to the tail of the list when they are added to
+// the generator. Control frames are removed from the head of the list when they
+// get acked. Control frame manager also keeps track of lost control frames
+// which need to be retransmitted.
+class QUIC_EXPORT_PRIVATE QuicControlFrameManager {
+ public:
+  class QUIC_EXPORT_PRIVATE DelegateInterface {
+   public:
+    virtual ~DelegateInterface() = default;
+
+    // Notifies the delegate of errors.
+    virtual void OnControlFrameManagerError(QuicErrorCode error_code,
+                                            std::string error_details) = 0;
+
+    virtual bool WriteControlFrame(const QuicFrame& frame,
+                                   TransmissionType type) = 0;
+  };
+
+  explicit QuicControlFrameManager(QuicSession* session);
+  QuicControlFrameManager(const QuicControlFrameManager& other) = delete;
+  QuicControlFrameManager(QuicControlFrameManager&& other) = delete;
+  ~QuicControlFrameManager();
+
+  // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferRstStream(QuicControlFrameId id, QuicResetStreamError error,
+                              QuicStreamOffset bytes_written);
+
+  // Tries to send a GOAWAY_FRAME. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferGoAway(QuicErrorCode error,
+                           QuicStreamId last_good_stream_id,
+                           const std::string& reason);
+
+  // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
+
+  // Tries to send a BLOCKED_FRAME. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferBlocked(QuicStreamId id);
+
+  // Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
+  // sent immediately.
+  void WriteOrBufferStreamsBlocked(QuicStreamCount count, bool unidirectional);
+
+  // Tries to send a MAX_STREAMS Frame. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferMaxStreams(QuicStreamCount count, bool unidirectional);
+
+  // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
+  // can not be sent immediately.
+  void WriteOrBufferStopSending(QuicResetStreamError error,
+                                QuicStreamId stream_id);
+
+  // Tries to send an HANDSHAKE_DONE frame. The frame is buffered if it can not
+  // be sent immediately.
+  void WriteOrBufferHandshakeDone();
+
+  // Tries to send an AckFrequencyFrame. The frame is buffered if it cannot be
+  // sent immediately.
+  void WriteOrBufferAckFrequency(
+      const QuicAckFrequencyFrame& ack_frequency_frame);
+
+  // Tries to send a NEW_CONNECTION_ID frame. The frame is buffered if it cannot
+  // be sent immediately.
+  void WriteOrBufferNewConnectionId(
+      const QuicConnectionId& connection_id, uint64_t sequence_number,
+      uint64_t retire_prior_to,
+      const StatelessResetToken& stateless_reset_token);
+
+  // Tries to send a RETIRE_CONNNECTION_ID frame. The frame is buffered if it
+  // cannot be sent immediately.
+  void WriteOrBufferRetireConnectionId(uint64_t sequence_number);
+
+  // Tries to send a NEW_TOKEN frame. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferNewToken(absl::string_view token);
+
+  // Called when |frame| gets acked. Returns true if |frame| gets acked for the
+  // first time, return false otherwise.
+  bool OnControlFrameAcked(const QuicFrame& frame);
+
+  // Called when |frame| is considered as lost.
+  void OnControlFrameLost(const QuicFrame& frame);
+
+  // Called by the session when the connection becomes writable.
+  void OnCanWrite();
+
+  // Retransmit |frame| if it is still outstanding. Returns false if the frame
+  // does not get retransmitted because the connection is blocked. Otherwise,
+  // returns true.
+  bool RetransmitControlFrame(const QuicFrame& frame, TransmissionType type);
+
+  // Returns true if |frame| is outstanding and waiting to be acked. Returns
+  // false otherwise.
+  bool IsControlFrameOutstanding(const QuicFrame& frame) const;
+
+  // Returns true if there is any lost control frames waiting to be
+  // retransmitted.
+  bool HasPendingRetransmission() const;
+
+  // Returns true if there are any lost or new control frames waiting to be
+  // sent.
+  bool WillingToWrite() const;
+
+ private:
+  friend class test::QuicControlFrameManagerPeer;
+
+  // Tries to write buffered control frames to the peer.
+  void WriteBufferedFrames();
+
+  // Called when |frame| is sent for the first time or gets retransmitted.
+  void OnControlFrameSent(const QuicFrame& frame);
+
+  // Writes pending retransmissions if any.
+  void WritePendingRetransmission();
+
+  // Called when frame with |id| gets acked. Returns true if |id| gets acked for
+  // the first time, return false otherwise.
+  bool OnControlFrameIdAcked(QuicControlFrameId id);
+
+  // Retrieves the next pending retransmission. This must only be called when
+  // there are pending retransmissions.
+  QuicFrame NextPendingRetransmission() const;
+
+  // Returns true if there are buffered frames waiting to be sent for the first
+  // time.
+  bool HasBufferedFrames() const;
+
+  // Writes or buffers a control frame.  Frame is buffered if there already
+  // are frames waiting to be sent. If no others waiting, will try to send the
+  // frame.
+  void WriteOrBufferQuicFrame(QuicFrame frame);
+
+  quiche::QuicheCircularDeque<QuicFrame> control_frames_;
+
+  // Id of latest saved control frame. 0 if no control frame has been saved.
+  QuicControlFrameId last_control_frame_id_;
+
+  // The control frame at the 0th index of control_frames_.
+  QuicControlFrameId least_unacked_;
+
+  // ID of the least unsent control frame.
+  QuicControlFrameId least_unsent_;
+
+  // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
+  // is not used here.
+  // Lost control frames waiting to be retransmitted.
+  quiche::QuicheLinkedHashMap<QuicControlFrameId, bool>
+      pending_retransmissions_;
+
+  DelegateInterface* delegate_;
+
+  // Last sent window update frame for each stream.
+  absl::flat_hash_map<QuicStreamId, QuicControlFrameId> window_update_frames_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
diff --git a/quiche/quic/core/quic_control_frame_manager_test.cc b/quiche/quic/core/quic_control_frame_manager_test.cc
new file mode 100644
index 0000000..821bcca
--- /dev/null
+++ b/quiche/quic/core/quic_control_frame_manager_test.cc
@@ -0,0 +1,363 @@
+// Copyright (c) 2017 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 "quiche/quic/core/quic_control_frame_manager.h"
+
+#include <utility>
+
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+
+class QuicControlFrameManagerPeer {
+ public:
+  static size_t QueueSize(QuicControlFrameManager* manager) {
+    return manager->control_frames_.size();
+  }
+};
+
+namespace {
+
+const QuicStreamId kTestStreamId = 5;
+const QuicRstStreamErrorCode kTestStopSendingCode =
+    QUIC_STREAM_ENCODER_STREAM_ERROR;
+
+class QuicControlFrameManagerTest : public QuicTest {
+ public:
+  bool SaveControlFrame(const QuicFrame& frame, TransmissionType /*type*/) {
+    frame_ = frame;
+    return true;
+  }
+
+ protected:
+  // Pre-fills the control frame queue with the following frames:
+  //  ID Type
+  //  1  RST_STREAM
+  //  2  GO_AWAY
+  //  3  WINDOW_UPDATE
+  //  4  BLOCKED
+  //  5  STOP_SENDING
+  // This is verified. The tests then perform manipulations on these.
+  void Initialize() {
+    connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
+                                         Perspective::IS_SERVER);
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
+    manager_ = std::make_unique<QuicControlFrameManager>(session_.get());
+    EXPECT_EQ(0u, QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+    EXPECT_FALSE(manager_->HasPendingRetransmission());
+    EXPECT_FALSE(manager_->WillingToWrite());
+
+    EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+    manager_->WriteOrBufferRstStream(
+        kTestStreamId,
+        QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0);
+    manager_->WriteOrBufferGoAway(QUIC_PEER_GOING_AWAY, kTestStreamId,
+                                  "Going away.");
+    manager_->WriteOrBufferWindowUpdate(kTestStreamId, 100);
+    manager_->WriteOrBufferBlocked(kTestStreamId);
+    manager_->WriteOrBufferStopSending(
+        QuicResetStreamError::FromInternal(kTestStopSendingCode),
+        kTestStreamId);
+    number_of_frames_ = 5u;
+    EXPECT_EQ(number_of_frames_,
+              QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(blocked_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(stop_sending_)));
+
+    EXPECT_FALSE(manager_->HasPendingRetransmission());
+    EXPECT_TRUE(manager_->WillingToWrite());
+  }
+
+  QuicRstStreamFrame rst_stream_ = {1, kTestStreamId, QUIC_STREAM_CANCELLED, 0};
+  QuicGoAwayFrame goaway_ = {2, QUIC_PEER_GOING_AWAY, kTestStreamId,
+                             "Going away."};
+  QuicWindowUpdateFrame window_update_ = {3, kTestStreamId, 100};
+  QuicBlockedFrame blocked_ = {4, kTestStreamId};
+  QuicStopSendingFrame stop_sending_ = {5, kTestStreamId, kTestStopSendingCode};
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  std::unique_ptr<StrictMock<MockQuicSession>> session_;
+  std::unique_ptr<QuicControlFrameManager> manager_;
+  QuicFrame frame_;
+  size_t number_of_frames_;
+};
+
+TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) {
+  Initialize();
+  InSequence s;
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(3)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  // Send control frames 1, 2, 3.
+  manager_->OnCanWrite();
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(blocked_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(stop_sending_)));
+
+  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(window_update_)));
+  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
+  EXPECT_EQ(number_of_frames_,
+            QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+
+  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
+  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
+  EXPECT_EQ(number_of_frames_,
+            QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&rst_stream_)));
+  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
+  // Only after the first frame in the queue is acked do the frames get
+  // removed ... now see that the length has been reduced by 3.
+  EXPECT_EQ(number_of_frames_ - 3u,
+            QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+  // Duplicate ack.
+  EXPECT_FALSE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
+
+  EXPECT_FALSE(manager_->HasPendingRetransmission());
+  EXPECT_TRUE(manager_->WillingToWrite());
+
+  // Send control frames 4, 5.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+  EXPECT_FALSE(manager_->WillingToWrite());
+}
+
+TEST_F(QuicControlFrameManagerTest, OnControlFrameLost) {
+  Initialize();
+  InSequence s;
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(3)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  // Send control frames 1, 2, 3.
+  manager_->OnCanWrite();
+
+  // Lost control frames 1, 2, 3.
+  manager_->OnControlFrameLost(QuicFrame(&rst_stream_));
+  manager_->OnControlFrameLost(QuicFrame(&goaway_));
+  manager_->OnControlFrameLost(QuicFrame(window_update_));
+  EXPECT_TRUE(manager_->HasPendingRetransmission());
+
+  // Ack control frame 2.
+  manager_->OnControlFrameAcked(QuicFrame(&goaway_));
+
+  // Retransmit control frames 1, 3.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+  EXPECT_FALSE(manager_->HasPendingRetransmission());
+  EXPECT_TRUE(manager_->WillingToWrite());
+
+  // Send control frames 4, 5, and 6.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(number_of_frames_ - 3u)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+  EXPECT_FALSE(manager_->WillingToWrite());
+}
+
+TEST_F(QuicControlFrameManagerTest, RetransmitControlFrame) {
+  Initialize();
+  InSequence s;
+  // Send control frames 1, 2, 3, 4.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(number_of_frames_)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  // Ack control frame 2.
+  manager_->OnControlFrameAcked(QuicFrame(&goaway_));
+  // Do not retransmit an acked frame
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(0);
+  EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&goaway_),
+                                               PTO_RETRANSMISSION));
+
+  // Retransmit control frame 3.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(window_update_),
+                                               PTO_RETRANSMISSION));
+
+  // Retransmit control frame 4, and connection is write blocked.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(window_update_),
+                                                PTO_RETRANSMISSION));
+}
+
+TEST_F(QuicControlFrameManagerTest, SendAndAckAckFrequencyFrame) {
+  Initialize();
+  InSequence s;
+  // Send Non-AckFrequency frame 1-5.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(5)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  manager_->OnCanWrite();
+
+  // Send AckFrequencyFrame as frame 6.
+  QuicAckFrequencyFrame frame_to_send;
+  frame_to_send.packet_tolerance = 10;
+  frame_to_send.max_ack_delay = QuicTime::Delta::FromMilliseconds(24);
+  manager_->WriteOrBufferAckFrequency(frame_to_send);
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  // Ack AckFrequencyFrame.
+  QuicAckFrequencyFrame expected_ack_frequency = {
+      6, 6, 10, QuicTime::Delta::FromMilliseconds(24)};
+  EXPECT_TRUE(
+      manager_->OnControlFrameAcked(QuicFrame(&expected_ack_frequency)));
+}
+
+TEST_F(QuicControlFrameManagerTest, NewAndRetireConnectionIdFrames) {
+  Initialize();
+  InSequence s;
+
+  // Send other frames 1-5.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(5)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  // Send NewConnectionIdFrame as frame 6.
+  manager_->WriteOrBufferNewConnectionId(
+      TestConnectionId(3), /*sequence_number=*/2, /*retire_prior_to=*/1,
+      /*stateless_reset_token=*/
+      {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1});
+  // Send RetireConnectionIdFrame as frame 7.
+  manager_->WriteOrBufferRetireConnectionId(/*sequence_number=*/0);
+  manager_->OnCanWrite();
+
+  // Ack both frames.
+  QuicNewConnectionIdFrame new_connection_id_frame;
+  new_connection_id_frame.control_frame_id = 6;
+  QuicRetireConnectionIdFrame retire_connection_id_frame;
+  retire_connection_id_frame.control_frame_id = 7;
+  EXPECT_TRUE(
+      manager_->OnControlFrameAcked(QuicFrame(&new_connection_id_frame)));
+  EXPECT_TRUE(
+      manager_->OnControlFrameAcked(QuicFrame(&retire_connection_id_frame)));
+}
+
+TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) {
+  Initialize();
+  // Send two more window updates of the same stream.
+  manager_->WriteOrBufferWindowUpdate(kTestStreamId, 200);
+  QuicWindowUpdateFrame window_update2(number_of_frames_ + 1, kTestStreamId,
+                                       200);
+
+  manager_->WriteOrBufferWindowUpdate(kTestStreamId, 300);
+  QuicWindowUpdateFrame window_update3(number_of_frames_ + 2, kTestStreamId,
+                                       300);
+  InSequence s;
+  // Flush all buffered control frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  // Mark all 3 window updates as lost.
+  manager_->OnControlFrameLost(QuicFrame(window_update_));
+  manager_->OnControlFrameLost(QuicFrame(window_update2));
+  manager_->OnControlFrameLost(QuicFrame(window_update3));
+  EXPECT_TRUE(manager_->HasPendingRetransmission());
+  EXPECT_TRUE(manager_->WillingToWrite());
+
+  // Verify only the latest window update gets retransmitted.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(this, &QuicControlFrameManagerTest::SaveControlFrame));
+  manager_->OnCanWrite();
+  EXPECT_EQ(number_of_frames_ + 2u,
+            frame_.window_update_frame.control_frame_id);
+  EXPECT_FALSE(manager_->HasPendingRetransmission());
+  EXPECT_FALSE(manager_->WillingToWrite());
+  DeleteFrame(&frame_);
+}
+
+TEST_F(QuicControlFrameManagerTest, RetransmitWindowUpdateOfDifferentStreams) {
+  Initialize();
+  // Send two more window updates of different streams.
+  manager_->WriteOrBufferWindowUpdate(kTestStreamId + 2, 200);
+  QuicWindowUpdateFrame window_update2(5, kTestStreamId + 2, 200);
+
+  manager_->WriteOrBufferWindowUpdate(kTestStreamId + 4, 300);
+  QuicWindowUpdateFrame window_update3(6, kTestStreamId + 4, 300);
+  InSequence s;
+  // Flush all buffered control frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  // Mark all 3 window updates as lost.
+  manager_->OnControlFrameLost(QuicFrame(window_update_));
+  manager_->OnControlFrameLost(QuicFrame(window_update2));
+  manager_->OnControlFrameLost(QuicFrame(window_update3));
+  EXPECT_TRUE(manager_->HasPendingRetransmission());
+  EXPECT_TRUE(manager_->WillingToWrite());
+
+  // Verify all 3 window updates get retransmitted.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(3)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+  EXPECT_FALSE(manager_->HasPendingRetransmission());
+  EXPECT_FALSE(manager_->WillingToWrite());
+}
+
+TEST_F(QuicControlFrameManagerTest, TooManyBufferedControlFrames) {
+  Initialize();
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(5)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  // Flush buffered frames.
+  manager_->OnCanWrite();
+  // Write 995 control frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  for (size_t i = 0; i < 995; ++i) {
+    manager_->WriteOrBufferRstStream(
+        kTestStreamId,
+        QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0);
+  }
+  // Verify write one more control frame causes connection close.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, _,
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  manager_->WriteOrBufferRstStream(
+      kTestStreamId, QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED),
+      0);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_client_handshaker.cc b/quiche/quic/core/quic_crypto_client_handshaker.cc
new file mode 100644
index 0000000..c4a8262
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_handshaker.cc
@@ -0,0 +1,629 @@
+// 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 "quiche/quic/core/quic_crypto_client_handshaker.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_client_stats.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
+    ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent)
+    : parent_(parent) {}
+
+QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
+    ~ProofVerifierCallbackImpl() {}
+
+void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Run(
+    bool ok,
+    const std::string& error_details,
+    std::unique_ptr<ProofVerifyDetails>* details) {
+  if (parent_ == nullptr) {
+    return;
+  }
+
+  parent_->verify_ok_ = ok;
+  parent_->verify_error_details_ = error_details;
+  parent_->verify_details_ = std::move(*details);
+  parent_->proof_verify_callback_ = nullptr;
+  parent_->DoHandshakeLoop(nullptr);
+
+  // The ProofVerifier owns this object and will delete it when this method
+  // returns.
+}
+
+void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Cancel() {
+  parent_ = nullptr;
+}
+
+QuicCryptoClientHandshaker::QuicCryptoClientHandshaker(
+    const QuicServerId& server_id,
+    QuicCryptoClientStream* stream,
+    QuicSession* session,
+    std::unique_ptr<ProofVerifyContext> verify_context,
+    QuicCryptoClientConfig* crypto_config,
+    QuicCryptoClientStream::ProofHandler* proof_handler)
+    : QuicCryptoHandshaker(stream, session),
+      stream_(stream),
+      session_(session),
+      delegate_(session),
+      next_state_(STATE_IDLE),
+      num_client_hellos_(0),
+      crypto_config_(crypto_config),
+      server_id_(server_id),
+      generation_counter_(0),
+      verify_context_(std::move(verify_context)),
+      proof_verify_callback_(nullptr),
+      proof_handler_(proof_handler),
+      verify_ok_(false),
+      proof_verify_start_time_(QuicTime::Zero()),
+      num_scup_messages_received_(0),
+      encryption_established_(false),
+      one_rtt_keys_available_(false),
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
+
+QuicCryptoClientHandshaker::~QuicCryptoClientHandshaker() {
+  if (proof_verify_callback_) {
+    proof_verify_callback_->Cancel();
+  }
+}
+
+void QuicCryptoClientHandshaker::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  QuicCryptoHandshaker::OnHandshakeMessage(message);
+  if (message.tag() == kSCUP) {
+    if (!one_rtt_keys_available()) {
+      stream_->OnUnrecoverableError(
+          QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
+          "Early SCUP disallowed");
+      return;
+    }
+
+    // |message| is an update from the server, so we treat it differently from a
+    // handshake message.
+    HandleServerConfigUpdateMessage(message);
+    num_scup_messages_received_++;
+    return;
+  }
+
+  // Do not process handshake messages after the handshake is confirmed.
+  if (one_rtt_keys_available()) {
+    stream_->OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+                                  "Unexpected handshake message");
+    return;
+  }
+
+  DoHandshakeLoop(&message);
+}
+
+bool QuicCryptoClientHandshaker::CryptoConnect() {
+  next_state_ = STATE_INITIALIZE;
+  DoHandshakeLoop(nullptr);
+  return session()->connection()->connected();
+}
+
+int QuicCryptoClientHandshaker::num_sent_client_hellos() const {
+  return num_client_hellos_;
+}
+
+bool QuicCryptoClientHandshaker::IsResumption() const {
+  QUIC_BUG_IF(quic_bug_12522_1, !one_rtt_keys_available_);
+  // While 0-RTT handshakes could be considered to be like resumption, QUIC
+  // Crypto doesn't have the same notion of a resumption like TLS does.
+  return false;
+}
+
+bool QuicCryptoClientHandshaker::EarlyDataAccepted() const {
+  QUIC_BUG_IF(quic_bug_12522_2, !one_rtt_keys_available_);
+  return num_client_hellos_ == 1;
+}
+
+ssl_early_data_reason_t QuicCryptoClientHandshaker::EarlyDataReason() const {
+  return early_data_reason_;
+}
+
+bool QuicCryptoClientHandshaker::ReceivedInchoateReject() const {
+  QUIC_BUG_IF(quic_bug_12522_3, !one_rtt_keys_available_);
+  return num_client_hellos_ >= 3;
+}
+
+int QuicCryptoClientHandshaker::num_scup_messages_received() const {
+  return num_scup_messages_received_;
+}
+
+std::string QuicCryptoClientHandshaker::chlo_hash() const {
+  return chlo_hash_;
+}
+
+bool QuicCryptoClientHandshaker::encryption_established() const {
+  return encryption_established_;
+}
+
+bool QuicCryptoClientHandshaker::one_rtt_keys_available() const {
+  return one_rtt_keys_available_;
+}
+
+const QuicCryptoNegotiatedParameters&
+QuicCryptoClientHandshaker::crypto_negotiated_params() const {
+  return *crypto_negotiated_params_;
+}
+
+CryptoMessageParser* QuicCryptoClientHandshaker::crypto_message_parser() {
+  return QuicCryptoHandshaker::crypto_message_parser();
+}
+
+HandshakeState QuicCryptoClientHandshaker::GetHandshakeState() const {
+  return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+}
+
+void QuicCryptoClientHandshaker::OnHandshakeDoneReceived() {
+  QUICHE_DCHECK(false);
+}
+
+void QuicCryptoClientHandshaker::OnNewTokenReceived(
+    absl::string_view /*token*/) {
+  QUICHE_DCHECK(false);
+}
+
+size_t QuicCryptoClientHandshaker::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicCryptoClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  // Key update is only defined in QUIC+TLS.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+std::unique_ptr<QuicEncrypter>
+QuicCryptoClientHandshaker::CreateCurrentOneRttEncrypter() {
+  // Key update is only defined in QUIC+TLS.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+void QuicCryptoClientHandshaker::OnConnectionClosed(
+    QuicErrorCode /*error*/,
+    ConnectionCloseSource /*source*/) {
+  next_state_ = STATE_CONNECTION_CLOSED;
+}
+
+void QuicCryptoClientHandshaker::HandleServerConfigUpdateMessage(
+    const CryptoHandshakeMessage& server_config_update) {
+  QUICHE_DCHECK(server_config_update.tag() == kSCUP);
+  std::string error_details;
+  QuicCryptoClientConfig::CachedState* cached =
+      crypto_config_->LookupOrCreate(server_id_);
+  QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate(
+      server_config_update, session()->connection()->clock()->WallNow(),
+      session()->transport_version(), chlo_hash_, cached,
+      crypto_negotiated_params_, &error_details);
+
+  if (error != QUIC_NO_ERROR) {
+    stream_->OnUnrecoverableError(
+        error, "Server config update invalid: " + error_details);
+    return;
+  }
+
+  QUICHE_DCHECK(one_rtt_keys_available());
+  if (proof_verify_callback_) {
+    proof_verify_callback_->Cancel();
+  }
+  next_state_ = STATE_INITIALIZE_SCUP;
+  DoHandshakeLoop(nullptr);
+}
+
+void QuicCryptoClientHandshaker::DoHandshakeLoop(
+    const CryptoHandshakeMessage* in) {
+  QuicCryptoClientConfig::CachedState* cached =
+      crypto_config_->LookupOrCreate(server_id_);
+
+  QuicAsyncStatus rv = QUIC_SUCCESS;
+  do {
+    QUICHE_CHECK_NE(STATE_NONE, next_state_);
+    const State state = next_state_;
+    next_state_ = STATE_IDLE;
+    rv = QUIC_SUCCESS;
+    switch (state) {
+      case STATE_INITIALIZE:
+        DoInitialize(cached);
+        break;
+      case STATE_SEND_CHLO:
+        DoSendCHLO(cached);
+        return;  // return waiting to hear from server.
+      case STATE_RECV_REJ:
+        DoReceiveREJ(in, cached);
+        break;
+      case STATE_VERIFY_PROOF:
+        rv = DoVerifyProof(cached);
+        break;
+      case STATE_VERIFY_PROOF_COMPLETE:
+        DoVerifyProofComplete(cached);
+        break;
+      case STATE_RECV_SHLO:
+        DoReceiveSHLO(in, cached);
+        break;
+      case STATE_IDLE:
+        // This means that the peer sent us a message that we weren't expecting.
+        stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                      "Handshake in idle state");
+        return;
+      case STATE_INITIALIZE_SCUP:
+        DoInitializeServerConfigUpdate(cached);
+        break;
+      case STATE_NONE:
+        QUIC_NOTREACHED();
+        return;
+      case STATE_CONNECTION_CLOSED:
+        rv = QUIC_FAILURE;
+        return;  // We are done.
+    }
+  } while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
+}
+
+void QuicCryptoClientHandshaker::DoInitialize(
+    QuicCryptoClientConfig::CachedState* cached) {
+  if (!cached->IsEmpty() && !cached->signature().empty()) {
+    // Note that we verify the proof even if the cached proof is valid.
+    // This allows us to respond to CA trust changes or certificate
+    // expiration because it may have been a while since we last verified
+    // the proof.
+    QUICHE_DCHECK(crypto_config_->proof_verifier());
+    // Track proof verification time when cached server config is used.
+    proof_verify_start_time_ = session()->connection()->clock()->Now();
+    chlo_hash_ = cached->chlo_hash();
+    // If the cached state needs to be verified, do it now.
+    next_state_ = STATE_VERIFY_PROOF;
+  } else {
+    next_state_ = STATE_SEND_CHLO;
+  }
+}
+
+void QuicCryptoClientHandshaker::DoSendCHLO(
+    QuicCryptoClientConfig::CachedState* cached) {
+  // Send the client hello in plaintext.
+  session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  encryption_established_ = false;
+  if (num_client_hellos_ >= QuicCryptoClientStream::kMaxClientHellos) {
+    stream_->OnUnrecoverableError(
+        QUIC_CRYPTO_TOO_MANY_REJECTS,
+        absl::StrCat("More than ", QuicCryptoClientStream::kMaxClientHellos,
+                     " rejects"));
+    return;
+  }
+  num_client_hellos_++;
+
+  CryptoHandshakeMessage out;
+  QUICHE_DCHECK(session() != nullptr);
+  QUICHE_DCHECK(session()->config() != nullptr);
+  // Send all the options, regardless of whether we're sending an
+  // inchoate or subsequent hello.
+  session()->config()->ToHandshakeMessage(&out, session()->transport_version());
+
+  bool fill_inchoate_client_hello = false;
+  if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
+    early_data_reason_ = ssl_early_data_no_session_offered;
+    fill_inchoate_client_hello = true;
+  } else if (session()->config()->HasClientRequestedIndependentOption(
+                 kQNZ2, session()->perspective()) &&
+             num_client_hellos_ == 1) {
+    early_data_reason_ = ssl_early_data_disabled;
+    fill_inchoate_client_hello = true;
+  }
+  if (fill_inchoate_client_hello) {
+    crypto_config_->FillInchoateClientHello(
+        server_id_, session()->supported_versions().front(), cached,
+        session()->connection()->random_generator(),
+        /* demand_x509_proof= */ true, crypto_negotiated_params_, &out);
+    // Pad the inchoate client hello to fill up a packet.
+    const QuicByteCount kFramingOverhead = 50;  // A rough estimate.
+    const QuicByteCount max_packet_size =
+        session()->connection()->max_packet_length();
+    if (max_packet_size <= kFramingOverhead) {
+      QUIC_DLOG(DFATAL) << "max_packet_length (" << max_packet_size
+                        << ") has no room for framing overhead.";
+      stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                                    "max_packet_size too smalll");
+      return;
+    }
+    if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
+      QUIC_DLOG(DFATAL) << "Client hello won't fit in a single packet.";
+      stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR, "CHLO too large");
+      return;
+    }
+    next_state_ = STATE_RECV_REJ;
+    chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
+    session()->connection()->set_fully_pad_crypto_handshake_packets(
+        crypto_config_->pad_inchoate_hello());
+    SendHandshakeMessage(out, ENCRYPTION_INITIAL);
+    return;
+  }
+
+  std::string error_details;
+  QuicErrorCode error = crypto_config_->FillClientHello(
+      server_id_, session()->connection()->connection_id(),
+      session()->supported_versions().front(),
+      session()->connection()->version(), cached,
+      session()->connection()->clock()->WallNow(),
+      session()->connection()->random_generator(), crypto_negotiated_params_,
+      &out, &error_details);
+  if (error != QUIC_NO_ERROR) {
+    // Flush the cached config so that, if it's bad, the server has a
+    // chance to send us another in the future.
+    cached->InvalidateServerConfig();
+    stream_->OnUnrecoverableError(error, error_details);
+    return;
+  }
+  chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
+  if (cached->proof_verify_details()) {
+    proof_handler_->OnProofVerifyDetailsAvailable(
+        *cached->proof_verify_details());
+  }
+  next_state_ = STATE_RECV_SHLO;
+  session()->connection()->set_fully_pad_crypto_handshake_packets(
+      crypto_config_->pad_full_hello());
+  SendHandshakeMessage(out, ENCRYPTION_INITIAL);
+  // Be prepared to decrypt with the new server write key.
+  delegate_->OnNewEncryptionKeyAvailable(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.encrypter));
+  delegate_->OnNewDecryptionKeyAvailable(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.decrypter),
+      /*set_alternative_decrypter=*/true,
+      /*latch_once_used=*/true);
+  encryption_established_ = true;
+  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  if (early_data_reason_ == ssl_early_data_unknown && num_client_hellos_ > 1) {
+    early_data_reason_ = ssl_early_data_peer_declined;
+  }
+}
+
+void QuicCryptoClientHandshaker::DoReceiveREJ(
+    const CryptoHandshakeMessage* in,
+    QuicCryptoClientConfig::CachedState* cached) {
+  // We sent a dummy CHLO because we didn't have enough information to
+  // perform a handshake, or we sent a full hello that the server
+  // rejected. Here we hope to have a REJ that contains the information
+  // that we need.
+  if (in->tag() != kREJ) {
+    next_state_ = STATE_NONE;
+    stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                  "Expected REJ");
+    return;
+  }
+
+  QuicTagVector reject_reasons;
+  static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
+  if (in->GetTaglist(kRREJ, &reject_reasons) == QUIC_NO_ERROR) {
+    uint32_t packed_error = 0;
+    for (size_t i = 0; i < reject_reasons.size(); ++i) {
+      // HANDSHAKE_OK is 0 and don't report that as error.
+      if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) {
+        continue;
+      }
+      HandshakeFailureReason reason =
+          static_cast<HandshakeFailureReason>(reject_reasons[i]);
+      packed_error |= 1 << (reason - 1);
+    }
+    QUIC_DVLOG(1) << "Reasons for rejection: " << packed_error;
+    if (num_client_hellos_ == QuicCryptoClientStream::kMaxClientHellos) {
+      QuicClientSparseHistogram("QuicClientHelloRejectReasons.TooMany",
+                                packed_error);
+    }
+    QuicClientSparseHistogram("QuicClientHelloRejectReasons.Secure",
+                              packed_error);
+  }
+
+  // Receipt of a REJ message means that the server received the CHLO
+  // so we can cancel and retransmissions.
+  delegate_->NeuterUnencryptedData();
+
+  std::string error_details;
+  QuicErrorCode error = crypto_config_->ProcessRejection(
+      *in, session()->connection()->clock()->WallNow(),
+      session()->transport_version(), chlo_hash_, cached,
+      crypto_negotiated_params_, &error_details);
+
+  if (error != QUIC_NO_ERROR) {
+    next_state_ = STATE_NONE;
+    stream_->OnUnrecoverableError(error, error_details);
+    return;
+  }
+  if (!cached->proof_valid()) {
+    if (!cached->signature().empty()) {
+      // Note that we only verify the proof if the cached proof is not
+      // valid. If the cached proof is valid here, someone else must have
+      // just added the server config to the cache and verified the proof,
+      // so we can assume no CA trust changes or certificate expiration
+      // has happened since then.
+      next_state_ = STATE_VERIFY_PROOF;
+      return;
+    }
+  }
+  next_state_ = STATE_SEND_CHLO;
+}
+
+QuicAsyncStatus QuicCryptoClientHandshaker::DoVerifyProof(
+    QuicCryptoClientConfig::CachedState* cached) {
+  ProofVerifier* verifier = crypto_config_->proof_verifier();
+  QUICHE_DCHECK(verifier);
+  next_state_ = STATE_VERIFY_PROOF_COMPLETE;
+  generation_counter_ = cached->generation_counter();
+
+  ProofVerifierCallbackImpl* proof_verify_callback =
+      new ProofVerifierCallbackImpl(this);
+
+  verify_ok_ = false;
+
+  QuicAsyncStatus status = verifier->VerifyProof(
+      server_id_.host(), server_id_.port(), cached->server_config(),
+      session()->transport_version(), chlo_hash_, cached->certs(),
+      cached->cert_sct(), cached->signature(), verify_context_.get(),
+      &verify_error_details_, &verify_details_,
+      std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
+
+  switch (status) {
+    case QUIC_PENDING:
+      proof_verify_callback_ = proof_verify_callback;
+      QUIC_DVLOG(1) << "Doing VerifyProof";
+      break;
+    case QUIC_FAILURE:
+      break;
+    case QUIC_SUCCESS:
+      verify_ok_ = true;
+      break;
+  }
+  return status;
+}
+
+void QuicCryptoClientHandshaker::DoVerifyProofComplete(
+    QuicCryptoClientConfig::CachedState* cached) {
+  if (proof_verify_start_time_.IsInitialized()) {
+    QUIC_CLIENT_HISTOGRAM_TIMES(
+        "QuicSession.VerifyProofTime.CachedServerConfig",
+        (session()->connection()->clock()->Now() - proof_verify_start_time_),
+        QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::FromSeconds(10),
+        50, "");
+  }
+  if (!verify_ok_) {
+    if (verify_details_) {
+      proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
+    }
+    if (num_client_hellos_ == 0) {
+      cached->Clear();
+      next_state_ = STATE_INITIALIZE;
+      return;
+    }
+    next_state_ = STATE_NONE;
+    QUIC_CLIENT_HISTOGRAM_BOOL("QuicVerifyProofFailed.HandshakeConfirmed",
+                               one_rtt_keys_available(), "");
+    stream_->OnUnrecoverableError(QUIC_PROOF_INVALID,
+                                  "Proof invalid: " + verify_error_details_);
+    return;
+  }
+
+  // Check if generation_counter has changed between STATE_VERIFY_PROOF and
+  // STATE_VERIFY_PROOF_COMPLETE state changes.
+  if (generation_counter_ != cached->generation_counter()) {
+    next_state_ = STATE_VERIFY_PROOF;
+  } else {
+    SetCachedProofValid(cached);
+    cached->SetProofVerifyDetails(verify_details_.release());
+    if (!one_rtt_keys_available()) {
+      next_state_ = STATE_SEND_CHLO;
+    } else {
+      next_state_ = STATE_NONE;
+    }
+  }
+}
+
+void QuicCryptoClientHandshaker::DoReceiveSHLO(
+    const CryptoHandshakeMessage* in,
+    QuicCryptoClientConfig::CachedState* cached) {
+  next_state_ = STATE_NONE;
+  // We sent a CHLO that we expected to be accepted and now we're
+  // hoping for a SHLO from the server to confirm that.  First check
+  // to see whether the response was a reject, and if so, move on to
+  // the reject-processing state.
+  if (in->tag() == kREJ) {
+    // A reject message must be sent in ENCRYPTION_INITIAL.
+    if (session()->connection()->last_decrypted_level() != ENCRYPTION_INITIAL) {
+      // The rejection was sent encrypted!
+      stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
+                                    "encrypted REJ message");
+      return;
+    }
+    next_state_ = STATE_RECV_REJ;
+    return;
+  }
+
+  if (in->tag() != kSHLO) {
+    stream_->OnUnrecoverableError(
+        QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+        absl::StrCat("Expected SHLO or REJ. Received: ",
+                     QuicTagToString(in->tag())));
+    return;
+  }
+
+  if (session()->connection()->last_decrypted_level() == ENCRYPTION_INITIAL) {
+    // The server hello was sent without encryption.
+    stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
+                                  "unencrypted SHLO message");
+    return;
+  }
+  if (num_client_hellos_ == 1) {
+    early_data_reason_ = ssl_early_data_accepted;
+  }
+
+  std::string error_details;
+  QuicErrorCode error = crypto_config_->ProcessServerHello(
+      *in, session()->connection()->connection_id(),
+      session()->connection()->version(),
+      session()->connection()->server_supported_versions(), cached,
+      crypto_negotiated_params_, &error_details);
+
+  if (error != QUIC_NO_ERROR) {
+    stream_->OnUnrecoverableError(error,
+                                  "Server hello invalid: " + error_details);
+    return;
+  }
+  error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details);
+  if (error != QUIC_NO_ERROR) {
+    stream_->OnUnrecoverableError(error,
+                                  "Server hello invalid: " + error_details);
+    return;
+  }
+  session()->OnConfigNegotiated();
+
+  CrypterPair* crypters = &crypto_negotiated_params_->forward_secure_crypters;
+  // TODO(agl): we don't currently latch this decrypter because the idea
+  // has been floated that the server shouldn't send packets encrypted
+  // with the FORWARD_SECURE key until it receives a FORWARD_SECURE
+  // packet from the client.
+  delegate_->OnNewEncryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
+                                         std::move(crypters->encrypter));
+  delegate_->OnNewDecryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
+                                         std::move(crypters->decrypter),
+                                         /*set_alternative_decrypter=*/true,
+                                         /*latch_once_used=*/false);
+  one_rtt_keys_available_ = true;
+  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  delegate_->NeuterHandshakeData();
+}
+
+void QuicCryptoClientHandshaker::DoInitializeServerConfigUpdate(
+    QuicCryptoClientConfig::CachedState* cached) {
+  bool update_ignored = false;
+  if (!cached->IsEmpty() && !cached->signature().empty()) {
+    // Note that we verify the proof even if the cached proof is valid.
+    QUICHE_DCHECK(crypto_config_->proof_verifier());
+    next_state_ = STATE_VERIFY_PROOF;
+  } else {
+    update_ignored = true;
+    next_state_ = STATE_NONE;
+  }
+  QUIC_CLIENT_HISTOGRAM_COUNTS("QuicNumServerConfig.UpdateMessagesIgnored",
+                               update_ignored, 1, 1000000, 50, "");
+}
+
+void QuicCryptoClientHandshaker::SetCachedProofValid(
+    QuicCryptoClientConfig::CachedState* cached) {
+  cached->SetProofValid();
+  proof_handler_->OnProofValid(*cached);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_client_handshaker.h b/quiche/quic/core/quic_crypto_client_handshaker.h
new file mode 100644
index 0000000..07404d6
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_handshaker.h
@@ -0,0 +1,211 @@
+// 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_CLIENT_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
+
+#include <string>
+
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+// An implementation of QuicCryptoClientStream::HandshakerInterface which uses
+// QUIC crypto as the crypto handshake protocol.
+class QUIC_EXPORT_PRIVATE QuicCryptoClientHandshaker
+    : public QuicCryptoClientStream::HandshakerInterface,
+      public QuicCryptoHandshaker {
+ public:
+  QuicCryptoClientHandshaker(
+      const QuicServerId& server_id,
+      QuicCryptoClientStream* stream,
+      QuicSession* session,
+      std::unique_ptr<ProofVerifyContext> verify_context,
+      QuicCryptoClientConfig* crypto_config,
+      QuicCryptoClientStream::ProofHandler* proof_handler);
+  QuicCryptoClientHandshaker(const QuicCryptoClientHandshaker&) = delete;
+  QuicCryptoClientHandshaker& operator=(const QuicCryptoClientHandshaker&) =
+      delete;
+
+  ~QuicCryptoClientHandshaker() override;
+
+  // From QuicCryptoClientStream::HandshakerInterface
+  bool CryptoConnect() override;
+  int num_sent_client_hellos() const override;
+  bool IsResumption() const override;
+  bool EarlyDataAccepted() const override;
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool ReceivedInchoateReject() const override;
+  int num_scup_messages_received() const override;
+  std::string chlo_hash() const override;
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  HandshakeState GetHandshakeState() const override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override;
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {
+    QUICHE_NOTREACHED();
+  }
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+
+  // From QuicCryptoHandshaker
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+
+ protected:
+  // Returns the QuicSession that this stream belongs to.
+  QuicSession* session() const { return session_; }
+
+  // Send either InchoateClientHello or ClientHello message to the server.
+  void DoSendCHLO(QuicCryptoClientConfig::CachedState* cached);
+
+ private:
+  // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof.
+  // The ProofVerifier calls this class with the result of proof verification
+  // when verification is performed asynchronously.
+  class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl
+      : public ProofVerifierCallback {
+   public:
+    explicit ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent);
+    ~ProofVerifierCallbackImpl() override;
+
+    // ProofVerifierCallback interface.
+    void Run(bool ok,
+             const std::string& error_details,
+             std::unique_ptr<ProofVerifyDetails>* details) override;
+
+    // Cancel causes any future callbacks to be ignored. It must be called on
+    // the same thread as the callback will be made on.
+    void Cancel();
+
+   private:
+    QuicCryptoClientHandshaker* parent_;
+  };
+
+  enum State {
+    STATE_IDLE,
+    STATE_INITIALIZE,
+    STATE_SEND_CHLO,
+    STATE_RECV_REJ,
+    STATE_VERIFY_PROOF,
+    STATE_VERIFY_PROOF_COMPLETE,
+    STATE_RECV_SHLO,
+    STATE_INITIALIZE_SCUP,
+    STATE_NONE,
+    STATE_CONNECTION_CLOSED,
+  };
+
+  // Handles new server config and optional source-address token provided by the
+  // server during a connection.
+  void HandleServerConfigUpdateMessage(
+      const CryptoHandshakeMessage& server_config_update);
+
+  // DoHandshakeLoop performs a step of the handshake state machine. Note that
+  // |in| may be nullptr if the call did not result from a received message.
+  void DoHandshakeLoop(const CryptoHandshakeMessage* in);
+
+  // Start the handshake process.
+  void DoInitialize(QuicCryptoClientConfig::CachedState* cached);
+
+  // Process REJ message from the server.
+  void DoReceiveREJ(const CryptoHandshakeMessage* in,
+                    QuicCryptoClientConfig::CachedState* cached);
+
+  // Start the proof verification process. Returns the QuicAsyncStatus returned
+  // by the ProofVerifier's VerifyProof.
+  QuicAsyncStatus DoVerifyProof(QuicCryptoClientConfig::CachedState* cached);
+
+  // If proof is valid then it sets the proof as valid (which persists the
+  // server config). If not, it closes the connection.
+  void DoVerifyProofComplete(QuicCryptoClientConfig::CachedState* cached);
+
+  // Process SHLO message from the server.
+  void DoReceiveSHLO(const CryptoHandshakeMessage* in,
+                     QuicCryptoClientConfig::CachedState* cached);
+
+  // Start the proof verification if |server_id_| is https and |cached| has
+  // signature.
+  void DoInitializeServerConfigUpdate(
+      QuicCryptoClientConfig::CachedState* cached);
+
+  // Called to set the proof of |cached| valid.  Also invokes the session's
+  // OnProofValid() method.
+  void SetCachedProofValid(QuicCryptoClientConfig::CachedState* cached);
+
+  QuicCryptoClientStream* stream_;
+
+  QuicSession* session_;
+  HandshakerDelegateInterface* delegate_;
+
+  State next_state_;
+  // num_client_hellos_ contains the number of client hello messages that this
+  // connection has sent.
+  int num_client_hellos_;
+
+  ssl_early_data_reason_t early_data_reason_ = ssl_early_data_unknown;
+
+  QuicCryptoClientConfig* const crypto_config_;
+
+  // SHA-256 hash of the most recently sent CHLO.
+  std::string chlo_hash_;
+
+  // Server's (hostname, port, is_https, privacy_mode) tuple.
+  const QuicServerId server_id_;
+
+  // Generation counter from QuicCryptoClientConfig's CachedState.
+  uint64_t generation_counter_;
+
+  // verify_context_ contains the context object that we pass to asynchronous
+  // proof verifications.
+  std::unique_ptr<ProofVerifyContext> verify_context_;
+
+  // proof_verify_callback_ contains the callback object that we passed to an
+  // asynchronous proof verification. The ProofVerifier owns this object.
+  ProofVerifierCallbackImpl* proof_verify_callback_;
+  // proof_handler_ contains the callback object used by a quic client
+  // for proof verification. It is not owned by this class.
+  QuicCryptoClientStream::ProofHandler* proof_handler_;
+
+  // These members are used to store the result of an asynchronous proof
+  // verification. These members must not be used after
+  // STATE_VERIFY_PROOF_COMPLETE.
+  bool verify_ok_;
+  std::string verify_error_details_;
+  std::unique_ptr<ProofVerifyDetails> verify_details_;
+
+  QuicTime proof_verify_start_time_;
+
+  int num_scup_messages_received_;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      crypto_negotiated_params_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
diff --git a/quiche/quic/core/quic_crypto_client_handshaker_test.cc b/quiche/quic/core/quic_crypto_client_handshaker_test.cc
new file mode 100644
index 0000000..65d98f9
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_handshaker_test.cc
@@ -0,0 +1,239 @@
+// 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 "quiche/quic/core/quic_crypto_client_handshaker.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace {
+
+class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
+ public:
+  ~TestProofHandler() override {}
+  void OnProofValid(
+      const QuicCryptoClientConfig::CachedState& /*cached*/) override {}
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& /*verify_details*/) override {}
+};
+
+class InsecureProofVerifier : public ProofVerifier {
+ public:
+  InsecureProofVerifier() {}
+  ~InsecureProofVerifier() override {}
+
+  // ProofVerifier override.
+  QuicAsyncStatus VerifyProof(
+      const std::string& /*hostname*/,
+      const uint16_t /*port*/,
+      const std::string& /*server_config*/,
+      QuicTransportVersion /*transport_version*/,
+      absl::string_view /*chlo_hash*/,
+      const std::vector<std::string>& /*certs*/,
+      const std::string& /*cert_sct*/,
+      const std::string& /*signature*/,
+      const ProofVerifyContext* /*context*/,
+      std::string* /*error_details*/,
+      std::unique_ptr<ProofVerifyDetails>* /*verify_details*/,
+      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
+    return QUIC_SUCCESS;
+  }
+
+  QuicAsyncStatus VerifyCertChain(
+      const std::string& /*hostname*/,
+      const uint16_t /*port*/,
+      const std::vector<std::string>& /*certs*/,
+      const std::string& /*ocsp_response*/,
+      const std::string& /*cert_sct*/,
+      const ProofVerifyContext* /*context*/,
+      std::string* /*error_details*/,
+      std::unique_ptr<ProofVerifyDetails>* /*details*/,
+      uint8_t* /*out_alert*/,
+      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
+    return QUIC_SUCCESS;
+  }
+
+  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
+    return nullptr;
+  }
+};
+
+class DummyProofSource : public ProofSource {
+ public:
+  DummyProofSource() {}
+  ~DummyProofSource() override {}
+
+  // ProofSource override.
+  void GetProof(const QuicSocketAddress& server_address,
+                const QuicSocketAddress& client_address,
+                const std::string& hostname,
+                const std::string& /*server_config*/,
+                QuicTransportVersion /*transport_version*/,
+                absl::string_view /*chlo_hash*/,
+                std::unique_ptr<Callback> callback) override {
+    bool cert_matched_sni;
+    quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
+        GetCertChain(server_address, client_address, hostname,
+                     &cert_matched_sni);
+    QuicCryptoProof proof;
+    proof.signature = "Dummy signature";
+    proof.leaf_cert_scts = "Dummy timestamp";
+    proof.cert_matched_sni = cert_matched_sni;
+    callback->Run(true, chain, proof, /*details=*/nullptr);
+  }
+
+  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
+      const QuicSocketAddress& /*server_address*/,
+      const QuicSocketAddress& /*client_address*/,
+      const std::string& /*hostname*/, bool* /*cert_matched_sni*/) override {
+    std::vector<std::string> certs;
+    certs.push_back("Dummy cert");
+    return quiche::QuicheReferenceCountedPointer<ProofSource::Chain>(
+        new ProofSource::Chain(certs));
+  }
+
+  void ComputeTlsSignature(
+      const QuicSocketAddress& /*server_address*/,
+      const QuicSocketAddress& /*client_address*/,
+      const std::string& /*hostname*/,
+      uint16_t /*signature_algorit*/,
+      absl::string_view /*in*/,
+      std::unique_ptr<SignatureCallback> callback) override {
+    callback->Run(true, "Dummy signature", /*details=*/nullptr);
+  }
+
+  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+      const override {
+    return {};
+  }
+
+  TicketCrypter* GetTicketCrypter() override { return nullptr; }
+};
+
+class Handshaker : public QuicCryptoClientHandshaker {
+ public:
+  Handshaker(const QuicServerId& server_id,
+             QuicCryptoClientStream* stream,
+             QuicSession* session,
+             std::unique_ptr<ProofVerifyContext> verify_context,
+             QuicCryptoClientConfig* crypto_config,
+             QuicCryptoClientStream::ProofHandler* proof_handler)
+      : QuicCryptoClientHandshaker(server_id,
+                                   stream,
+                                   session,
+                                   std::move(verify_context),
+                                   crypto_config,
+                                   proof_handler) {}
+
+  void DoSendCHLOTest(QuicCryptoClientConfig::CachedState* cached) {
+    QuicCryptoClientHandshaker::DoSendCHLO(cached);
+  }
+};
+
+class QuicCryptoClientHandshakerTest
+    : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicCryptoClientHandshakerTest()
+      : version_(GetParam()),
+        proof_handler_(),
+        helper_(),
+        alarm_factory_(),
+        server_id_("host", 123),
+        connection_(new test::MockQuicConnection(&helper_,
+                                                 &alarm_factory_,
+                                                 Perspective::IS_CLIENT,
+                                                 {version_})),
+        session_(connection_, false),
+        crypto_client_config_(std::make_unique<InsecureProofVerifier>()),
+        client_stream_(
+            new QuicCryptoClientStream(server_id_,
+                                       &session_,
+                                       nullptr,
+                                       &crypto_client_config_,
+                                       &proof_handler_,
+                                       /*has_application_state = */ false)),
+        handshaker_(server_id_,
+                    client_stream_,
+                    &session_,
+                    nullptr,
+                    &crypto_client_config_,
+                    &proof_handler_),
+        state_() {
+    // Session takes the ownership of the client stream! (but handshaker also
+    // takes a reference to it, but doesn't take the ownership).
+    session_.SetCryptoStream(client_stream_);
+    session_.Initialize();
+  }
+
+  void InitializeServerParametersToEnableFullHello() {
+    QuicCryptoServerConfig::ConfigOptions options;
+    QuicServerConfigProtobuf config = QuicCryptoServerConfig::GenerateConfig(
+        helper_.GetRandomGenerator(), helper_.GetClock(), options);
+    state_.Initialize(
+        config.config(), "sourcetoken", std::vector<std::string>{"Dummy cert"},
+        "", "chlo_hash", "signature", helper_.GetClock()->WallNow(),
+        helper_.GetClock()->WallNow().Add(QuicTime::Delta::FromSeconds(30)));
+
+    state_.SetProofValid();
+  }
+
+  ParsedQuicVersion version_;
+  TestProofHandler proof_handler_;
+  test::MockQuicConnectionHelper helper_;
+  test::MockAlarmFactory alarm_factory_;
+  QuicServerId server_id_;
+  // Session takes the ownership of the connection.
+  test::MockQuicConnection* connection_;
+  test::MockQuicSession session_;
+  QuicCryptoClientConfig crypto_client_config_;
+  QuicCryptoClientStream* client_stream_;
+  Handshaker handshaker_;
+  QuicCryptoClientConfig::CachedState state_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    QuicCryptoClientHandshakerTests,
+    QuicCryptoClientHandshakerTest,
+    ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
+    ::testing::PrintToStringParamName());
+
+TEST_P(QuicCryptoClientHandshakerTest, TestSendFullPaddingInInchoateHello) {
+  handshaker_.DoSendCHLOTest(&state_);
+
+  EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
+}
+
+TEST_P(QuicCryptoClientHandshakerTest, TestDisabledPaddingInInchoateHello) {
+  crypto_client_config_.set_pad_inchoate_hello(false);
+  handshaker_.DoSendCHLOTest(&state_);
+  EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
+}
+
+TEST_P(QuicCryptoClientHandshakerTest,
+       TestPaddingInFullHelloEvenIfInchoateDisabled) {
+  // Disable inchoate, but full hello should still be padded.
+  crypto_client_config_.set_pad_inchoate_hello(false);
+
+  InitializeServerParametersToEnableFullHello();
+
+  handshaker_.DoSendCHLOTest(&state_);
+  EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
+}
+
+TEST_P(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
+  crypto_client_config_.set_pad_full_hello(false);
+
+  InitializeServerParametersToEnableFullHello();
+
+  handshaker_.DoSendCHLOTest(&state_);
+  EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_client_stream.cc b/quiche/quic/core/quic_crypto_client_stream.cc
new file mode 100644
index 0000000..f9339dc
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_stream.cc
@@ -0,0 +1,169 @@
+// 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 "quiche/quic/core/quic_crypto_client_stream.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/quic_crypto_client_handshaker.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/tls_client_handshaker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+const int QuicCryptoClientStream::kMaxClientHellos;
+
+QuicCryptoClientStreamBase::QuicCryptoClientStreamBase(QuicSession* session)
+    : QuicCryptoStream(session) {}
+
+QuicCryptoClientStream::QuicCryptoClientStream(
+    const QuicServerId& server_id,
+    QuicSession* session,
+    std::unique_ptr<ProofVerifyContext> verify_context,
+    QuicCryptoClientConfig* crypto_config,
+    ProofHandler* proof_handler,
+    bool has_application_state)
+    : QuicCryptoClientStreamBase(session) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT,
+                   session->connection()->perspective());
+  switch (session->connection()->version().handshake_protocol) {
+    case PROTOCOL_QUIC_CRYPTO:
+      handshaker_ = std::make_unique<QuicCryptoClientHandshaker>(
+          server_id, this, session, std::move(verify_context), crypto_config,
+          proof_handler);
+      break;
+    case PROTOCOL_TLS1_3: {
+      auto handshaker = std::make_unique<TlsClientHandshaker>(
+          server_id, this, session, std::move(verify_context), crypto_config,
+          proof_handler, has_application_state);
+      tls_handshaker_ = handshaker.get();
+      handshaker_ = std::move(handshaker);
+      break;
+    }
+    case PROTOCOL_UNSUPPORTED:
+      QUIC_BUG(quic_bug_10296_1)
+          << "Attempting to create QuicCryptoClientStream for unknown "
+             "handshake protocol";
+  }
+}
+
+QuicCryptoClientStream::~QuicCryptoClientStream() {}
+
+bool QuicCryptoClientStream::CryptoConnect() {
+  return handshaker_->CryptoConnect();
+}
+
+int QuicCryptoClientStream::num_sent_client_hellos() const {
+  return handshaker_->num_sent_client_hellos();
+}
+
+bool QuicCryptoClientStream::IsResumption() const {
+  return handshaker_->IsResumption();
+}
+
+bool QuicCryptoClientStream::EarlyDataAccepted() const {
+  return handshaker_->EarlyDataAccepted();
+}
+
+ssl_early_data_reason_t QuicCryptoClientStream::EarlyDataReason() const {
+  return handshaker_->EarlyDataReason();
+}
+
+bool QuicCryptoClientStream::ReceivedInchoateReject() const {
+  return handshaker_->ReceivedInchoateReject();
+}
+
+int QuicCryptoClientStream::num_scup_messages_received() const {
+  return handshaker_->num_scup_messages_received();
+}
+
+bool QuicCryptoClientStream::encryption_established() const {
+  return handshaker_->encryption_established();
+}
+
+bool QuicCryptoClientStream::one_rtt_keys_available() const {
+  return handshaker_->one_rtt_keys_available();
+}
+
+const QuicCryptoNegotiatedParameters&
+QuicCryptoClientStream::crypto_negotiated_params() const {
+  return handshaker_->crypto_negotiated_params();
+}
+
+CryptoMessageParser* QuicCryptoClientStream::crypto_message_parser() {
+  return handshaker_->crypto_message_parser();
+}
+
+HandshakeState QuicCryptoClientStream::GetHandshakeState() const {
+  return handshaker_->GetHandshakeState();
+}
+
+size_t QuicCryptoClientStream::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return handshaker_->BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicCryptoClientStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return handshaker_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter>
+QuicCryptoClientStream::CreateCurrentOneRttEncrypter() {
+  return handshaker_->CreateCurrentOneRttEncrypter();
+}
+
+bool QuicCryptoClientStream::ExportKeyingMaterial(absl::string_view label,
+                                                  absl::string_view context,
+                                                  size_t result_len,
+                                                  std::string* result) {
+  return handshaker_->ExportKeyingMaterial(label, context, result_len, result);
+}
+
+std::string QuicCryptoClientStream::chlo_hash() const {
+  return handshaker_->chlo_hash();
+}
+
+void QuicCryptoClientStream::OnOneRttPacketAcknowledged() {
+  handshaker_->OnOneRttPacketAcknowledged();
+}
+
+void QuicCryptoClientStream::OnHandshakePacketSent() {
+  handshaker_->OnHandshakePacketSent();
+}
+
+void QuicCryptoClientStream::OnConnectionClosed(QuicErrorCode error,
+                                                ConnectionCloseSource source) {
+  handshaker_->OnConnectionClosed(error, source);
+}
+
+void QuicCryptoClientStream::OnHandshakeDoneReceived() {
+  handshaker_->OnHandshakeDoneReceived();
+}
+
+void QuicCryptoClientStream::OnNewTokenReceived(absl::string_view token) {
+  handshaker_->OnNewTokenReceived(token);
+}
+
+void QuicCryptoClientStream::SetServerApplicationStateForResumption(
+    std::unique_ptr<ApplicationState> application_state) {
+  handshaker_->SetServerApplicationStateForResumption(
+      std::move(application_state));
+}
+
+SSL* QuicCryptoClientStream::GetSsl() const {
+  return tls_handshaker_ == nullptr ? nullptr : tls_handshaker_->ssl();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_client_stream.h b/quiche/quic/core/quic_crypto_client_stream.h
new file mode 100644
index 0000000..64b110c
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_stream.h
@@ -0,0 +1,307 @@
+// 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_CLIENT_STREAM_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_crypto_handshaker.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicCryptoClientStreamPeer;
+}  // namespace test
+
+class TlsClientHandshaker;
+
+class QUIC_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
+ public:
+  explicit QuicCryptoClientStreamBase(QuicSession* session);
+
+  ~QuicCryptoClientStreamBase() override {}
+
+  // Performs a crypto handshake with the server. Returns true if the connection
+  // is still connected.
+  virtual bool CryptoConnect() = 0;
+
+  // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
+  // ReceivedInchoateReject instead.
+  //
+  // num_sent_client_hellos returns the number of client hello messages that
+  // have been sent. If the handshake has completed then this is one greater
+  // than the number of round-trips needed for the handshake.
+  virtual int num_sent_client_hellos() const = 0;
+
+  // Returns true if the handshake performed was a resumption instead of a full
+  // handshake. Resumption only makes sense for TLS handshakes - there is no
+  // concept of resumption for QUIC crypto even though it supports a 0-RTT
+  // handshake. This function only returns valid results once the handshake is
+  // complete.
+  virtual bool IsResumption() const = 0;
+
+  // Returns true if early data (0-RTT) was accepted in the connection.
+  virtual bool EarlyDataAccepted() const = 0;
+
+  // Returns true if the client received an inchoate REJ during the handshake,
+  // extending the handshake by one round trip. This only applies for QUIC
+  // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
+  // but that is handled at the connection layer instead of the crypto layer.
+  virtual bool ReceivedInchoateReject() const = 0;
+
+  // The number of server config update messages received by the
+  // client.  Does not count update messages that were received prior
+  // to handshake confirmation.
+  virtual int num_scup_messages_received() const = 0;
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_params*/) const override {
+    QUICHE_DCHECK(false);
+    return "";
+  }
+
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    QUICHE_DCHECK(false);
+    return false;
+  }
+
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    QUICHE_DCHECK(false);
+    return nullptr;
+  }
+
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {
+    QUICHE_DCHECK(false);
+  }
+};
+
+class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
+    : public QuicCryptoClientStreamBase {
+ public:
+  // kMaxClientHellos is the maximum number of times that we'll send a client
+  // hello. The value 4 accounts for:
+  //   * One failure due to an incorrect or missing source-address token.
+  //   * One failure due the server's certificate chain being unavailible and
+  //     the server being unwilling to send it without a valid source-address
+  //     token.
+  //   * One failure due to the ServerConfig private key being located on a
+  //     remote oracle which has become unavailable, forcing the server to send
+  //     the client a fallback ServerConfig.
+  static const int kMaxClientHellos = 4;
+
+  // QuicCryptoClientStream creates a HandshakerInterface at construction time
+  // based on the QuicTransportVersion of the connection. Different
+  // HandshakerInterfaces provide implementations of different crypto handshake
+  // protocols. Currently QUIC crypto is the only protocol implemented; a future
+  // HandshakerInterface will use TLS as the handshake protocol.
+  // QuicCryptoClientStream delegates all of its public methods to its
+  // HandshakerInterface.
+  //
+  // This setup of the crypto stream delegating its implementation to the
+  // handshaker results in the handshaker reading and writing bytes on the
+  // crypto stream, instead of the handshaker passing the stream bytes to send.
+  class QUIC_EXPORT_PRIVATE HandshakerInterface {
+   public:
+    virtual ~HandshakerInterface() {}
+
+    // Performs a crypto handshake with the server. Returns true if the
+    // connection is still connected.
+    virtual bool CryptoConnect() = 0;
+
+    // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
+    // ReceivedInchoateReject instead.
+    //
+    // num_sent_client_hellos returns the number of client hello messages that
+    // have been sent. If the handshake has completed then this is one greater
+    // than the number of round-trips needed for the handshake.
+    virtual int num_sent_client_hellos() const = 0;
+
+    // Returns true if the handshake performed was a resumption instead of a
+    // full handshake. Resumption only makes sense for TLS handshakes - there is
+    // no concept of resumption for QUIC crypto even though it supports a 0-RTT
+    // handshake. This function only returns valid results once the handshake is
+    // complete.
+    virtual bool IsResumption() const = 0;
+
+    // Returns true if early data (0-RTT) was accepted in the connection.
+    virtual bool EarlyDataAccepted() const = 0;
+
+    // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
+    // rejected.
+    virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
+
+    // Returns true if the client received an inchoate REJ during the handshake,
+    // extending the handshake by one round trip. This only applies for QUIC
+    // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
+    // but that is handled at the connection layer instead of the crypto layer.
+    virtual bool ReceivedInchoateReject() const = 0;
+
+    // The number of server config update messages received by the
+    // client.  Does not count update messages that were received prior
+    // to handshake confirmation.
+    virtual int num_scup_messages_received() const = 0;
+
+    virtual std::string chlo_hash() const = 0;
+
+    // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set
+    // for the connection.
+    virtual bool encryption_established() const = 0;
+
+    // Returns true once 1RTT keys are available.
+    virtual bool one_rtt_keys_available() const = 0;
+
+    // Returns the parameters negotiated in the crypto handshake.
+    virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+        const = 0;
+
+    // Used by QuicCryptoStream to parse data received on this stream.
+    virtual CryptoMessageParser* crypto_message_parser() = 0;
+
+    // Used by QuicCryptoStream to know how much unprocessed data can be
+    // buffered at each encryption level.
+    virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0;
+
+    // Called to generate a decrypter for the next key phase. Each call should
+    // generate the key for phase n+1.
+    virtual std::unique_ptr<QuicDecrypter>
+    AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
+
+    // Called to generate an encrypter for the same key phase of the last
+    // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
+    virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
+
+    // Returns current handshake state.
+    virtual HandshakeState GetHandshakeState() const = 0;
+
+    // Called when a 1RTT packet has been acknowledged.
+    virtual void OnOneRttPacketAcknowledged() = 0;
+
+    // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
+    virtual void OnHandshakePacketSent() = 0;
+
+    // Called when connection gets closed.
+    virtual void OnConnectionClosed(QuicErrorCode error,
+                                    ConnectionCloseSource source) = 0;
+
+    // Called when handshake done has been received.
+    virtual void OnHandshakeDoneReceived() = 0;
+
+    // Called when new token has been received.
+    virtual void OnNewTokenReceived(absl::string_view token) = 0;
+
+    // Called when application state is received.
+    virtual void SetServerApplicationStateForResumption(
+        std::unique_ptr<ApplicationState> application_state) = 0;
+
+    // Called to obtain keying material export of length |result_len| with the
+    // given |label| and |context|. Returns false on failure.
+    virtual bool ExportKeyingMaterial(absl::string_view label,
+                                      absl::string_view context,
+                                      size_t result_len,
+                                      std::string* result) = 0;
+  };
+
+  // ProofHandler is an interface that handles callbacks from the crypto
+  // stream when the client has proof verification details of the server.
+  class QUIC_EXPORT_PRIVATE ProofHandler {
+   public:
+    virtual ~ProofHandler() {}
+
+    // Called when the proof in |cached| is marked valid.  If this is a secure
+    // QUIC session, then this will happen only after the proof verifier
+    // completes.
+    virtual void OnProofValid(
+        const QuicCryptoClientConfig::CachedState& cached) = 0;
+
+    // Called when proof verification details become available, either because
+    // proof verification is complete, or when cached details are used. This
+    // will only be called for secure QUIC connections.
+    virtual void OnProofVerifyDetailsAvailable(
+        const ProofVerifyDetails& verify_details) = 0;
+  };
+
+  QuicCryptoClientStream(const QuicServerId& server_id,
+                         QuicSession* session,
+                         std::unique_ptr<ProofVerifyContext> verify_context,
+                         QuicCryptoClientConfig* crypto_config,
+                         ProofHandler* proof_handler,
+                         bool has_application_state);
+  QuicCryptoClientStream(const QuicCryptoClientStream&) = delete;
+  QuicCryptoClientStream& operator=(const QuicCryptoClientStream&) = delete;
+
+  ~QuicCryptoClientStream() override;
+
+  // From QuicCryptoClientStreamBase
+  bool CryptoConnect() override;
+  int num_sent_client_hellos() const override;
+  bool IsResumption() const override;
+  bool EarlyDataAccepted() const override;
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool ReceivedInchoateReject() const override;
+
+  int num_scup_messages_received() const override;
+
+  // From QuicCryptoStream
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override;
+  void OnHandshakePacketSent() override;
+  void OnConnectionClosed(QuicErrorCode error,
+                          ConnectionCloseSource source) override;
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  HandshakeState GetHandshakeState() const override;
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> application_state) override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  SSL* GetSsl() const override;
+  bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
+                            size_t result_len, std::string* result) override;
+  std::string chlo_hash() const;
+
+ protected:
+  void set_handshaker(std::unique_ptr<HandshakerInterface> handshaker) {
+    handshaker_ = std::move(handshaker);
+  }
+
+ private:
+  friend class test::QuicCryptoClientStreamPeer;
+  std::unique_ptr<HandshakerInterface> handshaker_;
+  // Points to |handshaker_| if it uses TLS1.3. Otherwise, nullptr.
+  // TODO(danzh) change the type of |handshaker_| to TlsClientHandshaker after
+  // deprecating Google QUIC.
+  TlsClientHandshaker* tls_handshaker_{nullptr};
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
diff --git a/quiche/quic/core/quic_crypto_client_stream_test.cc b/quiche/quic/core/quic_crypto_client_stream_test.cc
new file mode 100644
index 0000000..377f7a2
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_stream_test.cc
@@ -0,0 +1,371 @@
+// 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 "quiche/quic/core/quic_crypto_client_stream.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_quic_framer.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using testing::_;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kServerPort = 443;
+
+// This test tests the client-side of the QUIC crypto handshake. It does not
+// test the TLS handshake - that is in tls_client_handshaker_test.cc.
+class QuicCryptoClientStreamTest : public QuicTest {
+ public:
+  QuicCryptoClientStreamTest()
+      : supported_versions_(AllSupportedVersionsWithQuicCrypto()),
+        server_id_(kServerHostname, kServerPort, false),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+                       std::make_unique<test::SimpleSessionCache>()),
+        server_crypto_config_(
+            crypto_test_utils::CryptoServerConfigForTesting()) {
+    CreateConnection();
+  }
+
+  void CreateSession() {
+    session_ = std::make_unique<TestQuicSpdyClientSession>(
+        connection_, DefaultQuicConfig(), supported_versions_, server_id_,
+        &crypto_config_);
+    EXPECT_CALL(*session_, GetAlpnsToOffer())
+        .WillRepeatedly(testing::Return(std::vector<std::string>(
+            {AlpnForVersion(connection_->version())})));
+  }
+
+  void CreateConnection() {
+    connection_ =
+        new PacketSavingConnection(&client_helper_, &alarm_factory_,
+                                   Perspective::IS_CLIENT, supported_versions_);
+    // Advance the time, because timers do not like uninitialized times.
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    CreateSession();
+  }
+
+  void CompleteCryptoHandshake() {
+    int proof_verify_details_calls = 1;
+    if (stream()->handshake_protocol() != PROTOCOL_TLS1_3) {
+      EXPECT_CALL(*session_, OnProofValid(testing::_))
+          .Times(testing::AtLeast(1));
+      proof_verify_details_calls = 0;
+    }
+    EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
+        .Times(testing::AtLeast(proof_verify_details_calls));
+    stream()->CryptoConnect();
+    QuicConfig config;
+    crypto_test_utils::HandshakeWithFakeServer(
+        &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+        connection_, stream(), AlpnForVersion(connection_->version()));
+  }
+
+  QuicCryptoClientStream* stream() {
+    return session_->GetMutableCryptoStream();
+  }
+
+  MockQuicConnectionHelper server_helper_;
+  MockQuicConnectionHelper client_helper_;
+  MockAlarmFactory alarm_factory_;
+  PacketSavingConnection* connection_;
+  ParsedQuicVersionVector supported_versions_;
+  std::unique_ptr<TestQuicSpdyClientSession> session_;
+  QuicServerId server_id_;
+  CryptoHandshakeMessage message_;
+  QuicCryptoClientConfig crypto_config_;
+  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+};
+
+TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
+  EXPECT_FALSE(stream()->encryption_established());
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+}
+
+TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
+  CompleteCryptoHandshake();
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_no_session_offered);
+}
+
+TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
+  CompleteCryptoHandshake();
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
+  message_.set_tag(kCHLO);
+  crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
+                                                  Perspective::IS_CLIENT);
+}
+
+TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
+  stream()->CryptoConnect();
+
+  message_.set_tag(kCHLO);
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                            "Expected REJ", _));
+  crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
+                                                  Perspective::IS_CLIENT);
+}
+
+TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
+  CompleteCryptoHandshake();
+
+  const QuicConfig* config = session_->config();
+  EXPECT_EQ(kMaximumIdleTimeoutSecs, config->IdleNetworkTimeout().ToSeconds());
+
+  const QuicCryptoNegotiatedParameters& crypto_params(
+      stream()->crypto_negotiated_params());
+  EXPECT_EQ(crypto_config_.aead[0], crypto_params.aead);
+  EXPECT_EQ(crypto_config_.kexs[0], crypto_params.key_exchange);
+}
+
+TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
+  // Seed the config with a cached server config.
+  CompleteCryptoHandshake();
+
+  // Recreate connection with the new config.
+  CreateConnection();
+
+  // Advance time 5 years to ensure that we pass the expiry time of the cached
+  // server config.
+  connection_->AdvanceTime(
+      QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
+
+  EXPECT_CALL(*session_, OnProofValid(testing::_));
+  stream()->CryptoConnect();
+  // Check that a client hello was sent.
+  ASSERT_EQ(1u, connection_->encrypted_packets_.size());
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+}
+
+TEST_F(QuicCryptoClientStreamTest, ClientTurnedOffZeroRtt) {
+  // Seed the config with a cached server config.
+  CompleteCryptoHandshake();
+
+  // Recreate connection with the new config.
+  CreateConnection();
+
+  // Set connection option.
+  QuicTagVector options;
+  options.push_back(kQNZ2);
+  session_->config()->SetClientConnectionOptions(options);
+
+  CompleteCryptoHandshake();
+  // Check that two client hellos were sent, one inchoate and one normal.
+  EXPECT_EQ(2, stream()->num_sent_client_hellos());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_disabled);
+}
+
+TEST_F(QuicCryptoClientStreamTest, ClockSkew) {
+  // Test that if the client's clock is skewed with respect to the server,
+  // the handshake succeeds. In the past, the client would get the server
+  // config, notice that it had already expired and then close the connection.
+
+  // Advance time 5 years to ensure that we pass the expiry time in the server
+  // config, but the TTL is used instead.
+  connection_->AdvanceTime(
+      QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
+
+  // The handshakes completes!
+  CompleteCryptoHandshake();
+}
+
+TEST_F(QuicCryptoClientStreamTest, InvalidCachedServerConfig) {
+  // Seed the config with a cached server config.
+  CompleteCryptoHandshake();
+
+  // Recreate connection with the new config.
+  CreateConnection();
+
+  QuicCryptoClientConfig::CachedState* state =
+      crypto_config_.LookupOrCreate(server_id_);
+
+  std::vector<std::string> certs = state->certs();
+  std::string cert_sct = state->cert_sct();
+  std::string signature = state->signature();
+  std::string chlo_hash = state->chlo_hash();
+  state->SetProof(certs, cert_sct, chlo_hash, signature + signature);
+
+  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
+      .Times(testing::AnyNumber());
+  stream()->CryptoConnect();
+  // Check that a client hello was sent.
+  ASSERT_EQ(1u, connection_->encrypted_packets_.size());
+}
+
+TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
+  // Test that the crypto client stream can receive server config updates after
+  // the connection has been established.
+  CompleteCryptoHandshake();
+
+  QuicCryptoClientConfig::CachedState* state =
+      crypto_config_.LookupOrCreate(server_id_);
+
+  // Ensure cached STK is different to what we send in the handshake.
+  EXPECT_NE("xstk", state->source_address_token());
+
+  // Initialize using {...} syntax to avoid trailing \0 if converting from
+  // string.
+  unsigned char stk[] = {'x', 's', 't', 'k'};
+
+  // Minimum SCFG that passes config validation checks.
+  unsigned char scfg[] = {// SCFG
+                          0x53, 0x43, 0x46, 0x47,
+                          // num entries
+                          0x01, 0x00,
+                          // padding
+                          0x00, 0x00,
+                          // EXPY
+                          0x45, 0x58, 0x50, 0x59,
+                          // EXPY end offset
+                          0x08, 0x00, 0x00, 0x00,
+                          // Value
+                          '1', '2', '3', '4', '5', '6', '7', '8'};
+
+  CryptoHandshakeMessage server_config_update;
+  server_config_update.set_tag(kSCUP);
+  server_config_update.SetValue(kSourceAddressTokenTag, stk);
+  server_config_update.SetValue(kSCFG, scfg);
+  const uint64_t expiry_seconds = 60 * 60 * 24 * 2;
+  server_config_update.SetValue(kSTTL, expiry_seconds);
+
+  crypto_test_utils::SendHandshakeMessageToStream(
+      stream(), server_config_update, Perspective::IS_SERVER);
+
+  // Make sure that the STK and SCFG are cached correctly.
+  EXPECT_EQ("xstk", state->source_address_token());
+
+  const std::string& cached_scfg = state->server_config();
+  quiche::test::CompareCharArraysWithHexError(
+      "scfg", cached_scfg.data(), cached_scfg.length(),
+      reinterpret_cast<char*>(scfg), ABSL_ARRAYSIZE(scfg));
+
+  QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream());
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+}
+
+TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
+  // Test that the crypto client stream can receive and use server config
+  // updates with certificates after the connection has been established.
+  CompleteCryptoHandshake();
+
+  // Build a server config update message with certificates
+  QuicCryptoServerConfig crypto_config(
+      QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+      crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
+  crypto_test_utils::SetupCryptoServerConfigForTest(
+      connection_->clock(), QuicRandom::GetInstance(), &crypto_config);
+  SourceAddressTokens tokens;
+  QuicCompressedCertsCache cache(1);
+  CachedNetworkParameters network_params;
+  CryptoHandshakeMessage server_config_update;
+
+  class Callback : public BuildServerConfigUpdateMessageResultCallback {
+   public:
+    Callback(bool* ok, CryptoHandshakeMessage* message)
+        : ok_(ok), message_(message) {}
+    void Run(bool ok, const CryptoHandshakeMessage& message) override {
+      *ok_ = ok;
+      *message_ = message;
+    }
+
+   private:
+    bool* ok_;
+    CryptoHandshakeMessage* message_;
+  };
+
+  // Note: relies on the callback being invoked synchronously
+  bool ok = false;
+  crypto_config.BuildServerConfigUpdateMessage(
+      session_->transport_version(), stream()->chlo_hash(), tokens,
+      QuicSocketAddress(QuicIpAddress::Loopback6(), 1234),
+      QuicSocketAddress(QuicIpAddress::Loopback6(), 4321), connection_->clock(),
+      QuicRandom::GetInstance(), &cache, stream()->crypto_negotiated_params(),
+      &network_params,
+      std::unique_ptr<BuildServerConfigUpdateMessageResultCallback>(
+          new Callback(&ok, &server_config_update)));
+  EXPECT_TRUE(ok);
+
+  EXPECT_CALL(*session_, OnProofValid(testing::_));
+  crypto_test_utils::SendHandshakeMessageToStream(
+      stream(), server_config_update, Perspective::IS_SERVER);
+
+  // Recreate connection with the new config and verify a 0-RTT attempt.
+  CreateConnection();
+
+  EXPECT_CALL(*session_, OnProofValid(testing::_));
+  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
+      .Times(testing::AnyNumber());
+  stream()->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+}
+
+TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, _, _));
+  CryptoHandshakeMessage server_config_update;
+  server_config_update.set_tag(kSCUP);
+  crypto_test_utils::SendHandshakeMessageToStream(
+      stream(), server_config_update, Perspective::IS_SERVER);
+}
+
+TEST_F(QuicCryptoClientStreamTest, PreferredVersion) {
+  // This mimics the case where client receives version negotiation packet, such
+  // that, the preferred version is different from the packets' version.
+  connection_ = new PacketSavingConnection(
+      &client_helper_, &alarm_factory_, Perspective::IS_CLIENT,
+      ParsedVersionOfIndex(supported_versions_, 1));
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+  CreateSession();
+  CompleteCryptoHandshake();
+  // 2 CHLOs are sent.
+  ASSERT_EQ(2u, session_->sent_crypto_handshake_messages().size());
+  // Verify preferred version is the highest version that session supports, and
+  // is different from connection's version.
+  QuicVersionLabel client_version_label;
+  EXPECT_THAT(session_->sent_crypto_handshake_messages()[0].GetVersionLabel(
+                  kVER, &client_version_label),
+              IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
+            client_version_label);
+  EXPECT_THAT(session_->sent_crypto_handshake_messages()[1].GetVersionLabel(
+                  kVER, &client_version_label),
+              IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
+            client_version_label);
+  EXPECT_NE(CreateQuicVersionLabel(connection_->version()),
+            client_version_label);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_handshaker.cc b/quiche/quic/core/quic_crypto_handshaker.cc
new file mode 100644
index 0000000..57c7035
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_handshaker.cc
@@ -0,0 +1,53 @@
+// 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 "quiche/quic/core/quic_crypto_handshaker.h"
+
+#include "quiche/quic/core/quic_session.h"
+
+namespace quic {
+
+#define ENDPOINT \
+  (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+QuicCryptoHandshaker::QuicCryptoHandshaker(QuicCryptoStream* stream,
+                                           QuicSession* session)
+    : stream_(stream), session_(session), last_sent_handshake_message_tag_(0) {
+  crypto_framer_.set_visitor(this);
+}
+
+QuicCryptoHandshaker::~QuicCryptoHandshaker() {}
+
+void QuicCryptoHandshaker::SendHandshakeMessage(
+    const CryptoHandshakeMessage& message,
+    EncryptionLevel level) {
+  QUIC_DVLOG(1) << ENDPOINT << "Sending " << message.DebugString();
+  session()->NeuterUnencryptedData();
+  session()->OnCryptoHandshakeMessageSent(message);
+  last_sent_handshake_message_tag_ = message.tag();
+  const QuicData& data = message.GetSerialized();
+  stream_->WriteCryptoData(level, data.AsStringPiece());
+}
+
+void QuicCryptoHandshaker::OnError(CryptoFramer* framer) {
+  QUIC_DLOG(WARNING) << "Error processing crypto data: "
+                     << QuicErrorCodeToString(framer->error());
+}
+
+void QuicCryptoHandshaker::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  QUIC_DVLOG(1) << ENDPOINT << "Received " << message.DebugString();
+  session()->OnCryptoHandshakeMessageReceived(message);
+}
+
+CryptoMessageParser* QuicCryptoHandshaker::crypto_message_parser() {
+  return &crypto_framer_;
+}
+
+size_t QuicCryptoHandshaker::BufferSizeLimitForLevel(EncryptionLevel) const {
+  return GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes);
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_handshaker.h b/quiche/quic/core/quic_crypto_handshaker.h
new file mode 100644
index 0000000..526dbd5
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_handshaker.h
@@ -0,0 +1,52 @@
+// 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_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
+
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicCryptoHandshaker
+    : public CryptoFramerVisitorInterface {
+ public:
+  QuicCryptoHandshaker(QuicCryptoStream* stream, QuicSession* session);
+  QuicCryptoHandshaker(const QuicCryptoHandshaker&) = delete;
+  QuicCryptoHandshaker& operator=(const QuicCryptoHandshaker&) = delete;
+
+  ~QuicCryptoHandshaker() override;
+
+  // Sends |message| to the peer.
+  // TODO(wtc): return a success/failure status.
+  void SendHandshakeMessage(const CryptoHandshakeMessage& message,
+                            EncryptionLevel level);
+
+  void OnError(CryptoFramer* framer) override;
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+
+  CryptoMessageParser* crypto_message_parser();
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
+
+ protected:
+  QuicTag last_sent_handshake_message_tag() const {
+    return last_sent_handshake_message_tag_;
+  }
+
+ private:
+  QuicSession* session() { return session_; }
+
+  QuicCryptoStream* stream_;
+  QuicSession* session_;
+
+  CryptoFramer crypto_framer_;
+
+  // Records last sent crypto handshake message tag.
+  QuicTag last_sent_handshake_message_tag_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
diff --git a/quiche/quic/core/quic_crypto_server_stream.cc b/quiche/quic/core/quic_crypto_server_stream.cc
new file mode 100644
index 0000000..8cefbb5
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream.cc
@@ -0,0 +1,538 @@
+// 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 "quiche/quic/core/quic_crypto_server_stream.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_testvalue.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+class QuicCryptoServerStream::ProcessClientHelloCallback
+    : public ProcessClientHelloResultCallback {
+ public:
+  ProcessClientHelloCallback(
+      QuicCryptoServerStream* parent,
+      const quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>& result)
+      : parent_(parent), result_(result) {}
+
+  void Run(
+      QuicErrorCode error,
+      const std::string& error_details,
+      std::unique_ptr<CryptoHandshakeMessage> message,
+      std::unique_ptr<DiversificationNonce> diversification_nonce,
+      std::unique_ptr<ProofSource::Details> proof_source_details) override {
+    if (parent_ == nullptr) {
+      return;
+    }
+
+    parent_->FinishProcessingHandshakeMessageAfterProcessClientHello(
+        *result_, error, error_details, std::move(message),
+        std::move(diversification_nonce), std::move(proof_source_details));
+  }
+
+  void Cancel() { parent_ = nullptr; }
+
+ private:
+  QuicCryptoServerStream* parent_;
+  quiche::QuicheReferenceCountedPointer<
+      ValidateClientHelloResultCallback::Result>
+      result_;
+};
+
+QuicCryptoServerStream::QuicCryptoServerStream(
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    QuicSession* session,
+    QuicCryptoServerStreamBase::Helper* helper)
+    : QuicCryptoServerStreamBase(session),
+      QuicCryptoHandshaker(this, session),
+      session_(session),
+      delegate_(session),
+      crypto_config_(crypto_config),
+      compressed_certs_cache_(compressed_certs_cache),
+      signed_config_(new QuicSignedServerConfig),
+      helper_(helper),
+      num_handshake_messages_(0),
+      num_handshake_messages_with_server_nonces_(0),
+      send_server_config_update_cb_(nullptr),
+      num_server_config_update_messages_sent_(0),
+      zero_rtt_attempted_(false),
+      chlo_packet_size_(0),
+      validate_client_hello_cb_(nullptr),
+      process_client_hello_cb_(nullptr),
+      encryption_established_(false),
+      one_rtt_keys_available_(false),
+      one_rtt_packet_decrypted_(false),
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
+
+QuicCryptoServerStream::~QuicCryptoServerStream() {
+  CancelOutstandingCallbacks();
+}
+
+void QuicCryptoServerStream::CancelOutstandingCallbacks() {
+  // Detach from the validation callback.  Calling this multiple times is safe.
+  if (validate_client_hello_cb_ != nullptr) {
+    validate_client_hello_cb_->Cancel();
+    validate_client_hello_cb_ = nullptr;
+  }
+  if (send_server_config_update_cb_ != nullptr) {
+    send_server_config_update_cb_->Cancel();
+    send_server_config_update_cb_ = nullptr;
+  }
+  if (process_client_hello_cb_ != nullptr) {
+    process_client_hello_cb_->Cancel();
+    process_client_hello_cb_ = nullptr;
+  }
+}
+
+void QuicCryptoServerStream::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  QuicCryptoHandshaker::OnHandshakeMessage(message);
+  ++num_handshake_messages_;
+  chlo_packet_size_ = session()->connection()->GetCurrentPacket().length();
+
+  // Do not process handshake messages after the handshake is confirmed.
+  if (one_rtt_keys_available_) {
+    OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+                         "Unexpected handshake message from client");
+    return;
+  }
+
+  if (message.tag() != kCHLO) {
+    OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                         "Handshake packet not CHLO");
+    return;
+  }
+
+  if (validate_client_hello_cb_ != nullptr ||
+      process_client_hello_cb_ != nullptr) {
+    // Already processing some other handshake message.  The protocol
+    // does not allow for clients to send multiple handshake messages
+    // before the server has a chance to respond.
+    OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
+                         "Unexpected handshake message while processing CHLO");
+    return;
+  }
+
+  chlo_hash_ =
+      CryptoUtils::HashHandshakeMessage(message, Perspective::IS_SERVER);
+
+  std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this));
+  QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
+  QUICHE_DCHECK(process_client_hello_cb_ == nullptr);
+  validate_client_hello_cb_ = cb.get();
+  crypto_config_->ValidateClientHello(
+      message, GetClientAddress(), session()->connection()->self_address(),
+      transport_version(), session()->connection()->clock(), signed_config_,
+      std::move(cb));
+}
+
+void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        result,
+    std::unique_ptr<ProofSource::Details> details) {
+  // Clear the callback that got us here.
+  QUICHE_DCHECK(validate_client_hello_cb_ != nullptr);
+  QUICHE_DCHECK(process_client_hello_cb_ == nullptr);
+  validate_client_hello_cb_ = nullptr;
+
+  std::unique_ptr<ProcessClientHelloCallback> cb(
+      new ProcessClientHelloCallback(this, result));
+  process_client_hello_cb_ = cb.get();
+  ProcessClientHello(result, std::move(details), std::move(cb));
+}
+
+void QuicCryptoServerStream::
+    FinishProcessingHandshakeMessageAfterProcessClientHello(
+        const ValidateClientHelloResultCallback::Result& result,
+        QuicErrorCode error,
+        const std::string& error_details,
+        std::unique_ptr<CryptoHandshakeMessage> reply,
+        std::unique_ptr<DiversificationNonce> diversification_nonce,
+        std::unique_ptr<ProofSource::Details> proof_source_details) {
+  // Clear the callback that got us here.
+  QUICHE_DCHECK(process_client_hello_cb_ != nullptr);
+  QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
+  process_client_hello_cb_ = nullptr;
+  proof_source_details_ = std::move(proof_source_details);
+
+  AdjustTestValue("quic::QuicCryptoServerStream::after_process_client_hello",
+                  session());
+
+  if (!session()->connection()->connected()) {
+    QUIC_CODE_COUNT(quic_crypto_disconnected_after_process_client_hello);
+    QUIC_LOG_FIRST_N(INFO, 10)
+        << "After processing CHLO, QUIC connection has been closed with code "
+        << session()->error() << ", details: " << session()->error_details();
+    return;
+  }
+
+  const CryptoHandshakeMessage& message = result.client_hello;
+  if (error != QUIC_NO_ERROR) {
+    OnUnrecoverableError(error, error_details);
+    return;
+  }
+
+  if (reply->tag() != kSHLO) {
+    session()->connection()->set_fully_pad_crypto_handshake_packets(
+        crypto_config_->pad_rej());
+    // Send REJ in plaintext.
+    SendHandshakeMessage(*reply, ENCRYPTION_INITIAL);
+    return;
+  }
+
+  // If we are returning a SHLO then we accepted the handshake.  Now
+  // process the negotiated configuration options as part of the
+  // session config.
+  QuicConfig* config = session()->config();
+  OverrideQuicConfigDefaults(config);
+  std::string process_error_details;
+  const QuicErrorCode process_error =
+      config->ProcessPeerHello(message, CLIENT, &process_error_details);
+  if (process_error != QUIC_NO_ERROR) {
+    OnUnrecoverableError(process_error, process_error_details);
+    return;
+  }
+
+  session()->OnConfigNegotiated();
+
+  config->ToHandshakeMessage(reply.get(), session()->transport_version());
+
+  // Receiving a full CHLO implies the client is prepared to decrypt with
+  // the new server write key.  We can start to encrypt with the new server
+  // write key.
+  //
+  // NOTE: the SHLO will be encrypted with the new server write key.
+  delegate_->OnNewEncryptionKeyAvailable(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.encrypter));
+  delegate_->OnNewDecryptionKeyAvailable(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.decrypter),
+      /*set_alternative_decrypter=*/false,
+      /*latch_once_used=*/false);
+  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  delegate_->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
+  session()->connection()->SetDiversificationNonce(*diversification_nonce);
+
+  session()->connection()->set_fully_pad_crypto_handshake_packets(
+      crypto_config_->pad_shlo());
+  // Send SHLO in ENCRYPTION_ZERO_RTT.
+  SendHandshakeMessage(*reply, ENCRYPTION_ZERO_RTT);
+  delegate_->OnNewEncryptionKeyAvailable(
+      ENCRYPTION_FORWARD_SECURE,
+      std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter));
+  delegate_->OnNewDecryptionKeyAvailable(
+      ENCRYPTION_FORWARD_SECURE,
+      std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
+      /*set_alternative_decrypter=*/true,
+      /*latch_once_used=*/false);
+  encryption_established_ = true;
+  one_rtt_keys_available_ = true;
+  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+}
+
+void QuicCryptoServerStream::SendServerConfigUpdate(
+    const CachedNetworkParameters* cached_network_params) {
+  if (!one_rtt_keys_available_) {
+    return;
+  }
+
+  if (send_server_config_update_cb_ != nullptr) {
+    QUIC_DVLOG(1)
+        << "Skipped server config update since one is already in progress";
+    return;
+  }
+
+  std::unique_ptr<SendServerConfigUpdateCallback> cb(
+      new SendServerConfigUpdateCallback(this));
+  send_server_config_update_cb_ = cb.get();
+
+  crypto_config_->BuildServerConfigUpdateMessage(
+      session()->transport_version(), chlo_hash_,
+      previous_source_address_tokens_, session()->connection()->self_address(),
+      GetClientAddress(), session()->connection()->clock(),
+      session()->connection()->random_generator(), compressed_certs_cache_,
+      *crypto_negotiated_params_, cached_network_params, std::move(cb));
+}
+
+QuicCryptoServerStream::SendServerConfigUpdateCallback::
+    SendServerConfigUpdateCallback(QuicCryptoServerStream* parent)
+    : parent_(parent) {}
+
+void QuicCryptoServerStream::SendServerConfigUpdateCallback::Cancel() {
+  parent_ = nullptr;
+}
+
+// From BuildServerConfigUpdateMessageResultCallback
+void QuicCryptoServerStream::SendServerConfigUpdateCallback::Run(
+    bool ok,
+    const CryptoHandshakeMessage& message) {
+  if (parent_ == nullptr) {
+    return;
+  }
+  parent_->FinishSendServerConfigUpdate(ok, message);
+}
+
+void QuicCryptoServerStream::FinishSendServerConfigUpdate(
+    bool ok,
+    const CryptoHandshakeMessage& message) {
+  // Clear the callback that got us here.
+  QUICHE_DCHECK(send_server_config_update_cb_ != nullptr);
+  send_server_config_update_cb_ = nullptr;
+
+  if (!ok) {
+    QUIC_DVLOG(1) << "Server: Failed to build server config update (SCUP)!";
+    return;
+  }
+
+  QUIC_DVLOG(1) << "Server: Sending server config update: "
+                << message.DebugString();
+
+  // Send server config update in ENCRYPTION_FORWARD_SECURE.
+  SendHandshakeMessage(message, ENCRYPTION_FORWARD_SECURE);
+
+  ++num_server_config_update_messages_sent_;
+}
+
+bool QuicCryptoServerStream::DisableResumption() {
+  QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
+  return false;
+}
+
+bool QuicCryptoServerStream::IsZeroRtt() const {
+  return num_handshake_messages_ == 1 &&
+         num_handshake_messages_with_server_nonces_ == 0;
+}
+
+bool QuicCryptoServerStream::IsResumption() const {
+  // QUIC Crypto doesn't have a non-0-RTT resumption mode.
+  return IsZeroRtt();
+}
+
+int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
+  return num_server_config_update_messages_sent_;
+}
+
+const CachedNetworkParameters*
+QuicCryptoServerStream::PreviousCachedNetworkParams() const {
+  return previous_cached_network_params_.get();
+}
+
+bool QuicCryptoServerStream::ResumptionAttempted() const {
+  return zero_rtt_attempted_;
+}
+
+bool QuicCryptoServerStream::EarlyDataAttempted() const {
+  QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
+  return zero_rtt_attempted_;
+}
+
+void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
+    CachedNetworkParameters cached_network_params) {
+  previous_cached_network_params_.reset(
+      new CachedNetworkParameters(cached_network_params));
+}
+
+void QuicCryptoServerStream::OnPacketDecrypted(EncryptionLevel level) {
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    one_rtt_packet_decrypted_ = true;
+    delegate_->NeuterHandshakeData();
+  }
+}
+
+void QuicCryptoServerStream::OnHandshakeDoneReceived() {
+  QUICHE_DCHECK(false);
+}
+
+void QuicCryptoServerStream::OnNewTokenReceived(absl::string_view /*token*/) {
+  QUICHE_DCHECK(false);
+}
+
+std::string QuicCryptoServerStream::GetAddressToken(
+    const CachedNetworkParameters* /*cached_network_parameters*/) const {
+  QUICHE_DCHECK(false);
+  return "";
+}
+
+bool QuicCryptoServerStream::ValidateAddressToken(
+    absl::string_view /*token*/) const {
+  QUICHE_DCHECK(false);
+  return false;
+}
+
+bool QuicCryptoServerStream::ShouldSendExpectCTHeader() const {
+  return signed_config_->proof.send_expect_ct_header;
+}
+
+bool QuicCryptoServerStream::DidCertMatchSni() const {
+  return signed_config_->proof.cert_matched_sni;
+}
+
+const ProofSource::Details* QuicCryptoServerStream::ProofSourceDetails() const {
+  return proof_source_details_.get();
+}
+
+bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID(
+    std::string* output) const {
+  if (!encryption_established() ||
+      crypto_negotiated_params_->channel_id.empty()) {
+    return false;
+  }
+
+  const std::string& channel_id(crypto_negotiated_params_->channel_id);
+  uint8_t digest[SHA256_DIGEST_LENGTH];
+  SHA256(reinterpret_cast<const uint8_t*>(channel_id.data()), channel_id.size(),
+         digest);
+
+  quiche::QuicheTextUtils::Base64Encode(digest, ABSL_ARRAYSIZE(digest), output);
+  return true;
+}
+
+ssl_early_data_reason_t QuicCryptoServerStream::EarlyDataReason() const {
+  if (IsZeroRtt()) {
+    return ssl_early_data_accepted;
+  }
+  if (zero_rtt_attempted_) {
+    return ssl_early_data_session_not_resumed;
+  }
+  return ssl_early_data_no_session_offered;
+}
+
+bool QuicCryptoServerStream::encryption_established() const {
+  return encryption_established_;
+}
+
+bool QuicCryptoServerStream::one_rtt_keys_available() const {
+  return one_rtt_keys_available_;
+}
+
+const QuicCryptoNegotiatedParameters&
+QuicCryptoServerStream::crypto_negotiated_params() const {
+  return *crypto_negotiated_params_;
+}
+
+CryptoMessageParser* QuicCryptoServerStream::crypto_message_parser() {
+  return QuicCryptoHandshaker::crypto_message_parser();
+}
+
+HandshakeState QuicCryptoServerStream::GetHandshakeState() const {
+  return one_rtt_packet_decrypted_ ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+}
+
+void QuicCryptoServerStream::SetServerApplicationStateForResumption(
+    std::unique_ptr<ApplicationState> /*state*/) {
+  // QUIC Crypto doesn't need to remember any application state as part of doing
+  // 0-RTT resumption, so this function is a no-op.
+}
+
+size_t QuicCryptoServerStream::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicCryptoServerStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  // Key update is only defined in QUIC+TLS.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+std::unique_ptr<QuicEncrypter>
+QuicCryptoServerStream::CreateCurrentOneRttEncrypter() {
+  // Key update is only defined in QUIC+TLS.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+void QuicCryptoServerStream::ProcessClientHello(
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        result,
+    std::unique_ptr<ProofSource::Details> proof_source_details,
+    std::unique_ptr<ProcessClientHelloResultCallback> done_cb) {
+  proof_source_details_ = std::move(proof_source_details);
+  const CryptoHandshakeMessage& message = result->client_hello;
+  std::string error_details;
+  if (!helper_->CanAcceptClientHello(
+          message, GetClientAddress(), session()->connection()->peer_address(),
+          session()->connection()->self_address(), &error_details)) {
+    done_cb->Run(QUIC_HANDSHAKE_FAILED, error_details, nullptr, nullptr,
+                 nullptr);
+    return;
+  }
+
+  absl::string_view user_agent_id;
+  message.GetStringPiece(quic::kUAID, &user_agent_id);
+  if (!session()->user_agent_id().has_value() && !user_agent_id.empty()) {
+    session()->SetUserAgentId(std::string(user_agent_id));
+  }
+
+  if (!result->info.server_nonce.empty()) {
+    ++num_handshake_messages_with_server_nonces_;
+  }
+
+  if (num_handshake_messages_ == 1) {
+    // Client attempts zero RTT handshake by sending a non-inchoate CHLO.
+    absl::string_view public_value;
+    zero_rtt_attempted_ = message.GetStringPiece(kPUBS, &public_value);
+  }
+
+  // Store the bandwidth estimate from the client.
+  if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) {
+    previous_cached_network_params_.reset(
+        new CachedNetworkParameters(result->cached_network_params));
+  }
+  previous_source_address_tokens_ = result->info.source_address_tokens;
+
+  QuicConnection* connection = session()->connection();
+  crypto_config_->ProcessClientHello(
+      result, /*reject_only=*/false, connection->connection_id(),
+      connection->self_address(), GetClientAddress(), connection->version(),
+      session()->supported_versions(), connection->clock(),
+      connection->random_generator(), compressed_certs_cache_,
+      crypto_negotiated_params_, signed_config_,
+      QuicCryptoStream::CryptoMessageFramingOverhead(
+          transport_version(), connection->connection_id()),
+      chlo_packet_size_, std::move(done_cb));
+}
+
+void QuicCryptoServerStream::OverrideQuicConfigDefaults(
+    QuicConfig* /*config*/) {}
+
+QuicCryptoServerStream::ValidateCallback::ValidateCallback(
+    QuicCryptoServerStream* parent)
+    : parent_(parent) {}
+
+void QuicCryptoServerStream::ValidateCallback::Cancel() {
+  parent_ = nullptr;
+}
+
+void QuicCryptoServerStream::ValidateCallback::Run(
+    quiche::QuicheReferenceCountedPointer<Result> result,
+    std::unique_ptr<ProofSource::Details> details) {
+  if (parent_ != nullptr) {
+    parent_->FinishProcessingHandshakeMessage(std::move(result),
+                                              std::move(details));
+  }
+}
+
+const QuicSocketAddress QuicCryptoServerStream::GetClientAddress() {
+  return session()->connection()->peer_address();
+}
+
+SSL* QuicCryptoServerStream::GetSsl() const { return nullptr; }
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_server_stream.h b/quiche/quic/core/quic_crypto_server_stream.h
new file mode 100644
index 0000000..c66b229
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream.h
@@ -0,0 +1,267 @@
+// 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_SERVER_STREAM_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
+
+#include <string>
+
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/proto/source_address_token_proto.h"
+#include "quiche/quic/core/quic_crypto_handshaker.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicCryptoServerStreamPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
+    : public QuicCryptoServerStreamBase,
+      public QuicCryptoHandshaker {
+ public:
+  QuicCryptoServerStream(const QuicCryptoServerStream&) = delete;
+  QuicCryptoServerStream& operator=(const QuicCryptoServerStream&) = delete;
+
+  ~QuicCryptoServerStream() override;
+
+  // From QuicCryptoServerStreamBase
+  void CancelOutstandingCallbacks() override;
+  bool GetBase64SHA256ClientChannelID(std::string* output) const override;
+  void SendServerConfigUpdate(
+      const CachedNetworkParameters* cached_network_params) override;
+  bool DisableResumption() override;
+  bool IsZeroRtt() const override;
+  bool IsResumption() const override;
+  bool ResumptionAttempted() const override;
+  bool EarlyDataAttempted() const override;
+  int NumServerConfigUpdateMessagesSent() const override;
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters cached_network_params) override;
+  void OnPacketDecrypted(EncryptionLevel level) override;
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override {}
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_params*/) const override;
+  bool ValidateAddressToken(absl::string_view token) const override;
+  bool ShouldSendExpectCTHeader() const override;
+  bool DidCertMatchSni() const override;
+  const ProofSource::Details* ProofSourceDetails() const override;
+
+  // From QuicCryptoStream
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  HandshakeState GetHandshakeState() const override;
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> state) override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  SSL* GetSsl() const override;
+
+  // From QuicCryptoHandshaker
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+
+ protected:
+  QUIC_EXPORT_PRIVATE friend std::unique_ptr<QuicCryptoServerStreamBase>
+  CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+                           QuicCompressedCertsCache* compressed_certs_cache,
+                           QuicSession* session,
+                           QuicCryptoServerStreamBase::Helper* helper);
+
+  // |crypto_config| must outlive the stream.
+  // |session| must outlive the stream.
+  // |helper| must outlive the stream.
+  QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+                         QuicCompressedCertsCache* compressed_certs_cache,
+                         QuicSession* session,
+                         QuicCryptoServerStreamBase::Helper* helper);
+
+  virtual void ProcessClientHello(
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          result,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      std::unique_ptr<ProcessClientHelloResultCallback> done_cb);
+
+  // Hook that allows the server to set QuicConfig defaults just
+  // before going through the parameter negotiation step.
+  virtual void OverrideQuicConfigDefaults(QuicConfig* config);
+
+  // Returns client address used to generate and validate source address token.
+  virtual const QuicSocketAddress GetClientAddress();
+
+  // Returns the QuicSession that this stream belongs to.
+  QuicSession* session() const { return session_; }
+
+  void set_encryption_established(bool encryption_established) {
+    encryption_established_ = encryption_established;
+  }
+
+  void set_one_rtt_keys_available(bool one_rtt_keys_available) {
+    one_rtt_keys_available_ = one_rtt_keys_available;
+  }
+
+ private:
+  friend class test::QuicCryptoServerStreamPeer;
+
+  class QUIC_EXPORT_PRIVATE ValidateCallback
+      : public ValidateClientHelloResultCallback {
+   public:
+    explicit ValidateCallback(QuicCryptoServerStream* parent);
+    ValidateCallback(const ValidateCallback&) = delete;
+    ValidateCallback& operator=(const ValidateCallback&) = delete;
+    // To allow the parent to detach itself from the callback before deletion.
+    void Cancel();
+
+    // From ValidateClientHelloResultCallback
+    void Run(quiche::QuicheReferenceCountedPointer<Result> result,
+             std::unique_ptr<ProofSource::Details> details) override;
+
+   private:
+    QuicCryptoServerStream* parent_;
+  };
+
+  class SendServerConfigUpdateCallback
+      : public BuildServerConfigUpdateMessageResultCallback {
+   public:
+    explicit SendServerConfigUpdateCallback(QuicCryptoServerStream* parent);
+    SendServerConfigUpdateCallback(const SendServerConfigUpdateCallback&) =
+        delete;
+    void operator=(const SendServerConfigUpdateCallback&) = delete;
+
+    // To allow the parent to detach itself from the callback before deletion.
+    void Cancel();
+
+    // From BuildServerConfigUpdateMessageResultCallback
+    void Run(bool ok, const CryptoHandshakeMessage& message) override;
+
+   private:
+    QuicCryptoServerStream* parent_;
+  };
+
+  // Invoked by ValidateCallback::RunImpl once initial validation of
+  // the client hello is complete.  Finishes processing of the client
+  // hello message and handles handshake success/failure.
+  void FinishProcessingHandshakeMessage(
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          result,
+      std::unique_ptr<ProofSource::Details> details);
+
+  class ProcessClientHelloCallback;
+  friend class ProcessClientHelloCallback;
+
+  // Portion of FinishProcessingHandshakeMessage which executes after
+  // ProcessClientHello has been called.
+  void FinishProcessingHandshakeMessageAfterProcessClientHello(
+      const ValidateClientHelloResultCallback::Result& result,
+      QuicErrorCode error,
+      const std::string& error_details,
+      std::unique_ptr<CryptoHandshakeMessage> reply,
+      std::unique_ptr<DiversificationNonce> diversification_nonce,
+      std::unique_ptr<ProofSource::Details> proof_source_details);
+
+  // Invoked by SendServerConfigUpdateCallback::RunImpl once the proof has been
+  // received.  |ok| indicates whether or not the proof was successfully
+  // acquired, and |message| holds the partially-constructed message from
+  // SendServerConfigUpdate.
+  void FinishSendServerConfigUpdate(bool ok,
+                                    const CryptoHandshakeMessage& message);
+
+  // Returns the QuicTransportVersion of the connection.
+  QuicTransportVersion transport_version() const {
+    return session_->transport_version();
+  }
+
+  QuicSession* session_;
+  HandshakerDelegateInterface* delegate_;
+
+  // crypto_config_ contains crypto parameters for the handshake.
+  const QuicCryptoServerConfig* crypto_config_;
+
+  // compressed_certs_cache_ contains a set of most recently compressed certs.
+  // Owned by QuicDispatcher.
+  QuicCompressedCertsCache* compressed_certs_cache_;
+
+  // Server's certificate chain and signature of the server config, as provided
+  // by ProofSource::GetProof.
+  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
+
+  // Hash of the last received CHLO message which can be used for generating
+  // server config update messages.
+  std::string chlo_hash_;
+
+  // Pointer to the helper for this crypto stream. Must outlive this stream.
+  QuicCryptoServerStreamBase::Helper* helper_;
+
+  // Number of handshake messages received by this stream.
+  uint8_t num_handshake_messages_;
+
+  // Number of handshake messages received by this stream that contain
+  // server nonces (indicating that this is a non-zero-RTT handshake
+  // attempt).
+  uint8_t num_handshake_messages_with_server_nonces_;
+
+  // Pointer to the active callback that will receive the result of
+  // BuildServerConfigUpdateMessage and forward it to
+  // FinishSendServerConfigUpdate.  nullptr if no update message is currently
+  // being built.
+  SendServerConfigUpdateCallback* send_server_config_update_cb_;
+
+  // Number of server config update (SCUP) messages sent by this stream.
+  int num_server_config_update_messages_sent_;
+
+  // If the client provides CachedNetworkParameters in the STK in the CHLO, then
+  // store here, and send back in future STKs if we have no better bandwidth
+  // estimate to send.
+  std::unique_ptr<CachedNetworkParameters> previous_cached_network_params_;
+
+  // Contains any source address tokens which were present in the CHLO.
+  SourceAddressTokens previous_source_address_tokens_;
+
+  // True if client attempts 0-rtt handshake (which can succeed or fail).
+  bool zero_rtt_attempted_;
+
+  // Size of the packet containing the most recently received CHLO.
+  QuicByteCount chlo_packet_size_;
+
+  // Pointer to the active callback that will receive the result of the client
+  // hello validation request and forward it to FinishProcessingHandshakeMessage
+  // for processing.  nullptr if no handshake message is being validated.  Note
+  // that this field is mutually exclusive with process_client_hello_cb_.
+  ValidateCallback* validate_client_hello_cb_;
+
+  // Pointer to the active callback which will receive the results of
+  // ProcessClientHello and forward it to
+  // FinishProcessingHandshakeMessageAfterProcessClientHello.  Note that this
+  // field is mutually exclusive with validate_client_hello_cb_.
+  ProcessClientHelloCallback* process_client_hello_cb_;
+
+  // The ProofSource::Details from this connection.
+  std::unique_ptr<ProofSource::Details> proof_source_details_;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  bool one_rtt_packet_decrypted_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      crypto_negotiated_params_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
diff --git a/quiche/quic/core/quic_crypto_server_stream_base.cc b/quiche/quic/core/quic_crypto_server_stream_base.cc
new file mode 100644
index 0000000..7cff108
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream_base.cc
@@ -0,0 +1,51 @@
+// 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 "quiche/quic/core/quic_crypto_server_stream_base.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_crypto_server_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/tls_server_handshaker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicCryptoServerStreamBase::QuicCryptoServerStreamBase(QuicSession* session)
+    : QuicCryptoStream(session) {}
+
+std::unique_ptr<QuicCryptoServerStreamBase> CreateCryptoServerStream(
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    QuicSession* session,
+    QuicCryptoServerStreamBase::Helper* helper) {
+  switch (session->connection()->version().handshake_protocol) {
+    case PROTOCOL_QUIC_CRYPTO:
+      return std::unique_ptr<QuicCryptoServerStream>(new QuicCryptoServerStream(
+          crypto_config, compressed_certs_cache, session, helper));
+    case PROTOCOL_TLS1_3:
+      return std::unique_ptr<TlsServerHandshaker>(
+          new TlsServerHandshaker(session, crypto_config));
+    case PROTOCOL_UNSUPPORTED:
+      break;
+  }
+  QUIC_BUG(quic_bug_10492_1)
+      << "Unknown handshake protocol: "
+      << static_cast<int>(session->connection()->version().handshake_protocol);
+  return nullptr;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_server_stream_base.h b/quiche/quic/core/quic_crypto_server_stream_base.h
new file mode 100644
index 0000000..84d6190
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream_base.h
@@ -0,0 +1,122 @@
+// 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_SERVER_STREAM_BASE_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_crypto_handshaker.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class CachedNetworkParameters;
+class CryptoHandshakeMessage;
+class QuicCryptoServerConfig;
+class QuicCryptoServerStreamBase;
+
+// TODO(alyssar) see what can be moved out of QuicCryptoServerStream with
+// various code and test refactoring.
+class QUIC_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
+ public:
+  explicit QuicCryptoServerStreamBase(QuicSession* session);
+
+  class QUIC_EXPORT_PRIVATE Helper {
+   public:
+    virtual ~Helper() {}
+
+    // Returns true if |message|, which was received on |self_address| is
+    // acceptable according to the visitor's policy. Otherwise, returns false
+    // and populates |error_details|.
+    virtual bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
+                                      const QuicSocketAddress& client_address,
+                                      const QuicSocketAddress& peer_address,
+                                      const QuicSocketAddress& self_address,
+                                      std::string* error_details) const = 0;
+  };
+
+  ~QuicCryptoServerStreamBase() override {}
+
+  // Cancel any outstanding callbacks, such as asynchronous validation of client
+  // hello.
+  virtual void CancelOutstandingCallbacks() = 0;
+
+  // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded,
+  // SHA-256 hash of the client's ChannelID key and returns true, if the client
+  // presented a ChannelID. Otherwise it returns false.
+  virtual bool GetBase64SHA256ClientChannelID(std::string* output) const = 0;
+
+  virtual int NumServerConfigUpdateMessagesSent() const = 0;
+
+  // Sends the latest server config and source-address token to the client.
+  virtual void SendServerConfigUpdate(
+      const CachedNetworkParameters* cached_network_params) = 0;
+
+  // Disables TLS resumption, should be called as early as possible.
+  // Return true if resumption is disabled.
+  // Return false if nothing happened, typically it means it is called too late.
+  virtual bool DisableResumption() = 0;
+
+  // Returns true if the connection was a successful 0-RTT resumption.
+  virtual bool IsZeroRtt() const = 0;
+
+  // Returns true if the connection was the result of a resumption handshake,
+  // whether 0-RTT or not.
+  virtual bool IsResumption() const = 0;
+
+  // Returns true if the client attempted a resumption handshake, whether or not
+  // the resumption actually occurred.
+  virtual bool ResumptionAttempted() const = 0;
+
+  // Returns true if the client attempted to use early data, as indicated by the
+  // "early_data" TLS extension. TLS only.
+  virtual bool EarlyDataAttempted() const = 0;
+
+  // NOTE: Indicating that the Expect-CT header should be sent here presents
+  // a layering violation to some extent. The Expect-CT header only applies to
+  // HTTP connections, while this class can be used for non-HTTP applications.
+  // However, it is exposed here because that is the only place where the
+  // configuration for the certificate used in the connection is accessible.
+  virtual bool ShouldSendExpectCTHeader() const = 0;
+
+  // Return true if a cert was picked that matched the SNI hostname.
+  virtual bool DidCertMatchSni() const = 0;
+
+  // Returns the Details from the latest call to ProofSource::GetProof or
+  // ProofSource::ComputeTlsSignature. Returns nullptr if no such call has been
+  // made. The Details are owned by the QuicCryptoServerStreamBase and the
+  // pointer is only valid while the owning object is still valid.
+  virtual const ProofSource::Details* ProofSourceDetails() const = 0;
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+};
+
+// Creates an appropriate QuicCryptoServerStream for the provided parameters,
+// including the version used by |session|. |crypto_config|, |session|, and
+// |helper| must all outlive the stream. The caller takes ownership of the
+// returned object.
+QUIC_EXPORT_PRIVATE std::unique_ptr<QuicCryptoServerStreamBase>
+CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+                         QuicCompressedCertsCache* compressed_certs_cache,
+                         QuicSession* session,
+                         QuicCryptoServerStreamBase::Helper* helper);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
diff --git a/quiche/quic/core/quic_crypto_server_stream_test.cc b/quiche/quic/core/quic_crypto_server_stream_test.cc
new file mode 100644
index 0000000..649f340
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream_test.cc
@@ -0,0 +1,400 @@
+// 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 "quiche/quic/core/quic_crypto_server_stream_base.h"
+
+#include <map>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/failing_proof_source.h"
+#include "quiche/quic/test_tools/fake_proof_source.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+class QuicConnection;
+class QuicStream;
+}  // namespace quic
+
+using testing::_;
+using testing::NiceMock;
+
+namespace quic {
+namespace test {
+
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kServerPort = 443;
+
+// This test tests the server-side of the QUIC crypto handshake. It does not
+// test the TLS handshake - that is in tls_server_handshaker_test.cc.
+class QuicCryptoServerStreamTest : public QuicTest {
+ public:
+  QuicCryptoServerStreamTest()
+      : QuicCryptoServerStreamTest(crypto_test_utils::ProofSourceForTesting()) {
+  }
+
+  explicit QuicCryptoServerStreamTest(std::unique_ptr<ProofSource> proof_source)
+      : server_crypto_config_(QuicCryptoServerConfig::TESTING,
+                              QuicRandom::GetInstance(),
+                              std::move(proof_source),
+                              KeyExchangeSource::Default()),
+        server_compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+        server_id_(kServerHostname, kServerPort, false),
+        client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
+
+  void Initialize() { InitializeServer(); }
+
+  ~QuicCryptoServerStreamTest() override {
+    // Ensure that anything that might reference |helpers_| is destroyed before
+    // |helpers_| is destroyed.
+    server_session_.reset();
+    client_session_.reset();
+    helpers_.clear();
+    alarm_factories_.clear();
+  }
+
+  // Initializes the crypto server stream state for testing.  May be
+  // called multiple times.
+  void InitializeServer() {
+    TestQuicSpdyServerSession* server_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateServerSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        &server_crypto_config_, &server_compressed_certs_cache_,
+        &server_connection_, &server_session);
+    QUICHE_CHECK(server_session);
+    server_session_.reset(server_session);
+    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*server_session_, SelectAlpn(_))
+        .WillRepeatedly(
+            [this](const std::vector<absl::string_view>& alpns) {
+              return std::find(
+                  alpns.cbegin(), alpns.cend(),
+                  AlpnForVersion(server_session_->connection()->version()));
+            });
+    crypto_test_utils::SetupCryptoServerConfigForTest(
+        server_connection_->clock(), server_connection_->random_generator(),
+        &server_crypto_config_);
+  }
+
+  QuicCryptoServerStreamBase* server_stream() {
+    return server_session_->GetMutableCryptoStream();
+  }
+
+  QuicCryptoClientStream* client_stream() {
+    return client_session_->GetMutableCryptoStream();
+  }
+
+  // Initializes a fake client, and all its associated state, for
+  // testing.  May be called multiple times.
+  void InitializeFakeClient() {
+    TestQuicSpdyClientSession* client_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateClientSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        &client_crypto_config_, &client_connection_, &client_session);
+    QUICHE_CHECK(client_session);
+    client_session_.reset(client_session);
+  }
+
+  int CompleteCryptoHandshake() {
+    QUICHE_CHECK(server_connection_);
+    QUICHE_CHECK(server_session_ != nullptr);
+
+    return crypto_test_utils::HandshakeWithFakeClient(
+        helpers_.back().get(), alarm_factories_.back().get(),
+        server_connection_, server_stream(), server_id_, client_options_,
+        /*alpn=*/"");
+  }
+
+  // Performs a single round of handshake message-exchange between the
+  // client and server.
+  void AdvanceHandshakeWithFakeClient() {
+    QUICHE_CHECK(server_connection_);
+    QUICHE_CHECK(client_session_ != nullptr);
+
+    EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
+    EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    client_stream()->CryptoConnect();
+    crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 0,
+                                        server_connection_, server_stream(), 0);
+  }
+
+ protected:
+  // Every connection gets its own MockQuicConnectionHelper and
+  // MockAlarmFactory, tracked separately from the server and client state so
+  // their lifetimes persist through the whole test.
+  std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
+  std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
+
+  // Server state.
+  PacketSavingConnection* server_connection_;
+  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
+  QuicCryptoServerConfig server_crypto_config_;
+  QuicCompressedCertsCache server_compressed_certs_cache_;
+  QuicServerId server_id_;
+
+  // Client state.
+  PacketSavingConnection* client_connection_;
+  QuicCryptoClientConfig client_crypto_config_;
+  std::unique_ptr<TestQuicSpdyClientSession> client_session_;
+
+  CryptoHandshakeMessage message_;
+  crypto_test_utils::FakeClientOptions client_options_;
+
+  // Which QUIC versions the client and server support.
+  ParsedQuicVersionVector supported_versions_ =
+      AllSupportedVersionsWithQuicCrypto();
+};
+
+TEST_F(QuicCryptoServerStreamTest, NotInitiallyConected) {
+  Initialize();
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_F(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
+  // CompleteCryptoHandshake returns the number of client hellos sent. This
+  // test should send:
+  //   * One to get a source-address token and certificates.
+  //   * One to complete the handshake.
+  Initialize();
+  EXPECT_EQ(2, CompleteCryptoHandshake());
+  EXPECT_TRUE(server_stream()->encryption_established());
+  EXPECT_TRUE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_F(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) {
+  Initialize();
+  InitializeFakeClient();
+
+  // Do a first handshake in order to prime the client config with the server's
+  // information.
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+
+  // Now do another handshake, with the blocking SHLO connection option.
+  InitializeServer();
+  InitializeFakeClient();
+
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_TRUE(server_stream()->encryption_established());
+  EXPECT_TRUE(server_stream()->one_rtt_keys_available());
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE,
+            server_session_->connection()->encryption_level());
+}
+
+TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
+  Initialize();
+  InitializeFakeClient();
+
+  // Do a first handshake in order to prime the client config with the server's
+  // information.
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_stream()->ResumptionAttempted());
+
+  // Now do another handshake, hopefully in 0-RTT.
+  QUIC_LOG(INFO) << "Resetting for 0-RTT handshake attempt";
+  InitializeFakeClient();
+  InitializeServer();
+
+  EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
+  EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
+      .Times(testing::AnyNumber());
+  EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
+  client_stream()->CryptoConnect();
+
+  EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
+  EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
+      .Times(testing::AnyNumber());
+  EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
+  crypto_test_utils::CommunicateHandshakeMessages(
+      client_connection_, client_stream(), server_connection_, server_stream());
+
+  EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
+  EXPECT_TRUE(server_stream()->ResumptionAttempted());
+}
+
+TEST_F(QuicCryptoServerStreamTest, FailByPolicy) {
+  Initialize();
+  InitializeFakeClient();
+
+  EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  AdvanceHandshakeWithFakeClient();
+}
+
+TEST_F(QuicCryptoServerStreamTest, MessageAfterHandshake) {
+  Initialize();
+  CompleteCryptoHandshake();
+  EXPECT_CALL(
+      *server_connection_,
+      CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
+  message_.set_tag(kCHLO);
+  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
+                                                  Perspective::IS_CLIENT);
+}
+
+TEST_F(QuicCryptoServerStreamTest, BadMessageType) {
+  Initialize();
+
+  message_.set_tag(kSHLO);
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, _, _));
+  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
+                                                  Perspective::IS_SERVER);
+}
+
+TEST_F(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) {
+  // An attempt to send a SCUP before completing handshake should fail.
+  Initialize();
+
+  server_stream()->SendServerConfigUpdate(nullptr);
+  EXPECT_EQ(0, server_stream()->NumServerConfigUpdateMessagesSent());
+}
+
+TEST_F(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) {
+  Initialize();
+
+  InitializeFakeClient();
+
+  // Do a first handshake in order to prime the client config with the server's
+  // information.
+  AdvanceHandshakeWithFakeClient();
+
+  // Now do another handshake, with the blocking SHLO connection option.
+  InitializeServer();
+  InitializeFakeClient();
+  AdvanceHandshakeWithFakeClient();
+
+  // Send a SCUP message and ensure that the client was able to verify it.
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  server_stream()->SendServerConfigUpdate(nullptr);
+  crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 1,
+                                      server_connection_, server_stream(), 1);
+
+  EXPECT_EQ(1, server_stream()->NumServerConfigUpdateMessagesSent());
+  EXPECT_EQ(1, client_stream()->num_scup_messages_received());
+}
+
+class QuicCryptoServerStreamTestWithFailingProofSource
+    : public QuicCryptoServerStreamTest {
+ public:
+  QuicCryptoServerStreamTestWithFailingProofSource()
+      : QuicCryptoServerStreamTest(
+            std::unique_ptr<FailingProofSource>(new FailingProofSource)) {}
+};
+
+TEST_F(QuicCryptoServerStreamTestWithFailingProofSource, Test) {
+  Initialize();
+  InitializeFakeClient();
+
+  EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+      .WillOnce(testing::Return(true));
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to get proof", _));
+  // Regression test for b/31521252, in which a crash would happen here.
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+class QuicCryptoServerStreamTestWithFakeProofSource
+    : public QuicCryptoServerStreamTest {
+ public:
+  QuicCryptoServerStreamTestWithFakeProofSource()
+      : QuicCryptoServerStreamTest(
+            std::unique_ptr<FakeProofSource>(new FakeProofSource)),
+        crypto_config_peer_(&server_crypto_config_) {}
+
+  FakeProofSource* GetFakeProofSource() const {
+    return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
+  }
+
+ protected:
+  QuicCryptoServerConfigPeer crypto_config_peer_;
+};
+
+// Regression test for b/35422225, in which multiple CHLOs arriving on the same
+// connection in close succession could cause a crash.
+TEST_F(QuicCryptoServerStreamTestWithFakeProofSource, MultipleChlo) {
+  Initialize();
+  GetFakeProofSource()->Activate();
+  EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+      .WillOnce(testing::Return(true));
+
+  // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
+  // first one from the list of supported versions.
+  QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      transport_version = version.transport_version;
+      break;
+    }
+  }
+  ASSERT_NE(QUIC_VERSION_UNSUPPORTED, transport_version);
+
+  // Create a minimal CHLO
+  MockClock clock;
+  CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
+      &clock, transport_version, &server_crypto_config_);
+
+  // Send in the CHLO, and check that a callback is now pending in the
+  // ProofSource.
+  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
+                                                  Perspective::IS_CLIENT);
+  EXPECT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
+
+  // Send in a second CHLO while processing of the first is still pending.
+  // Verify that the server closes the connection rather than crashing.  Note
+  // that the crash is a use-after-free, so it may only show up consistently in
+  // ASAN tests.
+  EXPECT_CALL(
+      *server_connection_,
+      CloseConnection(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
+                      "Unexpected handshake message while processing CHLO", _));
+  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
+                                                  Perspective::IS_CLIENT);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_stream.cc b/quiche/quic/core/quic_crypto_stream.cc
new file mode 100644
index 0000000..1f442de
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_stream.cc
@@ -0,0 +1,482 @@
+// 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 "quiche/quic/core/quic_crypto_stream.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+#define ENDPOINT                                                   \
+  (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
+                                                      : "Client:"  \
+                                                        " ")
+
+QuicCryptoStream::QuicCryptoStream(QuicSession* session)
+    : QuicStream(
+          QuicVersionUsesCryptoFrames(session->transport_version())
+              ? QuicUtils::GetInvalidStreamId(session->transport_version())
+              : QuicUtils::GetCryptoStreamId(session->transport_version()),
+          session,
+          /*is_static=*/true,
+          QuicVersionUsesCryptoFrames(session->transport_version())
+              ? CRYPTO
+              : BIDIRECTIONAL),
+      substreams_{{{this, ENCRYPTION_INITIAL},
+                   {this, ENCRYPTION_HANDSHAKE},
+                   {this, ENCRYPTION_ZERO_RTT},
+                   {this, ENCRYPTION_FORWARD_SECURE}}} {
+  // The crypto stream is exempt from connection level flow control.
+  DisableConnectionFlowControlForThisStream();
+}
+
+QuicCryptoStream::~QuicCryptoStream() {}
+
+// static
+QuicByteCount QuicCryptoStream::CryptoMessageFramingOverhead(
+    QuicTransportVersion version,
+    QuicConnectionId connection_id) {
+  QUICHE_DCHECK(
+      QuicUtils::IsConnectionIdValidForVersion(connection_id, version));
+  QuicVariableLengthIntegerLength retry_token_length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_1;
+  QuicVariableLengthIntegerLength length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  if (!QuicVersionHasLongHeaderLengths(version)) {
+    retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  return QuicPacketCreator::StreamFramePacketOverhead(
+      version, static_cast<QuicConnectionIdLength>(connection_id.length()),
+      PACKET_0BYTE_CONNECTION_ID,
+      /*include_version=*/true,
+      /*include_diversification_nonce=*/true,
+      VersionHasIetfInvariantHeader(version) ? PACKET_4BYTE_PACKET_NUMBER
+                                             : PACKET_1BYTE_PACKET_NUMBER,
+      retry_token_length_length, length_length,
+      /*offset=*/0);
+}
+
+void QuicCryptoStream::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12573_1,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 shouldn't receive CRYPTO frames";
+  EncryptionLevel level = session()->connection()->last_decrypted_level();
+  substreams_[level].sequencer.OnCryptoFrame(frame);
+  EncryptionLevel frame_level = level;
+  if (substreams_[level].sequencer.NumBytesBuffered() >
+      BufferSizeLimitForLevel(frame_level)) {
+    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                         "Too much crypto data received");
+  }
+}
+
+void QuicCryptoStream::OnStreamFrame(const QuicStreamFrame& frame) {
+  if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    QUIC_PEER_BUG(quic_peer_bug_12573_2)
+        << "Crypto data received in stream frame instead of crypto frame";
+    OnUnrecoverableError(QUIC_INVALID_STREAM_DATA, "Unexpected stream frame");
+  }
+  QuicStream::OnStreamFrame(frame);
+}
+
+void QuicCryptoStream::OnDataAvailable() {
+  EncryptionLevel level = session()->connection()->last_decrypted_level();
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    // Versions less than 47 only support QUIC crypto, which ignores the
+    // EncryptionLevel passed into CryptoMessageParser::ProcessInput (and
+    // OnDataAvailableInSequencer).
+    OnDataAvailableInSequencer(sequencer(), level);
+    return;
+  }
+  OnDataAvailableInSequencer(&substreams_[level].sequencer, level);
+}
+
+void QuicCryptoStream::OnDataAvailableInSequencer(
+    QuicStreamSequencer* sequencer,
+    EncryptionLevel level) {
+  struct iovec iov;
+  while (sequencer->GetReadableRegion(&iov)) {
+    absl::string_view data(static_cast<char*>(iov.iov_base), iov.iov_len);
+    if (!crypto_message_parser()->ProcessInput(data, level)) {
+      OnUnrecoverableError(crypto_message_parser()->error(),
+                           crypto_message_parser()->error_detail());
+      return;
+    }
+    sequencer->MarkConsumed(iov.iov_len);
+    if (one_rtt_keys_available() &&
+        crypto_message_parser()->InputBytesRemaining() == 0) {
+      // If the handshake is complete and the current message has been fully
+      // processed then no more handshake messages are likely to arrive soon
+      // so release the memory in the stream sequencer.
+      sequencer->ReleaseBufferIfEmpty();
+    }
+  }
+}
+
+void QuicCryptoStream::WriteCryptoData(EncryptionLevel level,
+                                       absl::string_view data) {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    WriteOrBufferDataAtLevel(data, /*fin=*/false, level,
+                             /*ack_listener=*/nullptr);
+    return;
+  }
+  if (data.empty()) {
+    QUIC_BUG(quic_bug_10322_1) << "Empty crypto data being written";
+    return;
+  }
+  const bool had_buffered_data = HasBufferedCryptoFrames();
+  // Append |data| to the send buffer for this encryption level.
+  QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+  QuicStreamOffset offset = send_buffer->stream_offset();
+  send_buffer->SaveStreamData(data);
+  if (kMaxStreamLength - offset < data.length()) {
+    QUIC_BUG(quic_bug_10322_2) << "Writing too much crypto handshake data";
+    // TODO(nharper): Switch this to an IETF QUIC error code, possibly
+    // INTERNAL_ERROR?
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Writing too much crypto handshake data");
+  }
+  if (had_buffered_data) {
+    // Do not try to write if there is buffered data.
+    return;
+  }
+
+  size_t bytes_consumed = stream_delegate()->SendCryptoData(
+      level, data.length(), offset, NOT_RETRANSMISSION);
+  send_buffer->OnStreamDataConsumed(bytes_consumed);
+}
+
+size_t QuicCryptoStream::BufferSizeLimitForLevel(EncryptionLevel) const {
+  return GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes);
+}
+
+bool QuicCryptoStream::OnCryptoFrameAcked(const QuicCryptoFrame& frame,
+                                          QuicTime::Delta /*ack_delay_time*/) {
+  QuicByteCount newly_acked_length = 0;
+  if (!substreams_[frame.level].send_buffer.OnStreamDataAcked(
+          frame.offset, frame.data_length, &newly_acked_length)) {
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         "Trying to ack unsent crypto data.");
+    return false;
+  }
+  return newly_acked_length > 0;
+}
+
+void QuicCryptoStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
+                                   "Attempt to reset crypto stream");
+}
+
+void QuicCryptoStream::NeuterUnencryptedStreamData() {
+  NeuterStreamDataOfEncryptionLevel(ENCRYPTION_INITIAL);
+}
+
+void QuicCryptoStream::NeuterStreamDataOfEncryptionLevel(
+    EncryptionLevel level) {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    for (const auto& interval : bytes_consumed_[level]) {
+      QuicByteCount newly_acked_length = 0;
+      send_buffer().OnStreamDataAcked(
+          interval.min(), interval.max() - interval.min(), &newly_acked_length);
+    }
+    return;
+  }
+  QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+  // TODO(nharper): Consider adding a Clear() method to QuicStreamSendBuffer to
+  // replace the following code.
+  QuicIntervalSet<QuicStreamOffset> to_ack = send_buffer->bytes_acked();
+  to_ack.Complement(0, send_buffer->stream_offset());
+  for (const auto& interval : to_ack) {
+    QuicByteCount newly_acked_length = 0;
+    send_buffer->OnStreamDataAcked(
+        interval.min(), interval.max() - interval.min(), &newly_acked_length);
+  }
+}
+
+void QuicCryptoStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
+  if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    QUIC_BUG(quic_bug_10322_3)
+        << "Stream data consumed when CRYPTO frames should be in use";
+  }
+  if (bytes_consumed > 0) {
+    bytes_consumed_[session()->connection()->encryption_level()].Add(
+        stream_bytes_written(), stream_bytes_written() + bytes_consumed);
+  }
+  QuicStream::OnStreamDataConsumed(bytes_consumed);
+}
+
+namespace {
+
+constexpr std::array<EncryptionLevel, NUM_ENCRYPTION_LEVELS>
+AllEncryptionLevels() {
+  return {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
+          ENCRYPTION_FORWARD_SECURE};
+}
+
+}  // namespace
+
+bool QuicCryptoStream::HasPendingCryptoRetransmission() const {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    return false;
+  }
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    if (substreams_[level].send_buffer.HasPendingRetransmission()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicCryptoStream::WritePendingCryptoRetransmission() {
+  QUIC_BUG_IF(quic_bug_12573_3,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't write CRYPTO frames";
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+    while (send_buffer->HasPendingRetransmission()) {
+      auto pending = send_buffer->NextPendingRetransmission();
+      size_t bytes_consumed = stream_delegate()->SendCryptoData(
+          level, pending.length, pending.offset, HANDSHAKE_RETRANSMISSION);
+      send_buffer->OnStreamDataRetransmitted(pending.offset, bytes_consumed);
+      if (bytes_consumed < pending.length) {
+        return;
+      }
+    }
+  }
+}
+
+void QuicCryptoStream::WritePendingRetransmission() {
+  while (HasPendingRetransmission()) {
+    StreamPendingRetransmission pending =
+        send_buffer().NextPendingRetransmission();
+    QuicIntervalSet<QuicStreamOffset> retransmission(
+        pending.offset, pending.offset + pending.length);
+    EncryptionLevel retransmission_encryption_level = ENCRYPTION_INITIAL;
+    // Determine the encryption level to write the retransmission
+    // at. The retransmission should be written at the same encryption level
+    // as the original transmission.
+    for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
+      if (retransmission.Intersects(bytes_consumed_[i])) {
+        retransmission_encryption_level = static_cast<EncryptionLevel>(i);
+        retransmission.Intersection(bytes_consumed_[i]);
+        break;
+      }
+    }
+    pending.offset = retransmission.begin()->min();
+    pending.length =
+        retransmission.begin()->max() - retransmission.begin()->min();
+    QuicConsumedData consumed = RetransmitStreamDataAtLevel(
+        pending.offset, pending.length, retransmission_encryption_level,
+        HANDSHAKE_RETRANSMISSION);
+    if (consumed.bytes_consumed < pending.length) {
+      // The connection is write blocked.
+      break;
+    }
+  }
+}
+
+bool QuicCryptoStream::RetransmitStreamData(QuicStreamOffset offset,
+                                            QuicByteCount data_length,
+                                            bool /*fin*/,
+                                            TransmissionType type) {
+  QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
+  QuicIntervalSet<QuicStreamOffset> retransmission(offset,
+                                                   offset + data_length);
+  // Determine the encryption level to send data. This only needs to be once as
+  // [offset, offset + data_length) is guaranteed to be in the same packet.
+  EncryptionLevel send_encryption_level = ENCRYPTION_INITIAL;
+  for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    if (retransmission.Intersects(bytes_consumed_[i])) {
+      send_encryption_level = static_cast<EncryptionLevel>(i);
+      break;
+    }
+  }
+  retransmission.Difference(bytes_acked());
+  for (const auto& interval : retransmission) {
+    QuicStreamOffset retransmission_offset = interval.min();
+    QuicByteCount retransmission_length = interval.max() - interval.min();
+    QuicConsumedData consumed = RetransmitStreamDataAtLevel(
+        retransmission_offset, retransmission_length, send_encryption_level,
+        type);
+    if (consumed.bytes_consumed < retransmission_length) {
+      // The connection is write blocked.
+      return false;
+    }
+  }
+
+  return true;
+}
+
+QuicConsumedData QuicCryptoStream::RetransmitStreamDataAtLevel(
+    QuicStreamOffset retransmission_offset,
+    QuicByteCount retransmission_length,
+    EncryptionLevel encryption_level,
+    TransmissionType type) {
+  QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
+  const auto consumed = stream_delegate()->WritevData(
+      id(), retransmission_length, retransmission_offset, NO_FIN, type,
+      encryption_level);
+  QUIC_DVLOG(1) << ENDPOINT << "stream " << id()
+                << " is forced to retransmit stream data ["
+                << retransmission_offset << ", "
+                << retransmission_offset + retransmission_length
+                << "), with encryption level: " << encryption_level
+                << ", consumed: " << consumed;
+  OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
+                             consumed.fin_consumed);
+
+  return consumed;
+}
+
+uint64_t QuicCryptoStream::crypto_bytes_read() const {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    return stream_bytes_read();
+  }
+  uint64_t bytes_read = 0;
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    bytes_read += substreams_[level].sequencer.NumBytesConsumed();
+  }
+  return bytes_read;
+}
+
+uint64_t QuicCryptoStream::BytesReadOnLevel(EncryptionLevel level) const {
+  return substreams_[level].sequencer.NumBytesConsumed();
+}
+
+bool QuicCryptoStream::WriteCryptoFrame(EncryptionLevel level,
+                                        QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        QuicDataWriter* writer) {
+  QUIC_BUG_IF(quic_bug_12573_4,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't write CRYPTO frames (2)";
+  return substreams_[level].send_buffer.WriteStreamData(offset, data_length,
+                                                        writer);
+}
+
+void QuicCryptoStream::OnCryptoFrameLost(QuicCryptoFrame* crypto_frame) {
+  QUIC_BUG_IF(quic_bug_12573_5,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't lose CRYPTO frames";
+  substreams_[crypto_frame->level].send_buffer.OnStreamDataLost(
+      crypto_frame->offset, crypto_frame->data_length);
+}
+
+bool QuicCryptoStream::RetransmitData(QuicCryptoFrame* crypto_frame,
+                                      TransmissionType type) {
+  QUIC_BUG_IF(quic_bug_12573_6,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't retransmit CRYPTO frames";
+  QuicIntervalSet<QuicStreamOffset> retransmission(
+      crypto_frame->offset, crypto_frame->offset + crypto_frame->data_length);
+  QuicStreamSendBuffer* send_buffer =
+      &substreams_[crypto_frame->level].send_buffer;
+  retransmission.Difference(send_buffer->bytes_acked());
+  if (retransmission.Empty()) {
+    return true;
+  }
+  for (const auto& interval : retransmission) {
+    size_t retransmission_offset = interval.min();
+    size_t retransmission_length = interval.max() - interval.min();
+    size_t bytes_consumed = stream_delegate()->SendCryptoData(
+        crypto_frame->level, retransmission_length, retransmission_offset,
+        type);
+    send_buffer->OnStreamDataRetransmitted(retransmission_offset,
+                                           bytes_consumed);
+    if (bytes_consumed < retransmission_length) {
+      return false;
+    }
+  }
+  return true;
+}
+
+void QuicCryptoStream::WriteBufferedCryptoFrames() {
+  QUIC_BUG_IF(quic_bug_12573_7,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't use CRYPTO frames";
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+    const size_t data_length =
+        send_buffer->stream_offset() - send_buffer->stream_bytes_written();
+    if (data_length == 0) {
+      // No buffered data for this encryption level.
+      continue;
+    }
+    size_t bytes_consumed = stream_delegate()->SendCryptoData(
+        level, data_length, send_buffer->stream_bytes_written(),
+        NOT_RETRANSMISSION);
+    send_buffer->OnStreamDataConsumed(bytes_consumed);
+    if (bytes_consumed < data_length) {
+      // Connection is write blocked.
+      break;
+    }
+  }
+}
+
+bool QuicCryptoStream::HasBufferedCryptoFrames() const {
+  QUIC_BUG_IF(quic_bug_12573_8,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't use CRYPTO frames";
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    const QuicStreamSendBuffer& send_buffer = substreams_[level].send_buffer;
+    QUICHE_DCHECK_GE(send_buffer.stream_offset(),
+                     send_buffer.stream_bytes_written());
+    if (send_buffer.stream_offset() > send_buffer.stream_bytes_written()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicCryptoStream::IsFrameOutstanding(EncryptionLevel level,
+                                          size_t offset,
+                                          size_t length) const {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    // This only happens if a client was originally configured for a version
+    // greater than 45, but received a version negotiation packet and is
+    // attempting to retransmit for a version less than 47. Outside of tests,
+    // this is a misconfiguration of the client, and this connection will be
+    // doomed. Return false here to avoid trying to retransmit CRYPTO frames on
+    // the wrong transport version.
+    return false;
+  }
+  return substreams_[level].send_buffer.IsStreamDataOutstanding(offset, length);
+}
+
+bool QuicCryptoStream::IsWaitingForAcks() const {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    return QuicStream::IsWaitingForAcks();
+  }
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    if (substreams_[level].send_buffer.stream_bytes_outstanding()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+QuicCryptoStream::CryptoSubstream::CryptoSubstream(
+    QuicCryptoStream* crypto_stream,
+    EncryptionLevel)
+    : sequencer(crypto_stream),
+      send_buffer(crypto_stream->session()
+                      ->connection()
+                      ->helper()
+                      ->GetStreamSendBufferAllocator()) {}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_stream.h b/quiche/quic/core/quic_crypto_stream.h
new file mode 100644
index 0000000..64031b2
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_stream.h
@@ -0,0 +1,274 @@
+// 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 <array>
+#include <cstddef>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class CachedNetworkParameters;
+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);
+
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+  // 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. This
+  // method is only supported for IETF QUIC and MUST NOT be called in gQUIC as
+  // that'll trigger an assert in DEBUG build.
+  virtual bool ExportKeyingMaterial(absl::string_view label,
+                                    absl::string_view context,
+                                    size_t result_len, std::string* result) = 0;
+
+  // Writes |data| to the QuicStream at level |level|.
+  virtual void WriteCryptoData(EncryptionLevel level, absl::string_view data);
+
+  // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
+  // rejected. Note that the value returned by this function may vary during the
+  // handshake. Once |one_rtt_keys_available| returns true, the value returned
+  // by this function will not change for the rest of the lifetime of the
+  // QuicCryptoStream.
+  virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
+
+  // 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 one_rtt_keys_available() 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 a packet of encryption |level| has been successfully decrypted.
+  virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
+
+  // Called when a 1RTT packet has been acknowledged.
+  virtual void OnOneRttPacketAcknowledged() = 0;
+
+  // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
+  virtual void OnHandshakePacketSent() = 0;
+
+  // Called when a handshake done frame has been received.
+  virtual void OnHandshakeDoneReceived() = 0;
+
+  // Called when a new token frame has been received.
+  virtual void OnNewTokenReceived(absl::string_view token) = 0;
+
+  // Called to get an address token.
+  virtual std::string GetAddressToken(
+      const CachedNetworkParameters* cached_network_params) const = 0;
+
+  // Called to validate |token|.
+  virtual bool ValidateAddressToken(absl::string_view token) const = 0;
+
+  // Get the last CachedNetworkParameters received from a valid address token.
+  virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
+      const = 0;
+
+  // Set the CachedNetworkParameters that will be returned by
+  // PreviousCachedNetworkParams.
+  // TODO(wub): This function is test only, move it to a test only library.
+  virtual void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters cached_network_params) = 0;
+
+  // Returns current handshake state.
+  virtual HandshakeState GetHandshakeState() const = 0;
+
+  // Called to provide the server-side application state that must be checked
+  // when performing a 0-RTT TLS resumption.
+  //
+  // On a client, this may be called at any time; 0-RTT tickets will not be
+  // cached until this function is called. When a 0-RTT resumption is attempted,
+  // QuicSession::SetApplicationState will be called with the state provided by
+  // a call to this function on a previous connection.
+  //
+  // On a server, this function must be called before commencing the handshake,
+  // otherwise 0-RTT tickets will not be issued. On subsequent connections,
+  // 0-RTT will be rejected if the data passed into this function does not match
+  // the data passed in on the connection where the 0-RTT ticket was issued.
+  virtual void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> state) = 0;
+
+  // Returns the maximum number of bytes that can be buffered at a particular
+  // encryption level |level|.
+  virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
+
+  // Called to generate a decrypter for the next key phase. Each call should
+  // generate the key for phase n+1.
+  virtual std::unique_ptr<QuicDecrypter>
+  AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
+
+  // Called to generate an encrypter for the same key phase of the last
+  // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
+  virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
+
+  // Return the SSL struct object created by BoringSSL if the stream is using
+  // TLS1.3. Otherwise, return nullptr.
+  // This method is used in Envoy.
+  virtual SSL* GetSsl() const = 0;
+
+  // Called to cancel retransmission of unencrypted crypto stream data.
+  void NeuterUnencryptedStreamData();
+
+  // Called to cancel retransmission of data of encryption |level|.
+  void NeuterStreamDataOfEncryptionLevel(EncryptionLevel level);
+
+  // Override to record the encryption level of consumed data.
+  void OnStreamDataConsumed(QuicByteCount bytes_consumed) override;
+
+  // Returns whether there are any bytes pending retransmission in CRYPTO
+  // frames.
+  virtual bool HasPendingCryptoRetransmission() const;
+
+  // 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,
+                            TransmissionType type) override;
+
+  // Sends stream retransmission data at |encryption_level|.
+  QuicConsumedData RetransmitStreamDataAtLevel(
+      QuicStreamOffset retransmission_offset,
+      QuicByteCount retransmission_length,
+      EncryptionLevel encryption_level,
+      TransmissionType type);
+
+  // 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|. Returns true if all
+  // data gets retransmitted.
+  bool RetransmitData(QuicCryptoFrame* crypto_frame, TransmissionType type);
+
+  // Called to write buffered crypto frames.
+  void WriteBufferedCryptoFrames();
+
+  // Returns true if there is buffered crypto frames.
+  bool HasBufferedCryptoFrames() const;
+
+  // 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;
+
+  // Helper method for OnDataAvailable. Calls CryptoMessageParser::ProcessInput
+  // with the data available in |sequencer| and |level|, and marks the data
+  // passed to ProcessInput as consumed.
+  virtual void OnDataAvailableInSequencer(QuicStreamSequencer* sequencer,
+                                          EncryptionLevel level);
+
+  QuicStreamSequencer* GetStreamSequencerForLevel(EncryptionLevel level) {
+    return &substreams_[level].sequencer;
+  }
+
+ 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 QUIC_EXPORT_PRIVATE CryptoSubstream {
+    CryptoSubstream(QuicCryptoStream* crypto_stream, EncryptionLevel);
+
+    QuicStreamSequencer sequencer;
+    QuicStreamSendBuffer send_buffer;
+  };
+
+  // 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.
+  std::array<CryptoSubstream, NUM_ENCRYPTION_LEVELS> substreams_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
diff --git a/quiche/quic/core/quic_crypto_stream_test.cc b/quiche/quic/core/quic_crypto_stream_test.cc
new file mode 100644
index 0000000..4b298c3
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_stream_test.cc
@@ -0,0 +1,722 @@
+// 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 "quiche/quic/core/quic_crypto_stream.h"
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::Return;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockQuicCryptoStream : public QuicCryptoStream,
+                             public QuicCryptoHandshaker {
+ public:
+  explicit MockQuicCryptoStream(QuicSession* session)
+      : QuicCryptoStream(session),
+        QuicCryptoHandshaker(this, session),
+        params_(new QuicCryptoNegotiatedParameters) {}
+  MockQuicCryptoStream(const MockQuicCryptoStream&) = delete;
+  MockQuicCryptoStream& operator=(const MockQuicCryptoStream&) = delete;
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+    messages_.push_back(message);
+  }
+
+  std::vector<CryptoHandshakeMessage>* messages() { return &messages_; }
+
+  ssl_early_data_reason_t EarlyDataReason() const override {
+    return ssl_early_data_unknown;
+  }
+  bool encryption_established() const override { return false; }
+  bool one_rtt_keys_available() const override { return false; }
+
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override {
+    return *params_;
+  }
+  CryptoMessageParser* crypto_message_parser() override {
+    return QuicCryptoHandshaker::crypto_message_parser();
+  }
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_parameters*/)
+      const override {
+    return "";
+  }
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    return true;
+  }
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    return nullptr;
+  }
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {}
+  HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    return false;
+  }
+  SSL* GetSsl() const override { return nullptr; }
+
+ private:
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+  std::vector<CryptoHandshakeMessage> messages_;
+};
+
+class QuicCryptoStreamTest : public QuicTest {
+ public:
+  QuicCryptoStreamTest()
+      : connection_(new MockQuicConnection(&helper_,
+                                           &alarm_factory_,
+                                           Perspective::IS_CLIENT)),
+        session_(connection_, /*create_mock_crypto_stream=*/false) {
+    EXPECT_CALL(*static_cast<MockPacketWriter*>(connection_->writer()),
+                WritePacket(_, _, _, _, _))
+        .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
+    stream_ = new MockQuicCryptoStream(&session_);
+    session_.SetCryptoStream(stream_);
+    session_.Initialize();
+    message_.set_tag(kSHLO);
+    message_.SetStringPiece(1, "abc");
+    message_.SetStringPiece(2, "def");
+    ConstructHandshakeMessage();
+  }
+  QuicCryptoStreamTest(const QuicCryptoStreamTest&) = delete;
+  QuicCryptoStreamTest& operator=(const QuicCryptoStreamTest&) = delete;
+
+  void ConstructHandshakeMessage() {
+    CryptoFramer framer;
+    message_data_ = framer.ConstructHandshakeMessage(message_);
+  }
+
+ protected:
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  MockQuicSpdySession session_;
+  MockQuicCryptoStream* stream_;
+  CryptoHandshakeMessage message_;
+  std::unique_ptr<QuicData> message_data_;
+};
+
+TEST_F(QuicCryptoStreamTest, NotInitiallyConected) {
+  EXPECT_FALSE(stream_->encryption_established());
+  EXPECT_FALSE(stream_->one_rtt_keys_available());
+}
+
+TEST_F(QuicCryptoStreamTest, ProcessRawData) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    stream_->OnStreamFrame(QuicStreamFrame(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+        /*fin=*/false,
+        /*offset=*/0, message_data_->AsStringPiece()));
+  } else {
+    stream_->OnCryptoFrame(QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0,
+                                           message_data_->AsStringPiece()));
+  }
+  ASSERT_EQ(1u, stream_->messages()->size());
+  const CryptoHandshakeMessage& message = (*stream_->messages())[0];
+  EXPECT_EQ(kSHLO, message.tag());
+  EXPECT_EQ(2u, message.tag_value_map().size());
+  EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1));
+  EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, 2));
+}
+
+TEST_F(QuicCryptoStreamTest, ProcessBadData) {
+  std::string bad(message_data_->data(), message_data_->length());
+  const int kFirstTagIndex = sizeof(uint32_t) +  // message tag
+                             sizeof(uint16_t) +  // number of tag-value pairs
+                             sizeof(uint16_t);   // padding
+  EXPECT_EQ(1, bad[kFirstTagIndex]);
+  bad[kFirstTagIndex] = 0x7F;  // out of order tag
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_CRYPTO_TAGS_OUT_OF_ORDER,
+                                            testing::_, testing::_));
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    stream_->OnStreamFrame(QuicStreamFrame(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+        /*fin=*/false, /*offset=*/0, bad));
+  } else {
+    stream_->OnCryptoFrame(
+        QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0, bad));
+  }
+}
+
+TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) {
+  EXPECT_FALSE(
+      QuicStreamPeer::StreamContributesToConnectionFlowControl(stream_));
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Lost [0, 1000).
+  stream_->OnStreamFrameLost(0, 1000, false);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  // Lost [1200, 2000).
+  stream_->OnStreamFrameLost(1200, 800, false);
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1000, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
+  // they are in different encryption levels.
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 150, 1200, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 650, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->OnCanWrite();
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  std::unique_ptr<NullEncrypter> encrypter =
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
+  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+  connection_->SetEncrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Lost [0, 1000).
+  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Lost [1200, 2000).
+  lost_frame = QuicCryptoFrame(ENCRYPTION_INITIAL, 1200, 150);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
+  // they are in different encryption levels.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 150, 1200))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WritePendingCryptoRetransmission();
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+}
+
+// Regression test for handling the missing ENCRYPTION_HANDSHAKE in
+// quic_crypto_stream.cc. This test is essentially the same as
+// RetransmitCryptoDataInCryptoFrames, except it uses ENCRYPTION_HANDSHAKE in
+// place of ENCRYPTION_ZERO_RTT.
+TEST_F(QuicCryptoStreamTest, RetransmitEncryptionHandshakeLevelCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  InSequence s;
+  // Send [0, 1000) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1000, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  // Send [1000, 2000) in ENCRYPTION_HANDSHAKE.
+  std::unique_ptr<NullEncrypter> encrypter =
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
+  connection_->SetEncrypter(ENCRYPTION_HANDSHAKE, std::move(encrypter));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(ENCRYPTION_HANDSHAKE, connection_->encryption_level());
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 1000, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_HANDSHAKE, data);
+  connection_->SetEncrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Lost [1000, 1200).
+  QuicCryptoFrame lost_frame(ENCRYPTION_HANDSHAKE, 0, 200);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Verify [1000, 1200) is sent.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 200, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WritePendingCryptoRetransmission();
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+}
+
+TEST_F(QuicCryptoStreamTest, NeuterUnencryptedStreamData) {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+
+  // Lost [0, 1350).
+  stream_->OnStreamFrameLost(0, 1350, false);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  // Neuters [0, 1350).
+  stream_->NeuterUnencryptedStreamData();
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  // Lost [0, 1350) again.
+  stream_->OnStreamFrameLost(0, 1350, false);
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+
+  // Lost [1350, 2000).
+  stream_->OnStreamFrameLost(1350, 650, false);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  stream_->NeuterUnencryptedStreamData();
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+}
+
+TEST_F(QuicCryptoStreamTest, NeuterUnencryptedCryptoData) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  connection_->SetEncrypter(
+      ENCRYPTION_ZERO_RTT,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  std::unique_ptr<NullEncrypter> encrypter =
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
+  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+
+  // Lost [0, 1350).
+  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1350);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Neuters [0, 1350).
+  stream_->NeuterUnencryptedStreamData();
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+  // Lost [0, 1350) again.
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+
+  // Lost [1350, 2000), which starts at offset 0 at the ENCRYPTION_ZERO_RTT
+  // level.
+  lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  stream_->NeuterUnencryptedStreamData();
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Ack [2000, 2500).
+  QuicByteCount newly_acked_length = 0;
+  stream_->OnStreamFrameAcked(2000, 500, false, QuicTime::Delta::Zero(),
+                              QuicTime::Zero(), &newly_acked_length);
+  EXPECT_EQ(500u, newly_acked_length);
+
+  // Force crypto stream to send [1350, 2700) and only [1350, 1500) is consumed.
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 650, 1350, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_.ConsumeData(
+            QuicUtils::GetCryptoStreamId(connection_->transport_version()), 150,
+            1350, NO_FIN, HANDSHAKE_RETRANSMISSION, absl::nullopt);
+      }));
+
+  EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false,
+                                             HANDSHAKE_RETRANSMISSION));
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Force session to send [1350, 1500) again and all data is consumed.
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 650, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 200, 2500, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  EXPECT_TRUE(stream_->RetransmitStreamData(1350, 1350, false,
+                                            HANDSHAKE_RETRANSMISSION));
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
+  // Force to send an empty frame.
+  EXPECT_TRUE(
+      stream_->RetransmitStreamData(0, 0, false, HANDSHAKE_RETRANSMISSION));
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitStreamDataWithCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  std::unique_ptr<NullEncrypter> encrypter =
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
+  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+  connection_->SetEncrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Ack [2000, 2500).
+  QuicCryptoFrame acked_frame(ENCRYPTION_ZERO_RTT, 650, 500);
+  EXPECT_TRUE(
+      stream_->OnCryptoFrameAcked(acked_frame, QuicTime::Delta::Zero()));
+
+  // Retransmit only [1350, 1500).
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 150, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  QuicCryptoFrame frame_to_retransmit(ENCRYPTION_ZERO_RTT, 0, 150);
+  stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);
+
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Retransmit [1350, 2700) again and all data is sent.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 200, 1150))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  frame_to_retransmit = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 1350);
+  stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  // Force to send an empty frame.
+  QuicCryptoFrame empty_frame(ENCRYPTION_FORWARD_SECURE, 0, 0);
+  stream_->RetransmitData(&empty_frame, HANDSHAKE_RETRANSMISSION);
+}
+
+// Regression test for b/115926584.
+TEST_F(QuicCryptoStreamTest, HasUnackedCryptoData) {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  std::string data(1350, 'a');
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(testing::Return(QuicConsumedData(0, false)));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  // Although there is no outstanding data, verify session has pending crypto
+  // data.
+  EXPECT_TRUE(session_.HasUnackedCryptoData());
+
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->OnCanWrite();
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_.HasUnackedCryptoData());
+}
+
+TEST_F(QuicCryptoStreamTest, HasUnackedCryptoDataWithCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_.HasUnackedCryptoData());
+}
+
+// Regression test for bugfix of GetPacketHeaderSize.
+TEST_F(QuicCryptoStreamTest, CryptoMessageFramingOverhead) {
+  for (const ParsedQuicVersion& version :
+       AllSupportedVersionsWithQuicCrypto()) {
+    SCOPED_TRACE(version);
+    QuicByteCount expected_overhead = 48;
+    if (version.HasIetfInvariantHeader()) {
+      expected_overhead += 4;
+    }
+    if (version.HasLongHeaderLengths()) {
+      expected_overhead += 3;
+    }
+    if (version.HasLengthPrefixedConnectionIds()) {
+      expected_overhead += 1;
+    }
+    EXPECT_EQ(expected_overhead,
+              QuicCryptoStream::CryptoMessageFramingOverhead(
+                  version.transport_version, TestConnectionId()));
+  }
+}
+
+TEST_F(QuicCryptoStreamTest, WriteBufferedCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  // Only consumed 1000 bytes.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Return(1000));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
+
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT and verify no write is attempted
+  // because there is buffered data.
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  connection_->SetEncrypter(
+      ENCRYPTION_ZERO_RTT,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
+      .WillOnce(Return(350));
+  // Partial write of ENCRYPTION_ZERO_RTT data.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Return(1000));
+  stream_->WriteBufferedCryptoFrames();
+  EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 350, 1000))
+      .WillOnce(Return(350));
+  stream_->WriteBufferedCryptoFrames();
+  EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
+}
+
+TEST_F(QuicCryptoStreamTest, LimitBufferedCryptoData) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  std::string large_frame(2 * GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes),
+                          'a');
+
+  // Set offset to 1 so that we guarantee the data gets buffered instead of
+  // immediately processed.
+  QuicStreamOffset offset = 1;
+  stream_->OnCryptoFrame(
+      QuicCryptoFrame(ENCRYPTION_INITIAL, offset, large_frame));
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitCryptoFramesAndPartialWrite) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+
+  // Lost [0, 1000).
+  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Simulate connection is constrained by amplification restriction.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+      .WillOnce(Return(0));
+  stream_->WritePendingCryptoRetransmission();
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Connection gets unblocked.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WritePendingCryptoRetransmission();
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+}
+
+// Regression test for b/203199510
+TEST_F(QuicCryptoStreamTest, EmptyCryptoFrame) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  QuicCryptoFrame empty_crypto_frame(ENCRYPTION_INITIAL, 0, nullptr, 0);
+  stream_->OnCryptoFrame(empty_crypto_frame);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_data_reader.cc b/quiche/quic/core/quic_data_reader.cc
new file mode 100644
index 0000000..e82c598
--- /dev/null
+++ b/quiche/quic/core/quic_data_reader.cc
@@ -0,0 +1,176 @@
+// 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 "quiche/quic/core/quic_data_reader.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+QuicDataReader::QuicDataReader(absl::string_view data)
+    : quiche::QuicheDataReader(data) {}
+
+QuicDataReader::QuicDataReader(const char* data, const size_t len)
+    : QuicDataReader(data, len, quiche::NETWORK_BYTE_ORDER) {}
+
+QuicDataReader::QuicDataReader(const char* data,
+                               const size_t len,
+                               quiche::Endianness endianness)
+    : quiche::QuicheDataReader(data, len, endianness) {}
+
+bool QuicDataReader::ReadUFloat16(uint64_t* result) {
+  uint16_t value;
+  if (!ReadUInt16(&value)) {
+    return false;
+  }
+
+  *result = value;
+  if (*result < (1 << kUFloat16MantissaEffectiveBits)) {
+    // Fast path: either the value is denormalized (no hidden bit), or
+    // normalized (hidden bit set, exponent offset by one) with exponent zero.
+    // Zero exponent offset by one sets the bit exactly where the hidden bit is.
+    // So in both cases the value encodes itself.
+    return true;
+  }
+
+  uint16_t exponent =
+      value >> kUFloat16MantissaBits;  // No sign extend on uint!
+  // After the fast pass, the exponent is at least one (offset by one).
+  // Un-offset the exponent.
+  --exponent;
+  QUICHE_DCHECK_GE(exponent, 1);
+  QUICHE_DCHECK_LE(exponent, kUFloat16MaxExponent);
+  // Here we need to clear the exponent and set the hidden bit. We have already
+  // decremented the exponent, so when we subtract it, it leaves behind the
+  // hidden bit.
+  *result -= exponent << kUFloat16MantissaBits;
+  *result <<= exponent;
+  QUICHE_DCHECK_GE(*result,
+                   static_cast<uint64_t>(1 << kUFloat16MantissaEffectiveBits));
+  QUICHE_DCHECK_LE(*result, kUFloat16MaxValue);
+  return true;
+}
+
+bool QuicDataReader::ReadConnectionId(QuicConnectionId* connection_id,
+                                      uint8_t length) {
+  if (length == 0) {
+    connection_id->set_length(0);
+    return true;
+  }
+
+  if (BytesRemaining() < length) {
+    return false;
+  }
+
+  connection_id->set_length(length);
+  const bool ok =
+      ReadBytes(connection_id->mutable_data(), connection_id->length());
+  QUICHE_DCHECK(ok);
+  return ok;
+}
+
+bool QuicDataReader::ReadLengthPrefixedConnectionId(
+    QuicConnectionId* connection_id) {
+  uint8_t connection_id_length;
+  if (!ReadUInt8(&connection_id_length)) {
+    return false;
+  }
+  return ReadConnectionId(connection_id, connection_id_length);
+}
+
+QuicVariableLengthIntegerLength QuicDataReader::PeekVarInt62Length() {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+  const unsigned char* next =
+      reinterpret_cast<const unsigned char*>(data() + pos());
+  if (BytesRemaining() == 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  return static_cast<QuicVariableLengthIntegerLength>(
+      1 << ((*next & 0b11000000) >> 6));
+}
+
+// Read an IETF/QUIC formatted 62-bit Variable Length Integer.
+//
+// Performance notes
+//
+// Measurements and experiments showed that unrolling the four cases
+// like this and dereferencing next_ as we do (*(next_+n) --- and then
+// doing a single pos_+=x at the end) gains about 10% over making a
+// loop and dereferencing next_ such as *(next_++)
+//
+// Using a register for pos_ was not helpful.
+//
+// Branches are ordered to increase the likelihood of the first being
+// taken.
+//
+// Low-level optimization is useful here because this function will be
+// called frequently, leading to outsize benefits.
+bool QuicDataReader::ReadVarInt62(uint64_t* result) {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+
+  size_t remaining = BytesRemaining();
+  const unsigned char* next =
+      reinterpret_cast<const unsigned char*>(data() + pos());
+  if (remaining != 0) {
+    switch (*next & 0xc0) {
+      case 0xc0:
+        // Leading 0b11...... is 8 byte encoding
+        if (remaining >= 8) {
+          *result = (static_cast<uint64_t>((*(next)) & 0x3f) << 56) +
+                    (static_cast<uint64_t>(*(next + 1)) << 48) +
+                    (static_cast<uint64_t>(*(next + 2)) << 40) +
+                    (static_cast<uint64_t>(*(next + 3)) << 32) +
+                    (static_cast<uint64_t>(*(next + 4)) << 24) +
+                    (static_cast<uint64_t>(*(next + 5)) << 16) +
+                    (static_cast<uint64_t>(*(next + 6)) << 8) +
+                    (static_cast<uint64_t>(*(next + 7)) << 0);
+          AdvancePos(8);
+          return true;
+        }
+        return false;
+
+      case 0x80:
+        // Leading 0b10...... is 4 byte encoding
+        if (remaining >= 4) {
+          *result = (((*(next)) & 0x3f) << 24) + (((*(next + 1)) << 16)) +
+                    (((*(next + 2)) << 8)) + (((*(next + 3)) << 0));
+          AdvancePos(4);
+          return true;
+        }
+        return false;
+
+      case 0x40:
+        // Leading 0b01...... is 2 byte encoding
+        if (remaining >= 2) {
+          *result = (((*(next)) & 0x3f) << 8) + (*(next + 1));
+          AdvancePos(2);
+          return true;
+        }
+        return false;
+
+      case 0x00:
+        // Leading 0b00...... is 1 byte encoding
+        *result = (*next) & 0x3f;
+        AdvancePos(1);
+        return true;
+    }
+  }
+  return false;
+}
+
+bool QuicDataReader::ReadStringPieceVarInt62(absl::string_view* result) {
+  uint64_t result_length;
+  if (!ReadVarInt62(&result_length)) {
+    return false;
+  }
+  return ReadStringPiece(result, result_length);
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_data_reader.h b/quiche/quic/core/quic_data_reader.h
new file mode 100644
index 0000000..c21f2be
--- /dev/null
+++ b/quiche/quic/core/quic_data_reader.h
@@ -0,0 +1,93 @@
+// 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_DATA_READER_H_
+#define QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_data_reader.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+// Used for reading QUIC data. Though there isn't really anything terribly
+// QUIC-specific here, it's a helper class that's useful when doing QUIC
+// framing.
+//
+// To use, simply construct a QuicDataReader using the underlying buffer that
+// you'd like to read fields from, then call one of the Read*() methods to
+// actually do some reading.
+//
+// This class keeps an internal iterator to keep track of what's already been
+// read and each successive Read*() call automatically increments said iterator
+// on success. On failure, internal state of the QuicDataReader should not be
+// trusted and it is up to the caller to throw away the failed instance and
+// handle the error as appropriate. None of the Read*() methods should ever be
+// called after failure, as they will also fail immediately.
+class QUIC_EXPORT_PRIVATE QuicDataReader : public quiche::QuicheDataReader {
+ public:
+  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
+  // Caller must provide an underlying buffer to work on.
+  explicit QuicDataReader(absl::string_view data);
+  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
+  // Caller must provide an underlying buffer to work on.
+  QuicDataReader(const char* data, const size_t len);
+  // Constructs a reader using the specified endianness.
+  // Caller must provide an underlying buffer to work on.
+  QuicDataReader(const char* data,
+                 const size_t len,
+                 quiche::Endianness endianness);
+  QuicDataReader(const QuicDataReader&) = delete;
+  QuicDataReader& operator=(const QuicDataReader&) = delete;
+
+  // Empty destructor.
+  ~QuicDataReader() {}
+
+  // Reads a 16-bit unsigned float into the given output parameter.
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadUFloat16(uint64_t* result);
+
+  // Reads connection ID into the given output parameter.
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadConnectionId(QuicConnectionId* connection_id, uint8_t length);
+
+  // Reads 8-bit connection ID length followed by connection ID of that length.
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadLengthPrefixedConnectionId(QuicConnectionId* connection_id);
+
+  // Returns the length in bytes of a variable length integer based on the next
+  // two bits available. Returns 1, 2, 4, or 8 on success, and 0 on failure.
+  QuicVariableLengthIntegerLength PeekVarInt62Length();
+
+  // Read an IETF-encoded Variable Length Integer and place the result
+  // in |*result|.
+  // Returns true if it works, false if not. The only error is that
+  // there is not enough in the buffer to read the number.
+  // If there is an error, |*result| is not altered.
+  // Numbers are encoded per the rules in draft-ietf-quic-transport-10.txt
+  // and that the integers in the range 0 ... (2^62)-1.
+  bool ReadVarInt62(uint64_t* result);
+
+  // Reads a string prefixed with a Variable Length integer length into the
+  // given output parameter.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadStringPieceVarInt62(absl::string_view* result);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
diff --git a/quiche/quic/core/quic_data_writer.cc b/quiche/quic/core/quic_data_writer.cc
new file mode 100644
index 0000000..571d2b0
--- /dev/null
+++ b/quiche/quic/core/quic_data_writer.cc
@@ -0,0 +1,260 @@
+// 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 "quiche/quic/core/quic_data_writer.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+QuicDataWriter::QuicDataWriter(size_t size, char* buffer)
+    : quiche::QuicheDataWriter(size, buffer) {}
+
+QuicDataWriter::QuicDataWriter(size_t size,
+                               char* buffer,
+                               quiche::Endianness endianness)
+    : quiche::QuicheDataWriter(size, buffer, endianness) {}
+
+QuicDataWriter::~QuicDataWriter() {}
+
+bool QuicDataWriter::WriteUFloat16(uint64_t value) {
+  uint16_t result;
+  if (value < (UINT64_C(1) << kUFloat16MantissaEffectiveBits)) {
+    // Fast path: either the value is denormalized, or has exponent zero.
+    // Both cases are represented by the value itself.
+    result = static_cast<uint16_t>(value);
+  } else if (value >= kUFloat16MaxValue) {
+    // Value is out of range; clamp it to the maximum representable.
+    result = std::numeric_limits<uint16_t>::max();
+  } else {
+    // The highest bit is between position 13 and 42 (zero-based), which
+    // corresponds to exponent 1-30. In the output, mantissa is from 0 to 10,
+    // hidden bit is 11 and exponent is 11 to 15. Shift the highest bit to 11
+    // and count the shifts.
+    uint16_t exponent = 0;
+    for (uint16_t offset = 16; offset > 0; offset /= 2) {
+      // Right-shift the value until the highest bit is in position 11.
+      // For offset of 16, 8, 4, 2 and 1 (binary search over 1-30),
+      // shift if the bit is at or above 11 + offset.
+      if (value >= (UINT64_C(1) << (kUFloat16MantissaBits + offset))) {
+        exponent += offset;
+        value >>= offset;
+      }
+    }
+
+    QUICHE_DCHECK_GE(exponent, 1);
+    QUICHE_DCHECK_LE(exponent, kUFloat16MaxExponent);
+    QUICHE_DCHECK_GE(value, UINT64_C(1) << kUFloat16MantissaBits);
+    QUICHE_DCHECK_LT(value, UINT64_C(1) << kUFloat16MantissaEffectiveBits);
+
+    // Hidden bit (position 11) is set. We should remove it and increment the
+    // exponent. Equivalently, we just add it to the exponent.
+    // This hides the bit.
+    result = static_cast<uint16_t>(value + (exponent << kUFloat16MantissaBits));
+  }
+
+  if (endianness() == quiche::NETWORK_BYTE_ORDER) {
+    result = quiche::QuicheEndian::HostToNet16(result);
+  }
+  return WriteBytes(&result, sizeof(result));
+}
+
+bool QuicDataWriter::WriteConnectionId(QuicConnectionId connection_id) {
+  if (connection_id.IsEmpty()) {
+    return true;
+  }
+  return WriteBytes(connection_id.data(), connection_id.length());
+}
+
+bool QuicDataWriter::WriteLengthPrefixedConnectionId(
+    QuicConnectionId connection_id) {
+  return WriteUInt8(connection_id.length()) && WriteConnectionId(connection_id);
+}
+
+bool QuicDataWriter::WriteRandomBytes(QuicRandom* random, size_t length) {
+  char* dest = BeginWrite(length);
+  if (!dest) {
+    return false;
+  }
+
+  random->RandBytes(dest, length);
+  IncreaseLength(length);
+  return true;
+}
+
+bool QuicDataWriter::WriteInsecureRandomBytes(QuicRandom* random,
+                                              size_t length) {
+  char* dest = BeginWrite(length);
+  if (!dest) {
+    return false;
+  }
+
+  random->InsecureRandBytes(dest, length);
+  IncreaseLength(length);
+  return true;
+}
+
+// Converts a uint64_t into an IETF/Quic formatted Variable Length
+// Integer. IETF Variable Length Integers have 62 significant bits, so
+// the value to write must be in the range of 0..(2^62)-1.
+//
+// Performance notes
+//
+// Measurements and experiments showed that unrolling the four cases
+// like this and dereferencing next_ as we do (*(next_+n)) gains about
+// 10% over making a loop and dereferencing it as *(next_++)
+//
+// Using a register for next didn't help.
+//
+// Branches are ordered to increase the likelihood of the first being
+// taken.
+//
+// Low-level optimization is useful here because this function will be
+// called frequently, leading to outsize benefits.
+bool QuicDataWriter::WriteVarInt62(uint64_t value) {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+
+  size_t remaining_bytes = remaining();
+  char* next = buffer() + length();
+
+  if ((value & kVarInt62ErrorMask) == 0) {
+    // We know the high 2 bits are 0 so |value| is legal.
+    // We can do the encoding.
+    if ((value & kVarInt62Mask8Bytes) != 0) {
+      // Someplace in the high-4 bytes is a 1-bit. Do an 8-byte
+      // encoding.
+      if (remaining_bytes >= 8) {
+        *(next + 0) = ((value >> 56) & 0x3f) + 0xc0;
+        *(next + 1) = (value >> 48) & 0xff;
+        *(next + 2) = (value >> 40) & 0xff;
+        *(next + 3) = (value >> 32) & 0xff;
+        *(next + 4) = (value >> 24) & 0xff;
+        *(next + 5) = (value >> 16) & 0xff;
+        *(next + 6) = (value >> 8) & 0xff;
+        *(next + 7) = value & 0xff;
+        IncreaseLength(8);
+        return true;
+      }
+      return false;
+    }
+    // The high-order-4 bytes are all 0, check for a 1, 2, or 4-byte
+    // encoding
+    if ((value & kVarInt62Mask4Bytes) != 0) {
+      // The encoding will not fit into 2 bytes, Do a 4-byte
+      // encoding.
+      if (remaining_bytes >= 4) {
+        *(next + 0) = ((value >> 24) & 0x3f) + 0x80;
+        *(next + 1) = (value >> 16) & 0xff;
+        *(next + 2) = (value >> 8) & 0xff;
+        *(next + 3) = value & 0xff;
+        IncreaseLength(4);
+        return true;
+      }
+      return false;
+    }
+    // The high-order bits are all 0. Check to see if the number
+    // can be encoded as one or two bytes. One byte encoding has
+    // only 6 significant bits (bits 0xffffffff ffffffc0 are all 0).
+    // Two byte encoding has more than 6, but 14 or less significant
+    // bits (bits 0xffffffff ffffc000 are 0 and 0x00000000 00003fc0
+    // are not 0)
+    if ((value & kVarInt62Mask2Bytes) != 0) {
+      // Do 2-byte encoding
+      if (remaining_bytes >= 2) {
+        *(next + 0) = ((value >> 8) & 0x3f) + 0x40;
+        *(next + 1) = (value)&0xff;
+        IncreaseLength(2);
+        return true;
+      }
+      return false;
+    }
+    if (remaining_bytes >= 1) {
+      // Do 1-byte encoding
+      *next = (value & 0x3f);
+      IncreaseLength(1);
+      return true;
+    }
+    return false;
+  }
+  // Can not encode, high 2 bits not 0
+  return false;
+}
+
+bool QuicDataWriter::WriteVarInt62(
+    uint64_t value,
+    QuicVariableLengthIntegerLength write_length) {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+
+  size_t remaining_bytes = remaining();
+  if (remaining_bytes < write_length) {
+    return false;
+  }
+
+  const QuicVariableLengthIntegerLength min_length = GetVarInt62Len(value);
+  if (write_length < min_length) {
+    QUIC_BUG(quic_bug_10347_1) << "Cannot write value " << value
+                               << " with write_length " << write_length;
+    return false;
+  }
+  if (write_length == min_length) {
+    return WriteVarInt62(value);
+  }
+
+  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_2) {
+    return WriteUInt8(0b01000000) && WriteUInt8(value);
+  }
+  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_4) {
+    return WriteUInt8(0b10000000) && WriteUInt8(0) && WriteUInt16(value);
+  }
+  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_8) {
+    return WriteUInt8(0b11000000) && WriteUInt8(0) && WriteUInt16(0) &&
+           WriteUInt32(value);
+  }
+
+  QUIC_BUG(quic_bug_10347_2)
+      << "Invalid write_length " << static_cast<int>(write_length);
+  return false;
+}
+
+// static
+QuicVariableLengthIntegerLength QuicDataWriter::GetVarInt62Len(uint64_t value) {
+  if ((value & kVarInt62ErrorMask) != 0) {
+    QUIC_BUG(quic_bug_10347_3) << "Attempted to encode a value, " << value
+                               << ", that is too big for VarInt62";
+    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  if ((value & kVarInt62Mask8Bytes) != 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_8;
+  }
+  if ((value & kVarInt62Mask4Bytes) != 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_4;
+  }
+  if ((value & kVarInt62Mask2Bytes) != 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+  return VARIABLE_LENGTH_INTEGER_LENGTH_1;
+}
+
+bool QuicDataWriter::WriteStringPieceVarInt62(
+    const absl::string_view& string_piece) {
+  if (!WriteVarInt62(string_piece.size())) {
+    return false;
+  }
+  if (!string_piece.empty()) {
+    if (!WriteBytes(string_piece.data(), string_piece.size())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_data_writer.h b/quiche/quic/core/quic_data_writer.h
new file mode 100644
index 0000000..b1cd198
--- /dev/null
+++ b/quiche/quic/core/quic_data_writer.h
@@ -0,0 +1,100 @@
+// 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_DATA_WRITER_H_
+#define QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_data_writer.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+class QuicRandom;
+
+// Maximum value that can be properly encoded using VarInt62 coding.
+const uint64_t kVarInt62MaxValue = UINT64_C(0x3fffffffffffffff);
+
+// VarInt62 encoding masks
+// If a uint64_t anded with a mask is not 0 then the value is encoded
+// using that length (or is too big, in the case of kVarInt62ErrorMask).
+// Values must be checked in order (error, 8-, 4-, and then 2- bytes)
+// and if none are non-0, the value is encoded in 1 byte.
+const uint64_t kVarInt62ErrorMask = UINT64_C(0xc000000000000000);
+const uint64_t kVarInt62Mask8Bytes = UINT64_C(0x3fffffffc0000000);
+const uint64_t kVarInt62Mask4Bytes = UINT64_C(0x000000003fffc000);
+const uint64_t kVarInt62Mask2Bytes = UINT64_C(0x0000000000003fc0);
+
+// This class provides facilities for packing QUIC data.
+//
+// The QuicDataWriter supports appending primitive values (int, string, etc)
+// to a frame instance.  The internal memory buffer is exposed as the "data"
+// of the QuicDataWriter.
+class QUIC_EXPORT_PRIVATE QuicDataWriter : public quiche::QuicheDataWriter {
+ public:
+  // Creates a QuicDataWriter where |buffer| is not owned
+  // using NETWORK_BYTE_ORDER endianness.
+  QuicDataWriter(size_t size, char* buffer);
+  // Creates a QuicDataWriter where |buffer| is not owned
+  // using the specified endianness.
+  QuicDataWriter(size_t size, char* buffer, quiche::Endianness endianness);
+  QuicDataWriter(const QuicDataWriter&) = delete;
+  QuicDataWriter& operator=(const QuicDataWriter&) = delete;
+
+  ~QuicDataWriter();
+
+  // Methods for adding to the payload.  These values are appended to the end
+  // of the QuicDataWriter payload.
+
+  // Write an unsigned-integer value per the IETF QUIC/Variable Length
+  // Integer encoding rules (see draft-ietf-quic-transport-08.txt).
+  // IETF Variable Length Integers have 62 significant bits, so the
+  // value to write must be in the range of 0...(2^62)-1. Returns
+  // false if the value is out of range or if there is no room in the
+  // buffer.
+  bool WriteVarInt62(uint64_t value);
+
+  // Same as WriteVarInt62(uint64_t), but forces an encoding size to write to.
+  // This is not as optimized as WriteVarInt62(uint64_t).
+  // Returns false if the value does not fit in the specified write_length or if
+  // there is no room in the buffer.
+  bool WriteVarInt62(uint64_t value,
+                     QuicVariableLengthIntegerLength write_length);
+
+  // Writes a string piece as a consecutive length/content pair. The
+  // length is VarInt62 encoded.
+  bool WriteStringPieceVarInt62(const absl::string_view& string_piece);
+
+  // Utility function to return the number of bytes needed to encode
+  // the given value using IETF VarInt62 encoding. Returns the number
+  // of bytes required to encode the given integer or 0 if the value
+  // is too large to encode.
+  static QuicVariableLengthIntegerLength GetVarInt62Len(uint64_t value);
+
+  // Write unsigned floating point corresponding to the value. Large values are
+  // clamped to the maximum representable (kUFloat16MaxValue). Values that can
+  // not be represented directly are rounded down.
+  bool WriteUFloat16(uint64_t value);
+  // Write connection ID to the payload.
+  bool WriteConnectionId(QuicConnectionId connection_id);
+
+  // Write 8-bit length followed by connection ID to the payload.
+  bool WriteLengthPrefixedConnectionId(QuicConnectionId connection_id);
+
+  // Write |length| random bytes generated by |random|.
+  bool WriteRandomBytes(QuicRandom* random, size_t length);
+
+  // Write |length| random bytes generated by |random|. This MUST NOT be used
+  // for any application that requires cryptographically-secure randomness.
+  bool WriteInsecureRandomBytes(QuicRandom* random, size_t length);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
diff --git a/quiche/quic/core/quic_data_writer_test.cc b/quiche/quic/core/quic_data_writer_test.cc
new file mode 100644
index 0000000..40ad70e
--- /dev/null
+++ b/quiche/quic/core/quic_data_writer_test.cc
@@ -0,0 +1,1281 @@
+// 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 "quiche/quic/core/quic_data_writer.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+char* AsChars(unsigned char* data) {
+  return reinterpret_cast<char*>(data);
+}
+
+struct TestParams {
+  explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
+
+  quiche::Endianness endianness;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
+      "ByteOrder");
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (quiche::Endianness endianness :
+       {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
+    params.push_back(TestParams(endianness));
+  }
+  return params;
+}
+
+class QuicDataWriterTest : public QuicTestWithParam<TestParams> {};
+
+INSTANTIATE_TEST_SUITE_P(QuicDataWriterTests,
+                         QuicDataWriterTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) {
+  // Check the arithmetic on the constants - otherwise the values below make
+  // no sense.
+  EXPECT_EQ(30, kUFloat16MaxExponent);
+  EXPECT_EQ(11, kUFloat16MantissaBits);
+  EXPECT_EQ(12, kUFloat16MantissaEffectiveBits);
+  EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue);
+}
+
+TEST_P(QuicDataWriterTest, WriteUFloat16) {
+  struct TestCase {
+    uint64_t decoded;
+    uint16_t encoded;
+  };
+  TestCase test_cases[] = {
+      // Small numbers represent themselves.
+      {0, 0},
+      {1, 1},
+      {2, 2},
+      {3, 3},
+      {4, 4},
+      {5, 5},
+      {6, 6},
+      {7, 7},
+      {15, 15},
+      {31, 31},
+      {42, 42},
+      {123, 123},
+      {1234, 1234},
+      // Check transition through 2^11.
+      {2046, 2046},
+      {2047, 2047},
+      {2048, 2048},
+      {2049, 2049},
+      // Running out of mantissa at 2^12.
+      {4094, 4094},
+      {4095, 4095},
+      {4096, 4096},
+      {4097, 4096},
+      {4098, 4097},
+      {4099, 4097},
+      {4100, 4098},
+      {4101, 4098},
+      // Check transition through 2^13.
+      {8190, 6143},
+      {8191, 6143},
+      {8192, 6144},
+      {8193, 6144},
+      {8194, 6144},
+      {8195, 6144},
+      {8196, 6145},
+      {8197, 6145},
+      // Half-way through the exponents.
+      {0x7FF8000, 0x87FF},
+      {0x7FFFFFF, 0x87FF},
+      {0x8000000, 0x8800},
+      {0xFFF0000, 0x8FFF},
+      {0xFFFFFFF, 0x8FFF},
+      {0x10000000, 0x9000},
+      // Transition into the largest exponent.
+      {0x1FFFFFFFFFE, 0xF7FF},
+      {0x1FFFFFFFFFF, 0xF7FF},
+      {0x20000000000, 0xF800},
+      {0x20000000001, 0xF800},
+      {0x2003FFFFFFE, 0xF800},
+      {0x2003FFFFFFF, 0xF800},
+      {0x20040000000, 0xF801},
+      {0x20040000001, 0xF801},
+      // Transition into the max value and clamping.
+      {0x3FF80000000, 0xFFFE},
+      {0x3FFBFFFFFFF, 0xFFFE},
+      {0x3FFC0000000, 0xFFFF},
+      {0x3FFC0000001, 0xFFFF},
+      {0x3FFFFFFFFFF, 0xFFFF},
+      {0x40000000000, 0xFFFF},
+      {0xFFFFFFFFFFFFFFFF, 0xFFFF},
+  };
+  int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
+
+  for (int i = 0; i < num_test_cases; ++i) {
+    char buffer[2];
+    QuicDataWriter writer(2, buffer, GetParam().endianness);
+    EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
+    uint16_t result = *reinterpret_cast<uint16_t*>(writer.data());
+    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
+      result = quiche::QuicheEndian::HostToNet16(result);
+    }
+    EXPECT_EQ(test_cases[i].encoded, result);
+  }
+}
+
+TEST_P(QuicDataWriterTest, ReadUFloat16) {
+  struct TestCase {
+    uint64_t decoded;
+    uint16_t encoded;
+  };
+  TestCase test_cases[] = {
+      // There are fewer decoding test cases because encoding truncates, and
+      // decoding returns the smallest expansion.
+      // Small numbers represent themselves.
+      {0, 0},
+      {1, 1},
+      {2, 2},
+      {3, 3},
+      {4, 4},
+      {5, 5},
+      {6, 6},
+      {7, 7},
+      {15, 15},
+      {31, 31},
+      {42, 42},
+      {123, 123},
+      {1234, 1234},
+      // Check transition through 2^11.
+      {2046, 2046},
+      {2047, 2047},
+      {2048, 2048},
+      {2049, 2049},
+      // Running out of mantissa at 2^12.
+      {4094, 4094},
+      {4095, 4095},
+      {4096, 4096},
+      {4098, 4097},
+      {4100, 4098},
+      // Check transition through 2^13.
+      {8190, 6143},
+      {8192, 6144},
+      {8196, 6145},
+      // Half-way through the exponents.
+      {0x7FF8000, 0x87FF},
+      {0x8000000, 0x8800},
+      {0xFFF0000, 0x8FFF},
+      {0x10000000, 0x9000},
+      // Transition into the largest exponent.
+      {0x1FFE0000000, 0xF7FF},
+      {0x20000000000, 0xF800},
+      {0x20040000000, 0xF801},
+      // Transition into the max value.
+      {0x3FF80000000, 0xFFFE},
+      {0x3FFC0000000, 0xFFFF},
+  };
+  int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
+
+  for (int i = 0; i < num_test_cases; ++i) {
+    uint16_t encoded_ufloat = test_cases[i].encoded;
+    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
+      encoded_ufloat = quiche::QuicheEndian::HostToNet16(encoded_ufloat);
+    }
+    QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2,
+                          GetParam().endianness);
+    uint64_t value;
+    EXPECT_TRUE(reader.ReadUFloat16(&value));
+    EXPECT_EQ(test_cases[i].decoded, value);
+  }
+}
+
+TEST_P(QuicDataWriterTest, RoundTripUFloat16) {
+  // Just test all 16-bit encoded values. 0 and max already tested above.
+  uint64_t previous_value = 0;
+  for (uint16_t i = 1; i < 0xFFFF; ++i) {
+    // Read the two bytes.
+    uint16_t read_number = i;
+    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
+      read_number = quiche::QuicheEndian::HostToNet16(read_number);
+    }
+    QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2,
+                          GetParam().endianness);
+    uint64_t value;
+    // All values must be decodable.
+    EXPECT_TRUE(reader.ReadUFloat16(&value));
+    // Check that small numbers represent themselves
+    if (i < 4097) {
+      EXPECT_EQ(i, value);
+    }
+    // Check there's monotonic growth.
+    EXPECT_LT(previous_value, value);
+    // Check that precision is within 0.5% away from the denormals.
+    if (i > 2000) {
+      EXPECT_GT(previous_value * 1005, value * 1000);
+    }
+    // Check we're always within the promised range.
+    EXPECT_LT(value, UINT64_C(0x3FFC0000000));
+    previous_value = value;
+    char buffer[6];
+    QuicDataWriter writer(6, buffer, GetParam().endianness);
+    EXPECT_TRUE(writer.WriteUFloat16(value - 1));
+    EXPECT_TRUE(writer.WriteUFloat16(value));
+    EXPECT_TRUE(writer.WriteUFloat16(value + 1));
+    // Check minimal decoding (previous decoding has previous encoding).
+    uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data());
+    uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2);
+    uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4);
+    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
+      encoded1 = quiche::QuicheEndian::NetToHost16(encoded1);
+      encoded2 = quiche::QuicheEndian::NetToHost16(encoded2);
+      encoded3 = quiche::QuicheEndian::NetToHost16(encoded3);
+    }
+    EXPECT_EQ(i - 1, encoded1);
+    // Check roundtrip.
+    EXPECT_EQ(i, encoded2);
+    // Check next decoding.
+    EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3);
+  }
+}
+
+TEST_P(QuicDataWriterTest, WriteConnectionId) {
+  QuicConnectionId connection_id =
+      TestConnectionId(UINT64_C(0x0011223344556677));
+  char big_endian[] = {
+      0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+  };
+  EXPECT_EQ(connection_id.length(), ABSL_ARRAYSIZE(big_endian));
+  ASSERT_LE(connection_id.length(), 255);
+  char buffer[255];
+  QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteConnectionId(connection_id));
+  quiche::test::CompareCharArraysWithHexError(
+      "connection_id", buffer, connection_id.length(), big_endian,
+      connection_id.length());
+
+  QuicConnectionId read_connection_id;
+  QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness);
+  EXPECT_TRUE(
+      reader.ReadConnectionId(&read_connection_id, ABSL_ARRAYSIZE(big_endian)));
+  EXPECT_EQ(connection_id, read_connection_id);
+}
+
+TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) {
+  QuicConnectionId connection_id =
+      TestConnectionId(UINT64_C(0x0011223344556677));
+  char length_prefixed_connection_id[] = {
+      0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+  };
+  EXPECT_EQ(ABSL_ARRAYSIZE(length_prefixed_connection_id),
+            kConnectionIdLengthSize + connection_id.length());
+  char buffer[kConnectionIdLengthSize + 255] = {};
+  QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer);
+  EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
+  quiche::test::CompareCharArraysWithHexError(
+      "WriteLengthPrefixedConnectionId", buffer, writer.length(),
+      length_prefixed_connection_id,
+      ABSL_ARRAYSIZE(length_prefixed_connection_id));
+
+  // Verify that writing length then connection ID produces the same output.
+  memset(buffer, 0, ABSL_ARRAYSIZE(buffer));
+  QuicDataWriter writer2(ABSL_ARRAYSIZE(buffer), buffer);
+  EXPECT_TRUE(writer2.WriteUInt8(connection_id.length()));
+  EXPECT_TRUE(writer2.WriteConnectionId(connection_id));
+  quiche::test::CompareCharArraysWithHexError(
+      "Write length then ConnectionId", buffer, writer2.length(),
+      length_prefixed_connection_id,
+      ABSL_ARRAYSIZE(length_prefixed_connection_id));
+
+  QuicConnectionId read_connection_id;
+  QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer));
+  EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id));
+  EXPECT_EQ(connection_id, read_connection_id);
+
+  // Verify that reading length then connection ID produces the same output.
+  uint8_t read_connection_id_length2 = 33;
+  QuicConnectionId read_connection_id2;
+  QuicDataReader reader2(buffer, ABSL_ARRAYSIZE(buffer));
+  ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2));
+  EXPECT_EQ(connection_id.length(), read_connection_id_length2);
+  EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2,
+                                       read_connection_id_length2));
+  EXPECT_EQ(connection_id, read_connection_id2);
+}
+
+TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
+  QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
+  char buffer[2];
+  QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
+  EXPECT_TRUE(writer.WriteUInt8(1));
+  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
+  EXPECT_TRUE(writer.WriteUInt8(2));
+  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
+  EXPECT_FALSE(writer.WriteUInt8(3));
+
+  EXPECT_EQ(buffer[0], 1);
+  EXPECT_EQ(buffer[1], 2);
+
+  QuicConnectionId read_connection_id = TestConnectionId();
+  uint8_t read_byte;
+  QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer), GetParam().endianness);
+  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
+  EXPECT_EQ(read_connection_id, empty_connection_id);
+  EXPECT_TRUE(reader.ReadUInt8(&read_byte));
+  EXPECT_EQ(read_byte, 1);
+  // Reset read_connection_id to something else to verify that
+  // ReadConnectionId properly sets it back to empty.
+  read_connection_id = TestConnectionId();
+  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
+  EXPECT_EQ(read_connection_id, empty_connection_id);
+  EXPECT_TRUE(reader.ReadUInt8(&read_byte));
+  EXPECT_EQ(read_byte, 2);
+  read_connection_id = TestConnectionId();
+  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
+  EXPECT_EQ(read_connection_id, empty_connection_id);
+  EXPECT_FALSE(reader.ReadUInt8(&read_byte));
+}
+
+TEST_P(QuicDataWriterTest, WriteTag) {
+  char CHLO[] = {
+      'C',
+      'H',
+      'L',
+      'O',
+  };
+  const int kBufferLength = sizeof(QuicTag);
+  char buffer[kBufferLength];
+  QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
+  writer.WriteTag(kCHLO);
+  quiche::test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength,
+                                              CHLO, kBufferLength);
+
+  QuicTag read_chlo;
+  QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
+  reader.ReadTag(&read_chlo);
+  EXPECT_EQ(kCHLO, read_chlo);
+}
+
+TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
+  char little_endian16[] = {0x22, 0x11};
+  char big_endian16[] = {0x11, 0x22};
+  char buffer16[2];
+  {
+    uint16_t in_memory16 = 0x1122;
+    QuicDataWriter writer(2, buffer16, GetParam().endianness);
+    writer.WriteUInt16(in_memory16);
+    quiche::test::CompareCharArraysWithHexError(
+        "uint16_t", buffer16, 2,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
+                                                            : little_endian16,
+        2);
+
+    uint16_t read_number16;
+    QuicDataReader reader(buffer16, 2, GetParam().endianness);
+    reader.ReadUInt16(&read_number16);
+    EXPECT_EQ(in_memory16, read_number16);
+  }
+
+  {
+    uint64_t in_memory16 = 0x0000000000001122;
+    QuicDataWriter writer(2, buffer16, GetParam().endianness);
+    writer.WriteBytesToUInt64(2, in_memory16);
+    quiche::test::CompareCharArraysWithHexError(
+        "uint16_t", buffer16, 2,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
+                                                            : little_endian16,
+        2);
+
+    uint64_t read_number16;
+    QuicDataReader reader(buffer16, 2, GetParam().endianness);
+    reader.ReadBytesToUInt64(2, &read_number16);
+    EXPECT_EQ(in_memory16, read_number16);
+  }
+}
+
+TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
+  char little_endian24[] = {0x33, 0x22, 0x11};
+  char big_endian24[] = {0x11, 0x22, 0x33};
+  char buffer24[3];
+  uint64_t in_memory24 = 0x0000000000112233;
+  QuicDataWriter writer(3, buffer24, GetParam().endianness);
+  writer.WriteBytesToUInt64(3, in_memory24);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint24", buffer24, 3,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
+                                                          : little_endian24,
+      3);
+
+  uint64_t read_number24;
+  QuicDataReader reader(buffer24, 3, GetParam().endianness);
+  reader.ReadBytesToUInt64(3, &read_number24);
+  EXPECT_EQ(in_memory24, read_number24);
+}
+
+TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
+  char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
+  char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
+  char buffer32[4];
+  {
+    uint32_t in_memory32 = 0x11223344;
+    QuicDataWriter writer(4, buffer32, GetParam().endianness);
+    writer.WriteUInt32(in_memory32);
+    quiche::test::CompareCharArraysWithHexError(
+        "uint32_t", buffer32, 4,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
+                                                            : little_endian32,
+        4);
+
+    uint32_t read_number32;
+    QuicDataReader reader(buffer32, 4, GetParam().endianness);
+    reader.ReadUInt32(&read_number32);
+    EXPECT_EQ(in_memory32, read_number32);
+  }
+
+  {
+    uint64_t in_memory32 = 0x11223344;
+    QuicDataWriter writer(4, buffer32, GetParam().endianness);
+    writer.WriteBytesToUInt64(4, in_memory32);
+    quiche::test::CompareCharArraysWithHexError(
+        "uint32_t", buffer32, 4,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
+                                                            : little_endian32,
+        4);
+
+    uint64_t read_number32;
+    QuicDataReader reader(buffer32, 4, GetParam().endianness);
+    reader.ReadBytesToUInt64(4, &read_number32);
+    EXPECT_EQ(in_memory32, read_number32);
+  }
+}
+
+TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
+  uint64_t in_memory40 = 0x0000001122334455;
+  char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
+  char buffer40[5];
+  QuicDataWriter writer(5, buffer40, GetParam().endianness);
+  writer.WriteBytesToUInt64(5, in_memory40);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint40", buffer40, 5,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
+                                                          : little_endian40,
+      5);
+
+  uint64_t read_number40;
+  QuicDataReader reader(buffer40, 5, GetParam().endianness);
+  reader.ReadBytesToUInt64(5, &read_number40);
+  EXPECT_EQ(in_memory40, read_number40);
+}
+
+TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
+  uint64_t in_memory48 = 0x0000112233445566;
+  char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+  char buffer48[6];
+  QuicDataWriter writer(6, buffer48, GetParam().endianness);
+  writer.WriteBytesToUInt64(6, in_memory48);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint48", buffer48, 6,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
+                                                          : little_endian48,
+      6);
+
+  uint64_t read_number48;
+  QuicDataReader reader(buffer48, 6, GetParam().endianness);
+  reader.ReadBytesToUInt64(6., &read_number48);
+  EXPECT_EQ(in_memory48, read_number48);
+}
+
+TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
+  uint64_t in_memory56 = 0x0011223344556677;
+  char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+  char buffer56[7];
+  QuicDataWriter writer(7, buffer56, GetParam().endianness);
+  writer.WriteBytesToUInt64(7, in_memory56);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint56", buffer56, 7,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
+                                                          : little_endian56,
+      7);
+
+  uint64_t read_number56;
+  QuicDataReader reader(buffer56, 7, GetParam().endianness);
+  reader.ReadBytesToUInt64(7, &read_number56);
+  EXPECT_EQ(in_memory56, read_number56);
+}
+
+TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
+  uint64_t in_memory64 = 0x1122334455667788;
+  unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
+                                     0x44, 0x33, 0x22, 0x11};
+  unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
+                                  0x55, 0x66, 0x77, 0x88};
+  char buffer64[8];
+  QuicDataWriter writer(8, buffer64, GetParam().endianness);
+  writer.WriteBytesToUInt64(8, in_memory64);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint64_t", buffer64, 8,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
+          ? AsChars(big_endian64)
+          : AsChars(little_endian64),
+      8);
+
+  uint64_t read_number64;
+  QuicDataReader reader(buffer64, 8, GetParam().endianness);
+  reader.ReadBytesToUInt64(8, &read_number64);
+  EXPECT_EQ(in_memory64, read_number64);
+
+  QuicDataWriter writer2(8, buffer64, GetParam().endianness);
+  writer2.WriteUInt64(in_memory64);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint64_t", buffer64, 8,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
+          ? AsChars(big_endian64)
+          : AsChars(little_endian64),
+      8);
+  read_number64 = 0u;
+  QuicDataReader reader2(buffer64, 8, GetParam().endianness);
+  reader2.ReadUInt64(&read_number64);
+  EXPECT_EQ(in_memory64, read_number64);
+}
+
+TEST_P(QuicDataWriterTest, WriteIntegers) {
+  char buf[43];
+  uint8_t i8 = 0x01;
+  uint16_t i16 = 0x0123;
+  uint32_t i32 = 0x01234567;
+  uint64_t i64 = 0x0123456789ABCDEF;
+  QuicDataWriter writer(46, buf, GetParam().endianness);
+  for (size_t i = 0; i < 10; ++i) {
+    switch (i) {
+      case 0u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 1u:
+        EXPECT_TRUE(writer.WriteUInt8(i8));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 2u:
+        EXPECT_TRUE(writer.WriteUInt16(i16));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 3u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 4u:
+        EXPECT_TRUE(writer.WriteUInt32(i32));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 5u:
+      case 6u:
+      case 7u:
+      case 8u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      default:
+        EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
+    }
+  }
+
+  QuicDataReader reader(buf, 46, GetParam().endianness);
+  for (size_t i = 0; i < 10; ++i) {
+    uint8_t read8;
+    uint16_t read16;
+    uint32_t read32;
+    uint64_t read64;
+    switch (i) {
+      case 0u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0u, read64);
+        break;
+      case 1u:
+        EXPECT_TRUE(reader.ReadUInt8(&read8));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i8, read8);
+        EXPECT_EQ(0xEFu, read64);
+        break;
+      case 2u:
+        EXPECT_TRUE(reader.ReadUInt16(&read16));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i16, read16);
+        EXPECT_EQ(0xCDEFu, read64);
+        break;
+      case 3u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0xABCDEFu, read64);
+        break;
+      case 4u:
+        EXPECT_TRUE(reader.ReadUInt32(&read32));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i32, read32);
+        EXPECT_EQ(0x89ABCDEFu, read64);
+        break;
+      case 5u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x6789ABCDEFu, read64);
+        break;
+      case 6u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x456789ABCDEFu, read64);
+        break;
+      case 7u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x23456789ABCDEFu, read64);
+        break;
+      case 8u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x0123456789ABCDEFu, read64);
+        break;
+      default:
+        EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
+    }
+  }
+}
+
+TEST_P(QuicDataWriterTest, WriteBytes) {
+  char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+  char buf[ABSL_ARRAYSIZE(bytes)];
+  QuicDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes)));
+  for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) {
+    EXPECT_EQ(bytes[i], buf[i]);
+  }
+}
+
+const int kVarIntBufferLength = 1024;
+
+// Encodes and then decodes a specified value, checks that the
+// value that was encoded is the same as the decoded value, the length
+// is correct, and that after decoding, all data in the buffer has
+// been consumed..
+// Returns true if everything works, false if not.
+bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
+  // Init the buffer to all 0, just for cleanliness. Makes for better
+  // output if, in debugging, we need to dump out the buffer.
+  memset(buffer, 0, size_of_buffer);
+  // make a writer. Note that for IETF encoding
+  // we do not care about endianness... It's always big-endian,
+  // but the c'tor expects to be told what endianness is in force...
+  QuicDataWriter writer(size_of_buffer, buffer,
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+
+  // Try to write the value.
+  if (writer.WriteVarInt62(value_in) != true) {
+    return false;
+  }
+  // Look at the value we encoded. Determine how much should have been
+  // used based on the value, and then check the state of the writer
+  // to see that it matches.
+  size_t expected_length = 0;
+  if (value_in <= 0x3f) {
+    expected_length = 1;
+  } else if (value_in <= 0x3fff) {
+    expected_length = 2;
+  } else if (value_in <= 0x3fffffff) {
+    expected_length = 4;
+  } else {
+    expected_length = 8;
+  }
+  if (writer.length() != expected_length) {
+    return false;
+  }
+
+  // set up a reader, just the length we've used, no more, no less.
+  QuicDataReader reader(buffer, expected_length,
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  uint64_t value_out;
+
+  if (reader.ReadVarInt62(&value_out) == false) {
+    return false;
+  }
+  if (value_in != value_out) {
+    return false;
+  }
+  // We only write one value so there had better be nothing left to read
+  return reader.IsDoneReading();
+}
+
+// Test that 8-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt8Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x31 + 0xc0));  // 0xc0 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
+}
+
+// Test that 4-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt4Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x32 + 0x80));  // 0x80 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
+}
+
+// Test that 2-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt2Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3647));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x36 + 0x40));  // 0x40 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
+}
+
+// Test that 1-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt1Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer
+  // is correct. Bytes are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3f));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
+}
+
+// Test certain, targeted, values that are expected to succeed:
+// 0, 1,
+// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
+// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
+// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
+//                          transition)
+// 0x3ffffffffffffffe, 0x3fffffffffffffff,  (the highest valid values)
+// 0xfe, 0xff, 0x100, 0x101,
+// 0xfffe, 0xffff, 0x10000, 0x10001,
+// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
+// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
+// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
+// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
+// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
+TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
+  char buffer[kVarIntBufferLength];
+  uint64_t passing_values[] = {
+      0,
+      1,
+      0x3e,
+      0x3f,
+      0x40,
+      0x41,
+      0x3ffe,
+      0x3fff,
+      0x4000,
+      0x4001,
+      0x3ffffffe,
+      0x3fffffff,
+      0x40000000,
+      0x40000001,
+      0x3ffffffffffffffe,
+      0x3fffffffffffffff,
+      0xfe,
+      0xff,
+      0x100,
+      0x101,
+      0xfffe,
+      0xffff,
+      0x10000,
+      0x10001,
+      0xfffffe,
+      0xffffff,
+      0x1000000,
+      0x1000001,
+      0xfffffffe,
+      0xffffffff,
+      0x100000000,
+      0x100000001,
+      0xfffffffffe,
+      0xffffffffff,
+      0x10000000000,
+      0x10000000001,
+      0xfffffffffffe,
+      0xffffffffffff,
+      0x1000000000000,
+      0x1000000000001,
+      0xfffffffffffffe,
+      0xffffffffffffff,
+      0x100000000000000,
+      0x100000000000001,
+  };
+  for (uint64_t test_val : passing_values) {
+    EXPECT_TRUE(
+        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
+        << " encode/decode of " << test_val << " failed";
+  }
+}
+//
+// Test certain, targeted, values where failure is expected (the
+// values are invalid w.r.t. IETF VarInt encoding):
+// 0x4000000000000000, 0x4000000000000001,  ( Just above max allowed value)
+// 0xfffffffffffffffe, 0xffffffffffffffff,  (should fail)
+TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
+  char buffer[kVarIntBufferLength];
+  uint64_t failing_values[] = {
+      0x4000000000000000,
+      0x4000000000000001,
+      0xfffffffffffffffe,
+      0xffffffffffffffff,
+  };
+  for (uint64_t test_val : failing_values) {
+    EXPECT_FALSE(
+        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
+        << " encode/decode of " << test_val << " succeeded, but was an "
+        << "invalid value";
+  }
+}
+
+// Following tests all try to fill the buffer with multiple values,
+// go one value more than the buffer can accommodate, then read
+// the successfully encoded values, and try to read the unsuccessfully
+// encoded value. The following is the number of values to encode.
+const int kMultiVarCount = 1000;
+
+// Test writing & reading multiple 8-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt8) {
+  uint64_t test_val;
+  char buffer[8 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
+  }
+  EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 4-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt4) {
+  uint64_t test_val;
+  char buffer[4 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
+  }
+  EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 2-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt2) {
+  uint64_t test_val;
+  char buffer[2 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
+  }
+  EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 1-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt1) {
+  uint64_t test_val;
+  char buffer[1 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over. &0xf ensures we do not
+  // overflow the max value for single-byte encoding.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
+  }
+  EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing varints with a forced length.
+TEST_P(QuicDataWriterTest, VarIntFixedLength) {
+  char buffer[90];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+
+  uint64_t test_val = 0;
+  for (int i = 0; i < 4; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 1u);
+  }
+  for (int i = 0; i < 4; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 63u);
+  }
+
+  for (int i = 0; i < 3; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 64u);
+  }
+  for (int i = 0; i < 3; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 16383u);
+  }
+
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 16384u);
+  }
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 1073741823u);
+  }
+
+  EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+  EXPECT_EQ(test_val, 1073741824u);
+
+  // We are at the end of the buffer so this should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test encoding/decoding stream-id values.
+void EncodeDecodeStreamId(uint64_t value_in) {
+  char buffer[1 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+
+  // Encode the given Stream ID.
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(value_in));
+
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  QuicStreamId received_stream_id;
+  uint64_t temp;
+  EXPECT_TRUE(reader.ReadVarInt62(&temp));
+  received_stream_id = static_cast<QuicStreamId>(temp);
+  EXPECT_EQ(value_in, received_stream_id);
+}
+
+// Test writing & reading stream-ids of various value.
+TEST_P(QuicDataWriterTest, StreamId1) {
+  // Check a 1-byte QuicStreamId, should work
+  EncodeDecodeStreamId(UINT64_C(0x15));
+
+  // Check a 2-byte QuicStream ID. It should work.
+  EncodeDecodeStreamId(UINT64_C(0x1567));
+
+  // Check a QuicStreamId that requires 4 bytes of encoding
+  // This should work.
+  EncodeDecodeStreamId(UINT64_C(0x34567890));
+
+  // Check a QuicStreamId that requires 8 bytes of encoding
+  // but whose value is in the acceptable range.
+  // This should work.
+  EncodeDecodeStreamId(UINT64_C(0xf4567890));
+}
+
+TEST_P(QuicDataWriterTest, WriteRandomBytes) {
+  char buffer[20];
+  char expected[20];
+  for (size_t i = 0; i < 20; ++i) {
+    expected[i] = 'r';
+  }
+  MockRandom random;
+  QuicDataWriter writer(20, buffer, GetParam().endianness);
+  EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
+
+  EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
+  quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
+                                              20);
+}
+
+TEST_P(QuicDataWriterTest, WriteInsecureRandomBytes) {
+  char buffer[20];
+  char expected[20];
+  for (size_t i = 0; i < 20; ++i) {
+    expected[i] = 'r';
+  }
+  MockRandom random;
+  QuicDataWriter writer(20, buffer, GetParam().endianness);
+  EXPECT_FALSE(writer.WriteInsecureRandomBytes(&random, 30));
+
+  EXPECT_TRUE(writer.WriteInsecureRandomBytes(&random, 20));
+  quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
+                                              20);
+}
+
+TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
+  // In range [0, 63], variable length should be 1 byte.
+  char buffer[20];
+  QuicDataWriter writer(20, buffer, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(50));
+  QuicDataReader reader(buffer, 20, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_EQ(1, reader.PeekVarInt62Length());
+  // In range (63-16383], variable length should be 2 byte2.
+  char buffer2[20];
+  QuicDataWriter writer2(20, buffer2, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer2.WriteVarInt62(100));
+  QuicDataReader reader2(buffer2, 20, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_EQ(2, reader2.PeekVarInt62Length());
+  // In range (16383, 1073741823], variable length should be 4 bytes.
+  char buffer3[20];
+  QuicDataWriter writer3(20, buffer3, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer3.WriteVarInt62(20000));
+  QuicDataReader reader3(buffer3, 20, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_EQ(4, reader3.PeekVarInt62Length());
+  // In range (1073741823, 4611686018427387903], variable length should be 8
+  // bytes.
+  char buffer4[20];
+  QuicDataWriter writer4(20, buffer4, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
+  QuicDataReader reader4(buffer4, 20, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_EQ(8, reader4.PeekVarInt62Length());
+}
+
+TEST_P(QuicDataWriterTest, ValidStreamCount) {
+  char buffer[1024];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  QuicDataReader reader(buffer, sizeof(buffer));
+  const QuicStreamCount write_stream_count = 0xffeeddcc;
+  EXPECT_TRUE(writer.WriteVarInt62(write_stream_count));
+  QuicStreamCount read_stream_count;
+  uint64_t temp;
+  EXPECT_TRUE(reader.ReadVarInt62(&temp));
+  read_stream_count = static_cast<QuicStreamId>(temp);
+  EXPECT_EQ(write_stream_count, read_stream_count);
+}
+
+TEST_P(QuicDataWriterTest, Seek) {
+  char buffer[3] = {};
+  QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteUInt8(42));
+  EXPECT_TRUE(writer.Seek(1));
+  EXPECT_TRUE(writer.WriteUInt8(3));
+
+  char expected[] = {42, 0, 3};
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) {
+    EXPECT_EQ(buffer[i], expected[i]);
+  }
+}
+
+TEST_P(QuicDataWriterTest, SeekTooFarFails) {
+  char buffer[20];
+
+  // Check that one can seek to the end of the writer, but not past.
+  {
+    QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                          GetParam().endianness);
+    EXPECT_TRUE(writer.Seek(20));
+    EXPECT_FALSE(writer.Seek(1));
+  }
+
+  // Seeking several bytes past the end fails.
+  {
+    QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                          GetParam().endianness);
+    EXPECT_FALSE(writer.Seek(100));
+  }
+
+  // Seeking so far that arithmetic overflow could occur also fails.
+  {
+    QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                          GetParam().endianness);
+    EXPECT_TRUE(writer.Seek(10));
+    EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
+  }
+}
+
+TEST_P(QuicDataWriterTest, PayloadReads) {
+  char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+  char expected_first_read[4] = {1, 2, 3, 4};
+  char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+  QuicDataReader reader(buffer, sizeof(buffer));
+  char first_read_buffer[4] = {};
+  EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
+  quiche::test::CompareCharArraysWithHexError(
+      "first read", first_read_buffer, sizeof(first_read_buffer),
+      expected_first_read, sizeof(expected_first_read));
+  absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload();
+  quiche::test::CompareCharArraysWithHexError(
+      "peeked_remaining_payload", peeked_remaining_payload.data(),
+      peeked_remaining_payload.length(), expected_remaining,
+      sizeof(expected_remaining));
+  absl::string_view full_payload = reader.FullPayload();
+  quiche::test::CompareCharArraysWithHexError(
+      "full_payload", full_payload.data(), full_payload.length(), buffer,
+      sizeof(buffer));
+  absl::string_view read_remaining_payload = reader.ReadRemainingPayload();
+  quiche::test::CompareCharArraysWithHexError(
+      "read_remaining_payload", read_remaining_payload.data(),
+      read_remaining_payload.length(), expected_remaining,
+      sizeof(expected_remaining));
+  EXPECT_TRUE(reader.IsDoneReading());
+  absl::string_view full_payload2 = reader.FullPayload();
+  quiche::test::CompareCharArraysWithHexError(
+      "full_payload2", full_payload2.data(), full_payload2.length(), buffer,
+      sizeof(buffer));
+}
+
+TEST_P(QuicDataWriterTest, StringPieceVarInt62) {
+  char inner_buffer[16] = {1, 2,  3,  4,  5,  6,  7,  8,
+                           9, 10, 11, 12, 13, 14, 15, 16};
+  absl::string_view inner_payload_write(inner_buffer, sizeof(inner_buffer));
+  char buffer[sizeof(inner_buffer) + sizeof(uint8_t)] = {};
+  QuicDataWriter writer(sizeof(buffer), buffer);
+  EXPECT_TRUE(writer.WriteStringPieceVarInt62(inner_payload_write));
+  EXPECT_EQ(0u, writer.remaining());
+  QuicDataReader reader(buffer, sizeof(buffer));
+  absl::string_view inner_payload_read;
+  EXPECT_TRUE(reader.ReadStringPieceVarInt62(&inner_payload_read));
+  quiche::test::CompareCharArraysWithHexError(
+      "inner_payload", inner_payload_write.data(), inner_payload_write.length(),
+      inner_payload_read.data(), inner_payload_read.length());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_datagram_queue.cc b/quiche/quic/core/quic_datagram_queue.cc
new file mode 100644
index 0000000..412eeab
--- /dev/null
+++ b/quiche/quic/core/quic_datagram_queue.cc
@@ -0,0 +1,101 @@
+// Copyright 2019 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 "quiche/quic/core/quic_datagram_queue.h"
+
+#include "absl/types/span.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+
+constexpr float kExpiryInMinRtts = 1.25;
+constexpr float kMinPacingWindows = 4;
+
+QuicDatagramQueue::QuicDatagramQueue(QuicSession* session)
+    : QuicDatagramQueue(session, nullptr) {}
+
+QuicDatagramQueue::QuicDatagramQueue(QuicSession* session,
+                                     std::unique_ptr<Observer> observer)
+    : session_(session),
+      clock_(session->connection()->clock()),
+      observer_(std::move(observer)) {}
+
+MessageStatus QuicDatagramQueue::SendOrQueueDatagram(
+    quiche::QuicheMemSlice datagram) {
+  // If the queue is non-empty, always queue the daragram.  This ensures that
+  // the datagrams are sent in the same order that they were sent by the
+  // application.
+  if (queue_.empty()) {
+    MessageResult result = session_->SendMessage(absl::MakeSpan(&datagram, 1));
+    if (result.status != MESSAGE_STATUS_BLOCKED) {
+      if (observer_) {
+        observer_->OnDatagramProcessed(result.status);
+      }
+      return result.status;
+    }
+  }
+
+  queue_.emplace_back(Datagram{std::move(datagram),
+                               clock_->ApproximateNow() + GetMaxTimeInQueue()});
+  return MESSAGE_STATUS_BLOCKED;
+}
+
+absl::optional<MessageStatus> QuicDatagramQueue::TrySendingNextDatagram() {
+  RemoveExpiredDatagrams();
+  if (queue_.empty()) {
+    return absl::nullopt;
+  }
+
+  MessageResult result =
+      session_->SendMessage(absl::MakeSpan(&queue_.front().datagram, 1));
+  if (result.status != MESSAGE_STATUS_BLOCKED) {
+    queue_.pop_front();
+    if (observer_) {
+      observer_->OnDatagramProcessed(result.status);
+    }
+  }
+  return result.status;
+}
+
+size_t QuicDatagramQueue::SendDatagrams() {
+  size_t num_datagrams = 0;
+  for (;;) {
+    absl::optional<MessageStatus> status = TrySendingNextDatagram();
+    if (!status.has_value()) {
+      break;
+    }
+    if (*status == MESSAGE_STATUS_BLOCKED) {
+      break;
+    }
+    num_datagrams++;
+  }
+  return num_datagrams;
+}
+
+QuicTime::Delta QuicDatagramQueue::GetMaxTimeInQueue() const {
+  if (!max_time_in_queue_.IsZero()) {
+    return max_time_in_queue_;
+  }
+
+  const QuicTime::Delta min_rtt =
+      session_->connection()->sent_packet_manager().GetRttStats()->min_rtt();
+  return std::max(kExpiryInMinRtts * min_rtt,
+                  kMinPacingWindows * kAlarmGranularity);
+}
+
+void QuicDatagramQueue::RemoveExpiredDatagrams() {
+  QuicTime now = clock_->ApproximateNow();
+  while (!queue_.empty() && queue_.front().expiry <= now) {
+    queue_.pop_front();
+    if (observer_) {
+      observer_->OnDatagramProcessed(absl::nullopt);
+    }
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_datagram_queue.h b/quiche/quic/core/quic_datagram_queue.h
new file mode 100644
index 0000000..7120c51
--- /dev/null
+++ b/quiche/quic/core/quic_datagram_queue.h
@@ -0,0 +1,89 @@
+// Copyright 2019 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_DATAGRAM_QUEUE_H_
+#define QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
+
+#include <memory>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+class QuicSession;
+
+// Provides a way to buffer QUIC datagrams (messages) in case they cannot
+// be sent due to congestion control.  Datagrams are buffered for a limited
+// amount of time, and deleted after that time passes.
+class QUIC_EXPORT_PRIVATE QuicDatagramQueue {
+ public:
+  // An interface used to monitor events on the associated `QuicDatagramQueue`.
+  class QUIC_EXPORT_PRIVATE Observer {
+   public:
+    virtual ~Observer() = default;
+
+    // Called when a datagram in the associated queue is sent or discarded.
+    // Identity information for the datagram is not given, because the sending
+    // and discarding order is always first-in-first-out.
+    // This function is called synchronously in `QuicDatagramQueue` methods.
+    // `status` is nullopt when the datagram is dropped due to being in the
+    // queue for too long.
+    virtual void OnDatagramProcessed(absl::optional<MessageStatus> status) = 0;
+  };
+
+  // |session| is not owned and must outlive this object.
+  explicit QuicDatagramQueue(QuicSession* session);
+
+  // |session| is not owned and must outlive this object.
+  QuicDatagramQueue(QuicSession* session, std::unique_ptr<Observer> observer);
+
+  // Adds the datagram to the end of the queue.  May send it immediately; if
+  // not, MESSAGE_STATUS_BLOCKED is returned.
+  MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram);
+
+  // Attempts to send a single datagram from the queue.  Returns the result of
+  // SendMessage(), or nullopt if there were no unexpired datagrams to send.
+  absl::optional<MessageStatus> TrySendingNextDatagram();
+
+  // Sends all of the unexpired datagrams until either the connection becomes
+  // write-blocked or the queue is empty.  Returns the number of datagrams sent.
+  size_t SendDatagrams();
+
+  // Returns the amount of time a datagram is allowed to be in the queue before
+  // it is dropped.  If not set explicitly using SetMaxTimeInQueue(), an
+  // RTT-based heuristic is used.
+  QuicTime::Delta GetMaxTimeInQueue() const;
+
+  void SetMaxTimeInQueue(QuicTime::Delta max_time_in_queue) {
+    max_time_in_queue_ = max_time_in_queue;
+  }
+
+  size_t queue_size() { return queue_.size(); }
+
+  bool empty() { return queue_.empty(); }
+
+ private:
+  struct QUIC_EXPORT_PRIVATE Datagram {
+    quiche::QuicheMemSlice datagram;
+    QuicTime expiry;
+  };
+
+  // Removes expired datagrams from the front of the queue.
+  void RemoveExpiredDatagrams();
+
+  QuicSession* session_;  // Not owned.
+  const QuicClock* clock_;
+
+  QuicTime::Delta max_time_in_queue_ = QuicTime::Delta::Zero();
+  quiche::QuicheCircularDeque<Datagram> queue_;
+  std::unique_ptr<Observer> observer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
diff --git a/quiche/quic/core/quic_datagram_queue_test.cc b/quiche/quic/core/quic_datagram_queue_test.cc
new file mode 100644
index 0000000..9cb2c3c
--- /dev/null
+++ b/quiche/quic/core/quic_datagram_queue_test.cc
@@ -0,0 +1,299 @@
+// Copyright 2019 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 "quiche/quic/core/quic_datagram_queue.h"
+
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+
+using testing::_;
+using testing::ElementsAre;
+using testing::Return;
+
+class EstablishedCryptoStream : public MockQuicCryptoStream {
+ public:
+  using MockQuicCryptoStream::MockQuicCryptoStream;
+
+  bool encryption_established() const override { return true; }
+};
+
+class QuicDatagramQueueObserver final : public QuicDatagramQueue::Observer {
+ public:
+  class Context : public quiche::QuicheReferenceCounted {
+   public:
+    std::vector<absl::optional<MessageStatus>> statuses;
+  };
+
+  QuicDatagramQueueObserver() : context_(new Context()) {}
+  QuicDatagramQueueObserver(const QuicDatagramQueueObserver&) = delete;
+  QuicDatagramQueueObserver& operator=(const QuicDatagramQueueObserver&) =
+      delete;
+
+  void OnDatagramProcessed(absl::optional<MessageStatus> status) override {
+    context_->statuses.push_back(std::move(status));
+  }
+
+  const quiche::QuicheReferenceCountedPointer<Context>& context() {
+    return context_;
+  }
+
+ private:
+  quiche::QuicheReferenceCountedPointer<Context> context_;
+};
+
+class QuicDatagramQueueTestBase : public QuicTest {
+ protected:
+  QuicDatagramQueueTestBase()
+      : connection_(new MockQuicConnection(&helper_,
+                                           &alarm_factory_,
+                                           Perspective::IS_CLIENT)),
+        session_(connection_) {
+    session_.SetCryptoStream(new EstablishedCryptoStream(&session_));
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+  }
+
+  ~QuicDatagramQueueTestBase() = default;
+
+  quiche::QuicheMemSlice CreateMemSlice(absl::string_view data) {
+    return quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
+        helper_.GetStreamSendBufferAllocator(), data));
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;  // Owned by |session_|.
+  MockQuicSession session_;
+};
+
+class QuicDatagramQueueTest : public QuicDatagramQueueTestBase {
+ public:
+  QuicDatagramQueueTest() : queue_(&session_) {}
+
+ protected:
+  QuicDatagramQueue queue_;
+};
+
+TEST_F(QuicDatagramQueueTest, SendDatagramImmediately) {
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  MessageStatus status = queue_.SendOrQueueDatagram(CreateMemSlice("test"));
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS, status);
+  EXPECT_EQ(0u, queue_.queue_size());
+}
+
+TEST_F(QuicDatagramQueueTest, SendDatagramAfterBuffering) {
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  MessageStatus initial_status =
+      queue_.SendOrQueueDatagram(CreateMemSlice("test"));
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED, initial_status);
+  EXPECT_EQ(1u, queue_.queue_size());
+
+  // Verify getting write blocked does not remove the datagram from the queue.
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram();
+  ASSERT_TRUE(status.has_value());
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED, *status);
+  EXPECT_EQ(1u, queue_.queue_size());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  status = queue_.TrySendingNextDatagram();
+  ASSERT_TRUE(status.has_value());
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS, *status);
+  EXPECT_EQ(0u, queue_.queue_size());
+}
+
+TEST_F(QuicDatagramQueueTest, EmptyBuffer) {
+  absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram();
+  EXPECT_FALSE(status.has_value());
+
+  size_t num_messages = queue_.SendDatagrams();
+  EXPECT_EQ(0u, num_messages);
+}
+
+TEST_F(QuicDatagramQueueTest, MultipleDatagrams) {
+  // Note that SendMessage() is called only once here, since all the remaining
+  // messages are automatically queued due to the queue being non-empty.
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  queue_.SendOrQueueDatagram(CreateMemSlice("a"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("b"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("c"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("d"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("e"));
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .Times(5)
+      .WillRepeatedly(Return(MESSAGE_STATUS_SUCCESS));
+  size_t num_messages = queue_.SendDatagrams();
+  EXPECT_EQ(5u, num_messages);
+}
+
+TEST_F(QuicDatagramQueueTest, DefaultMaxTimeInQueue) {
+  EXPECT_EQ(QuicTime::Delta::Zero(),
+            connection_->sent_packet_manager().GetRttStats()->min_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(4), queue_.GetMaxTimeInQueue());
+
+  RttStats* stats =
+      const_cast<RttStats*>(connection_->sent_packet_manager().GetRttStats());
+  stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                   QuicTime::Delta::Zero(), helper_.GetClock()->Now());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(125), queue_.GetMaxTimeInQueue());
+}
+
+TEST_F(QuicDatagramQueueTest, Expiry) {
+  constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
+  queue_.SetMaxTimeInQueue(expiry);
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  queue_.SendOrQueueDatagram(CreateMemSlice("a"));
+  helper_.AdvanceTime(0.6 * expiry);
+  queue_.SendOrQueueDatagram(CreateMemSlice("b"));
+  helper_.AdvanceTime(0.6 * expiry);
+  queue_.SendOrQueueDatagram(CreateMemSlice("c"));
+
+  std::vector<std::string> messages;
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillRepeatedly([&messages](QuicMessageId /*id*/,
+                                  absl::Span<quiche::QuicheMemSlice> message,
+                                  bool /*flush*/) {
+        messages.push_back(std::string(message[0].AsStringView()));
+        return MESSAGE_STATUS_SUCCESS;
+      });
+  EXPECT_EQ(2u, queue_.SendDatagrams());
+  EXPECT_THAT(messages, ElementsAre("b", "c"));
+}
+
+TEST_F(QuicDatagramQueueTest, ExpireAll) {
+  constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
+  queue_.SetMaxTimeInQueue(expiry);
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  queue_.SendOrQueueDatagram(CreateMemSlice("a"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("b"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("c"));
+
+  helper_.AdvanceTime(100 * expiry);
+  EXPECT_CALL(*connection_, SendMessage(_, _, _)).Times(0);
+  EXPECT_EQ(0u, queue_.SendDatagrams());
+}
+
+class QuicDatagramQueueWithObserverTest : public QuicDatagramQueueTestBase {
+ public:
+  QuicDatagramQueueWithObserverTest()
+      : observer_(std::make_unique<QuicDatagramQueueObserver>()),
+        context_(observer_->context()),
+        queue_(&session_, std::move(observer_)) {}
+
+ protected:
+  // This is moved out immediately.
+  std::unique_ptr<QuicDatagramQueueObserver> observer_;
+
+  quiche::QuicheReferenceCountedPointer<QuicDatagramQueueObserver::Context>
+      context_;
+  QuicDatagramQueue queue_;
+};
+
+TEST_F(QuicDatagramQueueWithObserverTest, ObserveSuccessImmediately) {
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+
+  EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_SUCCESS));
+}
+
+TEST_F(QuicDatagramQueueWithObserverTest, ObserveFailureImmediately) {
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
+
+  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+
+  EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_TOO_LARGE));
+}
+
+TEST_F(QuicDatagramQueueWithObserverTest, BlockingShouldNotBeObserved) {
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillRepeatedly(Return(MESSAGE_STATUS_BLOCKED));
+
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+  EXPECT_EQ(0u, queue_.SendDatagrams());
+
+  EXPECT_TRUE(context_->statuses.empty());
+}
+
+TEST_F(QuicDatagramQueueWithObserverTest, ObserveSuccessAfterBuffering) {
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+
+  EXPECT_EQ(1u, queue_.SendDatagrams());
+  EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_SUCCESS));
+}
+
+TEST_F(QuicDatagramQueueWithObserverTest, ObserveExpiry) {
+  constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
+  queue_.SetMaxTimeInQueue(expiry);
+
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _)).Times(0);
+  helper_.AdvanceTime(100 * expiry);
+
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_EQ(0u, queue_.SendDatagrams());
+  EXPECT_THAT(context_->statuses, ElementsAre(absl::nullopt));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_default_packet_writer.cc b/quiche/quic/core/quic_default_packet_writer.cc
new file mode 100644
index 0000000..744591b
--- /dev/null
+++ b/quiche/quic/core/quic_default_packet_writer.cc
@@ -0,0 +1,75 @@
+// Copyright 2013 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 "quiche/quic/core/quic_default_packet_writer.h"
+
+#include "quiche/quic/core/quic_udp_socket.h"
+
+namespace quic {
+
+QuicDefaultPacketWriter::QuicDefaultPacketWriter(int fd)
+    : fd_(fd), write_blocked_(false) {}
+
+QuicDefaultPacketWriter::~QuicDefaultPacketWriter() = default;
+
+WriteResult QuicDefaultPacketWriter::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  QUICHE_DCHECK(!write_blocked_);
+  QUICHE_DCHECK(nullptr == options)
+      << "QuicDefaultPacketWriter does not accept any options.";
+  QuicUdpPacketInfo packet_info;
+  packet_info.SetPeerAddress(peer_address);
+  packet_info.SetSelfIp(self_address);
+  WriteResult result =
+      QuicUdpSocketApi().WritePacket(fd_, buffer, buf_len, packet_info);
+  if (IsWriteBlockedStatus(result.status)) {
+    write_blocked_ = true;
+  }
+  return result;
+}
+
+bool QuicDefaultPacketWriter::IsWriteBlocked() const {
+  return write_blocked_;
+}
+
+void QuicDefaultPacketWriter::SetWritable() {
+  write_blocked_ = false;
+}
+
+absl::optional<int> QuicDefaultPacketWriter::MessageTooBigErrorCode() const {
+  return EMSGSIZE;
+}
+
+QuicByteCount QuicDefaultPacketWriter::GetMaxPacketSize(
+    const QuicSocketAddress& /*peer_address*/) const {
+  return kMaxOutgoingPacketSize;
+}
+
+bool QuicDefaultPacketWriter::SupportsReleaseTime() const {
+  return false;
+}
+
+bool QuicDefaultPacketWriter::IsBatchMode() const {
+  return false;
+}
+
+QuicPacketBuffer QuicDefaultPacketWriter::GetNextWriteLocation(
+    const QuicIpAddress& /*self_address*/,
+    const QuicSocketAddress& /*peer_address*/) {
+  return {nullptr, nullptr};
+}
+
+WriteResult QuicDefaultPacketWriter::Flush() {
+  return WriteResult(WRITE_STATUS_OK, 0);
+}
+
+void QuicDefaultPacketWriter::set_write_blocked(bool is_blocked) {
+  write_blocked_ = is_blocked;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_default_packet_writer.h b/quiche/quic/core/quic_default_packet_writer.h
new file mode 100644
index 0000000..ad76cfa
--- /dev/null
+++ b/quiche/quic/core/quic_default_packet_writer.h
@@ -0,0 +1,57 @@
+// Copyright 2013 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_DEFAULT_PACKET_WRITER_H_
+#define QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
+
+#include <cstddef>
+
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+struct WriteResult;
+
+// Default packet writer which wraps QuicSocketUtils WritePacket.
+class QUIC_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter {
+ public:
+  explicit QuicDefaultPacketWriter(int fd);
+  QuicDefaultPacketWriter(const QuicDefaultPacketWriter&) = delete;
+  QuicDefaultPacketWriter& operator=(const QuicDefaultPacketWriter&) = delete;
+  ~QuicDefaultPacketWriter() override;
+
+  // QuicPacketWriter
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+  bool IsWriteBlocked() const override;
+  void SetWritable() override;
+  absl::optional<int> MessageTooBigErrorCode() const override;
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& peer_address) const override;
+  bool SupportsReleaseTime() const override;
+  bool IsBatchMode() const override;
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& self_address,
+      const QuicSocketAddress& peer_address) override;
+  WriteResult Flush() override;
+
+  void set_fd(int fd) { fd_ = fd; }
+
+ protected:
+  void set_write_blocked(bool is_blocked);
+  int fd() { return fd_; }
+
+ private:
+  int fd_;
+  bool write_blocked_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
diff --git a/quiche/quic/core/quic_dispatcher.cc b/quiche/quic/core/quic_dispatcher.cc
new file mode 100644
index 0000000..d5344a0
--- /dev/null
+++ b/quiche/quic/core/quic_dispatcher.cc
@@ -0,0 +1,1456 @@
+// 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 "quiche/quic/core/quic_dispatcher.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/chlo_extractor.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/tls_chlo_extractor.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
+using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
+using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
+
+namespace {
+
+// Minimal INITIAL packet length sent by clients is 1200.
+const QuicPacketLength kMinClientInitialPacketLength = 1200;
+
+// An alarm that informs the QuicDispatcher to delete old sessions.
+class DeleteSessionsAlarm : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher)
+      : dispatcher_(dispatcher) {}
+  DeleteSessionsAlarm(const DeleteSessionsAlarm&) = delete;
+  DeleteSessionsAlarm& operator=(const DeleteSessionsAlarm&) = delete;
+
+  void OnAlarm() override { dispatcher_->DeleteSessions(); }
+
+ private:
+  // Not owned.
+  QuicDispatcher* dispatcher_;
+};
+
+// An alarm that informs the QuicDispatcher to clear
+// recent_stateless_reset_addresses_.
+class ClearStatelessResetAddressesAlarm
+    : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit ClearStatelessResetAddressesAlarm(QuicDispatcher* dispatcher)
+      : dispatcher_(dispatcher) {}
+  ClearStatelessResetAddressesAlarm(const DeleteSessionsAlarm&) = delete;
+  ClearStatelessResetAddressesAlarm& operator=(const DeleteSessionsAlarm&) =
+      delete;
+
+  void OnAlarm() override { dispatcher_->ClearStatelessResetAddresses(); }
+
+ private:
+  // Not owned.
+  QuicDispatcher* dispatcher_;
+};
+
+// Collects packets serialized by a QuicPacketCreator in order
+// to be handed off to the time wait list manager.
+class PacketCollector : public QuicPacketCreator::DelegateInterface,
+                        public QuicStreamFrameDataProducer {
+ public:
+  explicit PacketCollector(quiche::QuicheBufferAllocator* allocator)
+      : send_buffer_(allocator) {}
+  ~PacketCollector() override = default;
+
+  // QuicPacketCreator::DelegateInterface methods:
+  void OnSerializedPacket(SerializedPacket serialized_packet) override {
+    // Make a copy of the serialized packet to send later.
+    packets_.emplace_back(
+        new QuicEncryptedPacket(CopyBuffer(serialized_packet),
+                                serialized_packet.encrypted_length, true));
+  }
+
+  QuicPacketBuffer GetPacketBuffer() override {
+    // Let QuicPacketCreator to serialize packets on stack buffer.
+    return {nullptr, nullptr};
+  }
+
+  void OnUnrecoverableError(QuicErrorCode /*error*/,
+                            const std::string& /*error_details*/) override {}
+
+  bool ShouldGeneratePacket(HasRetransmittableData /*retransmittable*/,
+                            IsHandshake /*handshake*/) override {
+    QUICHE_DCHECK(false);
+    return true;
+  }
+
+  const QuicFrames MaybeBundleAckOpportunistically() override {
+    QUICHE_DCHECK(false);
+    return {};
+  }
+
+  SerializedPacketFate GetSerializedPacketFate(
+      bool /*is_mtu_discovery*/,
+      EncryptionLevel /*encryption_level*/) override {
+    return SEND_TO_WRITER;
+  }
+
+  // QuicStreamFrameDataProducer
+  WriteStreamDataResult WriteStreamData(QuicStreamId /*id*/,
+                                        QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        QuicDataWriter* writer) override {
+    if (send_buffer_.WriteStreamData(offset, data_length, writer)) {
+      return WRITE_SUCCESS;
+    }
+    return WRITE_FAILED;
+  }
+  bool WriteCryptoData(EncryptionLevel /*level*/,
+                       QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer) override {
+    return send_buffer_.WriteStreamData(offset, data_length, writer);
+  }
+
+  std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
+    return &packets_;
+  }
+
+ private:
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
+  // This is only needed until the packets are encrypted. Once packets are
+  // encrypted, the stream data is no longer required.
+  QuicStreamSendBuffer send_buffer_;
+};
+
+// Helper for statelessly closing connections by generating the
+// correct termination packets and adding the connection to the time wait
+// list manager.
+class StatelessConnectionTerminator {
+ public:
+  StatelessConnectionTerminator(QuicConnectionId server_connection_id,
+                                const ParsedQuicVersion version,
+                                QuicConnectionHelperInterface* helper,
+                                QuicTimeWaitListManager* time_wait_list_manager)
+      : server_connection_id_(server_connection_id),
+        framer_(ParsedQuicVersionVector{version},
+                /*unused*/ QuicTime::Zero(),
+                Perspective::IS_SERVER,
+                /*unused*/ kQuicDefaultConnectionIdLength),
+        collector_(helper->GetStreamSendBufferAllocator()),
+        creator_(server_connection_id, &framer_, &collector_),
+        time_wait_list_manager_(time_wait_list_manager) {
+    framer_.set_data_producer(&collector_);
+    framer_.SetInitialObfuscators(server_connection_id);
+  }
+
+  ~StatelessConnectionTerminator() {
+    // Clear framer's producer.
+    framer_.set_data_producer(nullptr);
+  }
+
+  // Generates a packet containing a CONNECTION_CLOSE frame specifying
+  // |error_code| and |error_details| and add the connection to time wait.
+  void CloseConnection(QuicErrorCode error_code,
+                       const std::string& error_details,
+                       bool ietf_quic,
+                       std::vector<QuicConnectionId> active_connection_ids) {
+    SerializeConnectionClosePacket(error_code, error_details);
+
+    time_wait_list_manager_->AddConnectionIdToTimeWait(
+        QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+        TimeWaitConnectionInfo(ietf_quic, collector_.packets(),
+                               std::move(active_connection_ids),
+                               /*srtt=*/QuicTime::Delta::Zero()));
+  }
+
+ private:
+  void SerializeConnectionClosePacket(QuicErrorCode error_code,
+                                      const std::string& error_details) {
+    QuicConnectionCloseFrame* frame =
+        new QuicConnectionCloseFrame(framer_.transport_version(), error_code,
+                                     NO_IETF_QUIC_ERROR, error_details,
+                                     /*transport_close_frame_type=*/0);
+
+    if (!creator_.AddFrame(QuicFrame(frame), NOT_RETRANSMISSION)) {
+      QUIC_BUG(quic_bug_10287_1) << "Unable to add frame to an empty packet";
+      delete frame;
+      return;
+    }
+    creator_.FlushCurrentPacket();
+    QUICHE_DCHECK_EQ(1u, collector_.packets()->size());
+  }
+
+  QuicConnectionId server_connection_id_;
+  QuicFramer framer_;
+  // Set as the visitor of |creator_| to collect any generated packets.
+  PacketCollector collector_;
+  QuicPacketCreator creator_;
+  QuicTimeWaitListManager* time_wait_list_manager_;
+};
+
+// Class which extracts the ALPN and SNI from a QUIC_CRYPTO CHLO packet.
+class ChloAlpnSniExtractor : public ChloExtractor::Delegate {
+ public:
+  void OnChlo(QuicTransportVersion version,
+              QuicConnectionId /*server_connection_id*/,
+              const CryptoHandshakeMessage& chlo) override {
+    absl::string_view alpn_value;
+    if (chlo.GetStringPiece(kALPN, &alpn_value)) {
+      alpn_ = std::string(alpn_value);
+    }
+    absl::string_view sni;
+    if (chlo.GetStringPiece(quic::kSNI, &sni)) {
+      sni_ = std::string(sni);
+    }
+    absl::string_view uaid_value;
+    if (chlo.GetStringPiece(quic::kUAID, &uaid_value)) {
+      uaid_ = std::string(uaid_value);
+    }
+    if (version == LegacyVersionForEncapsulation().transport_version) {
+      absl::string_view qlve_value;
+      if (chlo.GetStringPiece(kQLVE, &qlve_value)) {
+        legacy_version_encapsulation_inner_packet_ = std::string(qlve_value);
+      }
+    }
+  }
+
+  std::string&& ConsumeAlpn() { return std::move(alpn_); }
+
+  std::string&& ConsumeSni() { return std::move(sni_); }
+
+  std::string&& ConsumeUaid() { return std::move(uaid_); }
+
+  std::string&& ConsumeLegacyVersionEncapsulationInnerPacket() {
+    return std::move(legacy_version_encapsulation_inner_packet_);
+  }
+
+ private:
+  std::string alpn_;
+  std::string sni_;
+  std::string uaid_;
+  std::string legacy_version_encapsulation_inner_packet_;
+};
+
+bool MaybeHandleLegacyVersionEncapsulation(
+    QuicDispatcher* dispatcher,
+    std::string legacy_version_encapsulation_inner_packet,
+    const ReceivedPacketInfo& packet_info) {
+  if (legacy_version_encapsulation_inner_packet.empty()) {
+    // This CHLO did not contain the Legacy Version Encapsulation tag.
+    return false;
+  }
+  PacketHeaderFormat format;
+  QuicLongHeaderType long_packet_type;
+  bool version_present;
+  bool has_length_prefix;
+  QuicVersionLabel version_label;
+  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+  QuicConnectionId destination_connection_id, source_connection_id;
+  absl::optional<absl::string_view> retry_token;
+  std::string detailed_error;
+  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+      QuicEncryptedPacket(legacy_version_encapsulation_inner_packet.data(),
+                          legacy_version_encapsulation_inner_packet.length()),
+      kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  if (error != QUIC_NO_ERROR) {
+    QUIC_DLOG(ERROR)
+        << "Failed to parse Legacy Version Encapsulation inner packet:"
+        << detailed_error;
+    return false;
+  }
+  if (destination_connection_id != packet_info.destination_connection_id) {
+    // We enforce that the inner and outer connection IDs match to make sure
+    // this never impacts routing of packets.
+    QUIC_DLOG(ERROR) << "Ignoring Legacy Version Encapsulation packet "
+                        "with mismatched connection ID "
+                     << destination_connection_id << " vs "
+                     << packet_info.destination_connection_id;
+    return false;
+  }
+  if (legacy_version_encapsulation_inner_packet.length() >=
+      packet_info.packet.length()) {
+    QUIC_BUG(quic_bug_10287_2)
+        << "Inner packet cannot be larger than outer "
+        << legacy_version_encapsulation_inner_packet.length() << " vs "
+        << packet_info.packet.length();
+    return false;
+  }
+
+  QUIC_DVLOG(1) << "Extracted a Legacy Version Encapsulation "
+                << legacy_version_encapsulation_inner_packet.length()
+                << " byte packet of version " << parsed_version;
+
+  // Append zeroes to the end of the packet. This will ensure that
+  // we use the right number of bytes for calculating anti-amplification
+  // limits. Note that this only works for long headers of versions that carry
+  // long header lengths, since they'll ignore any trailing zeroes. We still
+  // do this for all packets to ensure version negotiation works.
+  legacy_version_encapsulation_inner_packet.append(
+      packet_info.packet.length() -
+          legacy_version_encapsulation_inner_packet.length(),
+      0x00);
+
+  // Process the inner packet as if it had been received by itself.
+  QuicReceivedPacket received_encapsulated_packet(
+      legacy_version_encapsulation_inner_packet.data(),
+      legacy_version_encapsulation_inner_packet.length(),
+      packet_info.packet.receipt_time());
+  dispatcher->ProcessPacket(packet_info.self_address, packet_info.peer_address,
+                            received_encapsulated_packet);
+  QUIC_CODE_COUNT(quic_legacy_version_encapsulation_decapsulated);
+  return true;
+}
+
+}  // namespace
+
+QuicDispatcher::QuicDispatcher(
+    const QuicConfig* config, const QuicCryptoServerConfig* crypto_config,
+    QuicVersionManager* version_manager,
+    std::unique_ptr<QuicConnectionHelperInterface> helper,
+    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+    std::unique_ptr<QuicAlarmFactory> alarm_factory,
+    uint8_t expected_server_connection_id_length)
+    : config_(config),
+      crypto_config_(crypto_config),
+      compressed_certs_cache_(
+          QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+      helper_(std::move(helper)),
+      session_helper_(std::move(session_helper)),
+      alarm_factory_(std::move(alarm_factory)),
+      delete_sessions_alarm_(
+          alarm_factory_->CreateAlarm(new DeleteSessionsAlarm(this))),
+      buffered_packets_(this, helper_->GetClock(), alarm_factory_.get()),
+      version_manager_(version_manager),
+      last_error_(QUIC_NO_ERROR),
+      new_sessions_allowed_per_event_loop_(0u),
+      accept_new_connections_(true),
+      allow_short_initial_server_connection_ids_(false),
+      expected_server_connection_id_length_(
+          expected_server_connection_id_length),
+      clear_stateless_reset_addresses_alarm_(alarm_factory_->CreateAlarm(
+          new ClearStatelessResetAddressesAlarm(this))),
+      should_update_expected_server_connection_id_length_(false) {
+  QUIC_BUG_IF(quic_bug_12724_1, GetSupportedVersions().empty())
+      << "Trying to create dispatcher without any supported versions";
+  QUIC_DLOG(INFO) << "Created QuicDispatcher with versions: "
+                  << ParsedQuicVersionVectorToString(GetSupportedVersions());
+}
+
+QuicDispatcher::~QuicDispatcher() {
+  if (delete_sessions_alarm_ != nullptr) {
+    delete_sessions_alarm_->PermanentCancel();
+  }
+  if (clear_stateless_reset_addresses_alarm_ != nullptr) {
+    clear_stateless_reset_addresses_alarm_->PermanentCancel();
+  }
+  reference_counted_session_map_.clear();
+  closed_session_list_.clear();
+  num_sessions_in_session_map_ = 0;
+}
+
+void QuicDispatcher::InitializeWithWriter(QuicPacketWriter* writer) {
+  QUICHE_DCHECK(writer_ == nullptr);
+  writer_.reset(writer);
+  time_wait_list_manager_.reset(CreateQuicTimeWaitListManager());
+}
+
+void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address,
+                                   const QuicSocketAddress& peer_address,
+                                   const QuicReceivedPacket& packet) {
+  QUIC_DVLOG(2) << "Dispatcher received encrypted " << packet.length()
+                << " bytes:" << std::endl
+                << quiche::QuicheTextUtils::HexDump(
+                       absl::string_view(packet.data(), packet.length()));
+  ReceivedPacketInfo packet_info(self_address, peer_address, packet);
+  std::string detailed_error;
+  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+      packet, expected_server_connection_id_length_, &packet_info.form,
+      &packet_info.long_packet_type, &packet_info.version_flag,
+      &packet_info.use_length_prefix, &packet_info.version_label,
+      &packet_info.version, &packet_info.destination_connection_id,
+      &packet_info.source_connection_id, &packet_info.retry_token,
+      &detailed_error);
+  if (error != QUIC_NO_ERROR) {
+    // Packet has framing error.
+    SetLastError(error);
+    QUIC_DLOG(ERROR) << detailed_error;
+    return;
+  }
+  if (packet_info.destination_connection_id.length() !=
+          expected_server_connection_id_length_ &&
+      !should_update_expected_server_connection_id_length_ &&
+      packet_info.version.IsKnown() &&
+      !packet_info.version.AllowsVariableLengthConnectionIds()) {
+    SetLastError(QUIC_INVALID_PACKET_HEADER);
+    QUIC_DLOG(ERROR) << "Invalid Connection Id Length";
+    return;
+  }
+
+  if (packet_info.version_flag && IsSupportedVersion(packet_info.version)) {
+    if (!QuicUtils::IsConnectionIdValidForVersion(
+            packet_info.destination_connection_id,
+            packet_info.version.transport_version)) {
+      SetLastError(QUIC_INVALID_PACKET_HEADER);
+      QUIC_DLOG(ERROR)
+          << "Invalid destination connection ID length for version";
+      return;
+    }
+    if (packet_info.version.SupportsClientConnectionIds() &&
+        !QuicUtils::IsConnectionIdValidForVersion(
+            packet_info.source_connection_id,
+            packet_info.version.transport_version)) {
+      SetLastError(QUIC_INVALID_PACKET_HEADER);
+      QUIC_DLOG(ERROR) << "Invalid source connection ID length for version";
+      return;
+    }
+  }
+
+  if (should_update_expected_server_connection_id_length_) {
+    expected_server_connection_id_length_ =
+        packet_info.destination_connection_id.length();
+  }
+
+  if (MaybeDispatchPacket(packet_info)) {
+    // Packet has been dropped or successfully dispatched, stop processing.
+    return;
+  }
+  ProcessHeader(&packet_info);
+}
+
+QuicConnectionId QuicDispatcher::MaybeReplaceServerConnectionId(
+    const QuicConnectionId& server_connection_id,
+    const ParsedQuicVersion& version) const {
+  const uint8_t server_connection_id_length = server_connection_id.length();
+  if (server_connection_id_length == expected_server_connection_id_length_) {
+    return server_connection_id;
+  }
+  QUICHE_DCHECK(version.AllowsVariableLengthConnectionIds());
+  QuicConnectionId new_connection_id;
+  if (server_connection_id_length < expected_server_connection_id_length_) {
+    new_connection_id = ReplaceShortServerConnectionId(
+        version, server_connection_id, expected_server_connection_id_length_);
+    // Verify that ReplaceShortServerConnectionId is deterministic.
+    QUICHE_DCHECK_EQ(
+        new_connection_id,
+        ReplaceShortServerConnectionId(version, server_connection_id,
+                                       expected_server_connection_id_length_));
+  } else {
+    new_connection_id = ReplaceLongServerConnectionId(
+        version, server_connection_id, expected_server_connection_id_length_);
+    // Verify that ReplaceLongServerConnectionId is deterministic.
+    QUICHE_DCHECK_EQ(
+        new_connection_id,
+        ReplaceLongServerConnectionId(version, server_connection_id,
+                                      expected_server_connection_id_length_));
+  }
+  QUICHE_DCHECK_EQ(expected_server_connection_id_length_,
+                   new_connection_id.length());
+
+  QUIC_DLOG(INFO) << "Replacing incoming connection ID " << server_connection_id
+                  << " with " << new_connection_id;
+  return new_connection_id;
+}
+
+QuicConnectionId QuicDispatcher::ReplaceShortServerConnectionId(
+    const ParsedQuicVersion& /*version*/,
+    const QuicConnectionId& server_connection_id,
+    uint8_t expected_server_connection_id_length) const {
+  QUICHE_DCHECK_LT(server_connection_id.length(),
+                   expected_server_connection_id_length);
+  return QuicUtils::CreateReplacementConnectionId(
+      server_connection_id, expected_server_connection_id_length);
+}
+
+QuicConnectionId QuicDispatcher::ReplaceLongServerConnectionId(
+    const ParsedQuicVersion& /*version*/,
+    const QuicConnectionId& server_connection_id,
+    uint8_t expected_server_connection_id_length) const {
+  QUICHE_DCHECK_GT(server_connection_id.length(),
+                   expected_server_connection_id_length);
+  return QuicUtils::CreateReplacementConnectionId(
+      server_connection_id, expected_server_connection_id_length);
+}
+
+namespace {
+constexpr bool IsSourceUdpPortBlocked(uint16_t port) {
+  // These UDP source ports have been observed in large scale denial of service
+  // attacks and are not expected to ever carry user traffic, they are therefore
+  // blocked as a safety measure. See draft-ietf-quic-applicability for details.
+  constexpr uint16_t blocked_ports[] = {
+      0,      // We cannot send to port 0 so drop that source port.
+      17,     // Quote of the Day, can loop with QUIC.
+      19,     // Chargen, can loop with QUIC.
+      53,     // DNS, vulnerable to reflection attacks.
+      111,    // Portmap.
+      123,    // NTP, vulnerable to reflection attacks.
+      137,    // NETBIOS Name Service,
+      128,    // NETBIOS Datagram Service
+      161,    // SNMP.
+      389,    // CLDAP.
+      500,    // IKE, can loop with QUIC.
+      1900,   // SSDP, vulnerable to reflection attacks.
+      5353,   // mDNS, vulnerable to reflection attacks.
+      11211,  // memcache, vulnerable to reflection attacks.
+              // This list MUST be sorted in increasing order.
+  };
+  constexpr size_t num_blocked_ports = ABSL_ARRAYSIZE(blocked_ports);
+  constexpr uint16_t highest_blocked_port =
+      blocked_ports[num_blocked_ports - 1];
+  if (QUICHE_PREDICT_TRUE(port > highest_blocked_port)) {
+    // Early-return to skip comparisons for the majority of traffic.
+    return false;
+  }
+  for (size_t i = 0; i < num_blocked_ports; i++) {
+    if (port == blocked_ports[i]) {
+      return true;
+    }
+  }
+  return false;
+}
+}  // namespace
+
+bool QuicDispatcher::MaybeDispatchPacket(
+    const ReceivedPacketInfo& packet_info) {
+  if (IsSourceUdpPortBlocked(packet_info.peer_address.port())) {
+    // Silently drop the received packet.
+    QUIC_CODE_COUNT(quic_dropped_blocked_port);
+    return true;
+  }
+
+  QuicConnectionId server_connection_id = packet_info.destination_connection_id;
+
+  // The IETF spec requires the client to generate an initial server
+  // connection ID that is at least 64 bits long. After that initial
+  // connection ID, the dispatcher picks a new one of its expected length.
+  // Therefore we should never receive a connection ID that is smaller
+  // than 64 bits and smaller than what we expect. Unless the version is
+  // unknown, in which case we allow short connection IDs for version
+  // negotiation because that version could allow those.
+  if (packet_info.version_flag && packet_info.version.IsKnown() &&
+      server_connection_id.length() < kQuicMinimumInitialConnectionIdLength &&
+      server_connection_id.length() < expected_server_connection_id_length_ &&
+      !allow_short_initial_server_connection_ids_) {
+    QUICHE_DCHECK(packet_info.version_flag);
+    QUICHE_DCHECK(packet_info.version.AllowsVariableLengthConnectionIds());
+    QUIC_DLOG(INFO) << "Packet with short destination connection ID "
+                    << server_connection_id << " expected "
+                    << static_cast<int>(expected_server_connection_id_length_);
+    // Drop the packet silently.
+    QUIC_CODE_COUNT(quic_dropped_invalid_small_initial_connection_id);
+    return true;
+  }
+
+  if (packet_info.version_flag && packet_info.version.IsKnown() &&
+      !QuicUtils::IsConnectionIdLengthValidForVersion(
+          server_connection_id.length(),
+          packet_info.version.transport_version)) {
+    QUIC_DLOG(INFO) << "Packet with destination connection ID "
+                    << server_connection_id << " is invalid with version "
+                    << packet_info.version;
+    // Drop the packet silently.
+    QUIC_CODE_COUNT(quic_dropped_invalid_initial_connection_id);
+    return true;
+  }
+
+  // Packets with connection IDs for active connections are processed
+  // immediately.
+  auto it = reference_counted_session_map_.find(server_connection_id);
+  if (it != reference_counted_session_map_.end()) {
+    QUICHE_DCHECK(!buffered_packets_.HasBufferedPackets(server_connection_id));
+    if (packet_info.version_flag &&
+        packet_info.version != it->second->version() &&
+        packet_info.version == LegacyVersionForEncapsulation()) {
+      // This packet is using the Legacy Version Encapsulation version but the
+      // corresponding session isn't, attempt extraction of inner packet.
+      ChloAlpnSniExtractor alpn_extractor;
+      if (ChloExtractor::Extract(packet_info.packet, packet_info.version,
+                                 config_->create_session_tag_indicators(),
+                                 &alpn_extractor,
+                                 server_connection_id.length())) {
+        if (MaybeHandleLegacyVersionEncapsulation(
+                this,
+                alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket(),
+                packet_info)) {
+          return true;
+        }
+      }
+    }
+    it->second->ProcessUdpPacket(packet_info.self_address,
+                                 packet_info.peer_address, packet_info.packet);
+    return true;
+  }
+  if (packet_info.version.IsKnown()) {
+    // We did not find the connection ID, check if we've replaced it.
+    // This is only performed for supported versions because packets with
+    // unsupported versions can flow through this function in order to send
+    // a version negotiation packet, but we know that their connection ID
+    // did not get replaced since that is performed on connection creation,
+    // and that only happens for known verions.
+    QuicConnectionId replaced_connection_id = MaybeReplaceServerConnectionId(
+        server_connection_id, packet_info.version);
+    if (replaced_connection_id != server_connection_id) {
+      // Search for the replacement.
+      auto it2 = reference_counted_session_map_.find(replaced_connection_id);
+      if (it2 != reference_counted_session_map_.end()) {
+        QUICHE_DCHECK(
+            !buffered_packets_.HasBufferedPackets(replaced_connection_id));
+        it2->second->ProcessUdpPacket(packet_info.self_address,
+                                      packet_info.peer_address,
+                                      packet_info.packet);
+        return true;
+      }
+    }
+  }
+
+  if (buffered_packets_.HasChloForConnection(server_connection_id)) {
+    BufferEarlyPacket(packet_info);
+    return true;
+  }
+
+  if (OnFailedToDispatchPacket(packet_info)) {
+    return true;
+  }
+
+  if (time_wait_list_manager_->IsConnectionIdInTimeWait(server_connection_id)) {
+    // This connection ID is already in time-wait state.
+    time_wait_list_manager_->ProcessPacket(
+        packet_info.self_address, packet_info.peer_address,
+        packet_info.destination_connection_id, packet_info.form,
+        packet_info.packet.length(), GetPerPacketContext());
+    return true;
+  }
+
+  // The packet has an unknown connection ID.
+  if (!accept_new_connections_ && packet_info.version_flag) {
+    // If not accepting new connections, reject packets with version which can
+    // potentially result in new connection creation. But if the packet doesn't
+    // have version flag, leave it to ValidityChecks() to reset it.
+    // By adding the connection to time wait list, following packets on this
+    // connection will not reach ShouldAcceptNewConnections().
+    StatelesslyTerminateConnection(
+        packet_info.destination_connection_id, packet_info.form,
+        packet_info.version_flag, packet_info.use_length_prefix,
+        packet_info.version, QUIC_HANDSHAKE_FAILED,
+        "Stop accepting new connections",
+        quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
+    // Time wait list will reject the packet correspondingly..
+    time_wait_list_manager()->ProcessPacket(
+        packet_info.self_address, packet_info.peer_address,
+        packet_info.destination_connection_id, packet_info.form,
+        packet_info.packet.length(), GetPerPacketContext());
+    OnNewConnectionRejected();
+    return true;
+  }
+
+  // Unless the packet provides a version, assume that we can continue
+  // processing using our preferred version.
+  if (packet_info.version_flag) {
+    if (!IsSupportedVersion(packet_info.version)) {
+      if (ShouldCreateSessionForUnknownVersion(packet_info.version_label)) {
+        return false;
+      }
+      if (!crypto_config()->validate_chlo_size() ||
+          packet_info.packet.length() >= kMinPacketSizeForVersionNegotiation) {
+        // Since the version is not supported, send a version negotiation
+        // packet and stop processing the current packet.
+        QuicConnectionId client_connection_id =
+            packet_info.source_connection_id;
+        time_wait_list_manager()->SendVersionNegotiationPacket(
+            server_connection_id, client_connection_id,
+            packet_info.form != GOOGLE_QUIC_PACKET,
+            packet_info.use_length_prefix, GetSupportedVersions(),
+            packet_info.self_address, packet_info.peer_address,
+            GetPerPacketContext());
+      }
+      return true;
+    }
+
+    if (crypto_config()->validate_chlo_size() &&
+        packet_info.form == IETF_QUIC_LONG_HEADER_PACKET &&
+        packet_info.long_packet_type == INITIAL &&
+        packet_info.packet.length() < kMinClientInitialPacketLength) {
+      QUIC_DVLOG(1) << "Dropping initial packet which is too short, length: "
+                    << packet_info.packet.length();
+      QUIC_CODE_COUNT(quic_drop_small_initial_packets);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void QuicDispatcher::ProcessHeader(ReceivedPacketInfo* packet_info) {
+  QuicConnectionId server_connection_id =
+      packet_info->destination_connection_id;
+  // Packet's connection ID is unknown.  Apply the validity checks.
+  QuicPacketFate fate = ValidityChecks(*packet_info);
+
+  if (fate == kFateProcess) {
+    absl::optional<ParsedClientHello> parsed_chlo =
+        TryExtractChloOrBufferEarlyPacket(*packet_info);
+    if (!parsed_chlo.has_value()) {
+      // Client Hello incomplete. Packet has been buffered or (rarely) dropped.
+      return;
+    }
+
+    // Client Hello fully received.
+    fate = ValidityChecksOnFullChlo(*packet_info, *parsed_chlo);
+
+    if (fate == kFateProcess) {
+      QUICHE_DCHECK(
+          parsed_chlo->legacy_version_encapsulation_inner_packet.empty() ||
+          !packet_info->version.UsesTls());
+      if (MaybeHandleLegacyVersionEncapsulation(
+              this, parsed_chlo->legacy_version_encapsulation_inner_packet,
+              *packet_info)) {
+        return;
+      }
+
+      ProcessChlo(*std::move(parsed_chlo), packet_info);
+      return;
+    }
+  }
+
+  switch (fate) {
+    case kFateProcess:
+      // kFateProcess have been processed above.
+      QUIC_BUG(quic_dispatcher_bad_packet_fate) << fate;
+      break;
+    case kFateTimeWait:
+      // Add this connection_id to the time-wait state, to safely reject
+      // future packets.
+      QUIC_DLOG(INFO) << "Adding connection ID " << server_connection_id
+                      << " to time-wait list.";
+      QUIC_CODE_COUNT(quic_reject_fate_time_wait);
+      StatelesslyTerminateConnection(
+          server_connection_id, packet_info->form, packet_info->version_flag,
+          packet_info->use_length_prefix, packet_info->version,
+          QUIC_HANDSHAKE_FAILED, "Reject connection",
+          quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
+
+      QUICHE_DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
+          server_connection_id));
+      time_wait_list_manager_->ProcessPacket(
+          packet_info->self_address, packet_info->peer_address,
+          server_connection_id, packet_info->form, packet_info->packet.length(),
+          GetPerPacketContext());
+
+      buffered_packets_.DiscardPackets(server_connection_id);
+      break;
+    case kFateDrop:
+      break;
+  }
+}
+
+absl::optional<ParsedClientHello>
+QuicDispatcher::TryExtractChloOrBufferEarlyPacket(
+    const ReceivedPacketInfo& packet_info) {
+  if (packet_info.version.UsesTls()) {
+    bool has_full_tls_chlo = false;
+    std::string sni;
+    std::vector<std::string> alpns;
+    bool resumption_attempted = false, early_data_attempted = false;
+    if (buffered_packets_.HasBufferedPackets(
+            packet_info.destination_connection_id)) {
+      // If we already have buffered packets for this connection ID,
+      // use the associated TlsChloExtractor to parse this packet.
+      has_full_tls_chlo = buffered_packets_.IngestPacketForTlsChloExtraction(
+          packet_info.destination_connection_id, packet_info.version,
+          packet_info.packet, &alpns, &sni, &resumption_attempted,
+          &early_data_attempted);
+    } else {
+      // If we do not have a BufferedPacketList for this connection ID,
+      // create a single-use one to check whether this packet contains a
+      // full single-packet CHLO.
+      TlsChloExtractor tls_chlo_extractor;
+      tls_chlo_extractor.IngestPacket(packet_info.version, packet_info.packet);
+      if (tls_chlo_extractor.HasParsedFullChlo()) {
+        // This packet contains a full single-packet CHLO.
+        has_full_tls_chlo = true;
+        alpns = tls_chlo_extractor.alpns();
+        sni = tls_chlo_extractor.server_name();
+        resumption_attempted = tls_chlo_extractor.resumption_attempted();
+        early_data_attempted = tls_chlo_extractor.early_data_attempted();
+      }
+    }
+    if (!has_full_tls_chlo) {
+      // This packet does not contain a full CHLO. It could be a 0-RTT
+      // packet that arrived before the CHLO (due to loss or reordering),
+      // or it could be a fragment of a multi-packet CHLO.
+      BufferEarlyPacket(packet_info);
+      return absl::nullopt;
+    }
+
+    ParsedClientHello parsed_chlo;
+    parsed_chlo.sni = std::move(sni);
+    parsed_chlo.alpns = std::move(alpns);
+    if (packet_info.retry_token.has_value()) {
+      parsed_chlo.retry_token = std::string(*packet_info.retry_token);
+    }
+    parsed_chlo.resumption_attempted = resumption_attempted;
+    parsed_chlo.early_data_attempted = early_data_attempted;
+    return parsed_chlo;
+  }
+
+  ChloAlpnSniExtractor alpn_extractor;
+  if (GetQuicFlag(FLAGS_quic_allow_chlo_buffering) &&
+      !ChloExtractor::Extract(packet_info.packet, packet_info.version,
+                              config_->create_session_tag_indicators(),
+                              &alpn_extractor,
+                              packet_info.destination_connection_id.length())) {
+    // Buffer non-CHLO packets.
+    BufferEarlyPacket(packet_info);
+    return absl::nullopt;
+  }
+
+  // We only apply this check for versions that do not use the IETF
+  // invariant header because those versions are already checked in
+  // QuicDispatcher::MaybeDispatchPacket.
+  if (packet_info.version_flag &&
+      !packet_info.version.HasIetfInvariantHeader() &&
+      crypto_config()->validate_chlo_size() &&
+      packet_info.packet.length() < kMinClientInitialPacketLength) {
+    QUIC_DVLOG(1) << "Dropping CHLO packet which is too short, length: "
+                  << packet_info.packet.length();
+    QUIC_CODE_COUNT(quic_drop_small_chlo_packets);
+    return absl::nullopt;
+  }
+
+  ParsedClientHello parsed_chlo;
+  parsed_chlo.legacy_version_encapsulation_inner_packet =
+      alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket();
+  parsed_chlo.sni = alpn_extractor.ConsumeSni();
+  parsed_chlo.uaid = alpn_extractor.ConsumeUaid();
+  parsed_chlo.alpns = {alpn_extractor.ConsumeAlpn()};
+  return parsed_chlo;
+}
+
+std::string QuicDispatcher::SelectAlpn(const std::vector<std::string>& alpns) {
+  if (alpns.empty()) {
+    return "";
+  }
+  if (alpns.size() > 1u) {
+    const std::vector<std::string>& supported_alpns =
+        version_manager_->GetSupportedAlpns();
+    for (const std::string& alpn : alpns) {
+      if (std::find(supported_alpns.begin(), supported_alpns.end(), alpn) !=
+          supported_alpns.end()) {
+        return alpn;
+      }
+    }
+  }
+  return alpns[0];
+}
+
+QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
+    const ReceivedPacketInfo& packet_info) {
+  if (!packet_info.version_flag) {
+    QUIC_DLOG(INFO)
+        << "Packet without version arrived for unknown connection ID "
+        << packet_info.destination_connection_id;
+    MaybeResetPacketsWithNoVersion(packet_info);
+    return kFateDrop;
+  }
+
+  // Let the connection parse and validate packet number.
+  return kFateProcess;
+}
+
+void QuicDispatcher::CleanUpSession(QuicConnectionId server_connection_id,
+                                    QuicConnection* connection,
+                                    QuicErrorCode /*error*/,
+                                    const std::string& /*error_details*/,
+                                    ConnectionCloseSource /*source*/) {
+  write_blocked_list_.erase(connection);
+  QuicTimeWaitListManager::TimeWaitAction action =
+      QuicTimeWaitListManager::SEND_STATELESS_RESET;
+  if (connection->termination_packets() != nullptr &&
+      !connection->termination_packets()->empty()) {
+    action = QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS;
+  } else {
+    if (!connection->IsHandshakeComplete()) {
+      // TODO(fayang): Do not serialize connection close packet if the
+      // connection is closed by the client.
+      if (!connection->version().HasIetfInvariantHeader()) {
+        QUIC_CODE_COUNT(gquic_add_to_time_wait_list_with_handshake_failed);
+      } else {
+        QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_handshake_failed);
+      }
+      // This serializes a connection close termination packet and adds the
+      // connection to the time wait list.
+      StatelessConnectionTerminator terminator(
+          server_connection_id, connection->version(), helper_.get(),
+          time_wait_list_manager_.get());
+      terminator.CloseConnection(
+          QUIC_HANDSHAKE_FAILED,
+          "Connection is closed by server before handshake confirmed",
+          connection->version().HasIetfInvariantHeader(),
+          connection->GetActiveServerConnectionIds());
+      return;
+    }
+    QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_stateless_reset);
+  }
+  time_wait_list_manager_->AddConnectionIdToTimeWait(
+      action,
+      TimeWaitConnectionInfo(
+          connection->version().HasIetfInvariantHeader(),
+          connection->termination_packets(),
+          connection->GetActiveServerConnectionIds(),
+          connection->sent_packet_manager().GetRttStats()->smoothed_rtt()));
+}
+
+void QuicDispatcher::StartAcceptingNewConnections() {
+  accept_new_connections_ = true;
+}
+
+void QuicDispatcher::StopAcceptingNewConnections() {
+  accept_new_connections_ = false;
+  // No more CHLO will arrive and buffered CHLOs shouldn't be able to create
+  // connections.
+  buffered_packets_.DiscardAllPackets();
+}
+
+void QuicDispatcher::PerformActionOnActiveSessions(
+    std::function<void(QuicSession*)> operation) const {
+  absl::flat_hash_set<QuicSession*> visited_session;
+  visited_session.reserve(reference_counted_session_map_.size());
+  for (auto const& kv : reference_counted_session_map_) {
+    QuicSession* session = kv.second.get();
+    if (visited_session.insert(session).second) {
+      operation(session);
+    }
+  }
+}
+
+// Get a snapshot of all sessions.
+std::vector<std::shared_ptr<QuicSession>> QuicDispatcher::GetSessionsSnapshot()
+    const {
+  std::vector<std::shared_ptr<QuicSession>> snapshot;
+  snapshot.reserve(reference_counted_session_map_.size());
+  absl::flat_hash_set<QuicSession*> visited_session;
+  visited_session.reserve(reference_counted_session_map_.size());
+  for (auto const& kv : reference_counted_session_map_) {
+    QuicSession* session = kv.second.get();
+    if (visited_session.insert(session).second) {
+      snapshot.push_back(kv.second);
+    }
+  }
+  return snapshot;
+}
+
+std::unique_ptr<QuicPerPacketContext> QuicDispatcher::GetPerPacketContext()
+    const {
+  return nullptr;
+}
+
+void QuicDispatcher::DeleteSessions() {
+  if (!write_blocked_list_.empty()) {
+    for (const auto& session : closed_session_list_) {
+      if (write_blocked_list_.erase(session->connection()) != 0) {
+        QUIC_BUG(quic_bug_12724_2)
+            << "QuicConnection was in WriteBlockedList before destruction "
+            << session->connection()->connection_id();
+      }
+    }
+  }
+  closed_session_list_.clear();
+}
+
+void QuicDispatcher::ClearStatelessResetAddresses() {
+  recent_stateless_reset_addresses_.clear();
+}
+
+void QuicDispatcher::OnCanWrite() {
+  // The socket is now writable.
+  writer_->SetWritable();
+
+  // Move every blocked writer in |write_blocked_list_| to a temporary list.
+  const size_t num_blocked_writers_before = write_blocked_list_.size();
+  WriteBlockedList temp_list;
+  temp_list.swap(write_blocked_list_);
+  QUICHE_DCHECK(write_blocked_list_.empty());
+
+  // Give each blocked writer a chance to write what they indended to write.
+  // If they are blocked again, they will call |OnWriteBlocked| to add
+  // themselves back into |write_blocked_list_|.
+  while (!temp_list.empty()) {
+    QuicBlockedWriterInterface* blocked_writer = temp_list.begin()->first;
+    temp_list.erase(temp_list.begin());
+    blocked_writer->OnBlockedWriterCanWrite();
+  }
+  const size_t num_blocked_writers_after = write_blocked_list_.size();
+  if (num_blocked_writers_after != 0) {
+    if (num_blocked_writers_before == num_blocked_writers_after) {
+      QUIC_CODE_COUNT(quic_zero_progress_on_can_write);
+    } else {
+      QUIC_CODE_COUNT(quic_blocked_again_on_can_write);
+    }
+  }
+}
+
+bool QuicDispatcher::HasPendingWrites() const {
+  return !write_blocked_list_.empty();
+}
+
+void QuicDispatcher::Shutdown() {
+  while (!reference_counted_session_map_.empty()) {
+    QuicSession* session = reference_counted_session_map_.begin()->second.get();
+    session->connection()->CloseConnection(
+        QUIC_PEER_GOING_AWAY, "Server shutdown imminent",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    // Validate that the session removes itself from the session map on close.
+    QUICHE_DCHECK(reference_counted_session_map_.empty() ||
+                  reference_counted_session_map_.begin()->second.get() !=
+                      session);
+  }
+  DeleteSessions();
+}
+
+void QuicDispatcher::OnConnectionClosed(QuicConnectionId server_connection_id,
+                                        QuicErrorCode error,
+                                        const std::string& error_details,
+                                        ConnectionCloseSource source) {
+  auto it = reference_counted_session_map_.find(server_connection_id);
+  if (it == reference_counted_session_map_.end()) {
+    QUIC_BUG(quic_bug_10287_3) << "ConnectionId " << server_connection_id
+                               << " does not exist in the session map.  Error: "
+                               << QuicErrorCodeToString(error);
+    QUIC_BUG(quic_bug_10287_4) << QuicStackTrace();
+    return;
+  }
+
+  QUIC_DLOG_IF(INFO, error != QUIC_NO_ERROR)
+      << "Closing connection (" << server_connection_id
+      << ") due to error: " << QuicErrorCodeToString(error)
+      << ", with details: " << error_details;
+
+  QuicConnection* connection = it->second->connection();
+  if (ShouldDestroySessionAsynchronously()) {
+    // Set up alarm to fire immediately to bring destruction of this session
+    // out of current call stack.
+    if (closed_session_list_.empty()) {
+      delete_sessions_alarm_->Update(helper()->GetClock()->ApproximateNow(),
+                                     QuicTime::Delta::Zero());
+    }
+    closed_session_list_.push_back(std::move(it->second));
+  }
+  CleanUpSession(it->first, connection, error, error_details, source);
+  for (const QuicConnectionId& cid :
+       connection->GetActiveServerConnectionIds()) {
+    reference_counted_session_map_.erase(cid);
+  }
+  --num_sessions_in_session_map_;
+}
+
+void QuicDispatcher::OnWriteBlocked(
+    QuicBlockedWriterInterface* blocked_writer) {
+  if (!blocked_writer->IsWriterBlocked()) {
+    // It is a programming error if this ever happens. When we are sure it is
+    // not happening, replace it with a QUICHE_DCHECK.
+    QUIC_BUG(quic_bug_12724_4)
+        << "Tried to add writer into blocked list when it shouldn't be added";
+    // Return without adding the connection to the blocked list, to avoid
+    // infinite loops in OnCanWrite.
+    return;
+  }
+
+  write_blocked_list_.insert(std::make_pair(blocked_writer, true));
+}
+
+void QuicDispatcher::OnRstStreamReceived(const QuicRstStreamFrame& /*frame*/) {}
+
+void QuicDispatcher::OnStopSendingReceived(
+    const QuicStopSendingFrame& /*frame*/) {}
+
+void QuicDispatcher::OnNewConnectionIdSent(
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& new_connection_id) {
+  auto it = reference_counted_session_map_.find(server_connection_id);
+  if (it == reference_counted_session_map_.end()) {
+    QUIC_BUG(quic_bug_10287_7)
+        << "Couldn't locate the session that issues the connection ID in "
+           "reference_counted_session_map_.  server_connection_id:"
+        << server_connection_id << " new_connection_id: " << new_connection_id;
+    return;
+  }
+  // Count new connection ID added to the dispatcher map.
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 6, 6);
+  auto insertion_result = reference_counted_session_map_.insert(
+      std::make_pair(new_connection_id, it->second));
+  QUICHE_DCHECK(insertion_result.second);
+}
+
+void QuicDispatcher::OnConnectionIdRetired(
+    const QuicConnectionId& server_connection_id) {
+  reference_counted_session_map_.erase(server_connection_id);
+}
+
+void QuicDispatcher::OnConnectionAddedToTimeWaitList(
+    QuicConnectionId server_connection_id) {
+  QUIC_DLOG(INFO) << "Connection " << server_connection_id
+                  << " added to time wait list.";
+}
+
+void QuicDispatcher::StatelesslyTerminateConnection(
+    QuicConnectionId server_connection_id,
+    PacketHeaderFormat format,
+    bool version_flag,
+    bool use_length_prefix,
+    ParsedQuicVersion version,
+    QuicErrorCode error_code,
+    const std::string& error_details,
+    QuicTimeWaitListManager::TimeWaitAction action) {
+  if (format != IETF_QUIC_LONG_HEADER_PACKET && !version_flag) {
+    QUIC_DVLOG(1) << "Statelessly terminating " << server_connection_id
+                  << " based on a non-ietf-long packet, action:" << action
+                  << ", error_code:" << error_code
+                  << ", error_details:" << error_details;
+    time_wait_list_manager_->AddConnectionIdToTimeWait(
+        action, TimeWaitConnectionInfo(format != GOOGLE_QUIC_PACKET, nullptr,
+                                       {server_connection_id}));
+    return;
+  }
+
+  // If the version is known and supported by framer, send a connection close.
+  if (IsSupportedVersion(version)) {
+    QUIC_DVLOG(1)
+        << "Statelessly terminating " << server_connection_id
+        << " based on an ietf-long packet, which has a supported version:"
+        << version << ", error_code:" << error_code
+        << ", error_details:" << error_details;
+
+    StatelessConnectionTerminator terminator(server_connection_id, version,
+                                             helper_.get(),
+                                             time_wait_list_manager_.get());
+    // This also adds the connection to time wait list.
+    terminator.CloseConnection(
+        error_code, error_details, format != GOOGLE_QUIC_PACKET,
+        /*active_connection_ids=*/{server_connection_id});
+    QUIC_CODE_COUNT(quic_dispatcher_generated_connection_close);
+    QuicSession::RecordConnectionCloseAtServer(
+        error_code, ConnectionCloseSource::FROM_SELF);
+    return;
+  }
+
+  QUIC_DVLOG(1)
+      << "Statelessly terminating " << server_connection_id
+      << " based on an ietf-long packet, which has an unsupported version:"
+      << version << ", error_code:" << error_code
+      << ", error_details:" << error_details;
+  // Version is unknown or unsupported by framer, send a version negotiation
+  // with an empty version list, which can be understood by the client.
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(QuicFramer::BuildVersionNegotiationPacket(
+      server_connection_id, EmptyQuicConnectionId(),
+      /*ietf_quic=*/format != GOOGLE_QUIC_PACKET, use_length_prefix,
+      /*versions=*/{}));
+  time_wait_list_manager()->AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
+                             &termination_packets, {server_connection_id}));
+}
+
+bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(
+    QuicVersionLabel /*version_label*/) {
+  return false;
+}
+
+void QuicDispatcher::OnExpiredPackets(
+    QuicConnectionId server_connection_id,
+    BufferedPacketList early_arrived_packets) {
+  QUIC_CODE_COUNT(quic_reject_buffered_packets_expired);
+  StatelesslyTerminateConnection(
+      server_connection_id,
+      early_arrived_packets.ietf_quic ? IETF_QUIC_LONG_HEADER_PACKET
+                                      : GOOGLE_QUIC_PACKET,
+      /*version_flag=*/true,
+      early_arrived_packets.version.HasLengthPrefixedConnectionIds(),
+      early_arrived_packets.version, QUIC_HANDSHAKE_FAILED,
+      "Packets buffered for too long",
+      quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
+}
+
+void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) {
+  // Reset the counter before starting creating connections.
+  new_sessions_allowed_per_event_loop_ = max_connections_to_create;
+  for (; new_sessions_allowed_per_event_loop_ > 0;
+       --new_sessions_allowed_per_event_loop_) {
+    QuicConnectionId server_connection_id;
+    BufferedPacketList packet_list =
+        buffered_packets_.DeliverPacketsForNextConnection(
+            &server_connection_id);
+    const std::list<BufferedPacket>& packets = packet_list.buffered_packets;
+    if (packets.empty()) {
+      return;
+    }
+    if (!packet_list.parsed_chlo.has_value()) {
+      QUIC_BUG(quic_dispatcher_no_parsed_chlo_in_buffered_packets)
+          << "Buffered connection has no CHLO. connection_id:"
+          << server_connection_id;
+      continue;
+    }
+    const ParsedClientHello& parsed_chlo = *packet_list.parsed_chlo;
+    QuicConnectionId original_connection_id = server_connection_id;
+    server_connection_id = MaybeReplaceServerConnectionId(server_connection_id,
+                                                          packet_list.version);
+    std::string alpn = SelectAlpn(parsed_chlo.alpns);
+    std::unique_ptr<QuicSession> session = CreateQuicSession(
+        server_connection_id, packets.front().self_address,
+        packets.front().peer_address, alpn, packet_list.version, parsed_chlo);
+    if (original_connection_id != server_connection_id) {
+      session->connection()->SetOriginalDestinationConnectionId(
+          original_connection_id);
+    }
+    QUIC_DLOG(INFO) << "Created new session for " << server_connection_id;
+
+    auto insertion_result = reference_counted_session_map_.insert(
+        std::make_pair(server_connection_id,
+                       std::shared_ptr<QuicSession>(std::move(session))));
+    if (!insertion_result.second) {
+      QUIC_BUG(quic_bug_12724_5)
+          << "Tried to add a session to session_map with existing connection "
+             "id: "
+          << server_connection_id;
+    } else {
+      ++num_sessions_in_session_map_;
+    }
+    DeliverPacketsToSession(packets, insertion_result.first->second.get());
+  }
+}
+
+bool QuicDispatcher::HasChlosBuffered() const {
+  return buffered_packets_.HasChlosBuffered();
+}
+
+bool QuicDispatcher::ShouldCreateOrBufferPacketForConnection(
+    const ReceivedPacketInfo& packet_info) {
+  QUIC_VLOG(1) << "Received packet from new connection "
+               << packet_info.destination_connection_id;
+  return true;
+}
+
+// Return true if there is any packet buffered in the store.
+bool QuicDispatcher::HasBufferedPackets(QuicConnectionId server_connection_id) {
+  return buffered_packets_.HasBufferedPackets(server_connection_id);
+}
+
+void QuicDispatcher::OnBufferPacketFailure(
+    EnqueuePacketResult result,
+    QuicConnectionId server_connection_id) {
+  QUIC_DLOG(INFO) << "Fail to buffer packet on connection "
+                  << server_connection_id << " because of " << result;
+}
+
+QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
+  return new QuicTimeWaitListManager(writer_.get(), this, helper_->GetClock(),
+                                     alarm_factory_.get());
+}
+
+void QuicDispatcher::BufferEarlyPacket(const ReceivedPacketInfo& packet_info) {
+  bool is_new_connection = !buffered_packets_.HasBufferedPackets(
+      packet_info.destination_connection_id);
+  if (is_new_connection &&
+      !ShouldCreateOrBufferPacketForConnection(packet_info)) {
+    return;
+  }
+
+  EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
+      packet_info.destination_connection_id,
+      packet_info.form != GOOGLE_QUIC_PACKET, packet_info.packet,
+      packet_info.self_address, packet_info.peer_address, packet_info.version,
+      /*parsed_chlo=*/absl::nullopt);
+  if (rs != EnqueuePacketResult::SUCCESS) {
+    OnBufferPacketFailure(rs, packet_info.destination_connection_id);
+  }
+}
+
+void QuicDispatcher::ProcessChlo(ParsedClientHello parsed_chlo,
+                                 ReceivedPacketInfo* packet_info) {
+  if (!buffered_packets_.HasBufferedPackets(
+          packet_info->destination_connection_id) &&
+      !ShouldCreateOrBufferPacketForConnection(*packet_info)) {
+    return;
+  }
+  if (GetQuicFlag(FLAGS_quic_allow_chlo_buffering) &&
+      new_sessions_allowed_per_event_loop_ <= 0) {
+    // Can't create new session any more. Wait till next event loop.
+    QUIC_BUG_IF(quic_bug_12724_7, buffered_packets_.HasChloForConnection(
+                                      packet_info->destination_connection_id));
+    EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
+        packet_info->destination_connection_id,
+        packet_info->form != GOOGLE_QUIC_PACKET, packet_info->packet,
+        packet_info->self_address, packet_info->peer_address,
+        packet_info->version, std::move(parsed_chlo));
+    if (rs != EnqueuePacketResult::SUCCESS) {
+      OnBufferPacketFailure(rs, packet_info->destination_connection_id);
+    }
+    return;
+  }
+
+  QuicConnectionId original_connection_id =
+      packet_info->destination_connection_id;
+  packet_info->destination_connection_id = MaybeReplaceServerConnectionId(
+      original_connection_id, packet_info->version);
+  // Creates a new session and process all buffered packets for this connection.
+  std::string alpn = SelectAlpn(parsed_chlo.alpns);
+  std::unique_ptr<QuicSession> session = CreateQuicSession(
+      packet_info->destination_connection_id, packet_info->self_address,
+      packet_info->peer_address, alpn, packet_info->version, parsed_chlo);
+  if (QUIC_PREDICT_FALSE(session == nullptr)) {
+    QUIC_BUG(quic_bug_10287_8)
+        << "CreateQuicSession returned nullptr for "
+        << packet_info->destination_connection_id << " from "
+        << packet_info->peer_address << " to " << packet_info->self_address
+        << " ALPN \"" << alpn << "\" version " << packet_info->version;
+    return;
+  }
+  if (original_connection_id != packet_info->destination_connection_id) {
+    session->connection()->SetOriginalDestinationConnectionId(
+        original_connection_id);
+  }
+  QUIC_DLOG(INFO) << "Created new session for "
+                  << packet_info->destination_connection_id;
+
+  QuicSession* session_ptr;
+  auto insertion_result = reference_counted_session_map_.insert(std::make_pair(
+      packet_info->destination_connection_id,
+      std::shared_ptr<QuicSession>(std::move(session.release()))));
+  if (!insertion_result.second) {
+    QUIC_BUG(quic_bug_10287_9)
+        << "Tried to add a session to session_map with existing "
+           "connection id: "
+        << packet_info->destination_connection_id;
+  } else {
+    ++num_sessions_in_session_map_;
+  }
+  session_ptr = insertion_result.first->second.get();
+  std::list<BufferedPacket> packets =
+      buffered_packets_.DeliverPackets(packet_info->destination_connection_id)
+          .buffered_packets;
+  // Process CHLO at first.
+  session_ptr->ProcessUdpPacket(packet_info->self_address,
+                                packet_info->peer_address, packet_info->packet);
+  // Deliver queued-up packets in the same order as they arrived.
+  // Do this even when flag is off because there might be still some packets
+  // buffered in the store before flag is turned off.
+  DeliverPacketsToSession(packets, session_ptr);
+  --new_sessions_allowed_per_event_loop_;
+}
+
+bool QuicDispatcher::ShouldDestroySessionAsynchronously() {
+  return true;
+}
+
+void QuicDispatcher::SetLastError(QuicErrorCode error) {
+  last_error_ = error;
+}
+
+bool QuicDispatcher::OnFailedToDispatchPacket(
+    const ReceivedPacketInfo& /*packet_info*/) {
+  return false;
+}
+
+const ParsedQuicVersionVector& QuicDispatcher::GetSupportedVersions() {
+  return version_manager_->GetSupportedVersions();
+}
+
+void QuicDispatcher::DeliverPacketsToSession(
+    const std::list<BufferedPacket>& packets,
+    QuicSession* session) {
+  for (const BufferedPacket& packet : packets) {
+    session->ProcessUdpPacket(packet.self_address, packet.peer_address,
+                              *(packet.packet));
+  }
+}
+
+bool QuicDispatcher::IsSupportedVersion(const ParsedQuicVersion version) {
+  for (const ParsedQuicVersion& supported_version :
+       version_manager_->GetSupportedVersions()) {
+    if (version == supported_version) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicDispatcher::MaybeResetPacketsWithNoVersion(
+    const ReceivedPacketInfo& packet_info) {
+  QUICHE_DCHECK(!packet_info.version_flag);
+  // Do not send a stateless reset if a reset has been sent to this address
+  // recently.
+  if (recent_stateless_reset_addresses_.contains(packet_info.peer_address)) {
+    QUIC_CODE_COUNT(quic_donot_send_reset_repeatedly);
+    QUICHE_DCHECK(use_recent_reset_addresses_);
+    return;
+  }
+  if (packet_info.form != GOOGLE_QUIC_PACKET) {
+    // Drop IETF packets smaller than the minimal stateless reset length.
+    if (packet_info.packet.length() <=
+        QuicFramer::GetMinStatelessResetPacketLength()) {
+      QUIC_CODE_COUNT(quic_drop_too_small_short_header_packets);
+      return;
+    }
+  } else {
+    const size_t MinValidPacketLength =
+        kPacketHeaderTypeSize + expected_server_connection_id_length_ +
+        PACKET_1BYTE_PACKET_NUMBER + /*payload size=*/1 + /*tag size=*/12;
+    if (packet_info.packet.length() < MinValidPacketLength) {
+      // The packet size is too small.
+      QUIC_CODE_COUNT(drop_too_small_packets);
+      return;
+    }
+  }
+  if (use_recent_reset_addresses_) {
+    QUIC_RESTART_FLAG_COUNT(quic_use_recent_reset_addresses);
+    // Do not send a stateless reset if there are too many stateless reset
+    // addresses.
+    if (recent_stateless_reset_addresses_.size() >=
+        GetQuicFlag(FLAGS_quic_max_recent_stateless_reset_addresses)) {
+      QUIC_CODE_COUNT(quic_too_many_recent_reset_addresses);
+      return;
+    }
+    if (recent_stateless_reset_addresses_.empty()) {
+      clear_stateless_reset_addresses_alarm_->Update(
+          helper()->GetClock()->ApproximateNow() +
+              QuicTime::Delta::FromMilliseconds(GetQuicFlag(
+                  FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms)),
+          QuicTime::Delta::Zero());
+    }
+    recent_stateless_reset_addresses_.emplace(packet_info.peer_address);
+  }
+
+  time_wait_list_manager()->SendPublicReset(
+      packet_info.self_address, packet_info.peer_address,
+      packet_info.destination_connection_id,
+      packet_info.form != GOOGLE_QUIC_PACKET, packet_info.packet.length(),
+      GetPerPacketContext());
+}
+
+size_t QuicDispatcher::NumSessions() const {
+  return num_sessions_in_session_map_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_dispatcher.h b/quiche/quic/core/quic_dispatcher.h
new file mode 100644
index 0000000..e529eda
--- /dev/null
+++ b/quiche/quic/core/quic_dispatcher.h
@@ -0,0 +1,484 @@
+// 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.
+
+// A server side dispatcher which dispatches a given client's data to their
+// stream.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
+#define QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_blocked_writer_interface.h"
+#include "quiche/quic/core/quic_buffered_packet_store.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_process_packet_interface.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+#include "quiche/quic/core/quic_version_manager.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+namespace test {
+class QuicDispatcherPeer;
+}  // namespace test
+
+class QuicConfig;
+class QuicCryptoServerConfig;
+
+class QUIC_NO_EXPORT QuicDispatcher
+    : public QuicTimeWaitListManager::Visitor,
+      public ProcessPacketInterface,
+      public QuicBufferedPacketStore::VisitorInterface {
+ public:
+  // Ideally we'd have a linked_hash_set: the  boolean is unused.
+  using WriteBlockedList =
+      quiche::QuicheLinkedHashMap<QuicBlockedWriterInterface*, bool>;
+
+  QuicDispatcher(
+      const QuicConfig* config,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicVersionManager* version_manager,
+      std::unique_ptr<QuicConnectionHelperInterface> helper,
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      uint8_t expected_server_connection_id_length);
+  QuicDispatcher(const QuicDispatcher&) = delete;
+  QuicDispatcher& operator=(const QuicDispatcher&) = delete;
+
+  ~QuicDispatcher() override;
+
+  // Takes ownership of |writer|.
+  void InitializeWithWriter(QuicPacketWriter* writer);
+
+  // Process the incoming packet by creating a new session, passing it to
+  // an existing session, or passing it to the time wait list.
+  void ProcessPacket(const QuicSocketAddress& self_address,
+                     const QuicSocketAddress& peer_address,
+                     const QuicReceivedPacket& packet) override;
+
+  // Called when the socket becomes writable to allow queued writes to happen.
+  virtual void OnCanWrite();
+
+  // Returns true if there's anything in the blocked writer list.
+  virtual bool HasPendingWrites() const;
+
+  // Sends ConnectionClose frames to all connected clients.
+  void Shutdown();
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Ensure that the closed connection is cleaned up asynchronously.
+  void OnConnectionClosed(QuicConnectionId server_connection_id,
+                          QuicErrorCode error,
+                          const std::string& error_details,
+                          ConnectionCloseSource source) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Queues the blocked writer for later resumption.
+  void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Collects reset error code received on streams.
+  void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Collects reset error code received on streams.
+  void OnStopSendingReceived(const QuicStopSendingFrame& frame) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Add the newly issued connection ID to the session map.
+  void OnNewConnectionIdSent(
+      const QuicConnectionId& server_connection_id,
+      const QuicConnectionId& new_connection_id) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Remove the retired connection ID from the session map.
+  void OnConnectionIdRetired(
+      const QuicConnectionId& server_connection_id) override;
+
+  // QuicTimeWaitListManager::Visitor interface implementation
+  // Called whenever the time wait list manager adds a new connection to the
+  // time-wait list.
+  void OnConnectionAddedToTimeWaitList(
+      QuicConnectionId server_connection_id) override;
+
+  using ReferenceCountedSessionMap =
+      absl::flat_hash_map<QuicConnectionId,
+                          std::shared_ptr<QuicSession>,
+                          QuicConnectionIdHash>;
+
+  size_t NumSessions() const;
+
+  // Deletes all sessions on the closed session list and clears the list.
+  virtual void DeleteSessions();
+
+  // Clear recent_stateless_reset_addresses_.
+  void ClearStatelessResetAddresses();
+
+  using ConnectionIdMap = absl::
+      flat_hash_map<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>;
+
+  // QuicBufferedPacketStore::VisitorInterface implementation.
+  void OnExpiredPackets(QuicConnectionId server_connection_id,
+                        QuicBufferedPacketStore::BufferedPacketList
+                            early_arrived_packets) override;
+
+  // Create connections for previously buffered CHLOs as many as allowed.
+  virtual void ProcessBufferedChlos(size_t max_connections_to_create);
+
+  // Return true if there is CHLO buffered.
+  virtual bool HasChlosBuffered() const;
+
+  // Start accepting new ConnectionIds.
+  void StartAcceptingNewConnections();
+
+  // Stop accepting new ConnectionIds, either as a part of the lame
+  // duck process or because explicitly configured.
+  void StopAcceptingNewConnections();
+
+  // Apply an operation for each session.
+  void PerformActionOnActiveSessions(
+      std::function<void(QuicSession*)> operation) const;
+
+  // Get a snapshot of all sessions.
+  std::vector<std::shared_ptr<QuicSession>> GetSessionsSnapshot() const;
+
+  bool accept_new_connections() const { return accept_new_connections_; }
+
+ protected:
+  // Creates a QUIC session based on the given information.
+  // |alpn| is the selected ALPN from |parsed_chlo.alpns|.
+  virtual std::unique_ptr<QuicSession> CreateQuicSession(
+      QuicConnectionId server_connection_id,
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address, absl::string_view alpn,
+      const ParsedQuicVersion& version,
+      const ParsedClientHello& parsed_chlo) = 0;
+
+  // Tries to validate and dispatch packet based on available information.
+  // Returns true if packet is dropped or successfully dispatched (e.g.,
+  // processed by existing session, processed by time wait list, etc.),
+  // otherwise, returns false and the packet needs further processing.
+  virtual bool MaybeDispatchPacket(const ReceivedPacketInfo& packet_info);
+
+  // Generate a connection ID with a length that is expected by the dispatcher.
+  // Called only when |server_connection_id| is shorter than
+  // |expected_connection_id_length|.
+  // Note that this MUST produce a deterministic result (calling this method
+  // with two connection IDs that are equal must produce the same result).
+  // Note that this is not used in general operation because our default
+  // |expected_server_connection_id_length| is 8, and the IETF specification
+  // requires clients to use an initial length of at least 8. However, we
+  // allow disabling that requirement via
+  // |allow_short_initial_server_connection_ids_|.
+  virtual QuicConnectionId ReplaceShortServerConnectionId(
+      const ParsedQuicVersion& version,
+      const QuicConnectionId& server_connection_id,
+      uint8_t expected_server_connection_id_length) const;
+
+  // Generate a connection ID with a length that is expected by the dispatcher.
+  // Called only when |server_connection_id| is longer than
+  // |expected_connection_id_length|.
+  // Note that this MUST produce a deterministic result (calling this method
+  // with two connection IDs that are equal must produce the same result).
+  virtual QuicConnectionId ReplaceLongServerConnectionId(
+      const ParsedQuicVersion& version,
+      const QuicConnectionId& server_connection_id,
+      uint8_t expected_server_connection_id_length) const;
+
+  // Values to be returned by ValidityChecks() to indicate what should be done
+  // with a packet. Fates with greater values are considered to be higher
+  // priority. ValidityChecks should return fate based on the priority order
+  // (i.e., returns higher priority fate first)
+  enum QuicPacketFate {
+    // Process the packet normally, which is usually to establish a connection.
+    kFateProcess,
+    // Put the connection ID into time-wait state and send a public reset.
+    kFateTimeWait,
+    // Drop the packet.
+    kFateDrop,
+  };
+
+  // This method is called by ProcessHeader on packets not associated with a
+  // known connection ID.  It applies validity checks and returns a
+  // QuicPacketFate to tell what should be done with the packet.
+  // TODO(fayang): Merge ValidityChecks into MaybeDispatchPacket.
+  virtual QuicPacketFate ValidityChecks(const ReceivedPacketInfo& packet_info);
+
+  // Extra validity checks after the full Client Hello is parsed, this allows
+  // subclasses to reject a connection based on sni or alpn.
+  // Only called if ValidityChecks returns kFateProcess.
+  virtual QuicPacketFate ValidityChecksOnFullChlo(
+      const ReceivedPacketInfo& /*packet_info*/,
+      const ParsedClientHello& /*parsed_chlo*/) const {
+    return kFateProcess;
+  }
+
+  // Create and return the time wait list manager for this dispatcher, which
+  // will be owned by the dispatcher as time_wait_list_manager_
+  virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager();
+
+  // Buffers packet until it can be delivered to a connection.
+  void BufferEarlyPacket(const ReceivedPacketInfo& packet_info);
+
+  // Called when |packet_info| is the last received packet of the client hello.
+  // |parsed_chlo| is the parsed version of the client hello. Creates a new
+  // connection and delivers any buffered packets for that connection id.
+  void ProcessChlo(ParsedClientHello parsed_chlo,
+                   ReceivedPacketInfo* packet_info);
+
+  // Return true if dispatcher wants to destroy session outside of
+  // OnConnectionClosed() call stack.
+  virtual bool ShouldDestroySessionAsynchronously();
+
+  QuicTimeWaitListManager* time_wait_list_manager() {
+    return time_wait_list_manager_.get();
+  }
+
+  const ParsedQuicVersionVector& GetSupportedVersions();
+
+  const QuicConfig& config() const { return *config_; }
+
+  const QuicCryptoServerConfig* crypto_config() const { return crypto_config_; }
+
+  QuicCompressedCertsCache* compressed_certs_cache() {
+    return &compressed_certs_cache_;
+  }
+
+  QuicConnectionHelperInterface* helper() { return helper_.get(); }
+
+  QuicCryptoServerStreamBase::Helper* session_helper() {
+    return session_helper_.get();
+  }
+
+  const QuicCryptoServerStreamBase::Helper* session_helper() const {
+    return session_helper_.get();
+  }
+
+  QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
+
+  QuicPacketWriter* writer() { return writer_.get(); }
+
+  // Returns true if a session should be created for a connection with an
+  // unknown version identified by |version_label|.
+  virtual bool ShouldCreateSessionForUnknownVersion(
+      QuicVersionLabel version_label);
+
+  void SetLastError(QuicErrorCode error);
+
+  // Called by MaybeDispatchPacket when current packet cannot be dispatched.
+  // Used by subclasses to conduct specific logic to dispatch packet. Returns
+  // true if packet is successfully dispatched.
+  virtual bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info);
+
+  // Called when a new connection starts to be handled by this dispatcher.
+  // Either this connection is created or its packets is buffered while waiting
+  // for CHLO. Returns true if a new connection should be created or its packets
+  // should be buffered, false otherwise.
+  virtual bool ShouldCreateOrBufferPacketForConnection(
+      const ReceivedPacketInfo& packet_info);
+
+  bool HasBufferedPackets(QuicConnectionId server_connection_id);
+
+  // Called when BufferEarlyPacket() fail to buffer the packet.
+  virtual void OnBufferPacketFailure(
+      QuicBufferedPacketStore::EnqueuePacketResult result,
+      QuicConnectionId server_connection_id);
+
+  // Removes the session from the write blocked list, and adds the ConnectionId
+  // to the time-wait list.  The caller needs to manually remove the session
+  // from the map after that.
+  void CleanUpSession(QuicConnectionId server_connection_id,
+                      QuicConnection* connection,
+                      QuicErrorCode error,
+                      const std::string& error_details,
+                      ConnectionCloseSource source);
+
+  // Called to terminate a connection statelessly. Depending on |format|, either
+  // 1) send connection close with |error_code| and |error_details| and add
+  // connection to time wait list or 2) directly add connection to time wait
+  // list with |action|.
+  void StatelesslyTerminateConnection(
+      QuicConnectionId server_connection_id,
+      PacketHeaderFormat format,
+      bool version_flag,
+      bool use_length_prefix,
+      ParsedQuicVersion version,
+      QuicErrorCode error_code,
+      const std::string& error_details,
+      QuicTimeWaitListManager::TimeWaitAction action);
+
+  // Save/Restore per packet context.
+  virtual std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const;
+  virtual void RestorePerPacketContext(
+      std::unique_ptr<QuicPerPacketContext> /*context*/) {}
+
+  // If true, our framer will change its expected connection ID length
+  // to the received destination connection ID length of all IETF long headers.
+  void SetShouldUpdateExpectedServerConnectionIdLength(
+      bool should_update_expected_server_connection_id_length) {
+    should_update_expected_server_connection_id_length_ =
+        should_update_expected_server_connection_id_length;
+  }
+
+  // If true, the dispatcher will allow incoming initial packets that have
+  // destination connection IDs shorter than 64 bits.
+  void SetAllowShortInitialServerConnectionIds(
+      bool allow_short_initial_server_connection_ids) {
+    allow_short_initial_server_connection_ids_ =
+        allow_short_initial_server_connection_ids;
+  }
+
+  // Called if a packet from an unseen connection is reset or rejected.
+  virtual void OnNewConnectionRejected() {}
+
+  // Selects the preferred ALPN from a vector of ALPNs.
+  // This runs through the list of ALPNs provided by the client and picks the
+  // first one it supports. If no supported versions are found, the first
+  // element of the vector is returned.
+  std::string SelectAlpn(const std::vector<std::string>& alpns);
+
+  // If the connection ID length is different from what the dispatcher expects,
+  // replace the connection ID with one of the right length.
+  // Note that this MUST produce a deterministic result (calling this method
+  // with two connection IDs that are equal must produce the same result).
+  QuicConnectionId MaybeReplaceServerConnectionId(
+      const QuicConnectionId& server_connection_id,
+      const ParsedQuicVersion& version) const;
+
+  // Sends public/stateless reset packets with no version and unknown
+  // connection ID according to the packet's size.
+  virtual void MaybeResetPacketsWithNoVersion(
+      const quic::ReceivedPacketInfo& packet_info);
+
+ private:
+  friend class test::QuicDispatcherPeer;
+
+  // TODO(fayang): Consider to rename this function to
+  // ProcessValidatedPacketWithUnknownConnectionId.
+  void ProcessHeader(ReceivedPacketInfo* packet_info);
+
+  // Try to extract information(sni, alpns, ...) if the full Client Hello has
+  // been parsed.
+  //
+  // Return the parsed client hello if the full Client Hello has been
+  // successfully parsed.
+  //
+  // Otherwise return absl::nullopt and either buffer or (rarely) drop the
+  // packet.
+  absl::optional<ParsedClientHello> TryExtractChloOrBufferEarlyPacket(
+      const ReceivedPacketInfo& packet_info);
+
+  // Deliver |packets| to |session| for further processing.
+  void DeliverPacketsToSession(
+      const std::list<QuicBufferedPacketStore::BufferedPacket>& packets,
+      QuicSession* session);
+
+  // Returns true if |version| is a supported protocol version.
+  bool IsSupportedVersion(const ParsedQuicVersion version);
+
+  const QuicConfig* config_;
+
+  const QuicCryptoServerConfig* crypto_config_;
+
+  // The cache for most recently compressed certs.
+  QuicCompressedCertsCache compressed_certs_cache_;
+
+  // The list of connections waiting to write.
+  WriteBlockedList write_blocked_list_;
+
+  ReferenceCountedSessionMap reference_counted_session_map_;
+
+  // Entity that manages connection_ids in time wait state.
+  std::unique_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
+
+  // The list of closed but not-yet-deleted sessions.
+  std::vector<std::shared_ptr<QuicSession>> closed_session_list_;
+
+  // The helper used for all connections.
+  std::unique_ptr<QuicConnectionHelperInterface> helper_;
+
+  // The helper used for all sessions.
+  std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper_;
+
+  // Creates alarms.
+  std::unique_ptr<QuicAlarmFactory> alarm_factory_;
+
+  // An alarm which deletes closed sessions.
+  std::unique_ptr<QuicAlarm> delete_sessions_alarm_;
+
+  // The writer to write to the socket with.
+  std::unique_ptr<QuicPacketWriter> writer_;
+
+  // Packets which are buffered until a connection can be created to handle
+  // them.
+  QuicBufferedPacketStore buffered_packets_;
+
+  // Used to get the supported versions based on flag. Does not own.
+  QuicVersionManager* version_manager_;
+
+  // The last error set by SetLastError().
+  // TODO(fayang): consider removing last_error_.
+  QuicErrorCode last_error_;
+
+  // Number of unique session in session map.
+  size_t num_sessions_in_session_map_ = 0;
+
+  // A backward counter of how many new sessions can be create within current
+  // event loop. When reaches 0, it means can't create sessions for now.
+  int16_t new_sessions_allowed_per_event_loop_;
+
+  // True if this dispatcher is accepting new ConnectionIds (new client
+  // connections), false otherwise.
+  bool accept_new_connections_;
+
+  // If false, the dispatcher follows the IETF spec and rejects packets with
+  // invalid destination connection IDs lengths below 64 bits.
+  // If true they are allowed.
+  bool allow_short_initial_server_connection_ids_;
+
+  // IETF short headers contain a destination connection ID but do not
+  // encode its length. This variable contains the length we expect to read.
+  // This is also used to signal an error when a long header packet with
+  // different destination connection ID length is received when
+  // should_update_expected_server_connection_id_length_ is false and packet's
+  // version does not allow variable length connection ID.
+  uint8_t expected_server_connection_id_length_;
+
+  // Records client addresses that have been recently reset.
+  absl::flat_hash_set<QuicSocketAddress, QuicSocketAddressHash>
+      recent_stateless_reset_addresses_;
+
+  // An alarm which clear recent_stateless_reset_addresses_.
+  std::unique_ptr<QuicAlarm> clear_stateless_reset_addresses_alarm_;
+
+  // If true, change expected_server_connection_id_length_ to be the received
+  // destination connection ID length of all IETF long headers.
+  bool should_update_expected_server_connection_id_length_;
+
+  const bool use_recent_reset_addresses_ =
+      GetQuicRestartFlag(quic_use_recent_reset_addresses);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
diff --git a/quiche/quic/core/quic_dispatcher_test.cc b/quiche/quic/core/quic_dispatcher_test.cc
new file mode 100644
index 0000000..3dad096
--- /dev/null
+++ b/quiche/quic/core/quic_dispatcher_test.cc
@@ -0,0 +1,2914 @@
+// 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 "quiche/quic/core/quic_dispatcher.h"
+
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/chlo_extractor.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/fake_proof_source.h"
+#include "quiche/quic/test_tools/first_flight.h"
+#include "quiche/quic/test_tools/mock_quic_time_wait_list_manager.h"
+#include "quiche/quic/test_tools/quic_buffered_packet_store_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_time_wait_list_manager_peer.h"
+#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using testing::_;
+using testing::ByMove;
+using testing::Eq;
+using testing::InSequence;
+using testing::Invoke;
+using testing::NiceMock;
+using testing::Return;
+using testing::WithArg;
+using testing::WithoutArgs;
+
+static const size_t kDefaultMaxConnectionsInStore = 100;
+static const size_t kMaxConnectionsWithoutCHLO =
+    kDefaultMaxConnectionsInStore / 2;
+static const int16_t kMaxNumSessionsToCreate = 16;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestQuicSpdyServerSession : public QuicServerSessionBase {
+ public:
+  TestQuicSpdyServerSession(const QuicConfig& config,
+                            QuicConnection* connection,
+                            const QuicCryptoServerConfig* crypto_config,
+                            QuicCompressedCertsCache* compressed_certs_cache)
+      : QuicServerSessionBase(config, CurrentSupportedVersions(), connection,
+                              nullptr, nullptr, crypto_config,
+                              compressed_certs_cache) {
+    Initialize();
+  }
+  TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
+  TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
+      delete;
+
+  ~TestQuicSpdyServerSession() override { DeleteConnection(); }
+
+  MOCK_METHOD(void, OnConnectionClosed,
+              (const QuicConnectionCloseFrame& frame,
+               ConnectionCloseSource source),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
+              (override));
+
+  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) override {
+    return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
+                                    stream_helper());
+  }
+
+  QuicCryptoServerStreamBase::Helper* stream_helper() {
+    return QuicServerSessionBase::stream_helper();
+  }
+};
+
+class TestDispatcher : public QuicDispatcher {
+ public:
+  TestDispatcher(const QuicConfig* config,
+                 const QuicCryptoServerConfig* crypto_config,
+                 QuicVersionManager* version_manager, QuicRandom* random)
+      : QuicDispatcher(config, crypto_config, version_manager,
+                       std::make_unique<MockQuicConnectionHelper>(),
+                       std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
+                           new QuicSimpleCryptoServerStreamHelper()),
+                       std::make_unique<TestAlarmFactory>(),
+                       kQuicDefaultConnectionIdLength),
+        random_(random) {}
+
+  MOCK_METHOD(std::unique_ptr<QuicSession>, CreateQuicSession,
+              (QuicConnectionId connection_id,
+               const QuicSocketAddress& self_address,
+               const QuicSocketAddress& peer_address, absl::string_view alpn,
+               const ParsedQuicVersion& version,
+               const ParsedClientHello& parsed_chlo),
+              (override));
+
+  MOCK_METHOD(bool, ShouldCreateOrBufferPacketForConnection,
+              (const ReceivedPacketInfo& packet_info), (override));
+
+  struct TestQuicPerPacketContext : public QuicPerPacketContext {
+    std::string custom_packet_context;
+  };
+
+  std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const override {
+    auto test_context = std::make_unique<TestQuicPerPacketContext>();
+    test_context->custom_packet_context = custom_packet_context_;
+    return std::move(test_context);
+  }
+
+  void RestorePerPacketContext(
+      std::unique_ptr<QuicPerPacketContext> context) override {
+    TestQuicPerPacketContext* test_context =
+        static_cast<TestQuicPerPacketContext*>(context.get());
+    custom_packet_context_ = test_context->custom_packet_context;
+  }
+
+  std::string custom_packet_context_;
+
+  using QuicDispatcher::MaybeDispatchPacket;
+  using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
+  using QuicDispatcher::writer;
+
+  QuicRandom* random_;
+};
+
+// A Connection class which unregisters the session from the dispatcher when
+// sending connection close.
+// It'd be slightly more realistic to do this from the Session but it would
+// involve a lot more mocking.
+class MockServerConnection : public MockQuicConnection {
+ public:
+  MockServerConnection(QuicConnectionId connection_id,
+                       MockQuicConnectionHelper* helper,
+                       MockAlarmFactory* alarm_factory,
+                       QuicDispatcher* dispatcher)
+      : MockQuicConnection(connection_id, helper, alarm_factory,
+                           Perspective::IS_SERVER),
+        dispatcher_(dispatcher),
+        active_connection_ids_({connection_id}) {}
+
+  void AddNewConnectionId(QuicConnectionId id) {
+    dispatcher_->OnNewConnectionIdSent(active_connection_ids_.back(), id);
+    QuicConnectionPeer::SetServerConnectionId(this, id);
+    active_connection_ids_.push_back(id);
+  }
+
+  void RetireConnectionId(QuicConnectionId id) {
+    auto it = std::find(active_connection_ids_.begin(),
+                        active_connection_ids_.end(), id);
+    QUICHE_DCHECK(it != active_connection_ids_.end());
+    dispatcher_->OnConnectionIdRetired(id);
+    active_connection_ids_.erase(it);
+  }
+
+  std::vector<QuicConnectionId> GetActiveServerConnectionIds() const override {
+    return active_connection_ids_;
+  }
+
+  void UnregisterOnConnectionClosed() {
+    QUIC_LOG(ERROR) << "Unregistering " << connection_id();
+    dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
+                                    "Unregistering.",
+                                    ConnectionCloseSource::FROM_SELF);
+  }
+
+ private:
+  QuicDispatcher* dispatcher_;
+  std::vector<QuicConnectionId> active_connection_ids_;
+};
+
+class QuicDispatcherTestBase : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicDispatcherTestBase()
+      : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {}
+
+  explicit QuicDispatcherTestBase(std::unique_ptr<ProofSource> proof_source)
+      : version_(GetParam()),
+        version_manager_(AllSupportedVersions()),
+        crypto_config_(QuicCryptoServerConfig::TESTING,
+                       QuicRandom::GetInstance(), std::move(proof_source),
+                       KeyExchangeSource::Default()),
+        server_address_(QuicIpAddress::Any4(), 5),
+        dispatcher_(new NiceMock<TestDispatcher>(
+            &config_, &crypto_config_, &version_manager_,
+            mock_helper_.GetRandomGenerator())),
+        time_wait_list_manager_(nullptr),
+        session1_(nullptr),
+        session2_(nullptr),
+        store_(nullptr),
+        connection_id_(1) {}
+
+  void SetUp() override {
+    dispatcher_->InitializeWithWriter(new NiceMock<MockPacketWriter>());
+    // Set the counter to some value to start with.
+    QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
+        dispatcher_.get(), kMaxNumSessionsToCreate);
+    ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_))
+        .WillByDefault(Return(true));
+  }
+
+  MockQuicConnection* connection1() {
+    if (session1_ == nullptr) {
+      return nullptr;
+    }
+    return reinterpret_cast<MockQuicConnection*>(session1_->connection());
+  }
+
+  MockQuicConnection* connection2() {
+    if (session2_ == nullptr) {
+      return nullptr;
+    }
+    return reinterpret_cast<MockQuicConnection*>(session2_->connection());
+  }
+
+  // Process a packet with an 8 byte connection id,
+  // 6 byte packet number, default path id, and packet number 1,
+  // using the version under test.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     bool has_version_flag, const std::string& data) {
+    ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
+                  CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER);
+  }
+
+  // Process a packet with a default path id, and packet number 1,
+  // using the version under test.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     bool has_version_flag, const std::string& data,
+                     QuicConnectionIdIncluded server_connection_id_included,
+                     QuicPacketNumberLength packet_number_length) {
+    ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
+                  server_connection_id_included, packet_number_length, 1);
+  }
+
+  // Process a packet using the version under test.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     bool has_version_flag, const std::string& data,
+                     QuicConnectionIdIncluded server_connection_id_included,
+                     QuicPacketNumberLength packet_number_length,
+                     uint64_t packet_number) {
+    ProcessPacket(peer_address, server_connection_id, has_version_flag,
+                  version_, data, true, server_connection_id_included,
+                  packet_number_length, packet_number);
+  }
+
+  // Processes a packet.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     bool has_version_flag, ParsedQuicVersion version,
+                     const std::string& data, bool full_padding,
+                     QuicConnectionIdIncluded server_connection_id_included,
+                     QuicPacketNumberLength packet_number_length,
+                     uint64_t packet_number) {
+    ProcessPacket(peer_address, server_connection_id, EmptyQuicConnectionId(),
+                  has_version_flag, version, data, full_padding,
+                  server_connection_id_included, CONNECTION_ID_ABSENT,
+                  packet_number_length, packet_number);
+  }
+
+  // Processes a packet.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     QuicConnectionId client_connection_id,
+                     bool has_version_flag, ParsedQuicVersion version,
+                     const std::string& data, bool full_padding,
+                     QuicConnectionIdIncluded server_connection_id_included,
+                     QuicConnectionIdIncluded client_connection_id_included,
+                     QuicPacketNumberLength packet_number_length,
+                     uint64_t packet_number) {
+    ParsedQuicVersionVector versions(SupportedVersions(version));
+    std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+        server_connection_id, client_connection_id, has_version_flag, false,
+        packet_number, data, full_padding, server_connection_id_included,
+        client_connection_id_included, packet_number_length, &versions));
+    std::unique_ptr<QuicReceivedPacket> received_packet(
+        ConstructReceivedPacket(*packet, mock_helper_.GetClock()->Now()));
+    ProcessReceivedPacket(std::move(received_packet), peer_address, version,
+                          server_connection_id);
+  }
+
+  void ProcessReceivedPacket(
+      std::unique_ptr<QuicReceivedPacket> received_packet,
+      const QuicSocketAddress& peer_address, const ParsedQuicVersion& version,
+      const QuicConnectionId& server_connection_id) {
+    if (version.UsesQuicCrypto() &&
+        ChloExtractor::Extract(*received_packet, version, {}, nullptr,
+                               server_connection_id.length())) {
+      // Add CHLO packet to the beginning to be verified first, because it is
+      // also processed first by new session.
+      data_connection_map_[server_connection_id].push_front(
+          std::string(received_packet->data(), received_packet->length()));
+    } else {
+      // For non-CHLO, always append to last.
+      data_connection_map_[server_connection_id].push_back(
+          std::string(received_packet->data(), received_packet->length()));
+    }
+    dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
+  }
+
+  void ValidatePacket(QuicConnectionId conn_id,
+                      const QuicEncryptedPacket& packet) {
+    EXPECT_EQ(data_connection_map_[conn_id].front().length(),
+              packet.AsStringPiece().length());
+    EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
+    data_connection_map_[conn_id].pop_front();
+  }
+
+  std::unique_ptr<QuicSession> CreateSession(
+      TestDispatcher* dispatcher, const QuicConfig& config,
+      QuicConnectionId connection_id, const QuicSocketAddress& /*peer_address*/,
+      MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      TestQuicSpdyServerSession** session_ptr) {
+    MockServerConnection* connection = new MockServerConnection(
+        connection_id, helper, alarm_factory, dispatcher);
+    connection->SetQuicPacketWriter(dispatcher->writer(),
+                                    /*owns_writer=*/false);
+    auto session = std::make_unique<TestQuicSpdyServerSession>(
+        config, connection, crypto_config, compressed_certs_cache);
+    *session_ptr = session.get();
+    connection->set_visitor(session.get());
+    ON_CALL(*connection, CloseConnection(_, _, _))
+        .WillByDefault(WithoutArgs(Invoke(
+            connection, &MockServerConnection::UnregisterOnConnectionClosed)));
+    return session;
+  }
+
+  void CreateTimeWaitListManager() {
+    time_wait_list_manager_ = new MockTimeWaitListManager(
+        QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
+        mock_helper_.GetClock(), &mock_alarm_factory_);
+    // dispatcher_ takes the ownership of time_wait_list_manager_.
+    QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
+                                               time_wait_list_manager_);
+  }
+
+  std::string SerializeCHLO() {
+    CryptoHandshakeMessage client_hello;
+    client_hello.set_tag(kCHLO);
+    client_hello.SetStringPiece(kALPN, ExpectedAlpn());
+    return std::string(client_hello.GetSerialized().AsStringPiece());
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id) {
+    ProcessUndecryptableEarlyPacket(version_, peer_address,
+                                    server_connection_id);
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id) {
+    std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
+        GetUndecryptableEarlyPacket(version, server_connection_id);
+    std::unique_ptr<QuicReceivedPacket> received_packet(ConstructReceivedPacket(
+        *encrypted_packet, mock_helper_.GetClock()->Now()));
+    ProcessReceivedPacket(std::move(received_packet), peer_address, version,
+                          server_connection_id);
+  }
+
+  void ProcessFirstFlight(const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(version_, peer_address, server_connection_id);
+  }
+
+  void ProcessFirstFlight(const ParsedQuicVersion& version,
+                          const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(version, peer_address, server_connection_id,
+                       EmptyQuicConnectionId());
+  }
+
+  void ProcessFirstFlight(const ParsedQuicVersion& version,
+                          const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id,
+                          const QuicConnectionId& client_connection_id) {
+    ProcessFirstFlight(version, peer_address, server_connection_id,
+                       client_connection_id, TestClientCryptoConfig());
+  }
+
+  void ProcessFirstFlight(
+      const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id,
+      const QuicConnectionId& client_connection_id,
+      std::unique_ptr<QuicCryptoClientConfig> client_crypto_config) {
+    std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+        GetFirstFlightOfPackets(version, DefaultQuicConfig(),
+                                server_connection_id, client_connection_id,
+                                std::move(client_crypto_config));
+    for (auto&& packet : packets) {
+      ProcessReceivedPacket(std::move(packet), peer_address, version,
+                            server_connection_id);
+    }
+  }
+
+  std::unique_ptr<QuicCryptoClientConfig> TestClientCryptoConfig() {
+    auto client_crypto_config = std::make_unique<QuicCryptoClientConfig>(
+        crypto_test_utils::ProofVerifierForTesting());
+    if (address_token_.has_value()) {
+      client_crypto_config->LookupOrCreate(TestServerId())
+          ->set_source_address_token(*address_token_);
+    }
+    return client_crypto_config;
+  }
+
+  // If called, the first flight packets generated in |ProcessFirstFlight| will
+  // contain the given |address_token|.
+  void SetAddressToken(std::string address_token) {
+    address_token_ = std::move(address_token);
+  }
+
+  std::string ExpectedAlpnForVersion(ParsedQuicVersion version) {
+    return AlpnForVersion(version);
+  }
+
+  std::string ExpectedAlpn() { return ExpectedAlpnForVersion(version_); }
+
+  ParsedClientHello ParsedClientHelloForTest() {
+    ParsedClientHello parsed_chlo;
+    parsed_chlo.alpns = {ExpectedAlpn()};
+    parsed_chlo.sni = TestHostname();
+    return parsed_chlo;
+  }
+
+  void MarkSession1Deleted() { session1_ = nullptr; }
+
+  void VerifyVersionSupported(ParsedQuicVersion version) {
+    QuicConnectionId connection_id = TestConnectionId(++connection_id_);
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+    EXPECT_CALL(*dispatcher_,
+                CreateQuicSession(connection_id, _, client_address,
+                                  Eq(ExpectedAlpnForVersion(version)), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, connection_id, client_address,
+            &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(
+            Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
+              ValidatePacket(connection_id, packet);
+            })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(connection_id)));
+    ProcessFirstFlight(version, client_address, connection_id);
+  }
+
+  void VerifyVersionNotSupported(ParsedQuicVersion version) {
+    QuicConnectionId connection_id = TestConnectionId(++connection_id_);
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+    EXPECT_CALL(*dispatcher_,
+                CreateQuicSession(connection_id, _, client_address, _, _, _))
+        .Times(0);
+    ProcessFirstFlight(version, client_address, connection_id);
+  }
+
+  void TestTlsMultiPacketClientHello(bool add_reordering);
+
+  void TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+      const QuicConnectionId& server_connection_id,
+      const QuicConnectionId& client_connection_id);
+
+  TestAlarmFactory::TestAlarm* GetClearResetAddressesAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicDispatcherPeer::GetClearResetAddressesAlarm(dispatcher_.get()));
+  }
+
+  ParsedQuicVersion version_;
+  MockQuicConnectionHelper mock_helper_;
+  MockAlarmFactory mock_alarm_factory_;
+  QuicConfig config_;
+  QuicVersionManager version_manager_;
+  QuicCryptoServerConfig crypto_config_;
+  QuicSocketAddress server_address_;
+  std::unique_ptr<NiceMock<TestDispatcher>> dispatcher_;
+  MockTimeWaitListManager* time_wait_list_manager_;
+  TestQuicSpdyServerSession* session1_;
+  TestQuicSpdyServerSession* session2_;
+  std::map<QuicConnectionId, std::list<std::string>> data_connection_map_;
+  QuicBufferedPacketStore* store_;
+  uint64_t connection_id_;
+  absl::optional<std::string> address_token_;
+};
+
+class QuicDispatcherTestAllVersions : public QuicDispatcherTestBase {};
+class QuicDispatcherTestOneVersion : public QuicDispatcherTestBase {};
+
+INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsAllVersions,
+                         QuicDispatcherTestAllVersions,
+                         ::testing::ValuesIn(CurrentSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsOneVersion,
+                         QuicDispatcherTestOneVersion,
+                         ::testing::Values(CurrentSupportedVersions().front()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicDispatcherTestAllVersions, TlsClientHelloCreatesSession) {
+  if (version_.UsesQuicCrypto()) {
+    return;
+  }
+  SetAddressToken("hsdifghdsaifnasdpfjdsk");
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(
+      *dispatcher_,
+      CreateQuicSession(TestConnectionId(1), _, client_address,
+                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+}
+
+void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
+    bool add_reordering) {
+  if (!version_.UsesTls()) {
+    return;
+  }
+  SetAddressToken("857293462398");
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId server_connection_id = TestConnectionId();
+  QuicConfig client_config = DefaultQuicConfig();
+  // Add a 2000-byte custom parameter to increase the length of the CHLO.
+  constexpr auto kCustomParameterId =
+      static_cast<TransportParameters::TransportParameterId>(0xff33);
+  std::string kCustomParameterValue(2000, '-');
+  client_config.custom_transport_parameters_to_send()[kCustomParameterId] =
+      kCustomParameterValue;
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+      GetFirstFlightOfPackets(version_, client_config, server_connection_id,
+                              EmptyQuicConnectionId(),
+                              TestClientCryptoConfig());
+  ASSERT_EQ(packets.size(), 2u);
+  if (add_reordering) {
+    std::swap(packets[0], packets[1]);
+  }
+
+  // Processing the first packet should not create a new session.
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(server_connection_id)));
+  ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
+                        server_connection_id);
+
+  EXPECT_EQ(dispatcher_->NumSessions(), 0u)
+      << "No session should be created before the rest of the CHLO arrives.";
+
+  // Processing the second packet should create the new session.
+  EXPECT_CALL(
+      *dispatcher_,
+      CreateQuicSession(server_connection_id, _, client_address,
+                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, server_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(2);
+
+  ProcessReceivedPacket(std::move(packets[1]), client_address, version_,
+                        server_connection_id);
+  EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHello) {
+  TestTlsMultiPacketClientHello(/*add_reordering=*/false);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithReordering) {
+  TestTlsMultiPacketClientHello(/*add_reordering=*/true);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    return;
+  }
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId server_connection_id = TestConnectionId();
+  QuicConfig client_config = DefaultQuicConfig();
+  client_config.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+      GetFirstFlightOfPackets(version_, client_config, server_connection_id);
+  ASSERT_EQ(packets.size(), 1u);
+
+  // Validate that Legacy Version Encapsulation is actually being used by
+  // checking the version of the packet before processing it.
+  PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
+  QuicLongHeaderType long_packet_type;
+  bool version_present;
+  bool has_length_prefix;
+  QuicVersionLabel version_label;
+  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+  QuicConnectionId destination_connection_id, source_connection_id;
+  absl::optional<absl::string_view> retry_token;
+  std::string detailed_error;
+  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+      QuicEncryptedPacket(packets[0]->data(), packets[0]->length()),
+      kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+  EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
+  EXPECT_TRUE(version_present);
+  EXPECT_FALSE(has_length_prefix);
+  EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
+  EXPECT_EQ(destination_connection_id, server_connection_id);
+  EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_TRUE(detailed_error.empty());
+
+  // Processing the packet should create a new session.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(server_connection_id, _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, server_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(2);
+
+  ProcessReceivedPacket(packets[0]->Clone(), client_address, version_,
+                        server_connection_id);
+  EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+
+  // Processing the same packet a second time should also be routed by the
+  // dispatcher to the right connection (we expect ProcessUdpPacket to be
+  // called twice, see the EXPECT_CALL above).
+  ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
+                        server_connection_id);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(
+      *dispatcher_,
+      CreateQuicSession(TestConnectionId(1), _, client_address,
+                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+
+  EXPECT_CALL(
+      *dispatcher_,
+      CreateQuicSession(TestConnectionId(2), _, client_address,
+                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(2), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(2), packet);
+      })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
+  ProcessFirstFlight(client_address, TestConnectionId(2));
+
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(1)
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessPacket(client_address, TestConnectionId(1), false, "data");
+}
+
+// Regression test of b/93325907.
+TEST_P(QuicDispatcherTestAllVersions, DispatcherDoesNotRejectPacketNumberZero) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  // Verify both packets 1 and 2 are processed by connection 1.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(2)
+      .WillRepeatedly(
+          WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+            ValidatePacket(TestConnectionId(1), packet);
+          })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+  // Packet number 256 with packet number length 1 would be considered as 0 in
+  // dispatcher.
+  ProcessPacket(client_address, TestConnectionId(1), false, version_, "", true,
+                CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
+}
+
+TEST_P(QuicDispatcherTestOneVersion, StatelessVersionNegotiation) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(TestConnectionId(1), _, _, _, _, _, _, _))
+      .Times(1);
+  ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
+                     TestConnectionId(1));
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       StatelessVersionNegotiationWithVeryLongConnectionId) {
+  QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(33);
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(connection_id, _, _, _, _, _, _, _))
+      .Times(1);
+  ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
+                     connection_id);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       StatelessVersionNegotiationWithClientConnectionId) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(
+                  TestConnectionId(1), TestConnectionId(2), _, _, _, _, _, _))
+      .Times(1);
+  ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
+                     TestConnectionId(1), TestConnectionId(2));
+}
+
+TEST_P(QuicDispatcherTestOneVersion, NoVersionNegotiationWithSmallPacket) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
+      .Times(0);
+  std::string chlo = SerializeCHLO() + std::string(1200, 'a');
+  // Truncate to 1100 bytes of payload which results in a packet just
+  // under 1200 bytes after framing, packet, and encryption overhead.
+  QUICHE_DCHECK_LE(1200u, chlo.length());
+  std::string truncated_chlo = chlo.substr(0, 1100);
+  QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
+  ProcessPacket(client_address, TestConnectionId(1), true,
+                QuicVersionReservedForNegotiation(), truncated_chlo, false,
+                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
+}
+
+// Disabling CHLO size validation allows the dispatcher to send version
+// negotiation packets in response to a CHLO that is otherwise too small.
+TEST_P(QuicDispatcherTestOneVersion,
+       VersionNegotiationWithoutChloSizeValidation) {
+  crypto_config_.set_validate_chlo_size(false);
+
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
+      .Times(1);
+  std::string chlo = SerializeCHLO() + std::string(1200, 'a');
+  // Truncate to 1100 bytes of payload which results in a packet just
+  // under 1200 bytes after framing, packet, and encryption overhead.
+  QUICHE_DCHECK_LE(1200u, chlo.length());
+  std::string truncated_chlo = chlo.substr(0, 1100);
+  QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
+  ProcessPacket(client_address, TestConnectionId(1), true,
+                QuicVersionReservedForNegotiation(), truncated_chlo, true,
+                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, Shutdown) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(_, _, client_address, Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+
+  dispatcher_->Shutdown();
+}
+
+TEST_P(QuicDispatcherTestAllVersions, TimeWaitListManager) {
+  CreateTimeWaitListManager();
+
+  // Create a new session.
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, _, client_address,
+                                              Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, connection_id);
+
+  // Now close the connection, which should add it to the time wait list.
+  session1_->connection()->CloseConnection(
+      QUIC_INVALID_VERSION,
+      "Server: Packet 2 without version flag before version negotiated.",
+      ConnectionCloseBehavior::SILENT_CLOSE);
+  EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
+
+  // Dispatcher forwards subsequent packets for this connection_id to the time
+  // wait list manager.
+  EXPECT_CALL(*time_wait_list_manager_,
+              ProcessPacket(_, _, connection_id, _, _, _))
+      .Times(1);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessPacket(client_address, connection_id, true, "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, NoVersionPacketToTimeWaitListManager) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+  // Dispatcher forwards all packets for this connection_id to the time wait
+  // list manager.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              ProcessPacket(_, _, connection_id, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(1);
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions,
+       DonotTimeWaitPacketsWithUnknownConnectionIdAndNoVersion) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+
+  uint8_t short_packet[21] = {0x70, 0xa7, 0x02, 0x6b};
+  QuicReceivedPacket packet(reinterpret_cast<char*>(short_packet), 21,
+                            QuicTime::Zero());
+  uint8_t valid_size_packet[23] = {0x70, 0xa7, 0x02, 0x6c};
+  QuicReceivedPacket packet2(reinterpret_cast<char*>(valid_size_packet), 23,
+                             QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  // Verify small packet is silently dropped.
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(0);
+  dispatcher_->ProcessPacket(server_address_, client_address, packet);
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, packet2);
+}
+
+TEST_P(QuicDispatcherTestOneVersion, DropPacketWithInvalidFlags) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t all_zero_packet[1200] = {};
+  QuicReceivedPacket packet(reinterpret_cast<char*>(all_zero_packet),
+                            sizeof(all_zero_packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(0);
+  dispatcher_->ProcessPacket(server_address_, client_address, packet);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, LimitResetsToSameClientAddress) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
+  QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    // Verify only one reset is sent to the address, although multiple packets
+    // are received.
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(1);
+  } else {
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(3);
+  }
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data");
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data2");
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data3");
+
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(2);
+  ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
+                "data");
+  ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
+                "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions,
+       StopSendingResetOnTooManyRecentAddresses) {
+  SetQuicFlag(FLAGS_quic_max_recent_stateless_reset_addresses, 2);
+  const size_t kTestLifeTimeMs = 10;
+  SetQuicFlag(FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms,
+              kTestLifeTimeMs);
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
+  QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(2);
+  EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data");
+  const QuicTime expected_deadline =
+      mock_helper_.GetClock()->Now() +
+      QuicTime::Delta::FromMilliseconds(kTestLifeTimeMs);
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
+    EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
+  } else {
+    EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
+  }
+  // Received no version packet 2 after 5ms.
+  mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
+                "data");
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
+    // Verify deadline does not change.
+    EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
+  } else {
+    EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
+  }
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    // Verify reset gets throttled since there are too many recent addresses.
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(0);
+  } else {
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(1);
+  }
+  ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
+                "data");
+
+  mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    GetClearResetAddressesAlarm()->Fire();
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(2);
+  } else {
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(3);
+  }
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data");
+  ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
+                "data");
+  ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
+                "data");
+}
+
+// Makes sure nine-byte connection IDs are replaced by 8-byte ones.
+TEST_P(QuicDispatcherTestAllVersions, LongConnectionIdLengthReplaced) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    // When variable length connection IDs are not supported, the connection
+    // fails. See StrayPacketTruncatedConnectionId.
+    return;
+  }
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
+  QuicConnectionId fixed_connection_id =
+      QuicUtils::CreateReplacementConnectionId(bad_connection_id);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(fixed_connection_id, _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, fixed_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(
+          Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
+            ValidatePacket(bad_connection_id, packet);
+          })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
+  ProcessFirstFlight(client_address, bad_connection_id);
+}
+
+// Makes sure zero-byte connection IDs are replaced by 8-byte ones.
+TEST_P(QuicDispatcherTestAllVersions, InvalidShortConnectionIdLengthReplaced) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    // When variable length connection IDs are not supported, the connection
+    // fails. See StrayPacketTruncatedConnectionId.
+    return;
+  }
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
+  QuicConnectionId fixed_connection_id =
+      QuicUtils::CreateReplacementConnectionId(bad_connection_id);
+
+  // Disable validation of invalid short connection IDs.
+  dispatcher_->SetAllowShortInitialServerConnectionIds(true);
+  // Note that StrayPacketTruncatedConnectionId covers the case where the
+  // validation is still enabled.
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(fixed_connection_id, _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, fixed_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(
+          Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
+            ValidatePacket(bad_connection_id, packet);
+          })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
+  ProcessFirstFlight(client_address, bad_connection_id);
+}
+
+// Makes sure TestConnectionId(1) creates a new connection and
+// TestConnectionIdNineBytesLong(2) gets replaced.
+TEST_P(QuicDispatcherTestAllVersions, MixGoodAndBadConnectionIdLengthPackets) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    return;
+  }
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
+  QuicConnectionId fixed_connection_id =
+      QuicUtils::CreateReplacementConnectionId(bad_connection_id);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(fixed_connection_id, _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, fixed_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(
+          Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
+            ValidatePacket(bad_connection_id, packet);
+          })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
+  ProcessFirstFlight(client_address, bad_connection_id);
+
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(1)
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessPacket(client_address, TestConnectionId(1), false, "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithZeroPort) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
+
+  // dispatcher_ should drop this packet.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
+                                              client_address, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
+                "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithBlockedPort) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 17);
+
+  // dispatcher_ should drop this packet.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
+                                              client_address, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
+                "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithNonBlockedPort) {
+  CreateTimeWaitListManager();
+
+  // Port 443 must not be blocked because it might be useful for proxies to send
+  // proxied traffic with source port 443 as that allows building a full QUIC
+  // proxy using a single UDP socket.
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 443);
+
+  // dispatcher_ should not drop this packet.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+}
+
+TEST_P(QuicDispatcherTestAllVersions,
+       DropPacketWithKnownVersionAndInvalidShortInitialConnectionId) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    return;
+  }
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  // dispatcher_ should drop this packet.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessFirstFlight(client_address, EmptyQuicConnectionId());
+}
+
+TEST_P(QuicDispatcherTestAllVersions,
+       DropPacketWithKnownVersionAndInvalidInitialConnectionId) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress server_address;
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  // dispatcher_ should drop this packet with invalid connection ID.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  absl::string_view cid_str = "123456789abcdefg123456789abcdefg";
+  QuicConnectionId invalid_connection_id(cid_str.data(), cid_str.length());
+  QuicReceivedPacket packet("packet", 6, QuicTime::Zero());
+  ReceivedPacketInfo packet_info(server_address, client_address, packet);
+  packet_info.version_flag = true;
+  packet_info.version = version_;
+  packet_info.destination_connection_id = invalid_connection_id;
+
+  ASSERT_TRUE(dispatcher_->MaybeDispatchPacket(packet_info));
+}
+
+void QuicDispatcherTestBase::
+    TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+        const QuicConnectionId& server_connection_id,
+        const QuicConnectionId& client_connection_id) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(
+                  server_connection_id, client_connection_id,
+                  /*ietf_quic=*/true,
+                  /*use_length_prefix=*/true, _, _, client_address, _))
+      .Times(1);
+  ProcessFirstFlight(ParsedQuicVersion::ReservedForNegotiation(),
+                     client_address, server_connection_id,
+                     client_connection_id);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId) {
+  TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+      EmptyQuicConnectionId(), EmptyQuicConnectionId());
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId2) {
+  char server_connection_id_bytes[3] = {1, 2, 3};
+  QuicConnectionId server_connection_id(server_connection_id_bytes,
+                                        sizeof(server_connection_id_bytes));
+  TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+      server_connection_id, EmptyQuicConnectionId());
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId3) {
+  char client_connection_id_bytes[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+  QuicConnectionId client_connection_id(client_connection_id_bytes,
+                                        sizeof(client_connection_id_bytes));
+  TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+      EmptyQuicConnectionId(), client_connection_id);
+}
+
+TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) {
+  VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
+  for (ParsedQuicVersion version : CurrentSupportedVersions()) {
+    VerifyVersionSupported(version);
+    QuicDisableVersion(version);
+    VerifyVersionNotSupported(version);
+    QuicEnableVersion(version);
+    VerifyVersionSupported(version);
+  }
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionDraft28WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 0xFF, 0x00, 0x00, 28, /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionDraft27WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 0xFF, 0x00, 0x00, 27, /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionDraft25WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 0xFF, 0x00, 0x00, 25, /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionT050WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'T', '0', '5', '0', /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ049WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'Q', '0', '4', '9', /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ048WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'Q', '0', '4', '8', /*connection ID length byte*/ 0x50};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/false, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ047WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'Q', '0', '4', '7', /*connection ID length byte*/ 0x50};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/false, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ045WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'Q', '0', '4', '5', /*connection ID length byte*/ 0x50};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/false, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ044WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet44[kMinPacketSizeForVersionNegotiation] = {
+      0xFF, 'Q', '0', '4', '4', /*connection ID length byte*/ 0x50};
+  QuicReceivedPacket received_packet44(reinterpret_cast<char*>(packet44),
+                                       kMinPacketSizeForVersionNegotiation,
+                                       QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/false, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address,
+                             received_packet44);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionT051WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xFF, 'T', '0', '5', '1', /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     kMinPacketSizeForVersionNegotiation,
+                                     QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+static_assert(quic::SupportedVersions().size() == 6u,
+              "Please add new RejectDeprecatedVersion tests above this assert "
+              "when deprecating versions");
+
+TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  char packet[1200];
+  char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                            0x6c, 0x7a, 0x20, 0x21};
+  EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), destination_connection_id_bytes,
+      sizeof(destination_connection_id_bytes)));
+  QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
+  std::unique_ptr<QuicReceivedPacket> received_packet(
+      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
+  QuicConnectionId client_connection_id = EmptyQuicConnectionId();
+  QuicConnectionId server_connection_id(
+      destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(
+                  server_connection_id, client_connection_id,
+                  /*ietf_quic=*/true, /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+
+  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
+}
+
+// Testing packet writer that saves all packets instead of sending them.
+// Useful for tests that need access to sent packets.
+class SavingWriter : public QuicPacketWriterWrapper {
+ public:
+  bool IsWriteBlocked() const override { return false; }
+
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& /*self_client_address*/,
+                          const QuicSocketAddress& /*peer_client_address*/,
+                          PerPacketOptions* /*options*/) override {
+    packets_.push_back(
+        QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+  std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
+    return &packets_;
+  }
+
+ private:
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
+};
+
+TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) {
+  SavingWriter* saving_writer = new SavingWriter();
+  // dispatcher_ takes ownership of saving_writer.
+  QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
+
+  QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
+      saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
+      &mock_alarm_factory_);
+  // dispatcher_ takes ownership of time_wait_list_manager.
+  QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
+                                             time_wait_list_manager);
+  char packet[1200] = {};
+  char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                            0x6c, 0x7a, 0x20, 0x21};
+  EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), destination_connection_id_bytes,
+      sizeof(destination_connection_id_bytes)));
+  QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
+  std::unique_ptr<QuicReceivedPacket> received_packet(
+      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
+  ASSERT_EQ(1u, saving_writer->packets()->size());
+
+  char source_connection_id_bytes[255] = {};
+  uint8_t source_connection_id_length = sizeof(source_connection_id_bytes);
+  std::string detailed_error = "foobar";
+  EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
+      (*(saving_writer->packets()))[0]->data(),
+      (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ("", detailed_error);
+
+  // The source connection ID of the probe response should match the
+  // destination connection ID of the probe request.
+  quiche::test::CompareCharArraysWithHexError(
+      "parsed probe", source_connection_id_bytes, source_connection_id_length,
+      destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
+}
+
+TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) {
+  // WARNING: do not remove or modify this test without making sure that we
+  // still have adequate coverage for the Android conformance test.
+  SavingWriter* saving_writer = new SavingWriter();
+  // dispatcher_ takes ownership of saving_writer.
+  QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
+
+  QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
+      saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
+      &mock_alarm_factory_);
+  // dispatcher_ takes ownership of time_wait_list_manager.
+  QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
+                                             time_wait_list_manager);
+  // clang-format off
+  static const unsigned char packet[1200] = {
+    // Android UDP network conformance test packet as it was after this change:
+    // https://android-review.googlesource.com/c/platform/cts/+/1454515
+    0xc0,  // long header
+    0xaa, 0xda, 0xca, 0xca,  // reserved-space version number
+    0x08,  // destination connection ID length
+    0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,  // 8-byte connection ID
+    0x00,  // source connection ID length
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet), false);
+  std::unique_ptr<QuicReceivedPacket> received_packet(
+      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
+  ASSERT_EQ(1u, saving_writer->packets()->size());
+
+  // The Android UDP network conformance test directly checks that these bytes
+  // of the response match the connection ID that was sent.
+  ASSERT_GE((*(saving_writer->packets()))[0]->length(), 15u);
+  quiche::test::CompareCharArraysWithHexError(
+      "response connection ID", &(*(saving_writer->packets()))[0]->data()[7], 8,
+      reinterpret_cast<const char*>(&packet[6]), 8);
+}
+
+TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTestOld) {
+  // WARNING: this test covers an old Android Conformance Test that has now been
+  // changed, but it'll take time for the change to propagate through the
+  // Android ecosystem. The Android team has asked us to keep this test
+  // supported until at least 2021-03-31. After that date, and when we drop
+  // support for sending QUIC version negotiation packets using the legacy
+  // Google QUIC format (Q001-Q043), then we can delete this test.
+  // TODO(dschinazi) delete this test after 2021-03-31
+  SavingWriter* saving_writer = new SavingWriter();
+  // dispatcher_ takes ownership of saving_writer.
+  QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
+
+  QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
+      saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
+      &mock_alarm_factory_);
+  // dispatcher_ takes ownership of time_wait_list_manager.
+  QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
+                                             time_wait_list_manager);
+  // clang-format off
+  static const unsigned char packet[1200] = {
+    // Android UDP network conformance test packet as it was after this change:
+    // https://android-review.googlesource.com/c/platform/cts/+/1104285
+    // but before this change:
+    // https://android-review.googlesource.com/c/platform/cts/+/1454515
+    0x0d,  // public flags: version, 8-byte connection ID, 1-byte packet number
+    0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,  // 8-byte connection ID
+    0xaa, 0xda, 0xca, 0xaa,  // reserved-space version number
+    0x01,  // 1-byte packet number
+    0x00,  // private flags
+    0x07,  // PING frame
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet), false);
+  std::unique_ptr<QuicReceivedPacket> received_packet(
+      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
+  ASSERT_EQ(1u, saving_writer->packets()->size());
+
+  // The Android UDP network conformance test directly checks that bytes 1-9
+  // of the response match the connection ID that was sent.
+  static const char connection_id_bytes[] = {0x71, 0x72, 0x73, 0x74,
+                                             0x75, 0x76, 0x77, 0x78};
+  ASSERT_GE((*(saving_writer->packets()))[0]->length(),
+            1u + sizeof(connection_id_bytes));
+  quiche::test::CompareCharArraysWithHexError(
+      "response connection ID", &(*(saving_writer->packets()))[0]->data()[1],
+      sizeof(connection_id_bytes), connection_id_bytes,
+      sizeof(connection_id_bytes));
+}
+
+TEST_P(QuicDispatcherTestAllVersions, DoNotProcessSmallPacket) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
+                version_, SerializeCHLO(), /*full_padding=*/false,
+                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessSmallCoalescedPacket) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
+
+  // clang-format off
+  uint8_t coalesced_packet[1200] = {
+    // first coalesced packet
+      // public flags (long header with packet type INITIAL and
+      // 4-byte packet number)
+      0xC3,
+      // version
+      'Q', '0', '9', '9',
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x05,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // Padding
+      0x00,
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xC3,
+      // version
+      'Q', '0', '9', '9',
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+  };
+  // clang-format on
+  QuicReceivedPacket packet(reinterpret_cast<char*>(coalesced_packet), 1200,
+                            QuicTime::Zero());
+  dispatcher_->ProcessPacket(server_address_, client_address, packet);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, StopAcceptingNewConnections) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+
+  dispatcher_->StopAcceptingNewConnections();
+  EXPECT_FALSE(dispatcher_->accept_new_connections());
+
+  // No more new connections afterwards.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(2), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .Times(0u);
+  ProcessFirstFlight(client_address, TestConnectionId(2));
+
+  // Existing connections should be able to continue.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(1u)
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessPacket(client_address, TestConnectionId(1), false, "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, StartAcceptingNewConnections) {
+  dispatcher_->StopAcceptingNewConnections();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  // No more new connections afterwards.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(2), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .Times(0u);
+  ProcessFirstFlight(client_address, TestConnectionId(2));
+
+  dispatcher_->StartAcceptingNewConnections();
+  EXPECT_TRUE(dispatcher_->accept_new_connections());
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+}
+
+TEST_P(QuicDispatcherTestOneVersion, SelectAlpn) {
+  EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {}), "");
+  EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {""}), "");
+  EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"hq"}), "hq");
+  // Q033 is no longer supported but Q050 is.
+  QuicEnableVersion(ParsedQuicVersion::Q050());
+  EXPECT_EQ(
+      QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"h3-Q033", "h3-Q050"}),
+      "h3-Q050");
+}
+
+// Verify the stopgap test: Packets with truncated connection IDs should be
+// dropped.
+class QuicDispatcherTestStrayPacketConnectionId
+    : public QuicDispatcherTestBase {};
+
+INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsStrayPacketConnectionId,
+                         QuicDispatcherTestStrayPacketConnectionId,
+                         ::testing::ValuesIn(CurrentSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+// Packets with truncated connection IDs should be dropped.
+TEST_P(QuicDispatcherTestStrayPacketConnectionId,
+       StrayPacketTruncatedConnectionId) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+
+  ProcessPacket(client_address, connection_id, true, "data",
+                CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
+}
+
+class BlockingWriter : public QuicPacketWriterWrapper {
+ public:
+  BlockingWriter() : write_blocked_(false) {}
+
+  bool IsWriteBlocked() const override { return write_blocked_; }
+  void SetWritable() override { write_blocked_ = false; }
+
+  WriteResult WritePacket(const char* /*buffer*/, size_t /*buf_len*/,
+                          const QuicIpAddress& /*self_client_address*/,
+                          const QuicSocketAddress& /*peer_client_address*/,
+                          PerPacketOptions* /*options*/) override {
+    // It would be quite possible to actually implement this method here with
+    // the fake blocked status, but it would be significantly more work in
+    // Chromium, and since it's not called anyway, don't bother.
+    QUIC_LOG(DFATAL) << "Not supported";
+    return WriteResult();
+  }
+
+  bool write_blocked_;
+};
+
+class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTestBase {
+ public:
+  void SetUp() override {
+    QuicDispatcherTestBase::SetUp();
+    writer_ = new BlockingWriter;
+    QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
+
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(1), client_address,
+            &helper_, &alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+          ValidatePacket(TestConnectionId(1), packet);
+        })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+    ProcessFirstFlight(client_address, TestConnectionId(1));
+
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(2), client_address,
+            &helper_, &alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+          ValidatePacket(TestConnectionId(2), packet);
+        })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
+    ProcessFirstFlight(client_address, TestConnectionId(2));
+
+    blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
+  }
+
+  void TearDown() override {
+    if (connection1() != nullptr) {
+      EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+    }
+
+    if (connection2() != nullptr) {
+      EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+    }
+    dispatcher_->Shutdown();
+  }
+
+  // Set the dispatcher's writer to be blocked. By default, all connections use
+  // the same writer as the dispatcher in this test.
+  void SetBlocked() {
+    QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
+    writer_->write_blocked_ = true;
+  }
+
+  // Simulate what happens when connection1 gets blocked when writing.
+  void BlockConnection1() {
+    Connection1Writer()->write_blocked_ = true;
+    dispatcher_->OnWriteBlocked(connection1());
+  }
+
+  BlockingWriter* Connection1Writer() {
+    return static_cast<BlockingWriter*>(connection1()->writer());
+  }
+
+  // Simulate what happens when connection2 gets blocked when writing.
+  void BlockConnection2() {
+    Connection2Writer()->write_blocked_ = true;
+    dispatcher_->OnWriteBlocked(connection2());
+  }
+
+  BlockingWriter* Connection2Writer() {
+    return static_cast<BlockingWriter*>(connection2()->writer());
+  }
+
+ protected:
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  BlockingWriter* writer_;
+  QuicDispatcher::WriteBlockedList* blocked_list_;
+};
+
+INSTANTIATE_TEST_SUITE_P(QuicDispatcherWriteBlockedListTests,
+                         QuicDispatcherWriteBlockedListTest,
+                         ::testing::Values(CurrentSupportedVersions().front()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
+  // No OnCanWrite calls because no connections are blocked.
+  dispatcher_->OnCanWrite();
+
+  // Register connection 1 for events, and make sure it's notified.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+
+  // It should get only one notification.
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
+  // Make sure we handle events in order.
+  InSequence s;
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+
+  // Check the other ordering.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection2());
+  dispatcher_->OnWriteBlocked(connection1());
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
+  // Add and remove one connction.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  blocked_list_->erase(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
+  dispatcher_->OnCanWrite();
+
+  // Add and remove one connction and make sure it doesn't affect others.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  blocked_list_->erase(connection1());
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+
+  // Add it, remove it, and add it back and make sure things are OK.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  blocked_list_->erase(connection1());
+  dispatcher_->OnWriteBlocked(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
+  dispatcher_->OnCanWrite();
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
+  // Make sure a double add does not necessitate a double remove.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection1());
+  blocked_list_->erase(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
+  dispatcher_->OnCanWrite();
+
+  // Make sure a double add does not result in two OnCanWrite calls.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
+  dispatcher_->OnCanWrite();
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
+  // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
+  // into the write blocked list.
+  InSequence s;
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  EXPECT_CALL(*connection1(), OnCanWrite())
+      .WillOnce(
+          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+
+  // connection1 should be still in the write blocked list.
+  EXPECT_TRUE(dispatcher_->HasPendingWrites());
+
+  // Now call OnCanWrite again, connection1 should get its second chance.
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
+  // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
+  // into the write blocked list.
+  InSequence s;
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  EXPECT_CALL(*connection2(), OnCanWrite())
+      .WillOnce(
+          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
+  dispatcher_->OnCanWrite();
+
+  // connection2 should be still in the write blocked list.
+  EXPECT_TRUE(dispatcher_->HasPendingWrites());
+
+  // Now call OnCanWrite again, connection2 should get its second chance.
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest,
+       OnCanWriteHandleBlockBothConnections) {
+  // Both connections get blocked in OnCanWrite, and added back into the write
+  // blocked list.
+  InSequence s;
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  EXPECT_CALL(*connection1(), OnCanWrite())
+      .WillOnce(
+          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
+  EXPECT_CALL(*connection2(), OnCanWrite())
+      .WillOnce(
+          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
+  dispatcher_->OnCanWrite();
+
+  // Both connections should be still in the write blocked list.
+  EXPECT_TRUE(dispatcher_->HasPendingWrites());
+
+  // Now call OnCanWrite again, both connections should get its second chance.
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
+  // By default, all connections share the same packet writer with the
+  // dispatcher.
+  EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
+  EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
+
+  // Test the case where connection1 shares the same packet writer as the
+  // dispatcher, whereas connection2 owns it's packet writer.
+  // Change connection2's writer.
+  connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
+  EXPECT_NE(dispatcher_->writer(), connection2()->writer());
+
+  BlockConnection2();
+  EXPECT_TRUE(dispatcher_->HasPendingWrites());
+
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest,
+       RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
+  dispatcher_->OnConnectionClosed(connection1()->connection_id(),
+                                  QUIC_PACKET_WRITE_ERROR, "Closed by test.",
+                                  ConnectionCloseSource::FROM_SELF);
+
+  SetBlocked();
+
+  ASSERT_FALSE(dispatcher_->HasPendingWrites());
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  ASSERT_TRUE(dispatcher_->HasPendingWrites());
+
+  EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
+                  "QuicConnection was in WriteBlockedList before destruction");
+  MarkSession1Deleted();
+}
+
+class QuicDispatcherSupportMultipleConnectionIdPerConnectionTest
+    : public QuicDispatcherTestBase {
+ public:
+  QuicDispatcherSupportMultipleConnectionIdPerConnectionTest()
+      : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {
+    dispatcher_ = std::make_unique<NiceMock<TestDispatcher>>(
+        &config_, &crypto_config_, &version_manager_,
+        mock_helper_.GetRandomGenerator());
+  }
+  void AddConnection1() {
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(1), client_address,
+            &helper_, &alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+          ValidatePacket(TestConnectionId(1), packet);
+        })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+    ProcessFirstFlight(client_address, TestConnectionId(1));
+  }
+
+  void AddConnection2() {
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 2);
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(2), client_address,
+            &helper_, &alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+          ValidatePacket(TestConnectionId(2), packet);
+        })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
+    ProcessFirstFlight(client_address, TestConnectionId(2));
+  }
+
+ protected:
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    QuicDispatcherSupportMultipleConnectionIdPerConnectionTests,
+    QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+    ::testing::Values(CurrentSupportedVersions().front()),
+    ::testing::PrintToStringParamName());
+
+TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+       OnNewConnectionIdSent) {
+  AddConnection1();
+  ASSERT_EQ(dispatcher_->NumSessions(), 1u);
+  ASSERT_THAT(session1_, testing::NotNull());
+  MockServerConnection* mock_server_connection1 =
+      reinterpret_cast<MockServerConnection*>(connection1());
+
+  {
+    mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
+    EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+    auto* session =
+        QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(3));
+    ASSERT_EQ(session, session1_);
+  }
+
+  {
+    mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
+    EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+    auto* session =
+        QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(4));
+    ASSERT_EQ(session, session1_);
+  }
+
+  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  // Would timed out unless all sessions have been removed from the session map.
+  dispatcher_->Shutdown();
+}
+
+TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+       RetireConnectionIdFromSingleConnection) {
+  AddConnection1();
+  ASSERT_EQ(dispatcher_->NumSessions(), 1u);
+  ASSERT_THAT(session1_, testing::NotNull());
+  MockServerConnection* mock_server_connection1 =
+      reinterpret_cast<MockServerConnection*>(connection1());
+
+  // Adds 1 new connection id every turn and retires 2 connection ids every
+  // other turn.
+  for (int i = 2; i < 10; ++i) {
+    mock_server_connection1->AddNewConnectionId(TestConnectionId(i));
+    ASSERT_EQ(
+        QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(i)),
+        session1_);
+    ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
+                                              TestConnectionId(i - 1)),
+              session1_);
+    EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+    if (i % 2 == 1) {
+      mock_server_connection1->RetireConnectionId(TestConnectionId(i - 2));
+      mock_server_connection1->RetireConnectionId(TestConnectionId(i - 1));
+    }
+  }
+
+  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  // Would timed out unless all sessions have been removed from the session map.
+  dispatcher_->Shutdown();
+}
+
+TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+       RetireConnectionIdFromMultipleConnections) {
+  AddConnection1();
+  AddConnection2();
+  ASSERT_EQ(dispatcher_->NumSessions(), 2u);
+  MockServerConnection* mock_server_connection1 =
+      reinterpret_cast<MockServerConnection*>(connection1());
+  MockServerConnection* mock_server_connection2 =
+      reinterpret_cast<MockServerConnection*>(connection2());
+
+  for (int i = 2; i < 10; ++i) {
+    mock_server_connection1->AddNewConnectionId(TestConnectionId(2 * i - 1));
+    mock_server_connection2->AddNewConnectionId(TestConnectionId(2 * i));
+    ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
+                                              TestConnectionId(2 * i - 1)),
+              session1_);
+    ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
+                                              TestConnectionId(2 * i)),
+              session2_);
+    EXPECT_EQ(dispatcher_->NumSessions(), 2u);
+    mock_server_connection1->RetireConnectionId(TestConnectionId(2 * i - 3));
+    mock_server_connection2->RetireConnectionId(TestConnectionId(2 * i - 2));
+  }
+
+  mock_server_connection1->AddNewConnectionId(TestConnectionId(19));
+  mock_server_connection2->AddNewConnectionId(TestConnectionId(20));
+  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  // Would timed out unless all sessions have been removed from the session map.
+  dispatcher_->Shutdown();
+}
+
+TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+       TimeWaitListPoplulateCorrectly) {
+  QuicTimeWaitListManager* time_wait_list_manager =
+      QuicDispatcherPeer::GetTimeWaitListManager(dispatcher_.get());
+  AddConnection1();
+  MockServerConnection* mock_server_connection1 =
+      reinterpret_cast<MockServerConnection*>(connection1());
+
+  mock_server_connection1->AddNewConnectionId(TestConnectionId(2));
+  mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
+  mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
+  mock_server_connection1->RetireConnectionId(TestConnectionId(1));
+  mock_server_connection1->RetireConnectionId(TestConnectionId(2));
+
+  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  connection1()->CloseConnection(
+      QUIC_PEER_GOING_AWAY, "Close for testing",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_FALSE(
+      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(1)));
+  EXPECT_FALSE(
+      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(2)));
+  EXPECT_TRUE(
+      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(3)));
+  EXPECT_TRUE(
+      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(4)));
+
+  dispatcher_->Shutdown();
+}
+
+class BufferedPacketStoreTest : public QuicDispatcherTestBase {
+ public:
+  BufferedPacketStoreTest()
+      : QuicDispatcherTestBase(),
+        client_addr_(QuicIpAddress::Loopback4(), 1234) {}
+
+  void ProcessFirstFlight(const ParsedQuicVersion& version,
+                          const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id) {
+    QuicDispatcherTestBase::ProcessFirstFlight(version, peer_address,
+                                               server_connection_id);
+  }
+
+  void ProcessFirstFlight(const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(version_, peer_address, server_connection_id);
+  }
+
+  void ProcessFirstFlight(const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(client_addr_, server_connection_id);
+  }
+
+  void ProcessFirstFlight(const ParsedQuicVersion& version,
+                          const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(version, client_addr_, server_connection_id);
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id) {
+    QuicDispatcherTestBase::ProcessUndecryptableEarlyPacket(
+        version, peer_address, server_connection_id);
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id) {
+    ProcessUndecryptableEarlyPacket(version_, peer_address,
+                                    server_connection_id);
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const QuicConnectionId& server_connection_id) {
+    ProcessUndecryptableEarlyPacket(version_, client_addr_,
+                                    server_connection_id);
+  }
+
+ protected:
+  QuicSocketAddress client_addr_;
+};
+
+INSTANTIATE_TEST_SUITE_P(BufferedPacketStoreTests, BufferedPacketStoreTest,
+                         ::testing::ValuesIn(CurrentSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketBeforeChlo) {
+  InSequence s;
+  QuicConnectionId conn_id = TestConnectionId(1);
+  // Non-CHLO should be buffered upon arrival, and should trigger
+  // ShouldCreateOrBufferPacketForConnection().
+  EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
+                                ReceivedPacketInfoConnectionIdEquals(conn_id)));
+  // Process non-CHLO packet.
+  ProcessUndecryptableEarlyPacket(conn_id);
+  EXPECT_EQ(0u, dispatcher_->NumSessions())
+      << "No session should be created before CHLO arrives.";
+
+  // When CHLO arrives, a new session should be created, and all packets
+  // buffered should be delivered to the session.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(conn_id, _, client_addr_, Eq(ExpectedAlpn()), _,
+                                Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+          &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(2)  // non-CHLO + CHLO.
+      .WillRepeatedly(
+          WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(conn_id, packet);
+            }
+          })));
+  ProcessFirstFlight(conn_id);
+}
+
+TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
+  InSequence s;
+  QuicConnectionId conn_id = TestConnectionId(1);
+  // A bunch of non-CHLO should be buffered upon arrival, and the first one
+  // should trigger ShouldCreateOrBufferPacketForConnection().
+  EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
+                                ReceivedPacketInfoConnectionIdEquals(conn_id)));
+  for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
+    ProcessUndecryptableEarlyPacket(conn_id);
+  }
+  EXPECT_EQ(0u, dispatcher_->NumSessions())
+      << "No session should be created before CHLO arrives.";
+
+  // Pop out the last packet as it is also be dropped by the store.
+  data_connection_map_[conn_id].pop_back();
+  // When CHLO arrives, a new session should be created, and all packets
+  // buffered should be delivered to the session.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
+                                              Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+          &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+
+  // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
+  // should be delivered in arrival order.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(kDefaultMaxUndecryptablePackets + 1)  // + 1 for CHLO.
+      .WillRepeatedly(
+          WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(conn_id, packet);
+            }
+          })));
+  ProcessFirstFlight(conn_id);
+}
+
+TEST_P(BufferedPacketStoreTest,
+       ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
+  InSequence s;
+  // A bunch of non-CHLO should be buffered upon arrival.
+  size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
+  for (size_t i = 1; i <= kNumConnections; ++i) {
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
+    QuicConnectionId conn_id = TestConnectionId(i);
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(conn_id)));
+    ProcessUndecryptableEarlyPacket(client_address, conn_id);
+  }
+
+  // Pop out the packet on last connection as it shouldn't be enqueued in store
+  // as well.
+  data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
+
+  // Reset session creation counter to ensure processing CHLO can always
+  // create session.
+  QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
+                                                              kNumConnections);
+  // Process CHLOs to create session for these connections.
+  for (size_t i = 1; i <= kNumConnections; ++i) {
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
+    QuicConnectionId conn_id = TestConnectionId(i);
+    if (i == kNumConnections) {
+      EXPECT_CALL(*dispatcher_,
+                  ShouldCreateOrBufferPacketForConnection(
+                      ReceivedPacketInfoConnectionIdEquals(conn_id)));
+    }
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
+            &mock_alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    // First |kNumConnections| - 1 connections should have buffered
+    // a packet in store. The rest should have been dropped.
+    size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, client_address, _))
+        .Times(num_packet_to_process)
+        .WillRepeatedly(WithArg<2>(
+            Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+              if (version_.UsesQuicCrypto()) {
+                ValidatePacket(conn_id, packet);
+              }
+            })));
+
+    ProcessFirstFlight(client_address, conn_id);
+  }
+}
+
+// Tests that store delivers empty packet list if CHLO arrives firstly.
+TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
+  QuicConnectionId conn_id = TestConnectionId(1);
+  EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
+                                ReceivedPacketInfoConnectionIdEquals(conn_id)));
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
+                                              Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+          &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, client_addr_, _));
+  ProcessFirstFlight(conn_id);
+}
+
+// Tests that a retransmitted CHLO arrives after a connection for the
+// CHLO has been created.
+TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
+  InSequence s;
+  QuicConnectionId conn_id = TestConnectionId(1);
+  ProcessUndecryptableEarlyPacket(conn_id);
+
+  // When CHLO arrives, a new session should be created, and all packets
+  // buffered should be delivered to the session.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
+                                              Eq(ExpectedAlpn()), _, _))
+      .Times(1)  // Only triggered by 1st CHLO.
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+          &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(3)  // Triggered by 1 data packet and 2 CHLOs.
+      .WillRepeatedly(
+          WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(conn_id, packet);
+            }
+          })));
+
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+      GetFirstFlightOfPackets(version_, conn_id);
+  ASSERT_EQ(packets.size(), 1u);
+  // Receive the CHLO once.
+  ProcessReceivedPacket(packets[0]->Clone(), client_addr_, version_, conn_id);
+  // Receive the CHLO a second time to simulate retransmission.
+  ProcessReceivedPacket(std::move(packets[0]), client_addr_, version_, conn_id);
+}
+
+// Tests that expiration of a connection add connection id to time wait list.
+TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
+  InSequence s;
+  CreateTimeWaitListManager();
+  QuicBufferedPacketStore* store =
+      QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
+  QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
+
+  QuicConnectionId conn_id = TestConnectionId(1);
+  ProcessPacket(client_addr_, conn_id, true, absl::StrCat("data packet ", 2),
+                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
+                /*packet_number=*/2);
+
+  mock_helper_.AdvanceTime(
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
+  QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
+  // Cancel alarm as if it had been fired.
+  alarm->Cancel();
+  store->OnExpirationTimeout();
+  // New arrived CHLO will be dropped because this connection is in time wait
+  // list.
+  ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _, _));
+  ProcessFirstFlight(conn_id);
+}
+
+TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
+  // Process more than (|kMaxNumSessionsToCreate| +
+  // |kDefaultMaxConnectionsInStore|) CHLOs,
+  // the first |kMaxNumSessionsToCreate| should create connections immediately,
+  // the next |kDefaultMaxConnectionsInStore| should be buffered,
+  // the rest should be dropped.
+  QuicBufferedPacketStore* store =
+      QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
+  const size_t kNumCHLOs =
+      kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
+  for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
+    EXPECT_CALL(
+        *dispatcher_,
+        ShouldCreateOrBufferPacketForConnection(
+            ReceivedPacketInfoConnectionIdEquals(TestConnectionId(conn_id))));
+    if (conn_id <= kMaxNumSessionsToCreate) {
+      EXPECT_CALL(*dispatcher_,
+                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                    Eq(ExpectedAlpn()), _,
+                                    Eq(ParsedClientHelloForTest())))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillOnce(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(TestConnectionId(conn_id));
+    if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
+        conn_id > kMaxNumSessionsToCreate) {
+      EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
+    } else {
+      // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
+      // connections immediately, and the last CHLO should be dropped as the
+      // store is full.
+      EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
+    }
+  }
+
+  // Graduately consume buffered CHLOs. The buffered connections should be
+  // created but the dropped one shouldn't.
+  for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
+       conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
+       ++conn_id) {
+    EXPECT_CALL(*dispatcher_,
+                CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                  Eq(ExpectedAlpn()), _,
+                                  Eq(ParsedClientHelloForTest())))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
+            &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(
+            Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+              if (version_.UsesQuicCrypto()) {
+                ValidatePacket(TestConnectionId(conn_id), packet);
+              }
+            })));
+  }
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(kNumCHLOs), _, client_addr_,
+                                Eq(ExpectedAlpn()), _, _))
+      .Times(0);
+
+  while (store->HasChlosBuffered()) {
+    dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+  }
+
+  EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
+                             kDefaultMaxConnectionsInStore),
+            session1_->connection_id());
+}
+
+// Duplicated CHLO shouldn't be buffered.
+TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
+  for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
+       ++conn_id) {
+    // Last CHLO will be buffered. Others will create connection right away.
+    if (conn_id <= kMaxNumSessionsToCreate) {
+      EXPECT_CALL(*dispatcher_,
+                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                    Eq(ExpectedAlpn()), _, _))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillOnce(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(TestConnectionId(conn_id));
+  }
+  // Retransmit CHLO on last connection should be dropped.
+  QuicConnectionId last_connection =
+      TestConnectionId(kMaxNumSessionsToCreate + 1);
+  ProcessFirstFlight(last_connection);
+
+  size_t packets_buffered = 2;
+
+  // Reset counter and process buffered CHLO.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, _, client_addr_,
+                                              Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, last_connection, client_addr_,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  // Only one packet(CHLO) should be process.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(packets_buffered)
+      .WillRepeatedly(WithArg<2>(
+          Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(last_connection, packet);
+            }
+          })));
+  dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+}
+
+TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
+  uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
+  QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
+  for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
+    // Last CHLO will be buffered. Others will create connection right away.
+    if (conn_id <= kMaxNumSessionsToCreate) {
+      EXPECT_CALL(*dispatcher_,
+                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                    Eq(ExpectedAlpn()), _, _))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillRepeatedly(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(TestConnectionId(conn_id));
+  }
+
+  // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
+  // last one should be dropped.
+  for (uint64_t packet_number = 2;
+       packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
+    ProcessPacket(client_addr_, last_connection_id, true, "data packet");
+  }
+
+  // Reset counter and process buffered CHLO.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(last_connection_id, _, client_addr_,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, last_connection_id, client_addr_,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
+  // should be process.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(kDefaultMaxUndecryptablePackets + 1)
+      .WillRepeatedly(WithArg<2>(
+          Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(last_connection_id, packet);
+            }
+          })));
+  dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+}
+
+// Tests that when dispatcher's packet buffer is full, a CHLO on connection
+// which doesn't have buffered CHLO should be buffered.
+TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
+  QuicBufferedPacketStore* store =
+      QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
+
+  uint64_t conn_id = 1;
+  ProcessUndecryptableEarlyPacket(TestConnectionId(conn_id));
+  // Fill packet buffer to full with CHLOs on other connections. Need to feed
+  // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
+  // session directly.
+  for (conn_id = 2;
+       conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
+       ++conn_id) {
+    if (conn_id <= kMaxNumSessionsToCreate + 1) {
+      EXPECT_CALL(*dispatcher_,
+                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                    Eq(ExpectedAlpn()), _, _))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillOnce(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(TestConnectionId(conn_id));
+  }
+  EXPECT_FALSE(store->HasChloForConnection(
+      /*connection_id=*/TestConnectionId(1)));
+
+  // CHLO on connection 1 should still be buffered.
+  ProcessFirstFlight(TestConnectionId(1));
+  EXPECT_TRUE(store->HasChloForConnection(
+      /*connection_id=*/TestConnectionId(1)));
+}
+
+// Regression test for b/117874922.
+TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
+  // Ensure the preferred version is not supported by the server.
+  QuicDisableVersion(AllSupportedVersions().front());
+
+  uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
+  ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
+  for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
+    // Last 5 CHLOs will be buffered. Others will create connection right away.
+    ParsedQuicVersion version =
+        supported_versions[(conn_id - 1) % supported_versions.size()];
+    if (conn_id <= kMaxNumSessionsToCreate) {
+      EXPECT_CALL(
+          *dispatcher_,
+          CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                            Eq(ExpectedAlpnForVersion(version)), version, _))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillRepeatedly(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(version, TestConnectionId(conn_id));
+  }
+
+  // Process buffered CHLOs. Verify the version is correct.
+  for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
+       conn_id <= last_connection_id; ++conn_id) {
+    ParsedQuicVersion version =
+        supported_versions[(conn_id - 1) % supported_versions.size()];
+    EXPECT_CALL(
+        *dispatcher_,
+        CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                          Eq(ExpectedAlpnForVersion(version)), version, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
+            &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillRepeatedly(WithArg<2>(
+            Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+              if (version_.UsesQuicCrypto()) {
+                ValidatePacket(TestConnectionId(conn_id), packet);
+              }
+            })));
+  }
+  dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_alarm_factory.cc b/quiche/quic/core/quic_epoll_alarm_factory.cc
new file mode 100644
index 0000000..23df28b
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_alarm_factory.cc
@@ -0,0 +1,89 @@
+// 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 "quiche/quic/core/quic_epoll_alarm_factory.h"
+
+#include <type_traits>
+
+#include "quiche/quic/core/quic_arena_scoped_ptr.h"
+
+namespace quic {
+namespace {
+
+class QuicEpollAlarm : public QuicAlarm {
+ public:
+  QuicEpollAlarm(QuicEpollServer* epoll_server,
+                 QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
+      : QuicAlarm(std::move(delegate)),
+        epoll_server_(epoll_server),
+        epoll_alarm_impl_(this) {}
+
+ protected:
+  void SetImpl() override {
+    QUICHE_DCHECK(deadline().IsInitialized());
+    epoll_server_->RegisterAlarm(
+        (deadline() - QuicTime::Zero()).ToMicroseconds(), &epoll_alarm_impl_);
+  }
+
+  void CancelImpl() override {
+    QUICHE_DCHECK(!deadline().IsInitialized());
+    epoll_alarm_impl_.UnregisterIfRegistered();
+  }
+
+  void UpdateImpl() override {
+    QUICHE_DCHECK(deadline().IsInitialized());
+    int64_t epoll_deadline = (deadline() - QuicTime::Zero()).ToMicroseconds();
+    if (epoll_alarm_impl_.registered()) {
+      epoll_alarm_impl_.ReregisterAlarm(epoll_deadline);
+    } else {
+      epoll_server_->RegisterAlarm(epoll_deadline, &epoll_alarm_impl_);
+    }
+  }
+
+ private:
+  class EpollAlarmImpl : public QuicEpollAlarmBase {
+   public:
+    using int64_epoll = decltype(QuicEpollAlarmBase().OnAlarm());
+
+    explicit EpollAlarmImpl(QuicEpollAlarm* alarm) : alarm_(alarm) {}
+
+    // Use the same integer type as the base class.
+    int64_epoll OnAlarm() override {
+      QuicEpollAlarmBase::OnAlarm();
+      alarm_->Fire();
+      // Fire will take care of registering the alarm, if needed.
+      return 0;
+    }
+
+   private:
+    QuicEpollAlarm* alarm_;
+  };
+
+  QuicEpollServer* epoll_server_;
+  EpollAlarmImpl epoll_alarm_impl_;
+};
+
+}  // namespace
+
+QuicEpollAlarmFactory::QuicEpollAlarmFactory(QuicEpollServer* epoll_server)
+    : epoll_server_(epoll_server) {}
+
+QuicEpollAlarmFactory::~QuicEpollAlarmFactory() = default;
+
+QuicAlarm* QuicEpollAlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
+  return new QuicEpollAlarm(epoll_server_,
+                            QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
+}
+
+QuicArenaScopedPtr<QuicAlarm> QuicEpollAlarmFactory::CreateAlarm(
+    QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+    QuicConnectionArena* arena) {
+  if (arena != nullptr) {
+    return arena->New<QuicEpollAlarm>(epoll_server_, std::move(delegate));
+  }
+  return QuicArenaScopedPtr<QuicAlarm>(
+      new QuicEpollAlarm(epoll_server_, std::move(delegate)));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_alarm_factory.h b/quiche/quic/core/quic_epoll_alarm_factory.h
new file mode 100644
index 0000000..8ccc923
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_alarm_factory.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2015 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_EPOLL_ALARM_FACTORY_H_
+#define QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+
+namespace quic {
+
+// Creates alarms that use the supplied EpollServer for timing and firing.
+class QUIC_EXPORT_PRIVATE QuicEpollAlarmFactory : public QuicAlarmFactory {
+ public:
+  explicit QuicEpollAlarmFactory(QuicEpollServer* epoll_server);
+  QuicEpollAlarmFactory(const QuicEpollAlarmFactory&) = delete;
+  QuicEpollAlarmFactory& operator=(const QuicEpollAlarmFactory&) = delete;
+  ~QuicEpollAlarmFactory() override;
+
+  // QuicAlarmFactory interface.
+  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
+  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+      QuicConnectionArena* arena) override;
+
+ private:
+  QuicEpollServer* epoll_server_;  // Not owned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
diff --git a/quiche/quic/core/quic_epoll_alarm_factory_test.cc b/quiche/quic/core/quic_epoll_alarm_factory_test.cc
new file mode 100644
index 0000000..30fd188
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_alarm_factory_test.cc
@@ -0,0 +1,141 @@
+// Copyright (c) 2015 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 "quiche/quic/core/quic_epoll_alarm_factory.h"
+
+#include "quiche/quic/core/quic_epoll_clock.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/platform/api/quiche_epoll_test_tools.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestDelegate : public QuicAlarm::DelegateWithoutContext {
+ public:
+  TestDelegate() : fired_(false) {}
+
+  void OnAlarm() override { fired_ = true; }
+
+  bool fired() const { return fired_; }
+
+ private:
+  bool fired_;
+};
+
+// The boolean parameter denotes whether or not to use an arena.
+class QuicEpollAlarmFactoryTest : public QuicTestWithParam<bool> {
+ protected:
+  QuicEpollAlarmFactoryTest()
+      : clock_(&epoll_server_), alarm_factory_(&epoll_server_) {}
+
+  QuicConnectionArena* GetArenaParam() {
+    return GetParam() ? &arena_ : nullptr;
+  }
+
+  const QuicEpollClock clock_;
+  QuicEpollAlarmFactory alarm_factory_;
+  quiche::QuicheFakeEpollServer epoll_server_;
+  QuicConnectionArena arena_;
+};
+
+INSTANTIATE_TEST_SUITE_P(UseArena,
+                         QuicEpollAlarmFactoryTest,
+                         ::testing::ValuesIn({true, false}),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicEpollAlarmFactoryTest, CreateAlarm) {
+  QuicArenaScopedPtr<TestDelegate> delegate =
+      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
+  QuicArenaScopedPtr<QuicAlarm> alarm(
+      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
+
+  QuicTime start = clock_.Now();
+  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+  alarm->Set(start + delta);
+
+  epoll_server_.AdvanceByAndWaitForEventsAndExecuteCallbacks(
+      delta.ToMicroseconds());
+  EXPECT_EQ(start + delta, clock_.Now());
+}
+
+TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndCancel) {
+  QuicArenaScopedPtr<TestDelegate> delegate =
+      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
+  TestDelegate* unowned_delegate = delegate.get();
+  QuicArenaScopedPtr<QuicAlarm> alarm(
+      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
+
+  QuicTime start = clock_.Now();
+  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+  alarm->Set(start + delta);
+  alarm->Cancel();
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
+  EXPECT_EQ(start + delta, clock_.Now());
+  EXPECT_FALSE(unowned_delegate->fired());
+}
+
+TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndReset) {
+  QuicArenaScopedPtr<TestDelegate> delegate =
+      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
+  TestDelegate* unowned_delegate = delegate.get();
+  QuicArenaScopedPtr<QuicAlarm> alarm(
+      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
+
+  QuicTime start = clock_.Now();
+  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+  alarm->Set(clock_.Now() + delta);
+  alarm->Cancel();
+  QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
+  alarm->Set(clock_.Now() + new_delta);
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
+  EXPECT_EQ(start + delta, clock_.Now());
+  EXPECT_FALSE(unowned_delegate->fired());
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(
+      (new_delta - delta).ToMicroseconds());
+  EXPECT_EQ(start + new_delta, clock_.Now());
+  EXPECT_TRUE(unowned_delegate->fired());
+}
+
+TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndUpdate) {
+  QuicArenaScopedPtr<TestDelegate> delegate =
+      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
+  TestDelegate* unowned_delegate = delegate.get();
+  QuicArenaScopedPtr<QuicAlarm> alarm(
+      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
+
+  QuicTime start = clock_.Now();
+  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+  alarm->Set(clock_.Now() + delta);
+  QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
+  alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
+  EXPECT_EQ(start + delta, clock_.Now());
+  EXPECT_FALSE(unowned_delegate->fired());
+
+  // Move the alarm forward 1us and ensure it doesn't move forward.
+  alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(2));
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(
+      (new_delta - delta).ToMicroseconds());
+  EXPECT_EQ(start + new_delta, clock_.Now());
+  EXPECT_TRUE(unowned_delegate->fired());
+
+  // Set the alarm via an update call.
+  new_delta = QuicTime::Delta::FromMicroseconds(5);
+  alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
+  EXPECT_TRUE(alarm->IsSet());
+
+  // Update it with an uninitialized time and ensure it's cancelled.
+  alarm->Update(QuicTime::Zero(), QuicTime::Delta::FromMicroseconds(1));
+  EXPECT_FALSE(alarm->IsSet());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_clock.cc b/quiche/quic/core/quic_epoll_clock.cc
new file mode 100644
index 0000000..a4087a0
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_clock.cc
@@ -0,0 +1,46 @@
+// Copyright 2022 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 "quiche/quic/core/quic_epoll_clock.h"
+
+#include "quiche/common/platform/api/quiche_flag_utils.h"
+
+namespace quic {
+
+QuicEpollClock::QuicEpollClock(QuicEpollServer* epoll_server)
+    : epoll_server_(epoll_server), largest_time_(QuicTime::Zero()) {}
+
+QuicEpollClock::~QuicEpollClock() {}
+
+QuicTime QuicEpollClock::ApproximateNow() const {
+  return CreateTimeFromMicroseconds(epoll_server_->ApproximateNowInUsec());
+}
+
+QuicTime QuicEpollClock::Now() const {
+  QuicTime now = CreateTimeFromMicroseconds(epoll_server_->NowInUsec());
+
+  if (now <= largest_time_) {
+    if (now < largest_time_) {
+      QUICHE_CODE_COUNT(quic_epoll_clock_step_backward);
+    }
+    // Time not increasing, return |largest_time_|.
+    return largest_time_;
+  }
+
+  largest_time_ = now;
+  return largest_time_;
+}
+
+QuicWallTime QuicEpollClock::WallNow() const {
+  return QuicWallTime::FromUNIXMicroseconds(
+      epoll_server_->ApproximateNowInUsec());
+}
+
+QuicTime QuicEpollClock::ConvertWallTimeToQuicTime(
+    const QuicWallTime& walltime) const {
+  return QuicTime::Zero() +
+         QuicTime::Delta::FromMicroseconds(walltime.ToUNIXMicroseconds());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_clock.h b/quiche/quic/core/quic_epoll_clock.h
new file mode 100644
index 0000000..42bea33
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_clock.h
@@ -0,0 +1,48 @@
+// Copyright 2022 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_EPOLL_CLOCK_H_
+#define QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
+
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Clock to efficiently retrieve an approximately accurate time from an
+// EpollServer.
+class QUIC_EXPORT_PRIVATE QuicEpollClock : public QuicClock {
+ public:
+  explicit QuicEpollClock(QuicEpollServer* epoll_server);
+  QuicEpollClock(const QuicEpollClock&) = delete;
+  QuicEpollClock& operator=(const QuicEpollClock&) = delete;
+  ~QuicEpollClock() override;
+
+  // Returns the approximate current time as a QuicTime object.
+  QuicTime ApproximateNow() const override;
+
+  // Returns the current time as a QuicTime object.
+  // Note: this use significant resources please use only if needed.
+  QuicTime Now() const override;
+
+  // WallNow returns the current wall-time - a time that is consistent across
+  // different clocks.
+  QuicWallTime WallNow() const override;
+
+  // Override to do less work in this implementation.  The epoll clock is
+  // already based on system (unix epoch) time, no conversion required.
+  QuicTime ConvertWallTimeToQuicTime(
+      const QuicWallTime& walltime) const override;
+
+ protected:
+  QuicEpollServer* epoll_server_;
+  // Largest time returned from Now() so far.
+  mutable QuicTime largest_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
diff --git a/quiche/quic/core/quic_epoll_clock_test.cc b/quiche/quic/core/quic_epoll_clock_test.cc
new file mode 100644
index 0000000..e501fc4
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_clock_test.cc
@@ -0,0 +1,139 @@
+// Copyright 2022 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 "quiche/quic/core/quic_epoll_clock.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/platform/api/quiche_epoll_test_tools.h"
+
+namespace quic {
+namespace test {
+
+class QuicEpollClockTest : public QuicTest {};
+
+TEST_F(QuicEpollClockTest, ApproximateNowInUsec) {
+  quiche::QuicheFakeEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  epoll_server.set_now_in_usec(1000000);
+  EXPECT_EQ(1000000,
+            (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
+  EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
+  EXPECT_EQ(1000000u, clock.WallNow().ToUNIXMicroseconds());
+
+  epoll_server.AdvanceBy(5);
+  EXPECT_EQ(1000005,
+            (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
+  EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
+  EXPECT_EQ(1000005u, clock.WallNow().ToUNIXMicroseconds());
+
+  epoll_server.AdvanceBy(10 * 1000000);
+  EXPECT_EQ(11u, clock.WallNow().ToUNIXSeconds());
+  EXPECT_EQ(11000005u, clock.WallNow().ToUNIXMicroseconds());
+}
+
+TEST_F(QuicEpollClockTest, NowInUsec) {
+  quiche::QuicheFakeEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  epoll_server.set_now_in_usec(1000000);
+  EXPECT_EQ(1000000, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
+
+  epoll_server.AdvanceBy(5);
+  EXPECT_EQ(1000005, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
+}
+
+TEST_F(QuicEpollClockTest, CalibrateRealEpollClock) {
+  QuicEpollServer epoll_server;
+
+  QuicEpollClock uncalibrated_clock(&epoll_server);
+  QuicEpollClock calibrated_clock(&epoll_server);
+  EXPECT_TRUE(calibrated_clock.ComputeCalibrationOffset().IsZero());
+
+  for (int i = 0; i < 100; ++i) {
+    QuicWallTime wallnow = uncalibrated_clock.WallNow();
+    EXPECT_EQ(uncalibrated_clock.ConvertWallTimeToQuicTime(wallnow),
+              calibrated_clock.ConvertWallTimeToQuicTime(wallnow));
+  }
+}
+
+// ClockWithOffset is a clock whose offset(WallNow() - Now() at any instant) is
+// given at construction time.
+class ClockWithOffset : public QuicEpollClock {
+ public:
+  ClockWithOffset(QuicEpollServer* epoll_server, QuicTime::Delta offset)
+      : QuicEpollClock(epoll_server), offset_(offset) {}
+
+  QuicTime Now() const override { return QuicEpollClock::Now() - offset_; }
+
+  // QuicEpollClock disables ConvertWallTimeToQuicTime since it always have a
+  // zero offset. We need to re-enable it here in order to test the calibration
+  // and conversion code in QuicClock.
+  QuicTime ConvertWallTimeToQuicTime(
+      const QuicWallTime& walltime) const override {
+    return QuicClock::ConvertWallTimeToQuicTime(walltime);
+  }
+
+ private:
+  QuicTime::Delta offset_;
+};
+
+TEST_F(QuicEpollClockTest, CalibrateClockWithOffset) {
+  QuicEpollServer epoll_server;
+
+  for (const QuicTime::Delta& offset : {QuicTime::Delta::FromSeconds(5000),
+                                        QuicTime::Delta::FromSeconds(-8000)}) {
+    ClockWithOffset clock(&epoll_server, offset);
+    ASSERT_EQ(offset, clock.ComputeCalibrationOffset())
+        << "offset (us): " << offset.ToMicroseconds();
+    // Test fails without this.
+    clock.SetCalibrationOffset(offset);
+
+    QuicWallTime last_walltime = clock.WallNow();
+    QuicTime last_time = clock.ConvertWallTimeToQuicTime(last_walltime);
+
+    for (int i = 0; i < 1e5; ++i) {
+      QuicWallTime wallnow = clock.WallNow();
+      QuicTime now = clock.ConvertWallTimeToQuicTime(wallnow);
+
+      if (wallnow.IsAfter(last_walltime)) {
+        ASSERT_LT(0, (now - last_time).ToMicroseconds())
+            << "offset (us): " << offset.ToMicroseconds();
+
+        last_walltime = wallnow;
+        last_time = now;
+      }
+    }
+  }
+}
+
+TEST_F(QuicEpollClockTest, MonotonicityWithRealEpollClock) {
+  QuicEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  QuicTime last_now = clock.Now();
+  for (int i = 0; i < 1e5; ++i) {
+    QuicTime now = clock.Now();
+
+    ASSERT_LE(last_now, now);
+
+    last_now = now;
+  }
+}
+
+TEST_F(QuicEpollClockTest, MonotonicityWithFakeEpollClock) {
+  quiche::QuicheFakeEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  epoll_server.set_now_in_usec(100);
+  QuicTime last_now = clock.Now();
+
+  epoll_server.set_now_in_usec(90);
+  QuicTime now = clock.Now();
+
+  ASSERT_EQ(last_now, now);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_connection_helper.cc b/quiche/quic/core/quic_epoll_connection_helper.cc
new file mode 100644
index 0000000..0ccd2c1
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_connection_helper.cc
@@ -0,0 +1,40 @@
+// 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 "quiche/quic/core/quic_epoll_connection_helper.h"
+
+#include <errno.h>
+#include <sys/socket.h>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+
+namespace quic {
+
+QuicEpollConnectionHelper::QuicEpollConnectionHelper(
+    QuicEpollServer* epoll_server, QuicAllocator allocator_type)
+    : clock_(epoll_server),
+      random_generator_(QuicRandom::GetInstance()),
+      allocator_type_(allocator_type) {}
+
+QuicEpollConnectionHelper::~QuicEpollConnectionHelper() = default;
+
+const QuicClock* QuicEpollConnectionHelper::GetClock() const {
+  return &clock_;
+}
+
+QuicRandom* QuicEpollConnectionHelper::GetRandomGenerator() {
+  return random_generator_;
+}
+
+quiche::QuicheBufferAllocator*
+QuicEpollConnectionHelper::GetStreamSendBufferAllocator() {
+  if (allocator_type_ == QuicAllocator::BUFFER_POOL) {
+    return &stream_buffer_allocator_;
+  } else {
+    QUICHE_DCHECK(allocator_type_ == QuicAllocator::SIMPLE);
+    return &simple_buffer_allocator_;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_connection_helper.h b/quiche/quic/core/quic_epoll_connection_helper.h
new file mode 100644
index 0000000..a424770
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_connection_helper.h
@@ -0,0 +1,58 @@
+// 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 epoll-specific helper for QuicConnection which uses
+// EpollAlarm for alarms, and used an int fd_ for writing data.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
+#define QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
+
+#include <sys/types.h>
+
+#include <set>
+
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_default_packet_writer.h"
+#include "quiche/quic/core/quic_epoll_clock.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_stream_buffer_allocator.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+
+class QuicRandom;
+
+enum class QuicAllocator { SIMPLE, BUFFER_POOL };
+
+class QUIC_EXPORT_PRIVATE QuicEpollConnectionHelper
+    : public QuicConnectionHelperInterface {
+ public:
+  QuicEpollConnectionHelper(QuicEpollServer* epoll_server,
+                            QuicAllocator allocator_type);
+  QuicEpollConnectionHelper(const QuicEpollConnectionHelper&) = delete;
+  QuicEpollConnectionHelper& operator=(const QuicEpollConnectionHelper&) =
+      delete;
+  ~QuicEpollConnectionHelper() override;
+
+  // QuicConnectionHelperInterface
+  const QuicClock* GetClock() const override;
+  QuicRandom* GetRandomGenerator() override;
+  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override;
+
+ private:
+  const QuicEpollClock clock_;
+  QuicRandom* random_generator_;
+  // Set up allocators.  They take up minimal memory before use.
+  // Allocator for stream send buffers.
+  QuicStreamBufferAllocator stream_buffer_allocator_;
+  quiche::SimpleBufferAllocator simple_buffer_allocator_;
+  QuicAllocator allocator_type_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
diff --git a/quiche/quic/core/quic_epoll_connection_helper_test.cc b/quiche/quic/core/quic_epoll_connection_helper_test.cc
new file mode 100644
index 0000000..4ce2f17
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_connection_helper_test.cc
@@ -0,0 +1,41 @@
+// 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 "quiche/quic/core/quic_epoll_connection_helper.h"
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/platform/api/quiche_epoll_test_tools.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicEpollConnectionHelperTest : public QuicTest {
+ protected:
+  QuicEpollConnectionHelperTest()
+      : helper_(&epoll_server_, QuicAllocator::BUFFER_POOL) {}
+
+  quiche::QuicheFakeEpollServer epoll_server_;
+  QuicEpollConnectionHelper helper_;
+};
+
+TEST_F(QuicEpollConnectionHelperTest, GetClock) {
+  const QuicClock* clock = helper_.GetClock();
+  QuicTime start = clock->Now();
+
+  QuicTime::Delta delta = QuicTime::Delta::FromMilliseconds(5);
+  epoll_server_.AdvanceBy(delta.ToMicroseconds());
+
+  EXPECT_EQ(start + delta, clock->Now());
+}
+
+TEST_F(QuicEpollConnectionHelperTest, GetRandomGenerator) {
+  QuicRandom* random = helper_.GetRandomGenerator();
+  EXPECT_EQ(QuicRandom::GetInstance(), random);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_error_codes.cc b/quiche/quic/core/quic_error_codes.cc
new file mode 100644
index 0000000..b6cdd7b
--- /dev/null
+++ b/quiche/quic/core/quic_error_codes.cc
@@ -0,0 +1,975 @@
+// 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 "quiche/quic/core/quic_error_codes.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "absl/strings/str_cat.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x;
+
+const char* QuicRstStreamErrorCodeToString(QuicRstStreamErrorCode error) {
+  switch (error) {
+    RETURN_STRING_LITERAL(QUIC_STREAM_NO_ERROR);
+    RETURN_STRING_LITERAL(QUIC_ERROR_PROCESSING_STREAM);
+    RETURN_STRING_LITERAL(QUIC_MULTIPLE_TERMINATION_OFFSETS);
+    RETURN_STRING_LITERAL(QUIC_BAD_APPLICATION_PAYLOAD);
+    RETURN_STRING_LITERAL(QUIC_STREAM_CONNECTION_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_PEER_GOING_AWAY);
+    RETURN_STRING_LITERAL(QUIC_STREAM_CANCELLED);
+    RETURN_STRING_LITERAL(QUIC_RST_ACKNOWLEDGEMENT);
+    RETURN_STRING_LITERAL(QUIC_REFUSED_STREAM);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PROMISE_URL);
+    RETURN_STRING_LITERAL(QUIC_UNAUTHORIZED_PROMISE_URL);
+    RETURN_STRING_LITERAL(QUIC_DUPLICATE_PROMISE_URL);
+    RETURN_STRING_LITERAL(QUIC_PROMISE_VARY_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PROMISE_METHOD);
+    RETURN_STRING_LITERAL(QUIC_PUSH_STREAM_TIMED_OUT);
+    RETURN_STRING_LITERAL(QUIC_HEADERS_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_STREAM_TTL_EXPIRED);
+    RETURN_STRING_LITERAL(QUIC_DATA_AFTER_CLOSE_OFFSET);
+    RETURN_STRING_LITERAL(QUIC_STREAM_GENERAL_PROTOCOL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_STREAM_CREATION_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_CLOSED_CRITICAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_STREAM_FRAME_UNEXPECTED);
+    RETURN_STRING_LITERAL(QUIC_STREAM_FRAME_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_EXCESSIVE_LOAD);
+    RETURN_STRING_LITERAL(QUIC_STREAM_ID_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_SETTINGS_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_MISSING_SETTINGS);
+    RETURN_STRING_LITERAL(QUIC_STREAM_REQUEST_REJECTED);
+    RETURN_STRING_LITERAL(QUIC_STREAM_REQUEST_INCOMPLETE);
+    RETURN_STRING_LITERAL(QUIC_STREAM_CONNECT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_VERSION_FALLBACK);
+    RETURN_STRING_LITERAL(QUIC_STREAM_DECOMPRESSION_FAILED);
+    RETURN_STRING_LITERAL(QUIC_STREAM_ENCODER_STREAM_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_DECODER_STREAM_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE);
+    RETURN_STRING_LITERAL(QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
+    RETURN_STRING_LITERAL(
+        QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED);
+    RETURN_STRING_LITERAL(QUIC_STREAM_LAST_ERROR);
+  }
+  // Return a default value so that we return this when |error| doesn't match
+  // any of the QuicRstStreamErrorCodes. This can happen when the RstStream
+  // frame sent by the peer (attacker) has invalid error code.
+  return "INVALID_RST_STREAM_ERROR_CODE";
+}
+
+const char* QuicErrorCodeToString(QuicErrorCode error) {
+  switch (error) {
+    RETURN_STRING_LITERAL(QUIC_NO_ERROR);
+    RETURN_STRING_LITERAL(QUIC_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_DATA_AFTER_TERMINATION);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PACKET_HEADER);
+    RETURN_STRING_LITERAL(QUIC_INVALID_FRAME_DATA);
+    RETURN_STRING_LITERAL(QUIC_MISSING_PAYLOAD);
+    RETURN_STRING_LITERAL(QUIC_INVALID_FEC_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_OVERLAPPING_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_RST_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CONNECTION_CLOSE_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_GOAWAY_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_WINDOW_UPDATE_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_BLOCKED_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STOP_WAITING_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PATH_CLOSE_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_ACK_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PUBLIC_RST_PACKET);
+    RETURN_STRING_LITERAL(QUIC_DECRYPTION_FAILURE);
+    RETURN_STRING_LITERAL(QUIC_ENCRYPTION_FAILURE);
+    RETURN_STRING_LITERAL(QUIC_PACKET_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_PEER_GOING_AWAY);
+    RETURN_STRING_LITERAL(QUIC_HANDSHAKE_FAILED);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_TAGS_OUT_OF_ORDER);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_TOO_MANY_ENTRIES);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_TOO_MANY_REJECTS);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_INVALID_VALUE_LENGTH)
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_VERSION_NOT_SUPPORTED);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_NO_SUPPORT);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND);
+    RETURN_STRING_LITERAL(QUIC_UNSUPPORTED_PROOF_DEMAND);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_ID);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PRIORITY);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_OPEN_STREAMS);
+    RETURN_STRING_LITERAL(QUIC_PUBLIC_RESET);
+    RETURN_STRING_LITERAL(QUIC_INVALID_VERSION);
+    RETURN_STRING_LITERAL(QUIC_PACKET_WRONG_VERSION);
+    RETURN_STRING_LITERAL(QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
+    RETURN_STRING_LITERAL(QUIC_INVALID_HEADER_ID);
+    RETURN_STRING_LITERAL(QUIC_INVALID_NEGOTIATED_VALUE);
+    RETURN_STRING_LITERAL(QUIC_DECOMPRESSION_FAILURE);
+    RETURN_STRING_LITERAL(QUIC_NETWORK_IDLE_TIMEOUT);
+    RETURN_STRING_LITERAL(QUIC_HANDSHAKE_TIMEOUT);
+    RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_ADDRESS);
+    RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_PORT);
+    RETURN_STRING_LITERAL(QUIC_PACKET_WRITE_ERROR);
+    RETURN_STRING_LITERAL(QUIC_PACKET_READ_ERROR);
+    RETURN_STRING_LITERAL(QUIC_EMPTY_STREAM_FRAME_NO_FIN);
+    RETURN_STRING_LITERAL(QUIC_INVALID_HEADERS_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE);
+    RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA);
+    RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA);
+    RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_INVALID_WINDOW);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_IP_POOLED);
+    RETURN_STRING_LITERAL(QUIC_PROOF_INVALID);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_DUPLICATE_TAG);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_SERVER_CONFIG_EXPIRED);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CHANNEL_ID_SIGNATURE);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE);
+    RETURN_STRING_LITERAL(QUIC_VERSION_NEGOTIATION_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_CANCELLED);
+    RETURN_STRING_LITERAL(QUIC_BAD_PACKET_LOSS_RATE);
+    RETURN_STRING_LITERAL(QUIC_PUBLIC_RESETS_POST_HANDSHAKE);
+    RETURN_STRING_LITERAL(QUIC_FAILED_TO_SERIALIZE_PACKET);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_AVAILABLE_STREAMS);
+    RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_FEC_DATA);
+    RETURN_STRING_LITERAL(QUIC_BAD_MULTIPATH_FLAG);
+    RETURN_STRING_LITERAL(QUIC_IP_ADDRESS_CHANGED);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_RTOS);
+    RETURN_STRING_LITERAL(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_MAYBE_CORRUPTED_MEMORY);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_CHLO_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_DOES_NOT_EXIST);
+    RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_NOT_ACTIVE);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_STREAM_DATA_INTERVALS);
+    RETURN_STRING_LITERAL(QUIC_STREAM_SEQUENCER_INVALID_STATE);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_SESSIONS_ON_SERVER);
+    RETURN_STRING_LITERAL(QUIC_STREAM_LENGTH_OVERFLOW);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_INVALID_MAX_DATA_FRAME_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_BLOCKED_DATA);
+    RETURN_STRING_LITERAL(QUIC_MAX_STREAMS_DATA);
+    RETURN_STRING_LITERAL(QUIC_STREAMS_BLOCKED_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_NEW_CONNECTION_ID_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_ID_LIMIT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STOP_SENDING_FRAME_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PATH_CHALLENGE_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PATH_RESPONSE_DATA);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED);
+    RETURN_STRING_LITERAL(QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED);
+    RETURN_STRING_LITERAL(QUIC_INVALID_MESSAGE_DATA);
+    RETURN_STRING_LITERAL(IETF_QUIC_PROTOCOL_VIOLATION);
+    RETURN_STRING_LITERAL(QUIC_INVALID_NEW_TOKEN);
+    RETURN_STRING_LITERAL(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_STREAMS_BLOCKED_ERROR);
+    RETURN_STRING_LITERAL(QUIC_MAX_STREAMS_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HTTP_DECODER_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STALE_CONNECTION_CANCELLED);
+    RETURN_STRING_LITERAL(QUIC_IETF_GQUIC_ERROR_MISSING);
+    RETURN_STRING_LITERAL(
+        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES);
+    RETURN_STRING_LITERAL(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECOMPRESSION_FAILED);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_ERROR);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC);
+    RETURN_STRING_LITERAL(
+        QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX);
+    RETURN_STRING_LITERAL(
+        QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL);
+    RETURN_STRING_LITERAL(
+        QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX);
+    RETURN_STRING_LITERAL(
+        QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT);
+    RETURN_STRING_LITERAL(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET);
+    RETURN_STRING_LITERAL(QUIC_STREAM_MULTIPLE_OFFSET);
+    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_WRONG_DIRECTION);
+    RETURN_STRING_LITERAL(QUIC_HTTP_CLOSED_CRITICAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_MISSING_SETTINGS_FRAME);
+    RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER);
+    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_MAX_PUSH_ID);
+    RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_LIMIT_TOO_LOW);
+    RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID);
+    RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS);
+    RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_SETTING);
+    RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_FRAME);
+    RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SERVER_PUSH);
+    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_SETTING_VALUE);
+    RETURN_STRING_LITERAL(QUIC_HPACK_INDEX_VARINT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_NAME_LENGTH_VARINT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_NAME_TOO_LONG);
+    RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_TOO_LONG);
+    RETURN_STRING_LITERAL(QUIC_HPACK_NAME_HUFFMAN_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_HUFFMAN_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE);
+    RETURN_STRING_LITERAL(QUIC_HPACK_INVALID_INDEX);
+    RETURN_STRING_LITERAL(QUIC_HPACK_INVALID_NAME_INDEX);
+    RETURN_STRING_LITERAL(QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED);
+    RETURN_STRING_LITERAL(
+        QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK);
+    RETURN_STRING_LITERAL(
+        QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING);
+    RETURN_STRING_LITERAL(QUIC_HPACK_TRUNCATED_BLOCK);
+    RETURN_STRING_LITERAL(QUIC_HPACK_FRAGMENT_TOO_LONG);
+    RETURN_STRING_LITERAL(QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT);
+    RETURN_STRING_LITERAL(QUIC_ZERO_RTT_UNRETRANSMITTABLE);
+    RETURN_STRING_LITERAL(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED);
+    RETURN_STRING_LITERAL(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED);
+    RETURN_STRING_LITERAL(QUIC_SILENT_IDLE_TIMEOUT);
+    RETURN_STRING_LITERAL(QUIC_MISSING_WRITE_KEYS);
+    RETURN_STRING_LITERAL(QUIC_KEY_UPDATE_ERROR);
+    RETURN_STRING_LITERAL(QUIC_AEAD_LIMIT_REACHED);
+    RETURN_STRING_LITERAL(QUIC_MAX_AGE_TIMEOUT);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PRIORITY_UPDATE);
+    RETURN_STRING_LITERAL(QUIC_TLS_BAD_CERTIFICATE);
+    RETURN_STRING_LITERAL(QUIC_TLS_UNSUPPORTED_CERTIFICATE);
+    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_REVOKED);
+    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_EXPIRED);
+    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_UNKNOWN);
+    RETURN_STRING_LITERAL(QUIC_TLS_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_TLS_UNRECOGNIZED_NAME);
+    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_REQUIRED);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE);
+    RETURN_STRING_LITERAL(QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL);
+    RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE);
+    RETURN_STRING_LITERAL(QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED);
+
+    RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
+    // Intentionally have no default case, so we'll break the build
+    // if we add errors and don't put them here.
+  }
+  // Return a default value so that we return this when |error| doesn't match
+  // any of the QuicErrorCodes. This can happen when the ConnectionClose
+  // frame sent by the peer (attacker) has invalid error code.
+  return "INVALID_ERROR_CODE";
+}
+
+std::string QuicIetfTransportErrorCodeString(QuicIetfTransportErrorCodes c) {
+  if (c >= CRYPTO_ERROR_FIRST && c <= CRYPTO_ERROR_LAST) {
+    const int tls_error = static_cast<int>(c - CRYPTO_ERROR_FIRST);
+    const char* tls_error_description = SSL_alert_desc_string_long(tls_error);
+    if (strcmp("unknown", tls_error_description) != 0) {
+      return absl::StrCat("CRYPTO_ERROR(", tls_error_description, ")");
+    }
+    return absl::StrCat("CRYPTO_ERROR(unknown(", tls_error, "))");
+  }
+
+  switch (c) {
+    RETURN_STRING_LITERAL(NO_IETF_QUIC_ERROR);
+    RETURN_STRING_LITERAL(INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(SERVER_BUSY_ERROR);
+    RETURN_STRING_LITERAL(FLOW_CONTROL_ERROR);
+    RETURN_STRING_LITERAL(STREAM_LIMIT_ERROR);
+    RETURN_STRING_LITERAL(STREAM_STATE_ERROR);
+    RETURN_STRING_LITERAL(FINAL_SIZE_ERROR);
+    RETURN_STRING_LITERAL(FRAME_ENCODING_ERROR);
+    RETURN_STRING_LITERAL(TRANSPORT_PARAMETER_ERROR);
+    RETURN_STRING_LITERAL(CONNECTION_ID_LIMIT_ERROR);
+    RETURN_STRING_LITERAL(PROTOCOL_VIOLATION);
+    RETURN_STRING_LITERAL(INVALID_TOKEN);
+    RETURN_STRING_LITERAL(CRYPTO_BUFFER_EXCEEDED);
+    RETURN_STRING_LITERAL(KEY_UPDATE_ERROR);
+    RETURN_STRING_LITERAL(AEAD_LIMIT_REACHED);
+    // CRYPTO_ERROR is handled in the if before this switch, these cases do not
+    // change behavior and are only here to make the compiler happy.
+    case CRYPTO_ERROR_FIRST:
+    case CRYPTO_ERROR_LAST:
+      QUICHE_DCHECK(false) << "Unexpected error " << static_cast<uint64_t>(c);
+      break;
+  }
+
+  return absl::StrCat("Unknown(", static_cast<uint64_t>(c), ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicIetfTransportErrorCodes& c) {
+  os << QuicIetfTransportErrorCodeString(c);
+  return os;
+}
+
+QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode(
+    QuicErrorCode error) {
+  switch (error) {
+    case QUIC_NO_ERROR:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_INTERNAL_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_STREAM_DATA_AFTER_TERMINATION:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_PACKET_HEADER:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_FRAME_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_MISSING_PAYLOAD:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_FEC_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_STREAM_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_OVERLAPPING_STREAM_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_UNENCRYPTED_STREAM_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_MAYBE_CORRUPTED_MEMORY:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_UNENCRYPTED_FEC_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_RST_STREAM_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_CONNECTION_CLOSE_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_GOAWAY_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_WINDOW_UPDATE_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_BLOCKED_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_STOP_WAITING_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_PATH_CLOSE_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_ACK_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_MESSAGE_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_VERSION_NEGOTIATION_PACKET:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_PUBLIC_RST_PACKET:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_DECRYPTION_FAILURE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_ENCRYPTION_FAILURE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PACKET_TOO_LARGE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PEER_GOING_AWAY:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_STREAM_ID:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_PRIORITY:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_OPEN_STREAMS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TOO_MANY_AVAILABLE_STREAMS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PUBLIC_RESET:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_VERSION:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PACKET_WRONG_VERSION:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_HEADER_ID:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_NEGOTIATED_VALUE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_DECOMPRESSION_FAILURE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_NETWORK_IDLE_TIMEOUT:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_SILENT_IDLE_TIMEOUT:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_HANDSHAKE_TIMEOUT:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_ERROR_MIGRATING_ADDRESS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_ERROR_MIGRATING_PORT:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_PACKET_WRITE_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_PACKET_READ_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_EMPTY_STREAM_FRAME_NO_FIN:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_HEADERS_STREAM_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA:
+      return {true, static_cast<uint64_t>(FLOW_CONTROL_ERROR)};
+    case QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_FLOW_CONTROL_INVALID_WINDOW:
+      return {true, static_cast<uint64_t>(FLOW_CONTROL_ERROR)};
+    case QUIC_CONNECTION_IP_POOLED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_CANCELLED:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_BAD_PACKET_LOSS_RATE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_PUBLIC_RESETS_POST_HANDSHAKE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_FAILED_TO_SERIALIZE_PACKET:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_RTOS:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_HANDSHAKE_FAILED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_TAGS_OUT_OF_ORDER:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_TOO_MANY_ENTRIES:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_INVALID_VALUE_LENGTH:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_CRYPTO_MESSAGE_TYPE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_CHANNEL_ID_SIGNATURE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_UNSUPPORTED_PROOF_DEMAND:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_INTERNAL_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CRYPTO_VERSION_NOT_SUPPORTED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_NO_SUPPORT:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_TOO_MANY_REJECTS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PROOF_INVALID:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_DUPLICATE_TAG:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_SERVER_CONFIG_EXPIRED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_CHLO_TOO_LARGE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_VERSION_NEGOTIATION_MISMATCH:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_BAD_MULTIPATH_FLAG:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_MULTIPATH_PATH_DOES_NOT_EXIST:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_MULTIPATH_PATH_NOT_ACTIVE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_IP_ADDRESS_CHANGED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_STREAM_DATA_INTERVALS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_STREAM_SEQUENCER_INVALID_STATE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_SESSIONS_ON_SERVER:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_STREAM_LENGTH_OVERFLOW:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_MAX_DATA_FRAME_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_MAX_STREAMS_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_STREAMS_BLOCKED_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_STREAM_BLOCKED_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_NEW_CONNECTION_ID_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_STOP_SENDING_FRAME_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_PATH_CHALLENGE_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_PATH_RESPONSE_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case IETF_QUIC_PROTOCOL_VIOLATION:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_NEW_TOKEN:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM:
+      return {true, static_cast<uint64_t>(STREAM_STATE_ERROR)};
+    case QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_RETIRE_CONNECTION_ID_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_STREAMS_BLOCKED_ERROR:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_MAX_STREAMS_ERROR:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_HTTP_DECODER_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_STALE_CONNECTION_CANCELLED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_IETF_GQUIC_ERROR_MISSING:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TRANSPORT_INVALID_CLIENT_INDICATION:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_QPACK_DECOMPRESSION_FAILED:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECOMPRESSION_FAILED)};
+    case QUIC_QPACK_ENCODER_STREAM_ERROR:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_ERROR:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_STREAM_MULTIPLE_OFFSET:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_HTTP_FRAME_TOO_LARGE:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD)};
+    case QUIC_HTTP_FRAME_ERROR:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR)};
+    case QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR)};
+    case QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR)};
+    case QUIC_HTTP_STREAM_WRONG_DIRECTION:
+      return {true, static_cast<uint64_t>(STREAM_STATE_ERROR)};
+    case QUIC_HTTP_CLOSED_CRITICAL_STREAM:
+      return {false, static_cast<uint64_t>(
+                         QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM)};
+    case QUIC_HTTP_MISSING_SETTINGS_FRAME:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS)};
+    case QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
+    case QUIC_HTTP_INVALID_MAX_PUSH_ID:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
+    case QUIC_HTTP_STREAM_LIMIT_TOO_LOW:
+      return {false, static_cast<uint64_t>(
+                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
+    case QUIC_HTTP_RECEIVE_SERVER_PUSH:
+      return {false, static_cast<uint64_t>(
+                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
+    case QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
+    case QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HTTP_GOAWAY_INVALID_STREAM_ID:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
+    case QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
+    case QUIC_HTTP_RECEIVE_SPDY_SETTING:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
+    case QUIC_HTTP_INVALID_SETTING_VALUE:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
+    case QUIC_HTTP_RECEIVE_SPDY_FRAME:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HPACK_INDEX_VARINT_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_NAME_LENGTH_VARINT_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_NAME_TOO_LONG:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_VALUE_TOO_LONG:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_NAME_HUFFMAN_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_VALUE_HUFFMAN_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_INVALID_INDEX:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_INVALID_NAME_INDEX:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_TRUNCATED_BLOCK:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_FRAGMENT_TOO_LONG:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_ZERO_RTT_UNRETRANSMITTABLE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_MISSING_WRITE_KEYS:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_KEY_UPDATE_ERROR:
+      return {true, static_cast<uint64_t>(KEY_UPDATE_ERROR)};
+    case QUIC_AEAD_LIMIT_REACHED:
+      return {true, static_cast<uint64_t>(AEAD_LIMIT_REACHED)};
+    case QUIC_MAX_AGE_TIMEOUT:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR)};
+    case QUIC_INVALID_PRIORITY_UPDATE:
+      return {false, static_cast<uint64_t>(
+                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
+    case QUIC_TLS_BAD_CERTIFICATE:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_BAD_CERTIFICATE)};
+    case QUIC_TLS_UNSUPPORTED_CERTIFICATE:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_UNSUPPORTED_CERTIFICATE)};
+    case QUIC_TLS_CERTIFICATE_REVOKED:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_CERTIFICATE_REVOKED)};
+    case QUIC_TLS_CERTIFICATE_EXPIRED:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_CERTIFICATE_EXPIRED)};
+    case QUIC_TLS_CERTIFICATE_UNKNOWN:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_CERTIFICATE_UNKNOWN)};
+    case QUIC_TLS_INTERNAL_ERROR:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_INTERNAL_ERROR)};
+    case QUIC_TLS_UNRECOGNIZED_NAME:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_UNRECOGNIZED_NAME)};
+    case QUIC_TLS_CERTIFICATE_REQUIRED:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_CERTIFICATE_REQUIRED)};
+    case QUIC_CONNECTION_ID_LIMIT_ERROR:
+      return {true, static_cast<uint64_t>(CONNECTION_ID_LIMIT_ERROR)};
+    case QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_CHARACTER_IN_FIELD_VALUE:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::MESSAGE_ERROR)};
+    case QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_LAST_ERROR:
+      return {false, static_cast<uint64_t>(QUIC_LAST_ERROR)};
+  }
+  // This function should not be called with unknown error code.
+  return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+}
+
+QuicErrorCode TlsAlertToQuicErrorCode(uint8_t desc) {
+  switch (desc) {
+    case SSL_AD_BAD_CERTIFICATE:
+      return QUIC_TLS_BAD_CERTIFICATE;
+    case SSL_AD_UNSUPPORTED_CERTIFICATE:
+      return QUIC_TLS_UNSUPPORTED_CERTIFICATE;
+    case SSL_AD_CERTIFICATE_REVOKED:
+      return QUIC_TLS_CERTIFICATE_REVOKED;
+    case SSL_AD_CERTIFICATE_EXPIRED:
+      return QUIC_TLS_CERTIFICATE_EXPIRED;
+    case SSL_AD_CERTIFICATE_UNKNOWN:
+      return QUIC_TLS_CERTIFICATE_UNKNOWN;
+    case SSL_AD_INTERNAL_ERROR:
+      return QUIC_TLS_INTERNAL_ERROR;
+    case SSL_AD_UNRECOGNIZED_NAME:
+      return QUIC_TLS_UNRECOGNIZED_NAME;
+    case SSL_AD_CERTIFICATE_REQUIRED:
+      return QUIC_TLS_CERTIFICATE_REQUIRED;
+    default:
+      return QUIC_HANDSHAKE_FAILED;
+  }
+}
+
+// Convert a QuicRstStreamErrorCode to an application error code to be used in
+// an IETF QUIC RESET_STREAM frame
+uint64_t RstStreamErrorCodeToIetfResetStreamErrorCode(
+    QuicRstStreamErrorCode rst_stream_error_code) {
+  switch (rst_stream_error_code) {
+    case QUIC_STREAM_NO_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR);
+    case QUIC_ERROR_PROCESSING_STREAM:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_MULTIPLE_TERMINATION_OFFSETS:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_BAD_APPLICATION_PAYLOAD:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_STREAM_CONNECTION_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+    case QUIC_STREAM_PEER_GOING_AWAY:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_STREAM_CANCELLED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+    case QUIC_RST_ACKNOWLEDGEMENT:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR);
+    case QUIC_REFUSED_STREAM:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR);
+    case QUIC_INVALID_PROMISE_URL:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_UNAUTHORIZED_PROMISE_URL:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_DUPLICATE_PROMISE_URL:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_PROMISE_VARY_MISMATCH:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+    case QUIC_INVALID_PROMISE_METHOD:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_PUSH_STREAM_TIMED_OUT:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+    case QUIC_HEADERS_TOO_LARGE:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD);
+    case QUIC_STREAM_TTL_EXPIRED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+    case QUIC_DATA_AFTER_CLOSE_OFFSET:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_STREAM_GENERAL_PROTOCOL_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_STREAM_INTERNAL_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+    case QUIC_STREAM_STREAM_CREATION_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_STREAM_CLOSED_CRITICAL_STREAM:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM);
+    case QUIC_STREAM_FRAME_UNEXPECTED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED);
+    case QUIC_STREAM_FRAME_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR);
+    case QUIC_STREAM_EXCESSIVE_LOAD:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD);
+    case QUIC_STREAM_ID_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR);
+    case QUIC_STREAM_SETTINGS_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR);
+    case QUIC_STREAM_MISSING_SETTINGS:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS);
+    case QUIC_STREAM_REQUEST_REJECTED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED);
+    case QUIC_STREAM_REQUEST_INCOMPLETE:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE);
+    case QUIC_STREAM_CONNECT_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
+    case QUIC_STREAM_VERSION_FALLBACK:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK);
+    case QUIC_STREAM_DECOMPRESSION_FAILED:
+      return static_cast<uint64_t>(
+          QuicHttpQpackErrorCode::DECOMPRESSION_FAILED);
+    case QUIC_STREAM_ENCODER_STREAM_ERROR:
+      return static_cast<uint64_t>(
+          QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR);
+    case QUIC_STREAM_DECODER_STREAM_ERROR:
+      return static_cast<uint64_t>(
+          QuicHttpQpackErrorCode::DECODER_STREAM_ERROR);
+    case QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+    case QUIC_STREAM_WEBTRANSPORT_SESSION_GONE:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
+    case QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
+    case QUIC_STREAM_LAST_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+  }
+  return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+}
+
+// Convert the application error code of an IETF QUIC RESET_STREAM frame
+// to QuicRstStreamErrorCode.
+QuicRstStreamErrorCode IetfResetStreamErrorCodeToRstStreamErrorCode(
+    uint64_t ietf_error_code) {
+  switch (ietf_error_code) {
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR):
+      return QUIC_STREAM_NO_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR):
+      return QUIC_STREAM_GENERAL_PROTOCOL_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR):
+      return QUIC_STREAM_INTERNAL_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR):
+      return QUIC_STREAM_STREAM_CREATION_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM):
+      return QUIC_STREAM_CLOSED_CRITICAL_STREAM;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED):
+      return QUIC_STREAM_FRAME_UNEXPECTED;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR):
+      return QUIC_STREAM_FRAME_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD):
+      return QUIC_STREAM_EXCESSIVE_LOAD;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR):
+      return QUIC_STREAM_ID_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR):
+      return QUIC_STREAM_SETTINGS_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS):
+      return QUIC_STREAM_MISSING_SETTINGS;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED):
+      return QUIC_STREAM_REQUEST_REJECTED;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED):
+      return QUIC_STREAM_CANCELLED;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE):
+      return QUIC_STREAM_REQUEST_INCOMPLETE;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR):
+      return QUIC_STREAM_CONNECT_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK):
+      return QUIC_STREAM_VERSION_FALLBACK;
+    case static_cast<uint64_t>(QuicHttpQpackErrorCode::DECOMPRESSION_FAILED):
+      return QUIC_STREAM_DECOMPRESSION_FAILED;
+    case static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR):
+      return QUIC_STREAM_ENCODER_STREAM_ERROR;
+    case static_cast<uint64_t>(QuicHttpQpackErrorCode::DECODER_STREAM_ERROR):
+      return QUIC_STREAM_DECODER_STREAM_ERROR;
+  }
+  return QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE;
+}
+
+// static
+QuicResetStreamError QuicResetStreamError::FromInternal(
+    QuicRstStreamErrorCode code) {
+  return QuicResetStreamError(
+      code, RstStreamErrorCodeToIetfResetStreamErrorCode(code));
+}
+
+// static
+QuicResetStreamError QuicResetStreamError::FromIetf(uint64_t code) {
+  return QuicResetStreamError(
+      IetfResetStreamErrorCodeToRstStreamErrorCode(code), code);
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_error_codes.h b/quiche/quic/core/quic_error_codes.h
new file mode 100644
index 0000000..9c20cd5
--- /dev/null
+++ b/quiche/quic/core/quic_error_codes.h
@@ -0,0 +1,769 @@
+// 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_ERROR_CODES_H_
+#define QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
+
+#include <cstdint>
+#include <limits>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicRstStreamErrorCode is encoded as a single octet on-the-wire in IETF QUIC
+// and a 32-bit integer in gQUIC.
+enum QuicRstStreamErrorCode : uint32_t {
+  // Complete response has been sent, sending a RST to ask the other endpoint
+  // to stop sending request data without discarding the response.
+  QUIC_STREAM_NO_ERROR = 0,
+
+  // There was some error which halted stream processing.
+  QUIC_ERROR_PROCESSING_STREAM = 1,
+  // We got two fin or reset offsets which did not match.
+  QUIC_MULTIPLE_TERMINATION_OFFSETS = 2,
+  // We got bad payload and can not respond to it at the protocol level.
+  QUIC_BAD_APPLICATION_PAYLOAD = 3,
+  // Stream closed due to connection error. No reset frame is sent when this
+  // happens.
+  QUIC_STREAM_CONNECTION_ERROR = 4,
+  // GoAway frame sent. No more stream can be created.
+  QUIC_STREAM_PEER_GOING_AWAY = 5,
+  // The stream has been cancelled.
+  QUIC_STREAM_CANCELLED = 6,
+  // Closing stream locally, sending a RST to allow for proper flow control
+  // accounting. Sent in response to a RST from the peer.
+  QUIC_RST_ACKNOWLEDGEMENT = 7,
+  // Receiver refused to create the stream (because its limit on open streams
+  // has been reached).  The sender should retry the request later (using
+  // another stream).
+  QUIC_REFUSED_STREAM = 8,
+  // Invalid URL in PUSH_PROMISE request header.
+  QUIC_INVALID_PROMISE_URL = 9,
+  // Server is not authoritative for this URL.
+  QUIC_UNAUTHORIZED_PROMISE_URL = 10,
+  // Can't have more than one active PUSH_PROMISE per URL.
+  QUIC_DUPLICATE_PROMISE_URL = 11,
+  // Vary check failed.
+  QUIC_PROMISE_VARY_MISMATCH = 12,
+  // Only GET and HEAD methods allowed.
+  QUIC_INVALID_PROMISE_METHOD = 13,
+  // The push stream is unclaimed and timed out.
+  QUIC_PUSH_STREAM_TIMED_OUT = 14,
+  // Received headers were too large.
+  QUIC_HEADERS_TOO_LARGE = 15,
+  // The data is not likely arrive in time.
+  QUIC_STREAM_TTL_EXPIRED = 16,
+  // The stream received data that goes beyond its close offset.
+  QUIC_DATA_AFTER_CLOSE_OFFSET = 17,
+  // Peer violated protocol requirements in a way which does not match a more
+  // specific error code, or endpoint declines to use the more specific error
+  // code.
+  QUIC_STREAM_GENERAL_PROTOCOL_ERROR = 18,
+  // An internal error has occurred.
+  QUIC_STREAM_INTERNAL_ERROR = 19,
+  // Peer created a stream that will not be accepted.
+  QUIC_STREAM_STREAM_CREATION_ERROR = 20,
+  // A stream required by the connection was closed or reset.
+  QUIC_STREAM_CLOSED_CRITICAL_STREAM = 21,
+  // A frame was received which was not permitted in the current state or on the
+  // current stream.
+  QUIC_STREAM_FRAME_UNEXPECTED = 22,
+  // A frame that fails to satisfy layout requirements or with an invalid size
+  // was received.
+  QUIC_STREAM_FRAME_ERROR = 23,
+  // Peer exhibits a behavior that might be generating excessive load.
+  QUIC_STREAM_EXCESSIVE_LOAD = 24,
+  // A Stream ID or Push ID was used incorrectly, such as exceeding a limit,
+  // reducing a limit, or being reused.
+  QUIC_STREAM_ID_ERROR = 25,
+  // Error in the payload of a SETTINGS frame.
+  QUIC_STREAM_SETTINGS_ERROR = 26,
+  // No SETTINGS frame was received at the beginning of the control stream.
+  QUIC_STREAM_MISSING_SETTINGS = 27,
+  // A server rejected a request without performing any application processing.
+  QUIC_STREAM_REQUEST_REJECTED = 28,
+  // The client's stream terminated without containing a fully-formed request.
+  QUIC_STREAM_REQUEST_INCOMPLETE = 29,
+  // The connection established in response to a CONNECT request was reset or
+  // abnormally closed.
+  QUIC_STREAM_CONNECT_ERROR = 30,
+  // The requested operation cannot be served over HTTP/3.
+  // The peer should retry over HTTP/1.1.
+  QUIC_STREAM_VERSION_FALLBACK = 31,
+  // The QPACK decoder failed to interpret a header block and is not able to
+  // continue decoding that header block.
+  QUIC_STREAM_DECOMPRESSION_FAILED = 32,
+  // The QPACK decoder failed to interpret an encoder instruction received on
+  // the encoder stream.
+  QUIC_STREAM_ENCODER_STREAM_ERROR = 33,
+  // The QPACK encoder failed to interpret a decoder instruction received on the
+  // decoder stream.
+  QUIC_STREAM_DECODER_STREAM_ERROR = 34,
+  // IETF RESET_FRAME application error code not matching any HTTP/3 or QPACK
+  // error codes.
+  QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE = 35,
+  // WebTransport session is going away, causing all underlying streams to be
+  // reset.
+  QUIC_STREAM_WEBTRANSPORT_SESSION_GONE = 36,
+  // There is no corresponding WebTransport session to associate this stream
+  // with, and the limit for buffered streams has been exceeded.
+  QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED = 37,
+  // No error. Used as bound while iterating.
+  QUIC_STREAM_LAST_ERROR = 38,
+};
+// QuicRstStreamErrorCode is encoded as a single octet on-the-wire.
+static_assert(static_cast<int>(QUIC_STREAM_LAST_ERROR) <=
+                  std::numeric_limits<uint8_t>::max(),
+              "QuicRstStreamErrorCode exceeds single octet");
+
+// These values must remain stable as they are uploaded to UMA histograms.
+// To add a new error code, use the current value of QUIC_LAST_ERROR and
+// increment QUIC_LAST_ERROR.
+enum QuicErrorCode {
+  QUIC_NO_ERROR = 0,
+
+  // Connection has reached an invalid state.
+  QUIC_INTERNAL_ERROR = 1,
+  // There were data frames after the a fin or reset.
+  QUIC_STREAM_DATA_AFTER_TERMINATION = 2,
+  // Control frame is malformed.
+  QUIC_INVALID_PACKET_HEADER = 3,
+  // Frame data is malformed.
+  QUIC_INVALID_FRAME_DATA = 4,
+  // The packet contained no payload.
+  QUIC_MISSING_PAYLOAD = 48,
+  // FEC data is malformed.
+  QUIC_INVALID_FEC_DATA = 5,
+  // STREAM frame data is malformed.
+  QUIC_INVALID_STREAM_DATA = 46,
+  // STREAM frame data overlaps with buffered data.
+  QUIC_OVERLAPPING_STREAM_DATA = 87,
+  // Received STREAM frame data is not encrypted.
+  QUIC_UNENCRYPTED_STREAM_DATA = 61,
+  // Attempt to send unencrypted STREAM frame.
+  QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA = 88,
+  // Received a frame which is likely the result of memory corruption.
+  QUIC_MAYBE_CORRUPTED_MEMORY = 89,
+  // FEC frame data is not encrypted.
+  QUIC_UNENCRYPTED_FEC_DATA = 77,
+  // RST_STREAM frame data is malformed.
+  QUIC_INVALID_RST_STREAM_DATA = 6,
+  // CONNECTION_CLOSE frame data is malformed.
+  QUIC_INVALID_CONNECTION_CLOSE_DATA = 7,
+  // GOAWAY frame data is malformed.
+  QUIC_INVALID_GOAWAY_DATA = 8,
+  // WINDOW_UPDATE frame data is malformed.
+  QUIC_INVALID_WINDOW_UPDATE_DATA = 57,
+  // BLOCKED frame data is malformed.
+  QUIC_INVALID_BLOCKED_DATA = 58,
+  // STOP_WAITING frame data is malformed.
+  QUIC_INVALID_STOP_WAITING_DATA = 60,
+  // PATH_CLOSE frame data is malformed.
+  QUIC_INVALID_PATH_CLOSE_DATA = 78,
+  // ACK frame data is malformed.
+  QUIC_INVALID_ACK_DATA = 9,
+  // Message frame data is malformed.
+  QUIC_INVALID_MESSAGE_DATA = 112,
+
+  // Version negotiation packet is malformed.
+  QUIC_INVALID_VERSION_NEGOTIATION_PACKET = 10,
+  // Public RST packet is malformed.
+  QUIC_INVALID_PUBLIC_RST_PACKET = 11,
+  // There was an error decrypting.
+  QUIC_DECRYPTION_FAILURE = 12,
+  // There was an error encrypting.
+  QUIC_ENCRYPTION_FAILURE = 13,
+  // The packet exceeded kMaxOutgoingPacketSize.
+  QUIC_PACKET_TOO_LARGE = 14,
+  // The peer is going away.  May be a client or server.
+  QUIC_PEER_GOING_AWAY = 16,
+  // A stream ID was invalid.
+  QUIC_INVALID_STREAM_ID = 17,
+  // A priority was invalid.
+  QUIC_INVALID_PRIORITY = 49,
+  // Too many streams already open.
+  QUIC_TOO_MANY_OPEN_STREAMS = 18,
+  // The peer created too many available streams.
+  QUIC_TOO_MANY_AVAILABLE_STREAMS = 76,
+  // Received public reset for this connection.
+  QUIC_PUBLIC_RESET = 19,
+  // Version selected by client is not acceptable to the server.
+  QUIC_INVALID_VERSION = 20,
+  // Received packet indicates version that does not match connection version.
+  QUIC_PACKET_WRONG_VERSION = 212,
+
+  // The Header ID for a stream was too far from the previous.
+  QUIC_INVALID_HEADER_ID = 22,
+  // Negotiable parameter received during handshake had invalid value.
+  QUIC_INVALID_NEGOTIATED_VALUE = 23,
+  // There was an error decompressing data.
+  QUIC_DECOMPRESSION_FAILURE = 24,
+  // The connection timed out due to no network activity.
+  QUIC_NETWORK_IDLE_TIMEOUT = 25,
+  // The connection timed out waiting for the handshake to complete.
+  QUIC_HANDSHAKE_TIMEOUT = 67,
+  // There was an error encountered migrating addresses.
+  QUIC_ERROR_MIGRATING_ADDRESS = 26,
+  // There was an error encountered migrating port only.
+  QUIC_ERROR_MIGRATING_PORT = 86,
+  // There was an error while writing to the socket.
+  QUIC_PACKET_WRITE_ERROR = 27,
+  // There was an error while reading from the socket.
+  QUIC_PACKET_READ_ERROR = 51,
+  // We received a STREAM_FRAME with no data and no fin flag set.
+  QUIC_EMPTY_STREAM_FRAME_NO_FIN = 50,
+  // We received invalid data on the headers stream.
+  QUIC_INVALID_HEADERS_STREAM_DATA = 56,
+  // Invalid data on the headers stream received because of decompression
+  // failure.
+  QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE = 97,
+  // The peer received too much data, violating flow control.
+  QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA = 59,
+  // The peer sent too much data, violating flow control.
+  QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA = 63,
+  // The peer received an invalid flow control window.
+  QUIC_FLOW_CONTROL_INVALID_WINDOW = 64,
+  // The connection has been IP pooled into an existing connection.
+  QUIC_CONNECTION_IP_POOLED = 62,
+  // The connection has too many outstanding sent packets.
+  QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS = 68,
+  // The connection has too many outstanding received packets.
+  QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS = 69,
+  // The quic connection has been cancelled.
+  QUIC_CONNECTION_CANCELLED = 70,
+  // Disabled QUIC because of high packet loss rate.
+  QUIC_BAD_PACKET_LOSS_RATE = 71,
+  // Disabled QUIC because of too many PUBLIC_RESETs post handshake.
+  QUIC_PUBLIC_RESETS_POST_HANDSHAKE = 73,
+  // Closed because we failed to serialize a packet.
+  QUIC_FAILED_TO_SERIALIZE_PACKET = 75,
+  // QUIC timed out after too many RTOs.
+  QUIC_TOO_MANY_RTOS = 85,
+
+  // Crypto errors.
+
+  // Handshake failed.
+  QUIC_HANDSHAKE_FAILED = 28,
+  // Handshake message contained out of order tags.
+  QUIC_CRYPTO_TAGS_OUT_OF_ORDER = 29,
+  // Handshake message contained too many entries.
+  QUIC_CRYPTO_TOO_MANY_ENTRIES = 30,
+  // Handshake message contained an invalid value length.
+  QUIC_CRYPTO_INVALID_VALUE_LENGTH = 31,
+  // A crypto message was received after the handshake was complete.
+  QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE = 32,
+  // A crypto message was received with an illegal message tag.
+  QUIC_INVALID_CRYPTO_MESSAGE_TYPE = 33,
+  // A crypto message was received with an illegal parameter.
+  QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER = 34,
+  // An invalid channel id signature was supplied.
+  QUIC_INVALID_CHANNEL_ID_SIGNATURE = 52,
+  // A crypto message was received with a mandatory parameter missing.
+  QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND = 35,
+  // A crypto message was received with a parameter that has no overlap
+  // with the local parameter.
+  QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP = 36,
+  // A crypto message was received that contained a parameter with too few
+  // values.
+  QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND = 37,
+  // A demand for an unsupport proof type was received.
+  QUIC_UNSUPPORTED_PROOF_DEMAND = 94,
+  // An internal error occurred in crypto processing.
+  QUIC_CRYPTO_INTERNAL_ERROR = 38,
+  // A crypto handshake message specified an unsupported version.
+  QUIC_CRYPTO_VERSION_NOT_SUPPORTED = 39,
+  // (Deprecated) A crypto handshake message resulted in a stateless reject.
+  // QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT = 72,
+  // There was no intersection between the crypto primitives supported by the
+  // peer and ourselves.
+  QUIC_CRYPTO_NO_SUPPORT = 40,
+  // The server rejected our client hello messages too many times.
+  QUIC_CRYPTO_TOO_MANY_REJECTS = 41,
+  // The client rejected the server's certificate chain or signature.
+  QUIC_PROOF_INVALID = 42,
+  // A crypto message was received with a duplicate tag.
+  QUIC_CRYPTO_DUPLICATE_TAG = 43,
+  // A crypto message was received with the wrong encryption level (i.e. it
+  // should have been encrypted but was not.)
+  QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT = 44,
+  // The server config for a server has expired.
+  QUIC_CRYPTO_SERVER_CONFIG_EXPIRED = 45,
+  // We failed to setup the symmetric keys for a connection.
+  QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED = 53,
+  // A handshake message arrived, but we are still validating the
+  // previous handshake message.
+  QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO = 54,
+  // A server config update arrived before the handshake is complete.
+  QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE = 65,
+  // CHLO cannot fit in one packet.
+  QUIC_CRYPTO_CHLO_TOO_LARGE = 90,
+  // This connection involved a version negotiation which appears to have been
+  // tampered with.
+  QUIC_VERSION_NEGOTIATION_MISMATCH = 55,
+
+  // Multipath errors.
+  // Multipath is not enabled, but a packet with multipath flag on is received.
+  QUIC_BAD_MULTIPATH_FLAG = 79,
+  // A path is supposed to exist but does not.
+  QUIC_MULTIPATH_PATH_DOES_NOT_EXIST = 91,
+  // A path is supposed to be active but is not.
+  QUIC_MULTIPATH_PATH_NOT_ACTIVE = 92,
+
+  // IP address changed causing connection close.
+  QUIC_IP_ADDRESS_CHANGED = 80,
+
+  // Connection migration errors.
+  // Network changed, but connection had no migratable streams.
+  QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS = 81,
+  // Connection changed networks too many times.
+  QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES = 82,
+  // Connection migration was attempted, but there was no new network to
+  // migrate to.
+  QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK = 83,
+  // Network changed, but connection had one or more non-migratable streams.
+  QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM = 84,
+  // Network changed, but connection migration was disabled by config.
+  QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG = 99,
+  // Network changed, but error was encountered on the alternative network.
+  QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR = 100,
+  // Network changed, but handshake is not confirmed yet.
+  QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED = 111,
+  QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED = 194,
+
+  // Stream frames arrived too discontiguously so that stream sequencer buffer
+  // maintains too many intervals.
+  QUIC_TOO_MANY_STREAM_DATA_INTERVALS = 93,
+
+  // Sequencer buffer get into weird state where continuing read/write will lead
+  // to crash.
+  QUIC_STREAM_SEQUENCER_INVALID_STATE = 95,
+
+  // Connection closed because of server hits max number of sessions allowed.
+  QUIC_TOO_MANY_SESSIONS_ON_SERVER = 96,
+
+  // Receive a RST_STREAM with offset larger than kMaxStreamLength.
+  QUIC_STREAM_LENGTH_OVERFLOW = 98,
+  // Received a MAX DATA frame with errors.
+  QUIC_INVALID_MAX_DATA_FRAME_DATA = 102,
+  // Received a MAX STREAM DATA frame with errors.
+  QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA = 103,
+  // Received a MAX_STREAMS frame with bad data
+  QUIC_MAX_STREAMS_DATA = 104,
+  // Received a STREAMS_BLOCKED frame with bad data
+  QUIC_STREAMS_BLOCKED_DATA = 105,
+  // Error deframing a STREAM BLOCKED frame.
+  QUIC_INVALID_STREAM_BLOCKED_DATA = 106,
+  // NEW CONNECTION ID frame data is malformed.
+  QUIC_INVALID_NEW_CONNECTION_ID_DATA = 107,
+  // More connection IDs than allowed are issued.
+  QUIC_CONNECTION_ID_LIMIT_ERROR = 203,
+  // The peer retires connection IDs too quickly.
+  QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE = 204,
+  // Received a MAX STREAM DATA frame with errors.
+  QUIC_INVALID_STOP_SENDING_FRAME_DATA = 108,
+  // Error deframing PATH CHALLENGE or PATH RESPONSE frames.
+  QUIC_INVALID_PATH_CHALLENGE_DATA = 109,
+  QUIC_INVALID_PATH_RESPONSE_DATA = 110,
+  // This is used to indicate an IETF QUIC PROTOCOL VIOLATION
+  // transport error within Google (pre-v99) QUIC.
+  IETF_QUIC_PROTOCOL_VIOLATION = 113,
+  QUIC_INVALID_NEW_TOKEN = 114,
+
+  // Received stream data on a WRITE_UNIDIRECTIONAL stream.
+  QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM = 115,
+  // Try to send stream data on a READ_UNIDIRECTIONAL stream.
+  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM = 116,
+
+  // RETIRE CONNECTION ID frame data is malformed.
+  QUIC_INVALID_RETIRE_CONNECTION_ID_DATA = 117,
+
+  // Error in a received STREAMS BLOCKED frame.
+  QUIC_STREAMS_BLOCKED_ERROR = 118,
+  // Error in a received MAX STREAMS frame
+  QUIC_MAX_STREAMS_ERROR = 119,
+  // Error in Http decoder
+  QUIC_HTTP_DECODER_ERROR = 120,
+  // Connection from stale host needs to be cancelled.
+  QUIC_STALE_CONNECTION_CANCELLED = 121,
+
+  // A pseudo error, used as an extended error reason code in the error_details
+  // of IETF-QUIC CONNECTION_CLOSE frames. It is used in
+  // OnConnectionClosed upcalls to indicate that extended error information was
+  // not available in a received CONNECTION_CLOSE frame.
+  QUIC_IETF_GQUIC_ERROR_MISSING = 122,
+
+  // Received WindowUpdate on a READ_UNIDIRECTIONAL stream.
+  QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM = 123,
+
+  // There are too many buffered control frames in control frame manager.
+  QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES = 124,
+
+  // QuicTransport received invalid client indication.
+  QUIC_TRANSPORT_INVALID_CLIENT_INDICATION = 125,
+
+  // Internal error codes for QPACK errors.
+  QUIC_QPACK_DECOMPRESSION_FAILED = 126,
+
+  // Obsolete generic QPACK encoder and decoder stream error codes.
+  QUIC_QPACK_ENCODER_STREAM_ERROR = 127,
+  QUIC_QPACK_DECODER_STREAM_ERROR = 128,
+
+  // QPACK encoder stream errors.
+
+  // Variable integer exceeding 2^64-1 received.
+  QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE = 174,
+  // String literal exceeding kStringLiteralLengthLimit in length received.
+  QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG = 175,
+  // String literal with invalid Huffman encoding received.
+  QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR = 176,
+  // Invalid static table index in Insert With Name Reference instruction.
+  QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY = 177,
+  // Error inserting entry with static name reference in Insert With Name
+  // Reference instruction due to entry size exceeding dynamic table capacity.
+  QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC = 178,
+  // Invalid relative index in Insert With Name Reference instruction.
+  QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX = 179,
+  // Dynamic entry not found in Insert With Name Reference instruction.
+  QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND = 180,
+  // Error inserting entry with dynamic name reference in Insert With Name
+  // Reference instruction due to entry size exceeding dynamic table capacity.
+  QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC = 181,
+  // Error inserting entry in Insert With Literal Name instruction due to entry
+  // size exceeding dynamic table capacity.
+  QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL = 182,
+  // Invalid relative index in Duplicate instruction.
+  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX = 183,
+  // Dynamic entry not found in Duplicate instruction.
+  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND = 184,
+  // Error in Set Dynamic Table Capacity instruction due to new capacity
+  // exceeding maximum dynamic table capacity.
+  QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY = 185,
+
+  // QPACK decoder stream errors.
+
+  // Variable integer exceeding 2^64-1 received.
+  QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE = 186,
+  // Insert Count Increment instruction received with invalid 0 increment.
+  QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT = 187,
+  // Insert Count Increment instruction causes uint64_t overflow.
+  QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW = 188,
+  // Insert Count Increment instruction increases Known Received Count beyond
+  // inserted entry cound.
+  QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT = 189,
+  // Header Acknowledgement received for stream that has no outstanding header
+  // blocks.
+  QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT = 190,
+
+  // Received stream data beyond close offset.
+  QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET = 129,
+
+  // Received multiple close offset.
+  QUIC_STREAM_MULTIPLE_OFFSET = 130,
+
+  // HTTP/3 errors.
+
+  // Frame payload larger than what HttpDecoder is willing to buffer.
+  QUIC_HTTP_FRAME_TOO_LARGE = 131,
+  // Malformed HTTP/3 frame, or PUSH_PROMISE or CANCEL_PUSH received (which is
+  // an error because MAX_PUSH_ID is never sent).
+  QUIC_HTTP_FRAME_ERROR = 132,
+  // A frame that is never allowed on a request stream is received.
+  QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM = 133,
+  // A frame that is never allowed on the control stream is received.
+  QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM = 134,
+  // An invalid sequence of frames normally allowed on a request stream is
+  // received.
+  QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM = 151,
+  // A second SETTINGS frame is received on the control stream.
+  QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM = 152,
+  // A second instance of a unidirectional stream of a certain type is created.
+  QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM = 153,
+  // Client receives a server-initiated bidirectional stream.
+  QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM = 154,
+  // Server opens stream with stream ID corresponding to client-initiated
+  // stream or vice versa.
+  QUIC_HTTP_STREAM_WRONG_DIRECTION = 155,
+  // Peer closes one of the six critical unidirectional streams (control, QPACK
+  // encoder or decoder, in either direction).
+  QUIC_HTTP_CLOSED_CRITICAL_STREAM = 156,
+  // The first frame received on the control stream is not a SETTINGS frame.
+  QUIC_HTTP_MISSING_SETTINGS_FRAME = 157,
+  // The received SETTINGS frame contains duplicate setting identifiers.
+  QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER = 158,
+  // MAX_PUSH_ID frame received with push ID value smaller than a previously
+  // received value.
+  QUIC_HTTP_INVALID_MAX_PUSH_ID = 159,
+  // Received unidirectional stream limit is lower than required by HTTP/3.
+  QUIC_HTTP_STREAM_LIMIT_TOO_LOW = 160,
+  // Received mismatched SETTINGS frame from HTTP/3 connection where early data
+  // is accepted. Server violated the HTTP/3 spec.
+  QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH = 164,
+  // Received mismatched SETTINGS frame from HTTP/3 connection where early data
+  // is rejected. Our implementation currently doesn't support it.
+  QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH = 165,
+  // Client received GOAWAY frame with stream ID that is not for a
+  // client-initiated bidirectional stream.
+  QUIC_HTTP_GOAWAY_INVALID_STREAM_ID = 166,
+  // Received GOAWAY frame with ID that is greater than previously received ID.
+  QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS = 167,
+  // HTTP/3 session received SETTINGS frame which contains HTTP/2 specific
+  // settings.
+  QUIC_HTTP_RECEIVE_SPDY_SETTING = 169,
+  // HTTP/3 session received an HTTP/2 only frame.
+  QUIC_HTTP_RECEIVE_SPDY_FRAME = 171,
+  // HTTP/3 session received SERVER_PUSH stream, which is an error because
+  // PUSH_PROMISE is not accepted.
+  QUIC_HTTP_RECEIVE_SERVER_PUSH = 205,
+  // HTTP/3 session received invalid SETTING value.
+  QUIC_HTTP_INVALID_SETTING_VALUE = 207,
+
+  // HPACK header block decoding errors.
+  // Index varint beyond implementation limit.
+  QUIC_HPACK_INDEX_VARINT_ERROR = 135,
+  // Name length varint beyond implementation limit.
+  QUIC_HPACK_NAME_LENGTH_VARINT_ERROR = 136,
+  // Value length varint beyond implementation limit.
+  QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR = 137,
+  // Name length exceeds buffer limit.
+  QUIC_HPACK_NAME_TOO_LONG = 138,
+  // Value length exceeds buffer limit.
+  QUIC_HPACK_VALUE_TOO_LONG = 139,
+  // Name Huffman encoding error.
+  QUIC_HPACK_NAME_HUFFMAN_ERROR = 140,
+  // Value Huffman encoding error.
+  QUIC_HPACK_VALUE_HUFFMAN_ERROR = 141,
+  // Next instruction should have been a dynamic table size update.
+  QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE = 142,
+  // Invalid index in indexed header field representation.
+  QUIC_HPACK_INVALID_INDEX = 143,
+  // Invalid index in literal header field with indexed name representation.
+  QUIC_HPACK_INVALID_NAME_INDEX = 144,
+  // Dynamic table size update not allowed.
+  QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED = 145,
+  // Initial dynamic table size update is above low water mark.
+  QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK = 146,
+  // Dynamic table size update is above acknowledged setting.
+  QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING = 147,
+  // HPACK block ends in the middle of an instruction.
+  QUIC_HPACK_TRUNCATED_BLOCK = 148,
+  // Incoming data fragment exceeds buffer limit.
+  QUIC_HPACK_FRAGMENT_TOO_LONG = 149,
+  // Total compressed HPACK data size exceeds limit.
+  QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT = 150,
+
+  // Stream/flow control limit from 1-RTT handshake is too low to retransmit
+  // 0-RTT data. This is our implentation error. We could in theory keep the
+  // connection alive but chose not to for simplicity.
+  QUIC_ZERO_RTT_UNRETRANSMITTABLE = 161,
+  // Stream/flow control limit from 0-RTT rejection reduces cached limit.
+  // This is our implentation error. We could in theory keep the connection
+  // alive but chose not to for simplicity.
+  QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED = 162,
+  // Stream/flow control limit from 0-RTT resumption reduces cached limit.
+  // This is the peer violating QUIC spec.
+  QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED = 163,
+
+  // The connection silently timed out due to no network activity.
+  QUIC_SILENT_IDLE_TIMEOUT = 168,
+
+  // Try to write data without the right write keys.
+  QUIC_MISSING_WRITE_KEYS = 170,
+
+  // An endpoint detected errors in performing key updates.
+  QUIC_KEY_UPDATE_ERROR = 172,
+
+  // An endpoint has reached the confidentiality or integrity limit for the
+  // AEAD algorithm used by the given connection.
+  QUIC_AEAD_LIMIT_REACHED = 173,
+
+  // Connection reached maximum age (regardless of activity), no new requests
+  // are accepted.  This error code is sent in transport layer GOAWAY frame when
+  // using gQUIC, and only used internally when using HTTP/3.  Active requests
+  // are still served, after which connection will be closed due to idle
+  // timeout.
+  QUIC_MAX_AGE_TIMEOUT = 191,
+
+  // Decrypted a 0-RTT packet with a higher packet number than a 1-RTT packet.
+  QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER = 192,
+
+  // Received PRIORITY_UPDATE frame with invalid payload.
+  QUIC_INVALID_PRIORITY_UPDATE = 193,
+
+  // Maps to specific errors from the CRYPTO_ERROR range from
+  // https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#name-transport-error-codes
+  // This attempts to choose a subset of the most interesting errors rather
+  // than mapping every possible CRYPTO_ERROR code.
+  QUIC_TLS_BAD_CERTIFICATE = 195,
+  QUIC_TLS_UNSUPPORTED_CERTIFICATE = 196,
+  QUIC_TLS_CERTIFICATE_REVOKED = 197,
+  QUIC_TLS_CERTIFICATE_EXPIRED = 198,
+  QUIC_TLS_CERTIFICATE_UNKNOWN = 199,
+  QUIC_TLS_INTERNAL_ERROR = 200,
+  QUIC_TLS_UNRECOGNIZED_NAME = 201,
+  QUIC_TLS_CERTIFICATE_REQUIRED = 202,
+
+  // An HTTP field value containing an invalid character has been received.
+  QUIC_INVALID_CHARACTER_IN_FIELD_VALUE = 206,
+
+  // Error code related to the usage of TLS keying material export.
+  QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL = 208,
+  QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH = 209,
+  QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE = 210,
+  QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED = 211,
+
+  // No error. Used as bound while iterating.
+  QUIC_LAST_ERROR = 213,
+};
+// QuicErrorCodes is encoded as four octets on-the-wire when doing Google QUIC,
+// or a varint62 when doing IETF QUIC. Ensure that its value does not exceed
+// the smaller of the two limits.
+static_assert(static_cast<uint64_t>(QUIC_LAST_ERROR) <=
+                  static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()),
+              "QuicErrorCode exceeds four octets");
+
+// Represents a reason for resetting a stream in both gQUIC and IETF error code
+// space.  Both error codes have to be present.
+class QUIC_EXPORT_PRIVATE QuicResetStreamError {
+ public:
+  // Constructs a QuicResetStreamError from QuicRstStreamErrorCode; the IETF
+  // error code is inferred.
+  static QuicResetStreamError FromInternal(QuicRstStreamErrorCode code);
+  // Constructs a QuicResetStreamError from an IETF error code; the internal
+  // error code is inferred.
+  static QuicResetStreamError FromIetf(uint64_t code);
+  // Constructs a QuicResetStreamError with no error.
+  static QuicResetStreamError NoError() {
+    return FromInternal(QUIC_STREAM_NO_ERROR);
+  }
+
+  QuicResetStreamError(QuicRstStreamErrorCode internal_code,
+                       uint64_t ietf_application_code)
+      : internal_code_(internal_code),
+        ietf_application_code_(ietf_application_code) {}
+
+  QuicRstStreamErrorCode internal_code() const { return internal_code_; }
+  uint64_t ietf_application_code() const { return ietf_application_code_; }
+
+  bool operator==(const QuicResetStreamError& other) const {
+    return internal_code() == other.internal_code() &&
+           ietf_application_code() == other.ietf_application_code();
+  }
+
+  // Returns true if the object holds no error.
+  bool ok() const { return internal_code() == QUIC_STREAM_NO_ERROR; }
+
+ private:
+  // Error code used in gQUIC.  Even when IETF QUIC is in use, this needs to be
+  // populated as we use those internally.
+  QuicRstStreamErrorCode internal_code_;
+  // Application error code used in IETF QUIC.
+  uint64_t ietf_application_code_;
+};
+
+// Convert TLS alert code to QuicErrorCode.
+QUIC_EXPORT_PRIVATE QuicErrorCode TlsAlertToQuicErrorCode(uint8_t desc);
+
+// Returns the name of the QuicRstStreamErrorCode as a char*
+QUIC_EXPORT_PRIVATE const char* QuicRstStreamErrorCodeToString(
+    QuicRstStreamErrorCode error);
+
+// Returns the name of the QuicErrorCode as a char*
+QUIC_EXPORT_PRIVATE const char* QuicErrorCodeToString(QuicErrorCode error);
+
+// Wire values for QUIC transport errors.
+// https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#name-transport-error-codes
+enum QuicIetfTransportErrorCodes : uint64_t {
+  NO_IETF_QUIC_ERROR = 0x0,
+  INTERNAL_ERROR = 0x1,
+  SERVER_BUSY_ERROR = 0x2,
+  FLOW_CONTROL_ERROR = 0x3,
+  STREAM_LIMIT_ERROR = 0x4,
+  STREAM_STATE_ERROR = 0x5,
+  FINAL_SIZE_ERROR = 0x6,
+  FRAME_ENCODING_ERROR = 0x7,
+  TRANSPORT_PARAMETER_ERROR = 0x8,
+  CONNECTION_ID_LIMIT_ERROR = 0x9,
+  PROTOCOL_VIOLATION = 0xA,
+  INVALID_TOKEN = 0xB,
+  CRYPTO_BUFFER_EXCEEDED = 0xD,
+  KEY_UPDATE_ERROR = 0xE,
+  AEAD_LIMIT_REACHED = 0xF,
+  CRYPTO_ERROR_FIRST = 0x100,
+  CRYPTO_ERROR_LAST = 0x1FF,
+};
+
+QUIC_EXPORT_PRIVATE std::string QuicIetfTransportErrorCodeString(
+    QuicIetfTransportErrorCodes c);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const QuicIetfTransportErrorCodes& c);
+
+// A transport error code (if is_transport_close is true) or application error
+// code (if is_transport_close is false) to be used in CONNECTION_CLOSE frames.
+struct QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping {
+  bool is_transport_close;
+  uint64_t error_code;
+};
+
+// Convert QuicErrorCode to transport or application IETF error code
+// to be used in CONNECTION_CLOSE frames.
+QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping
+QuicErrorCodeToTransportErrorCode(QuicErrorCode error);
+
+// Wire values for HTTP/3 errors.
+// https://quicwg.org/base-drafts/draft-ietf-quic-http.html#http-error-codes
+enum class QuicHttp3ErrorCode {
+  // NO_ERROR is defined as a C preprocessor macro on Windows.
+  HTTP3_NO_ERROR = 0x100,
+  GENERAL_PROTOCOL_ERROR = 0x101,
+  INTERNAL_ERROR = 0x102,
+  STREAM_CREATION_ERROR = 0x103,
+  CLOSED_CRITICAL_STREAM = 0x104,
+  FRAME_UNEXPECTED = 0x105,
+  FRAME_ERROR = 0x106,
+  EXCESSIVE_LOAD = 0x107,
+  ID_ERROR = 0x108,
+  SETTINGS_ERROR = 0x109,
+  MISSING_SETTINGS = 0x10A,
+  REQUEST_REJECTED = 0x10B,
+  REQUEST_CANCELLED = 0x10C,
+  REQUEST_INCOMPLETE = 0x10D,
+  MESSAGE_ERROR = 0x10E,
+  CONNECT_ERROR = 0x10F,
+  VERSION_FALLBACK = 0x110,
+};
+
+// Wire values for QPACK errors.
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#error-code-registration
+enum class QuicHttpQpackErrorCode {
+  DECOMPRESSION_FAILED = 0x200,
+  ENCODER_STREAM_ERROR = 0x201,
+  DECODER_STREAM_ERROR = 0x202
+};
+
+// Convert a QuicRstStreamErrorCode to an application error code to be used in
+// an IETF QUIC RESET_STREAM frame
+QUIC_EXPORT_PRIVATE uint64_t RstStreamErrorCodeToIetfResetStreamErrorCode(
+    QuicRstStreamErrorCode rst_stream_error_code);
+
+// Convert the application error code of an IETF QUIC RESET_STREAM frame
+// to QuicRstStreamErrorCode.
+QUIC_EXPORT_PRIVATE QuicRstStreamErrorCode
+IetfResetStreamErrorCodeToRstStreamErrorCode(uint64_t ietf_error_code);
+
+QUIC_EXPORT_PRIVATE inline std::string HistogramEnumString(
+    QuicErrorCode enum_value) {
+  return QuicErrorCodeToString(enum_value);
+}
+
+QUIC_EXPORT_PRIVATE inline std::string HistogramEnumDescription(
+    QuicErrorCode /*dummy*/) {
+  return "cause";
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
diff --git a/quiche/quic/core/quic_error_codes_test.cc b/quiche/quic/core/quic_error_codes_test.cc
new file mode 100644
index 0000000..b888bb7
--- /dev/null
+++ b/quiche/quic/core/quic_error_codes_test.cc
@@ -0,0 +1,143 @@
+// Copyright (c) 2013 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 "quiche/quic/core/quic_error_codes.h"
+
+#include <cstdint>
+
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using QuicErrorCodesTest = QuicTest;
+
+TEST_F(QuicErrorCodesTest, QuicErrorCodeToString) {
+  EXPECT_STREQ("QUIC_NO_ERROR", QuicErrorCodeToString(QUIC_NO_ERROR));
+}
+
+TEST_F(QuicErrorCodesTest, QuicIetfTransportErrorCodeString) {
+  EXPECT_EQ("CRYPTO_ERROR(missing extension)",
+            QuicIetfTransportErrorCodeString(
+                static_cast<quic::QuicIetfTransportErrorCodes>(
+                    CRYPTO_ERROR_FIRST + SSL_AD_MISSING_EXTENSION)));
+
+  EXPECT_EQ("NO_IETF_QUIC_ERROR",
+            QuicIetfTransportErrorCodeString(NO_IETF_QUIC_ERROR));
+  EXPECT_EQ("INTERNAL_ERROR", QuicIetfTransportErrorCodeString(INTERNAL_ERROR));
+  EXPECT_EQ("SERVER_BUSY_ERROR",
+            QuicIetfTransportErrorCodeString(SERVER_BUSY_ERROR));
+  EXPECT_EQ("FLOW_CONTROL_ERROR",
+            QuicIetfTransportErrorCodeString(FLOW_CONTROL_ERROR));
+  EXPECT_EQ("STREAM_LIMIT_ERROR",
+            QuicIetfTransportErrorCodeString(STREAM_LIMIT_ERROR));
+  EXPECT_EQ("STREAM_STATE_ERROR",
+            QuicIetfTransportErrorCodeString(STREAM_STATE_ERROR));
+  EXPECT_EQ("FINAL_SIZE_ERROR",
+            QuicIetfTransportErrorCodeString(FINAL_SIZE_ERROR));
+  EXPECT_EQ("FRAME_ENCODING_ERROR",
+            QuicIetfTransportErrorCodeString(FRAME_ENCODING_ERROR));
+  EXPECT_EQ("TRANSPORT_PARAMETER_ERROR",
+            QuicIetfTransportErrorCodeString(TRANSPORT_PARAMETER_ERROR));
+  EXPECT_EQ("CONNECTION_ID_LIMIT_ERROR",
+            QuicIetfTransportErrorCodeString(CONNECTION_ID_LIMIT_ERROR));
+  EXPECT_EQ("PROTOCOL_VIOLATION",
+            QuicIetfTransportErrorCodeString(PROTOCOL_VIOLATION));
+  EXPECT_EQ("INVALID_TOKEN", QuicIetfTransportErrorCodeString(INVALID_TOKEN));
+  EXPECT_EQ("CRYPTO_BUFFER_EXCEEDED",
+            QuicIetfTransportErrorCodeString(CRYPTO_BUFFER_EXCEEDED));
+  EXPECT_EQ("KEY_UPDATE_ERROR",
+            QuicIetfTransportErrorCodeString(KEY_UPDATE_ERROR));
+  EXPECT_EQ("AEAD_LIMIT_REACHED",
+            QuicIetfTransportErrorCodeString(AEAD_LIMIT_REACHED));
+
+  EXPECT_EQ("Unknown(1024)",
+            QuicIetfTransportErrorCodeString(
+                static_cast<quic::QuicIetfTransportErrorCodes>(0x400)));
+}
+
+TEST_F(QuicErrorCodesTest, QuicErrorCodeToTransportErrorCode) {
+  for (int internal_error_code = 0; internal_error_code < QUIC_LAST_ERROR;
+       ++internal_error_code) {
+    std::string internal_error_code_string =
+        QuicErrorCodeToString(static_cast<QuicErrorCode>(internal_error_code));
+    if (internal_error_code_string == "INVALID_ERROR_CODE") {
+      // Not a valid QuicErrorCode.
+      continue;
+    }
+    QuicErrorCodeToIetfMapping ietf_error_code =
+        QuicErrorCodeToTransportErrorCode(
+            static_cast<QuicErrorCode>(internal_error_code));
+    if (ietf_error_code.is_transport_close) {
+      QuicIetfTransportErrorCodes transport_error_code =
+          static_cast<QuicIetfTransportErrorCodes>(ietf_error_code.error_code);
+      bool is_transport_crypto_error_code =
+          transport_error_code >= 0x100 && transport_error_code <= 0x1ff;
+      if (is_transport_crypto_error_code) {
+        // Ensure that every QuicErrorCode that maps to a CRYPTO_ERROR code has
+        // a corresponding reverse mapping in TlsAlertToQuicErrorCode:
+        EXPECT_EQ(
+            internal_error_code,
+            TlsAlertToQuicErrorCode(transport_error_code - CRYPTO_ERROR_FIRST));
+      }
+      bool is_valid_transport_error_code =
+          transport_error_code <= 0x0f || is_transport_crypto_error_code;
+      EXPECT_TRUE(is_valid_transport_error_code) << internal_error_code_string;
+    } else {
+      // Non-transport errors are application errors, either HTTP/3 or QPACK.
+      uint64_t application_error_code = ietf_error_code.error_code;
+      bool is_valid_http3_error_code =
+          application_error_code >= 0x100 && application_error_code <= 0x110;
+      bool is_valid_qpack_error_code =
+          application_error_code >= 0x200 && application_error_code <= 0x202;
+      EXPECT_TRUE(is_valid_http3_error_code || is_valid_qpack_error_code)
+          << internal_error_code_string;
+    }
+  }
+}
+
+using QuicRstErrorCodesTest = QuicTest;
+
+TEST_F(QuicRstErrorCodesTest, QuicRstStreamErrorCodeToString) {
+  EXPECT_STREQ("QUIC_BAD_APPLICATION_PAYLOAD",
+               QuicRstStreamErrorCodeToString(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+// When an IETF application protocol error code (sent on the wire in
+// RESET_STREAM and STOP_SENDING frames) is translated into a
+// QuicRstStreamErrorCode and back, it must yield the original value.
+TEST_F(QuicRstErrorCodesTest,
+       IetfResetStreamErrorCodeToRstStreamErrorCodeAndBack) {
+  for (uint64_t wire_code :
+       {static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK),
+        static_cast<uint64_t>(QuicHttpQpackErrorCode::DECOMPRESSION_FAILED),
+        static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR),
+        static_cast<uint64_t>(QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}) {
+    QuicRstStreamErrorCode rst_stream_error_code =
+        IetfResetStreamErrorCodeToRstStreamErrorCode(wire_code);
+    EXPECT_EQ(wire_code, RstStreamErrorCodeToIetfResetStreamErrorCode(
+                             rst_stream_error_code));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h
new file mode 100644
index 0000000..b0d34ab
--- /dev/null
+++ b/quiche/quic/core/quic_flags_list.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2022 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.
+
+// This file is autogenerated by the QUICHE Copybara export script.
+
+#ifdef QUIC_FLAG
+
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_set_burst_token, false)
+
+QUIC_FLAG(FLAGS_quic_restart_flag_quic_offload_pacing_to_usps2, false)
+// A testonly reloadable flag that will always default to false.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_false, false)
+// A testonly reloadable flag that will always default to true.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_true, true)
+// A testonly restart flag that will always default to false.
+QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_false, false)
+// A testonly restart flag that will always default to true.
+QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_true, true)
+// If bytes in flight has dipped below 1.25*MaxBW in the last round, do not exit PROBE_UP due to excess queue buildup.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_no_probe_up_exit_if_no_queue, true)
+// If true, 1) QUIC connections will use a lower minimum for trusted initial rtt, 2) When TRTT is received, QUIC server sessions will mark the initial rtt from CachedNetworkParameters as trusted.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_lower_min_for_trusted_irtt, true)
+// If true, QUIC connection will be closed if it fails to serialize a coalesced packet.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_close_connection_if_fail_to_serialzie_coalesced_packet2, true)
+// If true, QUIC will default enable MTU discovery at server, with a target of 1450 bytes.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false)
+// If true, QuicGsoBatchWriter will support release time if it is available and the process has the permission to do so.
+QUIC_FLAG(FLAGS_quic_restart_flag_quic_support_release_time_for_gso, false)
+// If true, TlsServerHandshaker will be able to 1) request client cert, and 2) verify the client cert in the virtual method TlsServerHandshaker::VerifyCertChain.
+QUIC_FLAG(FLAGS_quic_restart_flag_quic_tls_server_support_client_cert, true)
+// If true, abort async QPACK header decompression in QuicSpdyStream::Reset() and in QuicSpdyStream::OnStreamReset().
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_abort_qpack_on_stream_reset, true)
+// If true, ack frequency frame can be sent from server to client.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency, true)
+// If true, allow client to enable BBRv2 on server via connection option \'B2ON\'.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, true)
+// If true, close read side but not write side in QuicSpdyStream::OnStreamReset().
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_on_stream_reset, true)
+// If true, consolidate more logic into SetRetransmissionAlarm to ensure the logic is applied consistently.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_simplify_set_retransmission_alarm, true)
+// If true, default on PTO which unifies TLP + RTO loss recovery.
+QUIC_FLAG(FLAGS_quic_restart_flag_quic_default_on_pto2, true)
+// If true, default-enable 5RTO blachole detection.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true)
+// If true, disable QUIC version Q043.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q043, false)
+// If true, disable QUIC version Q046.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q046, false)
+// If true, disable QUIC version Q050.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q050, false)
+// If true, disable QUIC version h3 (RFCv1).
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_rfcv1, false)
+// If true, disable QUIC version h3-29.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_29, false)
+// If true, disable blackhole detection on server side.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_server_blackhole_detection, false)
+// If true, discard INITIAL packet if the key has been dropped.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, true)
+// If true, do not call ProofSourceHandle::SelectCertificate if QUIC connection has disconnected.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_tls_no_select_cert_if_disconnected, true)
+// If true, do not count bytes sent/received on the alternative path into the bytes sent/received on the default path.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_count_bytes_on_alternative_path_seperately, true)
+// If true, enable server retransmittable on wire PING.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_server_on_wire_ping, true)
+// If true, flush creator after coalesce packet of higher space.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_flush_after_coalesce_higher_space_packets, true)
+// If true, flush pending frames as well as pending padding bytes on connection migration.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_flush_pending_frames_and_padding_bytes_on_migration, true)
+// If true, ietf connection migration is no longer conditioned on connection option RVCM.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_remove_connection_migration_connection_option, false)
+// If true, ignore incoming MAX_PUSH_ID frames (expect for enforcing frame type rules).
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ignore_max_push_id, true)
+// If true, include stream information in idle timeout connection close detail.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_add_stream_info_to_idle_close_detail, true)
+// If true, limit the size of HPACK encoder dynamic table to 16 kB.  Only affects gQUIC; QPACK encoder dynamic table size used in IETF QUIC is already bounded.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_limit_encoder_dynamic_table_size, true)
+// If true, pass the received PATH_RESPONSE payload to path validator to move forward the path validation.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_pass_path_response_to_validator, true)
+// If true, quic server will send ENABLE_CONNECT_PROTOCOL setting and and endpoint will validate required request/response headers and extended CONNECT mechanism and update code counts of valid/invalid headers.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_verify_request_headers_2, true)
+// If true, record addresses that server has sent reset to recently, and do not send reset if the address lives in the set.
+QUIC_FLAG(FLAGS_quic_restart_flag_quic_use_recent_reset_addresses, true)
+// If true, reject or send error response code upon receiving invalid request or response headers. This flag depends on --gfe2_reloadable_flag_quic_verify_request_headers_2.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_act_upon_invalid_header, false)
+// If true, require handshake confirmation for QUIC connections, functionally disabling 0-rtt handshakes.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation, false)
+// If true, server proactively retires client issued connection ID on reverse path validation failure. 
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_retire_cid_on_reverse_path_validation_failure, true)
+// If true, servers drop received packets with changed server address.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_drop_packets_with_changed_server_address, false)
+// If true, set burst token to 2 in cwnd bootstrapping experiment.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_bursts, false)
+// If true, stop resetting ideal_next_packet_send_time_ in pacing sender.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
+// If true, update ACK timeout based on packet receipt time rather than now.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_update_ack_timeout_on_receipt_time, true)
+// If true, use BBRv2 as the default congestion controller. Takes precedence over --quic_default_to_bbr.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr_v2, false)
+// If true, use new connection ID in connection migration.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_connection_migration_use_new_cid_v2, true)
+// If true, uses conservative cwnd gain and pacing gain when cwnd gets bootstrapped.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, false)
+// If true, validate that peer owns the new address once the server detects peer migration or is probed from that address, and also apply anti-amplification limit while sending to that address.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_server_reverse_validate_new_path3, true)
+// If true, when a packet is forced retransmitted, only set packet state if all data gets retransmitted.
+QUIC_FLAG(FLAGS_quic_restart_flag_quic_set_packet_state_if_all_data_retransmitted, true)
+// When the flag is true, exit STARTUP after the same number of loss events as PROBE_UP.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_startup_probe_up_loss_events, true)
+// When true, defaults to BBR congestion control instead of Cubic.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr, false)
+// When true, prevents QUIC\'s PacingSender from generating bursts when the congestion controller is CWND limited and not pacing limited.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_pacing_sender_bursts, true)
+// When true, set the initial congestion control window from connection options in QuicSentPacketManager rather than TcpCubicSenderBytes.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, true)
+// When true, support draft-ietf-quic-v2-01
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_version_2_draft_01, false)
+// When true, the B203 connection option causes the Bbr2Sender to ignore inflight_hi during PROBE_UP and increase it when the bytes delivered without loss are higher.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_ignore_inflight_hi_in_probe_up, true)
+// When true, the B205 connection option enables extra acked in STARTUP, and B204 adds new logic to decrease it whenever max bandwidth increases.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_startup_extra_acked, true)
+// When true, the B207 connection option causes BBR2 to exit STARTUP if a persistent queue of 2*BDP has existed for the entire round.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_exit_startup_on_persistent_queue2, true)
+// When true, the BBQ0 connection option causes QUIC BBR2 to add bytes_acked to probe_up_acked if the connection hasn\'t been app-limited since inflight_hi was utilized.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_add_bytes_acked_after_inflight_hi_limited, true)
+// When true, the BBR4 copt sets the extra_acked window to 20 RTTs and BBR5 sets it to 40 RTTs.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_extra_acked_window, true)
+
+#endif
+
diff --git a/quiche/quic/core/quic_flow_controller.cc b/quiche/quic/core/quic_flow_controller.cc
new file mode 100644
index 0000000..6b5041d
--- /dev/null
+++ b/quiche/quic/core/quic_flow_controller.cc
@@ -0,0 +1,319 @@
+// 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 "quiche/quic/core/quic_flow_controller.h"
+
+#include <cstdint>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+std::string QuicFlowController::LogLabel() {
+  if (is_connection_flow_controller_) {
+    return "connection";
+  }
+  return absl::StrCat("stream ", id_);
+}
+
+QuicFlowController::QuicFlowController(
+    QuicSession* session,
+    QuicStreamId id,
+    bool is_connection_flow_controller,
+    QuicStreamOffset send_window_offset,
+    QuicStreamOffset receive_window_offset,
+    QuicByteCount receive_window_size_limit,
+    bool should_auto_tune_receive_window,
+    QuicFlowControllerInterface* session_flow_controller)
+    : session_(session),
+      connection_(session->connection()),
+      id_(id),
+      is_connection_flow_controller_(is_connection_flow_controller),
+      perspective_(session->perspective()),
+      bytes_sent_(0),
+      send_window_offset_(send_window_offset),
+      bytes_consumed_(0),
+      highest_received_byte_offset_(0),
+      receive_window_offset_(receive_window_offset),
+      receive_window_size_(receive_window_offset),
+      receive_window_size_limit_(receive_window_size_limit),
+      auto_tune_receive_window_(should_auto_tune_receive_window),
+      session_flow_controller_(session_flow_controller),
+      last_blocked_send_window_offset_(0),
+      prev_window_update_time_(QuicTime::Zero()) {
+  QUICHE_DCHECK_LE(receive_window_size_, receive_window_size_limit_);
+  QUICHE_DCHECK_EQ(
+      is_connection_flow_controller_,
+      QuicUtils::GetInvalidStreamId(session_->transport_version()) == id_);
+
+  QUIC_DVLOG(1) << ENDPOINT << "Created flow controller for " << LogLabel()
+                << ", setting initial receive window offset to: "
+                << receive_window_offset_
+                << ", max receive window to: " << receive_window_size_
+                << ", max receive window limit to: "
+                << receive_window_size_limit_
+                << ", setting send window offset to: " << send_window_offset_;
+}
+
+void QuicFlowController::AddBytesConsumed(QuicByteCount bytes_consumed) {
+  bytes_consumed_ += bytes_consumed;
+  QUIC_DVLOG(1) << ENDPOINT << LogLabel() << " consumed " << bytes_consumed_
+                << " bytes.";
+
+  MaybeSendWindowUpdate();
+}
+
+bool QuicFlowController::UpdateHighestReceivedOffset(
+    QuicStreamOffset new_offset) {
+  // Only update if offset has increased.
+  if (new_offset <= highest_received_byte_offset_) {
+    return false;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << LogLabel()
+                << " highest byte offset increased from "
+                << highest_received_byte_offset_ << " to " << new_offset;
+  highest_received_byte_offset_ = new_offset;
+  return true;
+}
+
+void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) {
+  if (bytes_sent_ + bytes_sent > send_window_offset_) {
+    QUIC_BUG(quic_bug_10836_1)
+        << ENDPOINT << LogLabel() << " Trying to send an extra " << bytes_sent
+        << " bytes, when bytes_sent = " << bytes_sent_
+        << ", and send_window_offset_ = " << send_window_offset_;
+    bytes_sent_ = send_window_offset_;
+
+    // This is an error on our side, close the connection as soon as possible.
+    connection_->CloseConnection(
+        QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA,
+        absl::StrCat(send_window_offset_ - (bytes_sent_ + bytes_sent),
+                     "bytes over send window offset"),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  bytes_sent_ += bytes_sent;
+  QUIC_DVLOG(1) << ENDPOINT << LogLabel() << " sent " << bytes_sent_
+                << " bytes.";
+}
+
+bool QuicFlowController::FlowControlViolation() {
+  if (highest_received_byte_offset_ > receive_window_offset_) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Flow control violation on " << LogLabel()
+                    << ", receive window offset: " << receive_window_offset_
+                    << ", highest received byte offset: "
+                    << highest_received_byte_offset_;
+    return true;
+  }
+  return false;
+}
+
+void QuicFlowController::MaybeIncreaseMaxWindowSize() {
+  // Core of receive window auto tuning.  This method should be called before a
+  // WINDOW_UPDATE frame is sent.  Ideally, window updates should occur close to
+  // once per RTT.  If a window update happens much faster than RTT, it implies
+  // that the flow control window is imposing a bottleneck.  To prevent this,
+  // this method will increase the receive window size (subject to a reasonable
+  // upper bound).  For simplicity this algorithm is deliberately asymmetric, in
+  // that it may increase window size but never decreases.
+
+  // Keep track of timing between successive window updates.
+  QuicTime now = connection_->clock()->ApproximateNow();
+  QuicTime prev = prev_window_update_time_;
+  prev_window_update_time_ = now;
+  if (!prev.IsInitialized()) {
+    QUIC_DVLOG(1) << ENDPOINT << "first window update for " << LogLabel();
+    return;
+  }
+
+  if (!auto_tune_receive_window_) {
+    return;
+  }
+
+  // Get outbound RTT.
+  QuicTime::Delta rtt =
+      connection_->sent_packet_manager().GetRttStats()->smoothed_rtt();
+  if (rtt.IsZero()) {
+    QUIC_DVLOG(1) << ENDPOINT << "rtt zero for " << LogLabel();
+    return;
+  }
+
+  // Now we can compare timing of window updates with RTT.
+  QuicTime::Delta since_last = now - prev;
+  QuicTime::Delta two_rtt = 2 * rtt;
+
+  if (since_last >= two_rtt) {
+    // If interval between window updates is sufficiently large, there
+    // is no need to increase receive_window_size_.
+    return;
+  }
+  QuicByteCount old_window = receive_window_size_;
+  IncreaseWindowSize();
+
+  if (receive_window_size_ > old_window) {
+    QUIC_DVLOG(1) << ENDPOINT << "New max window increase for " << LogLabel()
+                  << " after " << since_last.ToMicroseconds()
+                  << " us, and RTT is " << rtt.ToMicroseconds()
+                  << "us. max wndw: " << receive_window_size_;
+    if (session_flow_controller_ != nullptr) {
+      session_flow_controller_->EnsureWindowAtLeast(
+          kSessionFlowControlMultiplier * receive_window_size_);
+    }
+  } else {
+    // TODO(ckrasic) - add a varz to track this (?).
+    QUIC_LOG_FIRST_N(INFO, 1)
+        << ENDPOINT << "Max window at limit for " << LogLabel() << " after "
+        << since_last.ToMicroseconds() << " us, and RTT is "
+        << rtt.ToMicroseconds() << "us. Limit size: " << receive_window_size_;
+  }
+}
+
+void QuicFlowController::IncreaseWindowSize() {
+  receive_window_size_ *= 2;
+  receive_window_size_ =
+      std::min(receive_window_size_, receive_window_size_limit_);
+}
+
+QuicByteCount QuicFlowController::WindowUpdateThreshold() {
+  return receive_window_size_ / 2;
+}
+
+void QuicFlowController::MaybeSendWindowUpdate() {
+  if (!session_->connection()->connected()) {
+    return;
+  }
+  // Send WindowUpdate to increase receive window if
+  // (receive window offset - consumed bytes) < (max window / 2).
+  // This is behaviour copied from SPDY.
+  QUICHE_DCHECK_LE(bytes_consumed_, receive_window_offset_);
+  QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_;
+  QuicByteCount threshold = WindowUpdateThreshold();
+
+  if (!prev_window_update_time_.IsInitialized()) {
+    // Treat the initial window as if it is a window update, so if 1/2 the
+    // window is used in less than 2 RTTs, the window is increased.
+    prev_window_update_time_ = connection_->clock()->ApproximateNow();
+  }
+
+  if (available_window >= threshold) {
+    QUIC_DVLOG(1) << ENDPOINT << "Not sending WindowUpdate for " << LogLabel()
+                  << ", available window: " << available_window
+                  << " >= threshold: " << threshold;
+    return;
+  }
+
+  MaybeIncreaseMaxWindowSize();
+  UpdateReceiveWindowOffsetAndSendWindowUpdate(available_window);
+}
+
+void QuicFlowController::UpdateReceiveWindowOffsetAndSendWindowUpdate(
+    QuicStreamOffset available_window) {
+  // Update our receive window.
+  receive_window_offset_ += (receive_window_size_ - available_window);
+
+  QUIC_DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for " << LogLabel()
+                << ", consumed bytes: " << bytes_consumed_
+                << ", available window: " << available_window
+                << ", and threshold: " << WindowUpdateThreshold()
+                << ", and receive window size: " << receive_window_size_
+                << ". New receive window offset is: " << receive_window_offset_;
+
+  SendWindowUpdate();
+}
+
+bool QuicFlowController::ShouldSendBlocked() {
+  if (SendWindowSize() != 0 ||
+      last_blocked_send_window_offset_ >= send_window_offset_) {
+    return false;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << LogLabel() << " is flow control blocked. "
+                  << "Send window: " << SendWindowSize()
+                  << ", bytes sent: " << bytes_sent_
+                  << ", send limit: " << send_window_offset_;
+  // The entire send_window has been consumed, we are now flow control
+  // blocked.
+
+  // Keep track of when we last sent a BLOCKED frame so that we only send one
+  // at a given send offset.
+  last_blocked_send_window_offset_ = send_window_offset_;
+  return true;
+}
+
+bool QuicFlowController::UpdateSendWindowOffset(
+    QuicStreamOffset new_send_window_offset) {
+  // Only update if send window has increased.
+  if (new_send_window_offset <= send_window_offset_) {
+    return false;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for " << LogLabel()
+                << " with new offset " << new_send_window_offset
+                << " current offset: " << send_window_offset_
+                << " bytes_sent: " << bytes_sent_;
+
+  // The flow is now unblocked but could have also been unblocked
+  // before.  Return true iff this update caused a change from blocked
+  // to unblocked.
+  const bool was_previously_blocked = IsBlocked();
+  send_window_offset_ = new_send_window_offset;
+  return was_previously_blocked;
+}
+
+void QuicFlowController::EnsureWindowAtLeast(QuicByteCount window_size) {
+  if (receive_window_size_limit_ >= window_size) {
+    return;
+  }
+
+  QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_;
+  IncreaseWindowSize();
+  UpdateReceiveWindowOffsetAndSendWindowUpdate(available_window);
+}
+
+bool QuicFlowController::IsBlocked() const {
+  return SendWindowSize() == 0;
+}
+
+uint64_t QuicFlowController::SendWindowSize() const {
+  if (bytes_sent_ > send_window_offset_) {
+    return 0;
+  }
+  return send_window_offset_ - bytes_sent_;
+}
+
+void QuicFlowController::UpdateReceiveWindowSize(QuicStreamOffset size) {
+  QUICHE_DCHECK_LE(size, receive_window_size_limit_);
+  QUIC_DVLOG(1) << ENDPOINT << "UpdateReceiveWindowSize for " << LogLabel()
+                << ": " << size;
+  if (receive_window_size_ != receive_window_offset_) {
+    QUIC_BUG(quic_bug_10836_2)
+        << "receive_window_size_:" << receive_window_size_
+        << " != receive_window_offset:" << receive_window_offset_;
+    return;
+  }
+  receive_window_size_ = size;
+  receive_window_offset_ = size;
+}
+
+void QuicFlowController::SendWindowUpdate() {
+  QuicStreamId id = id_;
+  if (is_connection_flow_controller_) {
+    id = QuicUtils::GetInvalidStreamId(connection_->transport_version());
+  }
+  session_->SendWindowUpdate(id, receive_window_offset_);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_flow_controller.h b/quiche/quic/core/quic_flow_controller.h
new file mode 100644
index 0000000..69a4e94
--- /dev/null
+++ b/quiche/quic/core/quic_flow_controller.h
@@ -0,0 +1,217 @@
+// 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_CORE_QUIC_FLOW_CONTROLLER_H_
+#define QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicFlowControllerPeer;
+}  // namespace test
+
+class QuicConnection;
+class QuicSession;
+
+// How much larger the session flow control window needs to be relative to any
+// stream's flow control window.
+const float kSessionFlowControlMultiplier = 1.5;
+
+class QUIC_EXPORT_PRIVATE QuicFlowControllerInterface {
+ public:
+  virtual ~QuicFlowControllerInterface() {}
+
+  // Ensures the flow control window is at least |window_size| and send out an
+  // update frame if it is increased.
+  virtual void EnsureWindowAtLeast(QuicByteCount window_size) = 0;
+};
+
+// QuicFlowController allows a QUIC stream or connection to perform flow
+// control. The stream/connection owns a QuicFlowController which keeps track of
+// bytes sent/received, can tell the owner if it is flow control blocked, and
+// can send WINDOW_UPDATE or BLOCKED frames when needed.
+class QUIC_EXPORT_PRIVATE QuicFlowController
+    : public QuicFlowControllerInterface {
+ public:
+  QuicFlowController(QuicSession* session,
+                     QuicStreamId id,
+                     bool is_connection_flow_controller,
+                     QuicStreamOffset send_window_offset,
+                     QuicStreamOffset receive_window_offset,
+                     QuicByteCount receive_window_size_limit,
+                     bool should_auto_tune_receive_window,
+                     QuicFlowControllerInterface* session_flow_controller);
+
+  QuicFlowController(const QuicFlowController&) = delete;
+  QuicFlowController(QuicFlowController&&) = default;
+  QuicFlowController& operator=(const QuicFlowController&) = delete;
+
+  ~QuicFlowController() override {}
+
+  // Called when we see a new highest received byte offset from the peer, either
+  // via a data frame or a RST.
+  // Returns true if this call changes highest_received_byte_offset_, and false
+  // in the case where |new_offset| is <= highest_received_byte_offset_.
+  bool UpdateHighestReceivedOffset(QuicStreamOffset new_offset);
+
+  // Called when bytes received from the peer are consumed locally. This may
+  // trigger the sending of a WINDOW_UPDATE frame using |connection|.
+  void AddBytesConsumed(QuicByteCount bytes_consumed);
+
+  // Called when bytes are sent to the peer.
+  void AddBytesSent(QuicByteCount bytes_sent);
+
+  // Increases |send_window_offset_| if |new_send_window_offset| is
+  // greater than the current value.  Returns true if this increase
+  // also causes us to change from a blocked state to unblocked.  In
+  // all other cases, returns false.
+  bool UpdateSendWindowOffset(QuicStreamOffset new_send_window_offset);
+
+  // QuicFlowControllerInterface.
+  void EnsureWindowAtLeast(QuicByteCount window_size) override;
+
+  // Returns the current available send window.
+  QuicByteCount SendWindowSize() const;
+
+  QuicByteCount receive_window_size() const { return receive_window_size_; }
+
+  // Returns whether a BLOCKED frame should be sent.
+  bool ShouldSendBlocked();
+
+  // Returns true if flow control send limits have been reached.
+  bool IsBlocked() const;
+
+  // Returns true if flow control receive limits have been violated by the peer.
+  bool FlowControlViolation();
+
+  // Inform the peer of new receive window.
+  void SendWindowUpdate();
+
+  QuicByteCount bytes_consumed() const { return bytes_consumed_; }
+
+  QuicByteCount bytes_sent() const { return bytes_sent_; }
+
+  QuicStreamOffset send_window_offset() const { return send_window_offset_; }
+
+  QuicStreamOffset highest_received_byte_offset() const {
+    return highest_received_byte_offset_;
+  }
+
+  void set_receive_window_size_limit(QuicByteCount receive_window_size_limit) {
+    QUICHE_DCHECK_GE(receive_window_size_limit, receive_window_size_limit_);
+    receive_window_size_limit_ = receive_window_size_limit;
+  }
+
+  // Should only be called before any data is received.
+  void UpdateReceiveWindowSize(QuicStreamOffset size);
+
+  bool auto_tune_receive_window() { return auto_tune_receive_window_; }
+
+ private:
+  friend class test::QuicFlowControllerPeer;
+
+  // Send a WINDOW_UPDATE frame if appropriate.
+  void MaybeSendWindowUpdate();
+
+  // Auto-tune the max receive window size.
+  void MaybeIncreaseMaxWindowSize();
+
+  // Updates the current offset and sends a window update frame.
+  void UpdateReceiveWindowOffsetAndSendWindowUpdate(
+      QuicStreamOffset available_window);
+
+  // Double the window size as long as we haven't hit the max window size.
+  void IncreaseWindowSize();
+
+  // Returns "stream $ID" (where $ID is set to |id_|) or "connection" based on
+  // |is_connection_flow_controller_|.
+  std::string LogLabel();
+
+  // The parent session/connection, used to send connection close on flow
+  // control violation, and WINDOW_UPDATE and BLOCKED frames when appropriate.
+  // Not owned.
+  QuicSession* session_;
+  QuicConnection* connection_;
+
+  // ID of stream this flow controller belongs to. If
+  // |is_connection_flow_controller_| is false, this must be a valid stream ID.
+  QuicStreamId id_;
+
+  // Whether this flow controller is the connection level flow controller
+  // instead of the flow controller for a stream. If true, |id_| is ignored.
+  bool is_connection_flow_controller_;
+
+  // Tracks if this is owned by a server or a client.
+  Perspective perspective_;
+
+  // Tracks number of bytes sent to the peer.
+  QuicByteCount bytes_sent_;
+
+  // The absolute offset in the outgoing byte stream. If this offset is reached
+  // then we become flow control blocked until we receive a WINDOW_UPDATE.
+  QuicStreamOffset send_window_offset_;
+
+  // Overview of receive flow controller.
+  //
+  // 0=...===1=======2-------3 ...... FIN
+  //         |<--- <= 4  --->|
+  //
+
+  // 1) bytes_consumed_ - moves forward when data is read out of the
+  //    stream.
+  //
+  // 2) highest_received_byte_offset_ - moves when data is received
+  //    from the peer.
+  //
+  // 3) receive_window_offset_ - moves when WINDOW_UPDATE is sent.
+  //
+  // 4) receive_window_size_ - maximum allowed unread data (3 - 1).
+  //    This value may be increased by auto-tuning.
+  //
+  // 5) receive_window_size_limit_ - limit on receive_window_size_;
+  //    auto-tuning will not increase window size beyond this limit.
+
+  // Track number of bytes received from the peer, which have been consumed
+  // locally.
+  QuicByteCount bytes_consumed_;
+
+  // The highest byte offset we have seen from the peer. This could be the
+  // highest offset in a data frame, or a final value in a RST.
+  QuicStreamOffset highest_received_byte_offset_;
+
+  // The absolute offset in the incoming byte stream. The peer should never send
+  // us bytes which are beyond this offset.
+  QuicStreamOffset receive_window_offset_;
+
+  // Largest size the receive window can grow to.
+  QuicByteCount receive_window_size_;
+
+  // Upper limit on receive_window_size_;
+  QuicByteCount receive_window_size_limit_;
+
+  // Used to dynamically enable receive window auto-tuning.
+  bool auto_tune_receive_window_;
+
+  // The session's flow controller. Null if this is the session flow controller.
+  // Not owned.
+  QuicFlowControllerInterface* session_flow_controller_;
+
+  // Send window update when receive window size drops below this.
+  QuicByteCount WindowUpdateThreshold();
+
+  // Keep track of the last time we sent a BLOCKED frame. We should only send
+  // another when the number of bytes we have sent has changed.
+  QuicStreamOffset last_blocked_send_window_offset_;
+
+  // Keep time of the last time a window update was sent.  We use this
+  // as part of the receive window auto tuning.
+  QuicTime prev_window_update_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
diff --git a/quiche/quic/core/quic_flow_controller_test.cc b/quiche/quic/core/quic_flow_controller_test.cc
new file mode 100644
index 0000000..20cb599
--- /dev/null
+++ b/quiche/quic/core/quic_flow_controller_test.cc
@@ -0,0 +1,408 @@
+// 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 "quiche/quic/core/quic_flow_controller.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::Invoke;
+
+namespace quic {
+namespace test {
+
+// Receive window auto-tuning uses RTT in its logic.
+const int64_t kRtt = 100;
+
+class MockFlowController : public QuicFlowControllerInterface {
+ public:
+  MockFlowController() {}
+  MockFlowController(const MockFlowController&) = delete;
+  MockFlowController& operator=(const MockFlowController&) = delete;
+  ~MockFlowController() override {}
+
+  MOCK_METHOD(void, EnsureWindowAtLeast, (QuicByteCount), (override));
+};
+
+class QuicFlowControllerTest : public QuicTest {
+ public:
+  void Initialize() {
+    connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
+                                         Perspective::IS_CLIENT);
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    session_ = std::make_unique<MockQuicSession>(connection_);
+    flow_controller_ = std::make_unique<QuicFlowController>(
+        session_.get(), stream_id_, /*is_connection_flow_controller*/ false,
+        send_window_, receive_window_, kStreamReceiveWindowLimit,
+        should_auto_tune_receive_window_, &session_flow_controller_);
+  }
+
+ protected:
+  QuicStreamId stream_id_ = 1234;
+  QuicByteCount send_window_ = kInitialSessionFlowControlWindowForTest;
+  QuicByteCount receive_window_ = kInitialSessionFlowControlWindowForTest;
+  std::unique_ptr<QuicFlowController> flow_controller_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  std::unique_ptr<MockQuicSession> session_;
+  MockFlowController session_flow_controller_;
+  bool should_auto_tune_receive_window_ = false;
+};
+
+TEST_F(QuicFlowControllerTest, SendingBytes) {
+  Initialize();
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+
+  // Send some bytes, but not enough to block.
+  flow_controller_->AddBytesSent(send_window_ / 2);
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize());
+
+  // Send enough bytes to block.
+  flow_controller_->AddBytesSent(send_window_ / 2);
+  EXPECT_TRUE(flow_controller_->IsBlocked());
+  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
+
+  // BLOCKED frame should get sent.
+  EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
+
+  // Update the send window, and verify this has unblocked.
+  EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+
+  // Updating with a smaller offset doesn't change anything.
+  EXPECT_FALSE(flow_controller_->UpdateSendWindowOffset(send_window_ / 10));
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+
+  // Try to send more bytes, violating flow control.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, _, _));
+  EXPECT_QUIC_BUG(
+      flow_controller_->AddBytesSent(send_window_ * 10),
+      absl::StrCat("Trying to send an extra ", send_window_ * 10, " bytes"));
+  EXPECT_TRUE(flow_controller_->IsBlocked());
+  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytes) {
+  Initialize();
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(
+      flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ((receive_window_ / 2) - 1,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Consume enough bytes to send a WINDOW_UPDATE frame.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
+
+  flow_controller_->AddBytesConsumed(1 + receive_window_ / 2);
+
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+}
+
+TEST_F(QuicFlowControllerTest, Move) {
+  Initialize();
+
+  flow_controller_->AddBytesSent(send_window_ / 2);
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize());
+
+  EXPECT_TRUE(
+      flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ((receive_window_ / 2) - 1,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicFlowController flow_controller2(std::move(*flow_controller_));
+  EXPECT_EQ(send_window_ / 2, flow_controller2.SendWindowSize());
+  EXPECT_FALSE(flow_controller2.FlowControlViolation());
+  EXPECT_EQ((receive_window_ / 2) - 1,
+            QuicFlowControllerPeer::ReceiveWindowSize(&flow_controller2));
+}
+
+TEST_F(QuicFlowControllerTest, OnlySendBlockedFrameOncePerOffset) {
+  Initialize();
+
+  // Test that we don't send duplicate BLOCKED frames. We should only send one
+  // BLOCKED frame at a given send window offset.
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+
+  // Send enough bytes to block.
+  flow_controller_->AddBytesSent(send_window_);
+  EXPECT_TRUE(flow_controller_->IsBlocked());
+  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
+
+  // BLOCKED frame should get sent.
+  EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
+
+  // BLOCKED frame should not get sent again until our send offset changes.
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+
+  // Update the send window, then send enough bytes to block again.
+  EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+  flow_controller_->AddBytesSent(send_window_);
+  EXPECT_TRUE(flow_controller_->IsBlocked());
+  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
+
+  // BLOCKED frame should get sent as send offset has changed.
+  EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) {
+  should_auto_tune_receive_window_ = true;
+  Initialize();
+  // This test will generate two WINDOW_UPDATE frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
+  EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
+
+  // Make sure clock is inititialized.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicSentPacketManager* manager =
+      QuicConnectionPeer::GetSentPacketManager(connection_);
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicByteCount threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  QuicStreamOffset receive_offset = threshold + 1;
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+  EXPECT_CALL(
+      session_flow_controller_,
+      EnsureWindowAtLeast(kInitialSessionFlowControlWindowForTest * 2 * 1.5));
+
+  // Consume enough bytes to send a WINDOW_UPDATE frame.
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(2 * kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1));
+  receive_offset += threshold + 1;
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  QuicByteCount new_threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+  EXPECT_GT(new_threshold, threshold);
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytesFastNoAutoTune) {
+  Initialize();
+  // This test will generate two WINDOW_UPDATE frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
+
+  // Make sure clock is inititialized.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicSentPacketManager* manager =
+      QuicConnectionPeer::GetSentPacketManager(connection_);
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicByteCount threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  QuicStreamOffset receive_offset = threshold + 1;
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Consume enough bytes to send a WINDOW_UPDATE frame.
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Move time forward, but by less than two RTTs.  Then receive and consume
+  // some more, forcing a second WINDOW_UPDATE with an increased max window
+  // size.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1));
+  receive_offset += threshold + 1;
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  QuicByteCount new_threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+  EXPECT_EQ(new_threshold, threshold);
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytesNormalStableFlowWindow) {
+  should_auto_tune_receive_window_ = true;
+  Initialize();
+  // This test will generate two WINDOW_UPDATE frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
+  EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
+
+  // Make sure clock is inititialized.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicSentPacketManager* manager =
+      QuicConnectionPeer::GetSentPacketManager(connection_);
+  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicByteCount threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  QuicStreamOffset receive_offset = threshold + 1;
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+  EXPECT_CALL(
+      session_flow_controller_,
+      EnsureWindowAtLeast(kInitialSessionFlowControlWindowForTest * 2 * 1.5));
+  flow_controller_->AddBytesConsumed(threshold + 1);
+
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(2 * kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Move time forward, but by more than two RTTs.  Then receive and consume
+  // some more, forcing a second WINDOW_UPDATE with unchanged max window size.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1));
+
+  receive_offset += threshold + 1;
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+
+  QuicByteCount new_threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+  EXPECT_EQ(new_threshold, 2 * threshold);
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytesNormalNoAutoTune) {
+  Initialize();
+  // This test will generate two WINDOW_UPDATE frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
+
+  // Make sure clock is inititialized.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicSentPacketManager* manager =
+      QuicConnectionPeer::GetSentPacketManager(connection_);
+  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicByteCount threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  QuicStreamOffset receive_offset = threshold + 1;
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  flow_controller_->AddBytesConsumed(threshold + 1);
+
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Move time forward, but by more than two RTTs.  Then receive and consume
+  // some more, forcing a second WINDOW_UPDATE with unchanged max window size.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1));
+
+  receive_offset += threshold + 1;
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+
+  QuicByteCount new_threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  EXPECT_EQ(new_threshold, threshold);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_framer.cc b/quiche/quic/core/quic_framer.cc
new file mode 100644
index 0000000..193ceff
--- /dev/null
+++ b/quiche/quic/core/quic_framer.cc
@@ -0,0 +1,7244 @@
+// 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 "quiche/quic/core/quic_framer.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/base/macros.h"
+#include "absl/base/optimization.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_client_stats.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+namespace {
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+// Number of bits the packet number length bits are shifted from the right
+// edge of the header.
+const uint8_t kPublicHeaderSequenceNumberShift = 4;
+
+// There are two interpretations for the Frame Type byte in the QUIC protocol,
+// resulting in two Frame Types: Special Frame Types and Regular Frame Types.
+//
+// Regular Frame Types use the Frame Type byte simply. Currently defined
+// Regular Frame Types are:
+// Padding            : 0b 00000000 (0x00)
+// ResetStream        : 0b 00000001 (0x01)
+// ConnectionClose    : 0b 00000010 (0x02)
+// GoAway             : 0b 00000011 (0x03)
+// WindowUpdate       : 0b 00000100 (0x04)
+// Blocked            : 0b 00000101 (0x05)
+//
+// Special Frame Types encode both a Frame Type and corresponding flags
+// all in the Frame Type byte. Currently defined Special Frame Types
+// are:
+// Stream             : 0b 1xxxxxxx
+// Ack                : 0b 01xxxxxx
+//
+// Semantics of the flag bits above (the x bits) depends on the frame type.
+
+// Masks to determine if the frame type is a special use
+// and for specific special frame types.
+const uint8_t kQuicFrameTypeBrokenMask = 0xE0;   // 0b 11100000
+const uint8_t kQuicFrameTypeSpecialMask = 0xC0;  // 0b 11000000
+const uint8_t kQuicFrameTypeStreamMask = 0x80;
+const uint8_t kQuicFrameTypeAckMask = 0x40;
+static_assert(kQuicFrameTypeSpecialMask ==
+                  (kQuicFrameTypeStreamMask | kQuicFrameTypeAckMask),
+              "Invalid kQuicFrameTypeSpecialMask");
+
+// The stream type format is 1FDOOOSS, where
+//    F is the fin bit.
+//    D is the data length bit (0 or 2 bytes).
+//    OO/OOO are the size of the offset.
+//    SS is the size of the stream ID.
+// Note that the stream encoding can not be determined by inspection. It can
+// be determined only by knowing the QUIC Version.
+// Stream frame relative shifts and masks for interpreting the stream flags.
+// StreamID may be 1, 2, 3, or 4 bytes.
+const uint8_t kQuicStreamIdShift = 2;
+const uint8_t kQuicStreamIDLengthMask = 0x03;
+
+// Offset may be 0, 2, 4, or 8 bytes.
+const uint8_t kQuicStreamShift = 3;
+const uint8_t kQuicStreamOffsetMask = 0x07;
+
+// Data length may be 0 or 2 bytes.
+const uint8_t kQuicStreamDataLengthShift = 1;
+const uint8_t kQuicStreamDataLengthMask = 0x01;
+
+// Fin bit may be set or not.
+const uint8_t kQuicStreamFinShift = 1;
+const uint8_t kQuicStreamFinMask = 0x01;
+
+// The format is 01M0LLOO, where
+//   M if set, there are multiple ack blocks in the frame.
+//  LL is the size of the largest ack field.
+//  OO is the size of the ack blocks offset field.
+// packet number size shift used in AckFrames.
+const uint8_t kQuicSequenceNumberLengthNumBits = 2;
+const uint8_t kActBlockLengthOffset = 0;
+const uint8_t kLargestAckedOffset = 2;
+
+// Acks may have only one ack block.
+const uint8_t kQuicHasMultipleAckBlocksOffset = 5;
+
+// Timestamps are 4 bytes followed by 2 bytes.
+const uint8_t kQuicNumTimestampsLength = 1;
+const uint8_t kQuicFirstTimestampLength = 4;
+const uint8_t kQuicTimestampLength = 2;
+// Gaps between packet numbers are 1 byte.
+const uint8_t kQuicTimestampPacketNumberGapLength = 1;
+
+// Maximum length of encoded error strings.
+const int kMaxErrorStringLength = 256;
+
+const uint8_t kConnectionIdLengthAdjustment = 3;
+const uint8_t kDestinationConnectionIdLengthMask = 0xF0;
+const uint8_t kSourceConnectionIdLengthMask = 0x0F;
+
+// Returns the absolute value of the difference between |a| and |b|.
+uint64_t Delta(uint64_t a, uint64_t b) {
+  // Since these are unsigned numbers, we can't just return abs(a - b)
+  if (a < b) {
+    return b - a;
+  }
+  return a - b;
+}
+
+uint64_t ClosestTo(uint64_t target, uint64_t a, uint64_t b) {
+  return (Delta(target, a) < Delta(target, b)) ? a : b;
+}
+
+QuicPacketNumberLength ReadSequenceNumberLength(uint8_t flags) {
+  switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
+    case PACKET_FLAGS_8BYTE_PACKET:
+      return PACKET_6BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_4BYTE_PACKET:
+      return PACKET_4BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_2BYTE_PACKET:
+      return PACKET_2BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_1BYTE_PACKET:
+      return PACKET_1BYTE_PACKET_NUMBER;
+    default:
+      QUIC_BUG(quic_bug_10850_1) << "Unreachable case statement.";
+      return PACKET_6BYTE_PACKET_NUMBER;
+  }
+}
+
+QuicPacketNumberLength ReadAckPacketNumberLength(uint8_t flags) {
+  switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
+    case PACKET_FLAGS_8BYTE_PACKET:
+      return PACKET_6BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_4BYTE_PACKET:
+      return PACKET_4BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_2BYTE_PACKET:
+      return PACKET_2BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_1BYTE_PACKET:
+      return PACKET_1BYTE_PACKET_NUMBER;
+    default:
+      QUIC_BUG(quic_bug_10850_2) << "Unreachable case statement.";
+      return PACKET_6BYTE_PACKET_NUMBER;
+  }
+}
+
+uint8_t PacketNumberLengthToOnWireValue(
+    QuicPacketNumberLength packet_number_length) {
+  return packet_number_length - 1;
+}
+
+QuicPacketNumberLength GetShortHeaderPacketNumberLength(uint8_t type) {
+  QUICHE_DCHECK(!(type & FLAGS_LONG_HEADER));
+  return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
+}
+
+uint8_t LongHeaderTypeToOnWireValue(QuicLongHeaderType type,
+                                    const ParsedQuicVersion& version) {
+  switch (type) {
+    case INITIAL:
+      return version.UsesV2PacketTypes() ? (1 << 4) : 0;
+    case ZERO_RTT_PROTECTED:
+      return version.UsesV2PacketTypes() ? (2 << 4) : (1 << 4);
+    case HANDSHAKE:
+      return version.UsesV2PacketTypes() ? (3 << 4) : (2 << 4);
+    case RETRY:
+      return version.UsesV2PacketTypes() ? 0 : (3 << 4);
+    case VERSION_NEGOTIATION:
+      return 0xF0;  // Value does not matter
+    default:
+      QUIC_BUG(quic_bug_10850_3) << "Invalid long header type: " << type;
+      return 0xFF;
+  }
+}
+
+QuicLongHeaderType GetLongHeaderType(uint8_t type,
+                                     const ParsedQuicVersion& version) {
+  QUICHE_DCHECK((type & FLAGS_LONG_HEADER));
+  switch ((type & 0x30) >> 4) {
+    case 0:
+      return version.UsesV2PacketTypes() ? RETRY : INITIAL;
+    case 1:
+      return version.UsesV2PacketTypes() ? INITIAL : ZERO_RTT_PROTECTED;
+    case 2:
+      return version.UsesV2PacketTypes() ? ZERO_RTT_PROTECTED : HANDSHAKE;
+    case 3:
+      return version.UsesV2PacketTypes() ? HANDSHAKE : RETRY;
+    default:
+      QUIC_BUG(quic_bug_10850_4) << "Unreachable statement";
+      return INVALID_PACKET_TYPE;
+  }
+}
+
+QuicPacketNumberLength GetLongHeaderPacketNumberLength(uint8_t type) {
+  return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
+}
+
+// Used to get packet number space before packet gets decrypted.
+PacketNumberSpace GetPacketNumberSpace(const QuicPacketHeader& header) {
+  switch (header.form) {
+    case GOOGLE_QUIC_PACKET:
+      QUIC_BUG(quic_bug_10850_5)
+          << "Try to get packet number space of Google QUIC packet";
+      break;
+    case IETF_QUIC_SHORT_HEADER_PACKET:
+      return APPLICATION_DATA;
+    case IETF_QUIC_LONG_HEADER_PACKET:
+      switch (header.long_packet_type) {
+        case INITIAL:
+          return INITIAL_DATA;
+        case HANDSHAKE:
+          return HANDSHAKE_DATA;
+        case ZERO_RTT_PROTECTED:
+          return APPLICATION_DATA;
+        case VERSION_NEGOTIATION:
+        case RETRY:
+        case INVALID_PACKET_TYPE:
+          QUIC_BUG(quic_bug_10850_6)
+              << "Try to get packet number space of long header type: "
+              << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
+          break;
+      }
+  }
+
+  return NUM_PACKET_NUMBER_SPACES;
+}
+
+EncryptionLevel GetEncryptionLevel(const QuicPacketHeader& header) {
+  switch (header.form) {
+    case GOOGLE_QUIC_PACKET:
+      QUIC_BUG(quic_bug_10850_7)
+          << "Cannot determine EncryptionLevel from Google QUIC header";
+      break;
+    case IETF_QUIC_SHORT_HEADER_PACKET:
+      return ENCRYPTION_FORWARD_SECURE;
+    case IETF_QUIC_LONG_HEADER_PACKET:
+      switch (header.long_packet_type) {
+        case INITIAL:
+          return ENCRYPTION_INITIAL;
+        case HANDSHAKE:
+          return ENCRYPTION_HANDSHAKE;
+        case ZERO_RTT_PROTECTED:
+          return ENCRYPTION_ZERO_RTT;
+        case VERSION_NEGOTIATION:
+        case RETRY:
+        case INVALID_PACKET_TYPE:
+          QUIC_BUG(quic_bug_10850_8)
+              << "No encryption used with type "
+              << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
+      }
+  }
+  return NUM_ENCRYPTION_LEVELS;
+}
+
+absl::string_view TruncateErrorString(absl::string_view error) {
+  if (error.length() <= kMaxErrorStringLength) {
+    return error;
+  }
+  return absl::string_view(error.data(), kMaxErrorStringLength);
+}
+
+size_t TruncatedErrorStringSize(const absl::string_view& error) {
+  if (error.length() < kMaxErrorStringLength) {
+    return error.length();
+  }
+  return kMaxErrorStringLength;
+}
+
+uint8_t GetConnectionIdLengthValue(QuicConnectionIdLength length) {
+  if (length == 0) {
+    return 0;
+  }
+  return static_cast<uint8_t>(length - kConnectionIdLengthAdjustment);
+}
+
+bool IsValidPacketNumberLength(QuicPacketNumberLength packet_number_length) {
+  size_t length = packet_number_length;
+  return length == 1 || length == 2 || length == 4 || length == 6 ||
+         length == 8;
+}
+
+bool IsValidFullPacketNumber(uint64_t full_packet_number,
+                             ParsedQuicVersion version) {
+  return full_packet_number > 0 || version.HasIetfQuicFrames();
+}
+
+bool AppendIetfConnectionIds(bool version_flag, bool use_length_prefix,
+                             QuicConnectionId destination_connection_id,
+                             QuicConnectionId source_connection_id,
+                             QuicDataWriter* writer) {
+  if (!version_flag) {
+    return writer->WriteConnectionId(destination_connection_id);
+  }
+
+  if (use_length_prefix) {
+    return writer->WriteLengthPrefixedConnectionId(destination_connection_id) &&
+           writer->WriteLengthPrefixedConnectionId(source_connection_id);
+  }
+
+  // Compute connection ID length byte.
+  uint8_t dcil = GetConnectionIdLengthValue(
+      static_cast<QuicConnectionIdLength>(destination_connection_id.length()));
+  uint8_t scil = GetConnectionIdLengthValue(
+      static_cast<QuicConnectionIdLength>(source_connection_id.length()));
+  uint8_t connection_id_length = dcil << 4 | scil;
+
+  return writer->WriteUInt8(connection_id_length) &&
+         writer->WriteConnectionId(destination_connection_id) &&
+         writer->WriteConnectionId(source_connection_id);
+}
+
+enum class DroppedPacketReason {
+  // General errors
+  INVALID_PUBLIC_HEADER,
+  VERSION_MISMATCH,
+  // Version negotiation packet errors
+  INVALID_VERSION_NEGOTIATION_PACKET,
+  // Public reset packet errors, pre-v44
+  INVALID_PUBLIC_RESET_PACKET,
+  // Data packet errors
+  INVALID_PACKET_NUMBER,
+  INVALID_DIVERSIFICATION_NONCE,
+  DECRYPTION_FAILURE,
+  NUM_REASONS,
+};
+
+void RecordDroppedPacketReason(DroppedPacketReason reason) {
+  QUIC_CLIENT_HISTOGRAM_ENUM("QuicDroppedPacketReason", reason,
+                             DroppedPacketReason::NUM_REASONS,
+                             "The reason a packet was not processed. Recorded "
+                             "each time such a packet is dropped");
+}
+
+PacketHeaderFormat GetIetfPacketHeaderFormat(uint8_t type_byte) {
+  return type_byte & FLAGS_LONG_HEADER ? IETF_QUIC_LONG_HEADER_PACKET
+                                       : IETF_QUIC_SHORT_HEADER_PACKET;
+}
+
+std::string GenerateErrorString(std::string initial_error_string,
+                                QuicErrorCode quic_error_code) {
+  if (quic_error_code == QUIC_IETF_GQUIC_ERROR_MISSING) {
+    // QUIC_IETF_GQUIC_ERROR_MISSING is special -- it means not to encode
+    // the error value in the string.
+    return initial_error_string;
+  }
+  return absl::StrCat(std::to_string(static_cast<unsigned>(quic_error_code)),
+                      ":", initial_error_string);
+}
+
+}  // namespace
+
+QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
+                       QuicTime creation_time, Perspective perspective,
+                       uint8_t expected_server_connection_id_length)
+    : visitor_(nullptr),
+      error_(QUIC_NO_ERROR),
+      last_serialized_server_connection_id_(EmptyQuicConnectionId()),
+      last_serialized_client_connection_id_(EmptyQuicConnectionId()),
+      version_(ParsedQuicVersion::Unsupported()),
+      supported_versions_(supported_versions),
+      decrypter_level_(ENCRYPTION_INITIAL),
+      alternative_decrypter_level_(NUM_ENCRYPTION_LEVELS),
+      alternative_decrypter_latch_(false),
+      perspective_(perspective),
+      validate_flags_(true),
+      process_timestamps_(false),
+      max_receive_timestamps_per_ack_(std::numeric_limits<uint32_t>::max()),
+      receive_timestamps_exponent_(0),
+      creation_time_(creation_time),
+      last_timestamp_(QuicTime::Delta::Zero()),
+      support_key_update_for_connection_(false),
+      current_key_phase_bit_(false),
+      potential_peer_key_update_attempt_count_(0),
+      first_sending_packet_number_(FirstSendingPacketNumber()),
+      data_producer_(nullptr),
+      infer_packet_header_type_from_version_(perspective ==
+                                             Perspective::IS_CLIENT),
+      expected_server_connection_id_length_(
+          expected_server_connection_id_length),
+      expected_client_connection_id_length_(0),
+      supports_multiple_packet_number_spaces_(false),
+      last_written_packet_number_length_(0),
+      peer_ack_delay_exponent_(kDefaultAckDelayExponent),
+      local_ack_delay_exponent_(kDefaultAckDelayExponent),
+      current_received_frame_type_(0),
+      previously_received_frame_type_(0) {
+  QUICHE_DCHECK(!supported_versions.empty());
+  version_ = supported_versions_[0];
+  QUICHE_DCHECK(version_.IsKnown())
+      << ParsedQuicVersionVectorToString(supported_versions_);
+}
+
+QuicFramer::~QuicFramer() {}
+
+// static
+size_t QuicFramer::GetMinStreamFrameSize(QuicTransportVersion version,
+                                         QuicStreamId stream_id,
+                                         QuicStreamOffset offset,
+                                         bool last_frame_in_packet,
+                                         size_t data_length) {
+  if (VersionHasIetfQuicFrames(version)) {
+    return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(stream_id) +
+           (last_frame_in_packet
+                ? 0
+                : QuicDataWriter::GetVarInt62Len(data_length)) +
+           (offset != 0 ? QuicDataWriter::GetVarInt62Len(offset) : 0);
+  }
+  return kQuicFrameTypeSize + GetStreamIdSize(stream_id) +
+         GetStreamOffsetSize(offset) +
+         (last_frame_in_packet ? 0 : kQuicStreamPayloadLengthSize);
+}
+
+// static
+size_t QuicFramer::GetMinCryptoFrameSize(QuicStreamOffset offset,
+                                         QuicPacketLength data_length) {
+  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(offset) +
+         QuicDataWriter::GetVarInt62Len(data_length);
+}
+
+// static
+size_t QuicFramer::GetMessageFrameSize(QuicTransportVersion version,
+                                       bool last_frame_in_packet,
+                                       QuicByteCount length) {
+  QUIC_BUG_IF(quic_bug_12975_1, !VersionSupportsMessageFrames(version))
+      << "Try to serialize MESSAGE frame in " << version;
+  return kQuicFrameTypeSize +
+         (last_frame_in_packet ? 0 : QuicDataWriter::GetVarInt62Len(length)) +
+         length;
+}
+
+// static
+size_t QuicFramer::GetMinAckFrameSize(
+    QuicTransportVersion version, const QuicAckFrame& ack_frame,
+    uint32_t local_ack_delay_exponent,
+    bool use_ietf_ack_with_receive_timestamp) {
+  if (VersionHasIetfQuicFrames(version)) {
+    // The minimal ack frame consists of the following fields: Largest
+    // Acknowledged, ACK Delay, 0 ACK Block Count, First ACK Block and either 0
+    // Timestamp Range Count or ECN counts.
+    // Type byte + largest acked.
+    size_t min_size =
+        kQuicFrameTypeSize +
+        QuicDataWriter::GetVarInt62Len(LargestAcked(ack_frame).ToUint64());
+    // Ack delay.
+    min_size += QuicDataWriter::GetVarInt62Len(
+        ack_frame.ack_delay_time.ToMicroseconds() >> local_ack_delay_exponent);
+    // 0 ack block count.
+    min_size += QuicDataWriter::GetVarInt62Len(0);
+    // First ack block.
+    min_size += QuicDataWriter::GetVarInt62Len(
+        ack_frame.packets.Empty() ? 0
+                                  : ack_frame.packets.rbegin()->Length() - 1);
+
+    if (use_ietf_ack_with_receive_timestamp) {
+      // 0 Timestamp Range Count.
+      min_size += QuicDataWriter::GetVarInt62Len(0);
+    } else if (ack_frame.ecn_counters_populated &&
+               (ack_frame.ect_0_count || ack_frame.ect_1_count ||
+                ack_frame.ecn_ce_count)) {
+      // ECN counts.
+      min_size += (QuicDataWriter::GetVarInt62Len(ack_frame.ect_0_count) +
+                   QuicDataWriter::GetVarInt62Len(ack_frame.ect_1_count) +
+                   QuicDataWriter::GetVarInt62Len(ack_frame.ecn_ce_count));
+    }
+    return min_size;
+  }
+  return kQuicFrameTypeSize +
+         GetMinPacketNumberLength(LargestAcked(ack_frame)) +
+         kQuicDeltaTimeLargestObservedSize + kQuicNumTimestampsSize;
+}
+
+// static
+size_t QuicFramer::GetStopWaitingFrameSize(
+    QuicPacketNumberLength packet_number_length) {
+  size_t min_size = kQuicFrameTypeSize + packet_number_length;
+  return min_size;
+}
+
+// static
+size_t QuicFramer::GetRstStreamFrameSize(QuicTransportVersion version,
+                                         const QuicRstStreamFrame& frame) {
+  if (VersionHasIetfQuicFrames(version)) {
+    return QuicDataWriter::GetVarInt62Len(frame.stream_id) +
+           QuicDataWriter::GetVarInt62Len(frame.byte_offset) +
+           kQuicFrameTypeSize +
+           QuicDataWriter::GetVarInt62Len(frame.ietf_error_code);
+  }
+  return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize +
+         kQuicErrorCodeSize;
+}
+
+// static
+size_t QuicFramer::GetConnectionCloseFrameSize(
+    QuicTransportVersion version, const QuicConnectionCloseFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    // Not IETF QUIC, return Google QUIC CONNECTION CLOSE frame size.
+    return kQuicFrameTypeSize + kQuicErrorCodeSize +
+           kQuicErrorDetailsLengthSize +
+           TruncatedErrorStringSize(frame.error_details);
+  }
+
+  // Prepend the extra error information to the string and get the result's
+  // length.
+  const size_t truncated_error_string_size = TruncatedErrorStringSize(
+      GenerateErrorString(frame.error_details, frame.quic_error_code));
+
+  const size_t frame_size =
+      truncated_error_string_size +
+      QuicDataWriter::GetVarInt62Len(truncated_error_string_size) +
+      kQuicFrameTypeSize +
+      QuicDataWriter::GetVarInt62Len(frame.wire_error_code);
+  if (frame.close_type == IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
+    return frame_size;
+  }
+  // The Transport close frame has the transport_close_frame_type, so include
+  // its length.
+  return frame_size +
+         QuicDataWriter::GetVarInt62Len(frame.transport_close_frame_type);
+}
+
+// static
+size_t QuicFramer::GetMinGoAwayFrameSize() {
+  return kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicErrorDetailsLengthSize +
+         kQuicMaxStreamIdSize;
+}
+
+// static
+size_t QuicFramer::GetWindowUpdateFrameSize(
+    QuicTransportVersion version, const QuicWindowUpdateFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
+  }
+  if (frame.stream_id == QuicUtils::GetInvalidStreamId(version)) {
+    // Frame would be a MAX DATA frame, which has only a Maximum Data field.
+    return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.max_data);
+  }
+  // Frame would be MAX STREAM DATA, has Maximum Stream Data and Stream ID
+  // fields.
+  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.max_data) +
+         QuicDataWriter::GetVarInt62Len(frame.stream_id);
+}
+
+// static
+size_t QuicFramer::GetMaxStreamsFrameSize(QuicTransportVersion version,
+                                          const QuicMaxStreamsFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    QUIC_BUG(quic_bug_10850_9)
+        << "In version " << version
+        << ", which does not support IETF Frames, and tried to serialize "
+           "MaxStreams Frame.";
+  }
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.stream_count);
+}
+
+// static
+size_t QuicFramer::GetStreamsBlockedFrameSize(
+    QuicTransportVersion version, const QuicStreamsBlockedFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    QUIC_BUG(quic_bug_10850_10)
+        << "In version " << version
+        << ", which does not support IETF frames, and tried to serialize "
+           "StreamsBlocked Frame.";
+  }
+
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.stream_count);
+}
+
+// static
+size_t QuicFramer::GetBlockedFrameSize(QuicTransportVersion version,
+                                       const QuicBlockedFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    return kQuicFrameTypeSize + kQuicMaxStreamIdSize;
+  }
+  if (frame.stream_id == QuicUtils::GetInvalidStreamId(version)) {
+    // return size of IETF QUIC Blocked frame
+    return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.offset);
+  }
+  // return size of IETF QUIC Stream Blocked frame.
+  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.offset) +
+         QuicDataWriter::GetVarInt62Len(frame.stream_id);
+}
+
+// static
+size_t QuicFramer::GetStopSendingFrameSize(const QuicStopSendingFrame& frame) {
+  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.stream_id) +
+         QuicDataWriter::GetVarInt62Len(frame.ietf_error_code);
+}
+
+// static
+size_t QuicFramer::GetAckFrequencyFrameSize(
+    const QuicAckFrequencyFrame& frame) {
+  return QuicDataWriter::GetVarInt62Len(IETF_ACK_FREQUENCY) +
+         QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
+         QuicDataWriter::GetVarInt62Len(frame.packet_tolerance) +
+         QuicDataWriter::GetVarInt62Len(frame.max_ack_delay.ToMicroseconds()) +
+         // One byte for encoding boolean
+         1;
+}
+
+// static
+size_t QuicFramer::GetPathChallengeFrameSize(
+    const QuicPathChallengeFrame& frame) {
+  return kQuicFrameTypeSize + sizeof(frame.data_buffer);
+}
+
+// static
+size_t QuicFramer::GetPathResponseFrameSize(
+    const QuicPathResponseFrame& frame) {
+  return kQuicFrameTypeSize + sizeof(frame.data_buffer);
+}
+
+// static
+size_t QuicFramer::GetRetransmittableControlFrameSize(
+    QuicTransportVersion version, const QuicFrame& frame) {
+  switch (frame.type) {
+    case PING_FRAME:
+      // Ping has no payload.
+      return kQuicFrameTypeSize;
+    case RST_STREAM_FRAME:
+      return GetRstStreamFrameSize(version, *frame.rst_stream_frame);
+    case CONNECTION_CLOSE_FRAME:
+      return GetConnectionCloseFrameSize(version,
+                                         *frame.connection_close_frame);
+    case GOAWAY_FRAME:
+      return GetMinGoAwayFrameSize() +
+             TruncatedErrorStringSize(frame.goaway_frame->reason_phrase);
+    case WINDOW_UPDATE_FRAME:
+      // For IETF QUIC, this could be either a MAX DATA or MAX STREAM DATA.
+      // GetWindowUpdateFrameSize figures this out and returns the correct
+      // length.
+      return GetWindowUpdateFrameSize(version, frame.window_update_frame);
+    case BLOCKED_FRAME:
+      return GetBlockedFrameSize(version, frame.blocked_frame);
+    case NEW_CONNECTION_ID_FRAME:
+      return GetNewConnectionIdFrameSize(*frame.new_connection_id_frame);
+    case RETIRE_CONNECTION_ID_FRAME:
+      return GetRetireConnectionIdFrameSize(*frame.retire_connection_id_frame);
+    case NEW_TOKEN_FRAME:
+      return GetNewTokenFrameSize(*frame.new_token_frame);
+    case MAX_STREAMS_FRAME:
+      return GetMaxStreamsFrameSize(version, frame.max_streams_frame);
+    case STREAMS_BLOCKED_FRAME:
+      return GetStreamsBlockedFrameSize(version, frame.streams_blocked_frame);
+    case PATH_RESPONSE_FRAME:
+      return GetPathResponseFrameSize(*frame.path_response_frame);
+    case PATH_CHALLENGE_FRAME:
+      return GetPathChallengeFrameSize(*frame.path_challenge_frame);
+    case STOP_SENDING_FRAME:
+      return GetStopSendingFrameSize(frame.stop_sending_frame);
+    case HANDSHAKE_DONE_FRAME:
+      // HANDSHAKE_DONE has no payload.
+      return kQuicFrameTypeSize;
+    case ACK_FREQUENCY_FRAME:
+      return GetAckFrequencyFrameSize(*frame.ack_frequency_frame);
+    case STREAM_FRAME:
+    case ACK_FRAME:
+    case STOP_WAITING_FRAME:
+    case MTU_DISCOVERY_FRAME:
+    case PADDING_FRAME:
+    case MESSAGE_FRAME:
+    case CRYPTO_FRAME:
+    case NUM_FRAME_TYPES:
+      QUICHE_DCHECK(false);
+      return 0;
+  }
+
+  // Not reachable, but some Chrome compilers can't figure that out.  *sigh*
+  QUICHE_DCHECK(false);
+  return 0;
+}
+
+// static
+size_t QuicFramer::GetStreamIdSize(QuicStreamId stream_id) {
+  // Sizes are 1 through 4 bytes.
+  for (int i = 1; i <= 4; ++i) {
+    stream_id >>= 8;
+    if (stream_id == 0) {
+      return i;
+    }
+  }
+  QUIC_BUG(quic_bug_10850_11) << "Failed to determine StreamIDSize.";
+  return 4;
+}
+
+// static
+size_t QuicFramer::GetStreamOffsetSize(QuicStreamOffset offset) {
+  // 0 is a special case.
+  if (offset == 0) {
+    return 0;
+  }
+  // 2 through 8 are the remaining sizes.
+  offset >>= 8;
+  for (int i = 2; i <= 8; ++i) {
+    offset >>= 8;
+    if (offset == 0) {
+      return i;
+    }
+  }
+  QUIC_BUG(quic_bug_10850_12) << "Failed to determine StreamOffsetSize.";
+  return 8;
+}
+
+// static
+size_t QuicFramer::GetNewConnectionIdFrameSize(
+    const QuicNewConnectionIdFrame& frame) {
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
+         QuicDataWriter::GetVarInt62Len(frame.retire_prior_to) +
+         kConnectionIdLengthSize + frame.connection_id.length() +
+         sizeof(frame.stateless_reset_token);
+}
+
+// static
+size_t QuicFramer::GetRetireConnectionIdFrameSize(
+    const QuicRetireConnectionIdFrame& frame) {
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.sequence_number);
+}
+
+// static
+size_t QuicFramer::GetNewTokenFrameSize(const QuicNewTokenFrame& frame) {
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.token.length()) +
+         frame.token.length();
+}
+
+// TODO(nharper): Change this method to take a ParsedQuicVersion.
+bool QuicFramer::IsSupportedTransportVersion(
+    const QuicTransportVersion version) const {
+  for (const ParsedQuicVersion& supported_version : supported_versions_) {
+    if (version == supported_version.transport_version) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicFramer::IsSupportedVersion(const ParsedQuicVersion version) const {
+  for (const ParsedQuicVersion& supported_version : supported_versions_) {
+    if (version == supported_version) {
+      return true;
+    }
+  }
+  return false;
+}
+
+size_t QuicFramer::GetSerializedFrameLength(
+    const QuicFrame& frame, size_t free_bytes, bool first_frame,
+    bool last_frame, QuicPacketNumberLength packet_number_length) {
+  // Prevent a rare crash reported in b/19458523.
+  if (frame.type == ACK_FRAME && frame.ack_frame == nullptr) {
+    QUIC_BUG(quic_bug_10850_13)
+        << "Cannot compute the length of a null ack frame. free_bytes:"
+        << free_bytes << " first_frame:" << first_frame
+        << " last_frame:" << last_frame
+        << " seq num length:" << packet_number_length;
+    set_error(QUIC_INTERNAL_ERROR);
+    visitor_->OnError(this);
+    return 0;
+  }
+  if (frame.type == PADDING_FRAME) {
+    if (frame.padding_frame.num_padding_bytes == -1) {
+      // Full padding to the end of the packet.
+      return free_bytes;
+    } else {
+      // Lite padding.
+      return free_bytes <
+                     static_cast<size_t>(frame.padding_frame.num_padding_bytes)
+                 ? free_bytes
+                 : frame.padding_frame.num_padding_bytes;
+    }
+  }
+
+  size_t frame_len =
+      ComputeFrameLength(frame, last_frame, packet_number_length);
+  if (frame_len <= free_bytes) {
+    // Frame fits within packet. Note that acks may be truncated.
+    return frame_len;
+  }
+  // Only truncate the first frame in a packet, so if subsequent ones go
+  // over, stop including more frames.
+  if (!first_frame) {
+    return 0;
+  }
+  bool can_truncate =
+      frame.type == ACK_FRAME &&
+      free_bytes >=
+          GetMinAckFrameSize(version_.transport_version, *frame.ack_frame,
+                             local_ack_delay_exponent_,
+                             UseIetfAckWithReceiveTimestamp(*frame.ack_frame));
+  if (can_truncate) {
+    // Truncate the frame so the packet will not exceed kMaxOutgoingPacketSize.
+    // Note that we may not use every byte of the writer in this case.
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Truncating large frame, free bytes: " << free_bytes;
+    return free_bytes;
+  }
+  return 0;
+}
+
+QuicFramer::AckFrameInfo::AckFrameInfo()
+    : max_block_length(0), first_block_length(0), num_ack_blocks(0) {}
+
+QuicFramer::AckFrameInfo::AckFrameInfo(const AckFrameInfo& other) = default;
+
+QuicFramer::AckFrameInfo::~AckFrameInfo() {}
+
+bool QuicFramer::WriteIetfLongHeaderLength(const QuicPacketHeader& header,
+                                           QuicDataWriter* writer,
+                                           size_t length_field_offset,
+                                           EncryptionLevel level) {
+  if (!QuicVersionHasLongHeaderLengths(transport_version()) ||
+      !header.version_flag || length_field_offset == 0) {
+    return true;
+  }
+  if (writer->length() < length_field_offset ||
+      writer->length() - length_field_offset <
+          kQuicDefaultLongHeaderLengthLength) {
+    set_detailed_error("Invalid length_field_offset.");
+    QUIC_BUG(quic_bug_10850_14) << "Invalid length_field_offset.";
+    return false;
+  }
+  size_t length_to_write = writer->length() - length_field_offset -
+                           kQuicDefaultLongHeaderLengthLength;
+  // Add length of auth tag.
+  length_to_write = GetCiphertextSize(level, length_to_write);
+
+  QuicDataWriter length_writer(writer->length() - length_field_offset,
+                               writer->data() + length_field_offset);
+  if (!length_writer.WriteVarInt62(length_to_write,
+                                   kQuicDefaultLongHeaderLengthLength)) {
+    set_detailed_error("Failed to overwrite long header length.");
+    QUIC_BUG(quic_bug_10850_15) << "Failed to overwrite long header length.";
+    return false;
+  }
+  return true;
+}
+
+size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
+                                   const QuicFrames& frames, char* buffer,
+                                   size_t packet_length,
+                                   EncryptionLevel level) {
+  QUIC_BUG_IF(quic_bug_12975_2,
+              header.version_flag && version().HasIetfInvariantHeader() &&
+                  header.long_packet_type == RETRY && !frames.empty())
+      << "IETF RETRY packets cannot contain frames " << header;
+  QuicDataWriter writer(packet_length, buffer);
+  size_t length_field_offset = 0;
+  if (!AppendPacketHeader(header, &writer, &length_field_offset)) {
+    QUIC_BUG(quic_bug_10850_16) << "AppendPacketHeader failed";
+    return 0;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    if (AppendIetfFrames(frames, &writer) == 0) {
+      return 0;
+    }
+    if (!WriteIetfLongHeaderLength(header, &writer, length_field_offset,
+                                   level)) {
+      return 0;
+    }
+    return writer.length();
+  }
+
+  size_t i = 0;
+  for (const QuicFrame& frame : frames) {
+    // Determine if we should write stream frame length in header.
+    const bool last_frame_in_packet = i == frames.size() - 1;
+    if (!AppendTypeByte(frame, last_frame_in_packet, &writer)) {
+      QUIC_BUG(quic_bug_10850_17) << "AppendTypeByte failed";
+      return 0;
+    }
+
+    switch (frame.type) {
+      case PADDING_FRAME:
+        if (!AppendPaddingFrame(frame.padding_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_18)
+              << "AppendPaddingFrame of "
+              << frame.padding_frame.num_padding_bytes << " failed";
+          return 0;
+        }
+        break;
+      case STREAM_FRAME:
+        if (!AppendStreamFrame(frame.stream_frame, last_frame_in_packet,
+                               &writer)) {
+          QUIC_BUG(quic_bug_10850_19) << "AppendStreamFrame failed";
+          return 0;
+        }
+        break;
+      case ACK_FRAME:
+        if (!AppendAckFrameAndTypeByte(*frame.ack_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_20)
+              << "AppendAckFrameAndTypeByte failed: " << detailed_error_;
+          return 0;
+        }
+        break;
+      case STOP_WAITING_FRAME:
+        if (!AppendStopWaitingFrame(header, frame.stop_waiting_frame,
+                                    &writer)) {
+          QUIC_BUG(quic_bug_10850_21) << "AppendStopWaitingFrame failed";
+          return 0;
+        }
+        break;
+      case MTU_DISCOVERY_FRAME:
+        // MTU discovery frames are serialized as ping frames.
+        ABSL_FALLTHROUGH_INTENDED;
+      case PING_FRAME:
+        // Ping has no payload.
+        break;
+      case RST_STREAM_FRAME:
+        if (!AppendRstStreamFrame(*frame.rst_stream_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_22) << "AppendRstStreamFrame failed";
+          return 0;
+        }
+        break;
+      case CONNECTION_CLOSE_FRAME:
+        if (!AppendConnectionCloseFrame(*frame.connection_close_frame,
+                                        &writer)) {
+          QUIC_BUG(quic_bug_10850_23) << "AppendConnectionCloseFrame failed";
+          return 0;
+        }
+        break;
+      case GOAWAY_FRAME:
+        if (!AppendGoAwayFrame(*frame.goaway_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_24) << "AppendGoAwayFrame failed";
+          return 0;
+        }
+        break;
+      case WINDOW_UPDATE_FRAME:
+        if (!AppendWindowUpdateFrame(frame.window_update_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_25) << "AppendWindowUpdateFrame failed";
+          return 0;
+        }
+        break;
+      case BLOCKED_FRAME:
+        if (!AppendBlockedFrame(frame.blocked_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_26) << "AppendBlockedFrame failed";
+          return 0;
+        }
+        break;
+      case NEW_CONNECTION_ID_FRAME:
+        set_detailed_error(
+            "Attempt to append NEW_CONNECTION_ID frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case RETIRE_CONNECTION_ID_FRAME:
+        set_detailed_error(
+            "Attempt to append RETIRE_CONNECTION_ID frame and not in IETF "
+            "QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case NEW_TOKEN_FRAME:
+        set_detailed_error(
+            "Attempt to append NEW_TOKEN_ID frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case MAX_STREAMS_FRAME:
+        set_detailed_error(
+            "Attempt to append MAX_STREAMS frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case STREAMS_BLOCKED_FRAME:
+        set_detailed_error(
+            "Attempt to append STREAMS_BLOCKED frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case PATH_RESPONSE_FRAME:
+        set_detailed_error(
+            "Attempt to append PATH_RESPONSE frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case PATH_CHALLENGE_FRAME:
+        set_detailed_error(
+            "Attempt to append PATH_CHALLENGE frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case STOP_SENDING_FRAME:
+        set_detailed_error(
+            "Attempt to append STOP_SENDING frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case MESSAGE_FRAME:
+        if (!AppendMessageFrameAndTypeByte(*frame.message_frame,
+                                           last_frame_in_packet, &writer)) {
+          QUIC_BUG(quic_bug_10850_27) << "AppendMessageFrame failed";
+          return 0;
+        }
+        break;
+      case CRYPTO_FRAME:
+        if (!QuicVersionUsesCryptoFrames(version_.transport_version)) {
+          set_detailed_error(
+              "Attempt to append CRYPTO frame in version prior to 47.");
+          return RaiseError(QUIC_INTERNAL_ERROR);
+        }
+        if (!AppendCryptoFrame(*frame.crypto_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_28) << "AppendCryptoFrame failed";
+          return 0;
+        }
+        break;
+      case HANDSHAKE_DONE_FRAME:
+        // HANDSHAKE_DONE has no payload.
+        break;
+      default:
+        RaiseError(QUIC_INVALID_FRAME_DATA);
+        QUIC_BUG(quic_bug_10850_29) << "QUIC_INVALID_FRAME_DATA";
+        return 0;
+    }
+    ++i;
+  }
+
+  if (!WriteIetfLongHeaderLength(header, &writer, length_field_offset, level)) {
+    return 0;
+  }
+
+  return writer.length();
+}
+
+size_t QuicFramer::AppendIetfFrames(const QuicFrames& frames,
+                                    QuicDataWriter* writer) {
+  size_t i = 0;
+  for (const QuicFrame& frame : frames) {
+    // Determine if we should write stream frame length in header.
+    const bool last_frame_in_packet = i == frames.size() - 1;
+    if (!AppendIetfFrameType(frame, last_frame_in_packet, writer)) {
+      QUIC_BUG(quic_bug_10850_30)
+          << "AppendIetfFrameType failed: " << detailed_error();
+      return 0;
+    }
+
+    switch (frame.type) {
+      case PADDING_FRAME:
+        if (!AppendPaddingFrame(frame.padding_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_31) << "AppendPaddingFrame of "
+                                      << frame.padding_frame.num_padding_bytes
+                                      << " failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case STREAM_FRAME:
+        if (!AppendStreamFrame(frame.stream_frame, last_frame_in_packet,
+                               writer)) {
+          QUIC_BUG(quic_bug_10850_32)
+              << "AppendStreamFrame " << frame.stream_frame
+              << " failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case ACK_FRAME:
+        if (!AppendIetfAckFrameAndTypeByte(*frame.ack_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_33)
+              << "AppendIetfAckFrameAndTypeByte failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case STOP_WAITING_FRAME:
+        set_detailed_error(
+            "Attempt to append STOP WAITING frame in IETF QUIC.");
+        RaiseError(QUIC_INTERNAL_ERROR);
+        QUIC_BUG(quic_bug_10850_34) << detailed_error();
+        return 0;
+      case MTU_DISCOVERY_FRAME:
+        // MTU discovery frames are serialized as ping frames.
+        ABSL_FALLTHROUGH_INTENDED;
+      case PING_FRAME:
+        // Ping has no payload.
+        break;
+      case RST_STREAM_FRAME:
+        if (!AppendRstStreamFrame(*frame.rst_stream_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_35)
+              << "AppendRstStreamFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case CONNECTION_CLOSE_FRAME:
+        if (!AppendIetfConnectionCloseFrame(*frame.connection_close_frame,
+                                            writer)) {
+          QUIC_BUG(quic_bug_10850_36)
+              << "AppendIetfConnectionCloseFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case GOAWAY_FRAME:
+        set_detailed_error("Attempt to append GOAWAY frame in IETF QUIC.");
+        RaiseError(QUIC_INTERNAL_ERROR);
+        QUIC_BUG(quic_bug_10850_37) << detailed_error();
+        return 0;
+      case WINDOW_UPDATE_FRAME:
+        // Depending on whether there is a stream ID or not, will be either a
+        // MAX STREAM DATA frame or a MAX DATA frame.
+        if (frame.window_update_frame.stream_id ==
+            QuicUtils::GetInvalidStreamId(transport_version())) {
+          if (!AppendMaxDataFrame(frame.window_update_frame, writer)) {
+            QUIC_BUG(quic_bug_10850_38)
+                << "AppendMaxDataFrame failed: " << detailed_error();
+            return 0;
+          }
+        } else {
+          if (!AppendMaxStreamDataFrame(frame.window_update_frame, writer)) {
+            QUIC_BUG(quic_bug_10850_39)
+                << "AppendMaxStreamDataFrame failed: " << detailed_error();
+            return 0;
+          }
+        }
+        break;
+      case BLOCKED_FRAME:
+        if (!AppendBlockedFrame(frame.blocked_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_40)
+              << "AppendBlockedFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case MAX_STREAMS_FRAME:
+        if (!AppendMaxStreamsFrame(frame.max_streams_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_41)
+              << "AppendMaxStreamsFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case STREAMS_BLOCKED_FRAME:
+        if (!AppendStreamsBlockedFrame(frame.streams_blocked_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_42)
+              << "AppendStreamsBlockedFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case NEW_CONNECTION_ID_FRAME:
+        if (!AppendNewConnectionIdFrame(*frame.new_connection_id_frame,
+                                        writer)) {
+          QUIC_BUG(quic_bug_10850_43)
+              << "AppendNewConnectionIdFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case RETIRE_CONNECTION_ID_FRAME:
+        if (!AppendRetireConnectionIdFrame(*frame.retire_connection_id_frame,
+                                           writer)) {
+          QUIC_BUG(quic_bug_10850_44)
+              << "AppendRetireConnectionIdFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case NEW_TOKEN_FRAME:
+        if (!AppendNewTokenFrame(*frame.new_token_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_45)
+              << "AppendNewTokenFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case STOP_SENDING_FRAME:
+        if (!AppendStopSendingFrame(frame.stop_sending_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_46)
+              << "AppendStopSendingFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case PATH_CHALLENGE_FRAME:
+        if (!AppendPathChallengeFrame(*frame.path_challenge_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_47)
+              << "AppendPathChallengeFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case PATH_RESPONSE_FRAME:
+        if (!AppendPathResponseFrame(*frame.path_response_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_48)
+              << "AppendPathResponseFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case MESSAGE_FRAME:
+        if (!AppendMessageFrameAndTypeByte(*frame.message_frame,
+                                           last_frame_in_packet, writer)) {
+          QUIC_BUG(quic_bug_10850_49)
+              << "AppendMessageFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case CRYPTO_FRAME:
+        if (!AppendCryptoFrame(*frame.crypto_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_50)
+              << "AppendCryptoFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case HANDSHAKE_DONE_FRAME:
+        // HANDSHAKE_DONE has no payload.
+        break;
+      case ACK_FREQUENCY_FRAME:
+        if (!AppendAckFrequencyFrame(*frame.ack_frequency_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_51)
+              << "AppendAckFrequencyFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      default:
+        set_detailed_error("Tried to append unknown frame type.");
+        RaiseError(QUIC_INVALID_FRAME_DATA);
+        QUIC_BUG(quic_bug_10850_52)
+            << "QUIC_INVALID_FRAME_DATA: " << frame.type;
+        return 0;
+    }
+    ++i;
+  }
+
+  return writer->length();
+}
+
+// static
+std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildPublicResetPacket(
+    const QuicPublicResetPacket& packet) {
+  CryptoHandshakeMessage reset;
+  reset.set_tag(kPRST);
+  reset.SetValue(kRNON, packet.nonce_proof);
+  if (packet.client_address.host().address_family() !=
+      IpAddressFamily::IP_UNSPEC) {
+    // packet.client_address is non-empty.
+    QuicSocketAddressCoder address_coder(packet.client_address);
+    std::string serialized_address = address_coder.Encode();
+    if (serialized_address.empty()) {
+      return nullptr;
+    }
+    reset.SetStringPiece(kCADR, serialized_address);
+  }
+  if (!packet.endpoint_id.empty()) {
+    reset.SetStringPiece(kEPID, packet.endpoint_id);
+  }
+  const QuicData& reset_serialized = reset.GetSerialized();
+
+  size_t len = kPublicFlagsSize + packet.connection_id.length() +
+               reset_serialized.length();
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get());
+
+  uint8_t flags = static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_RST |
+                                       PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID);
+  // This hack makes post-v33 public reset packet look like pre-v33 packets.
+  flags |= static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD);
+  if (!writer.WriteUInt8(flags)) {
+    return nullptr;
+  }
+
+  if (!writer.WriteConnectionId(packet.connection_id)) {
+    return nullptr;
+  }
+
+  if (!writer.WriteBytes(reset_serialized.data(), reset_serialized.length())) {
+    return nullptr;
+  }
+
+  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
+}
+
+// static
+size_t QuicFramer::GetMinStatelessResetPacketLength() {
+  // 5 bytes (40 bits) = 2 Fixed Bits (01) + 38 Unpredictable bits
+  return 5 + kStatelessResetTokenLength;
+}
+
+// static
+std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildIetfStatelessResetPacket(
+    QuicConnectionId /*connection_id*/, size_t received_packet_length,
+    StatelessResetToken stateless_reset_token) {
+  QUIC_DVLOG(1) << "Building IETF stateless reset packet.";
+  if (received_packet_length <= GetMinStatelessResetPacketLength()) {
+    QUICHE_DLOG(ERROR)
+        << "Tried to build stateless reset packet with received packet "
+           "length "
+        << received_packet_length;
+    return nullptr;
+  }
+  // To ensure stateless reset is indistinguishable from a valid packet,
+  // include the max connection ID length.
+  size_t len = std::min(received_packet_length - 1,
+                        GetMinStatelessResetPacketLength() + 1 +
+                            kQuicMaxConnectionIdWithLengthPrefixLength);
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get());
+  // Append random bytes. This randomness only exists to prevent middleboxes
+  // from comparing the entire packet to a known value. Therefore it has no
+  // cryptographic use, and does not need a secure cryptographic pseudo-random
+  // number generator. It's therefore safe to use WriteInsecureRandomBytes.
+  if (!writer.WriteInsecureRandomBytes(QuicRandom::GetInstance(),
+                                       len - kStatelessResetTokenLength)) {
+    QUIC_BUG(362045737_2) << "Failed to append random bytes of length: "
+                          << len - kStatelessResetTokenLength;
+    return nullptr;
+  }
+  // Change first 2 fixed bits to 01.
+  buffer[0] &= ~FLAGS_LONG_HEADER;
+  buffer[0] |= FLAGS_FIXED_BIT;
+
+  // Append stateless reset token.
+  if (!writer.WriteBytes(&stateless_reset_token,
+                         sizeof(stateless_reset_token))) {
+    QUIC_BUG(362045737_3) << "Failed to write stateless reset token";
+    return nullptr;
+  }
+  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len,
+                                               /*owns_buffer=*/true);
+}
+
+// static
+std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
+    QuicConnectionId server_connection_id,
+    QuicConnectionId client_connection_id, bool ietf_quic,
+    bool use_length_prefix, const ParsedQuicVersionVector& versions) {
+  QUIC_CODE_COUNT(quic_build_version_negotiation);
+  if (use_length_prefix) {
+    QUICHE_DCHECK(ietf_quic);
+    QUIC_CODE_COUNT(quic_build_version_negotiation_ietf);
+  } else if (ietf_quic) {
+    QUIC_CODE_COUNT(quic_build_version_negotiation_old_ietf);
+  } else {
+    QUIC_CODE_COUNT(quic_build_version_negotiation_old_gquic);
+  }
+  ParsedQuicVersionVector wire_versions = versions;
+  // Add a version reserved for negotiation as suggested by the
+  // "Using Reserved Versions" section of draft-ietf-quic-transport.
+  if (wire_versions.empty()) {
+    // Ensure that version negotiation packets we send have at least two
+    // versions. This guarantees that, under all circumstances, all QUIC
+    // packets we send are at least 14 bytes long.
+    wire_versions = {QuicVersionReservedForNegotiation(),
+                     QuicVersionReservedForNegotiation()};
+  } else {
+    // This is not uniformely distributed but is acceptable since no security
+    // depends on this randomness.
+    size_t version_index = 0;
+    const bool disable_randomness =
+        GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness);
+    if (!disable_randomness) {
+      version_index =
+          QuicRandom::GetInstance()->RandUint64() % (wire_versions.size() + 1);
+    }
+    wire_versions.insert(wire_versions.begin() + version_index,
+                         QuicVersionReservedForNegotiation());
+  }
+  if (ietf_quic) {
+    return BuildIetfVersionNegotiationPacket(
+        use_length_prefix, server_connection_id, client_connection_id,
+        wire_versions);
+  }
+
+  // The GQUIC encoding does not support encoding client connection IDs.
+  QUICHE_DCHECK(client_connection_id.IsEmpty());
+  // The GQUIC encoding does not support length-prefixed connection IDs.
+  QUICHE_DCHECK(!use_length_prefix);
+
+  QUICHE_DCHECK(!wire_versions.empty());
+  size_t len = kPublicFlagsSize + server_connection_id.length() +
+               wire_versions.size() * kQuicVersionSize;
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get());
+
+  uint8_t flags = static_cast<uint8_t>(
+      PACKET_PUBLIC_FLAGS_VERSION | PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID |
+      PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD);
+  if (!writer.WriteUInt8(flags)) {
+    return nullptr;
+  }
+
+  if (!writer.WriteConnectionId(server_connection_id)) {
+    return nullptr;
+  }
+
+  for (const ParsedQuicVersion& version : wire_versions) {
+    if (!writer.WriteUInt32(CreateQuicVersionLabel(version))) {
+      return nullptr;
+    }
+  }
+
+  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
+}
+
+// static
+std::unique_ptr<QuicEncryptedPacket>
+QuicFramer::BuildIetfVersionNegotiationPacket(
+    bool use_length_prefix, QuicConnectionId server_connection_id,
+    QuicConnectionId client_connection_id,
+    const ParsedQuicVersionVector& versions) {
+  QUIC_DVLOG(1) << "Building IETF version negotiation packet with"
+                << (use_length_prefix ? "" : "out")
+                << " length prefix, server_connection_id "
+                << server_connection_id << " client_connection_id "
+                << client_connection_id << " versions "
+                << ParsedQuicVersionVectorToString(versions);
+  QUICHE_DCHECK(!versions.empty());
+  size_t len = kPacketHeaderTypeSize + kConnectionIdLengthSize +
+               client_connection_id.length() + server_connection_id.length() +
+               (versions.size() + 1) * kQuicVersionSize;
+  if (use_length_prefix) {
+    // When using length-prefixed connection IDs, packets carry two lengths
+    // instead of one.
+    len += kConnectionIdLengthSize;
+  }
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get());
+
+  // TODO(fayang): Randomly select a value for the type.
+  uint8_t type = static_cast<uint8_t>(FLAGS_LONG_HEADER | FLAGS_FIXED_BIT);
+  if (!writer.WriteUInt8(type)) {
+    return nullptr;
+  }
+
+  if (!writer.WriteUInt32(0)) {
+    return nullptr;
+  }
+
+  if (!AppendIetfConnectionIds(true, use_length_prefix, client_connection_id,
+                               server_connection_id, &writer)) {
+    return nullptr;
+  }
+
+  for (const ParsedQuicVersion& version : versions) {
+    if (!writer.WriteUInt32(CreateQuicVersionLabel(version))) {
+      return nullptr;
+    }
+  }
+
+  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
+}
+
+bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
+  QUICHE_DCHECK(!is_processing_packet_) << ENDPOINT << "Nested ProcessPacket";
+  is_processing_packet_ = true;
+  bool result = ProcessPacketInternal(packet);
+  is_processing_packet_ = false;
+  return result;
+}
+
+bool QuicFramer::ProcessPacketInternal(const QuicEncryptedPacket& packet) {
+  QuicDataReader reader(packet.data(), packet.length());
+
+  bool packet_has_ietf_packet_header = false;
+  if (infer_packet_header_type_from_version_) {
+    packet_has_ietf_packet_header = version_.HasIetfInvariantHeader();
+  } else if (!reader.IsDoneReading()) {
+    uint8_t type = reader.PeekByte();
+    packet_has_ietf_packet_header = QuicUtils::IsIetfPacketHeader(type);
+  }
+  if (packet_has_ietf_packet_header) {
+    QUIC_DVLOG(1) << ENDPOINT << "Processing IETF QUIC packet.";
+  }
+
+  visitor_->OnPacket();
+
+  QuicPacketHeader header;
+  if (!ProcessPublicHeader(&reader, packet_has_ietf_packet_header, &header)) {
+    QUICHE_DCHECK_NE("", detailed_error_);
+    QUIC_DVLOG(1) << ENDPOINT << "Unable to process public header. Error: "
+                  << detailed_error_;
+    QUICHE_DCHECK_NE("", detailed_error_);
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_HEADER);
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+
+  if (!visitor_->OnUnauthenticatedPublicHeader(header)) {
+    // The visitor suppresses further processing of the packet.
+    return true;
+  }
+
+  if (IsVersionNegotiation(header, packet_has_ietf_packet_header)) {
+    if (perspective_ == Perspective::IS_CLIENT) {
+      QUIC_DVLOG(1) << "Client received version negotiation packet";
+      return ProcessVersionNegotiationPacket(&reader, header);
+    } else {
+      QUIC_DLOG(ERROR) << "Server received version negotiation packet";
+      set_detailed_error("Server received version negotiation packet.");
+      return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+    }
+  }
+
+  if (header.version_flag && header.version != version_) {
+    if (perspective_ == Perspective::IS_SERVER) {
+      if (!visitor_->OnProtocolVersionMismatch(header.version)) {
+        RecordDroppedPacketReason(DroppedPacketReason::VERSION_MISMATCH);
+        return true;
+      }
+    } else {
+      // A client received a packet of a different version but that packet is
+      // not a version negotiation packet. It is therefore invalid and dropped.
+      QUIC_DLOG(ERROR) << "Client received unexpected version "
+                       << ParsedQuicVersionToString(header.version)
+                       << " instead of " << ParsedQuicVersionToString(version_);
+      set_detailed_error("Client received unexpected version.");
+      return RaiseError(QUIC_PACKET_WRONG_VERSION);
+    }
+  }
+
+  bool rv;
+  if (header.long_packet_type == RETRY) {
+    rv = ProcessRetryPacket(&reader, header);
+  } else if (header.reset_flag) {
+    rv = ProcessPublicResetPacket(&reader, header);
+  } else if (packet.length() <= kMaxIncomingPacketSize) {
+    // The optimized decryption algorithm implementations run faster when
+    // operating on aligned memory.
+    ABSL_CACHELINE_ALIGNED char buffer[kMaxIncomingPacketSize];
+    if (packet_has_ietf_packet_header) {
+      rv = ProcessIetfDataPacket(&reader, &header, packet, buffer,
+                                 ABSL_ARRAYSIZE(buffer));
+    } else {
+      rv = ProcessDataPacket(&reader, &header, packet, buffer,
+                             ABSL_ARRAYSIZE(buffer));
+    }
+  } else {
+    std::unique_ptr<char[]> large_buffer(new char[packet.length()]);
+    if (packet_has_ietf_packet_header) {
+      rv = ProcessIetfDataPacket(&reader, &header, packet, large_buffer.get(),
+                                 packet.length());
+    } else {
+      rv = ProcessDataPacket(&reader, &header, packet, large_buffer.get(),
+                             packet.length());
+    }
+    QUIC_BUG_IF(quic_bug_10850_53, rv)
+        << "QUIC should never successfully process packets larger"
+        << "than kMaxIncomingPacketSize. packet size:" << packet.length();
+  }
+  return rv;
+}
+
+bool QuicFramer::ProcessVersionNegotiationPacket(
+    QuicDataReader* reader, const QuicPacketHeader& header) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+
+  QuicVersionNegotiationPacket packet(
+      GetServerConnectionIdAsRecipient(header, perspective_));
+  // Try reading at least once to raise error if the packet is invalid.
+  do {
+    QuicVersionLabel version_label;
+    if (!ProcessVersionLabel(reader, &version_label)) {
+      set_detailed_error("Unable to read supported version in negotiation.");
+      RecordDroppedPacketReason(
+          DroppedPacketReason::INVALID_VERSION_NEGOTIATION_PACKET);
+      return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+    }
+    ParsedQuicVersion parsed_version = ParseQuicVersionLabel(version_label);
+    if (parsed_version != UnsupportedQuicVersion()) {
+      packet.versions.push_back(parsed_version);
+    }
+  } while (!reader->IsDoneReading());
+
+  QUIC_DLOG(INFO) << ENDPOINT << "parsed version negotiation: "
+                  << ParsedQuicVersionVectorToString(packet.versions);
+
+  visitor_->OnVersionNegotiationPacket(packet);
+  return true;
+}
+
+bool QuicFramer::ProcessRetryPacket(QuicDataReader* reader,
+                                    const QuicPacketHeader& header) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+  if (drop_incoming_retry_packets_) {
+    QUIC_DLOG(INFO) << "Ignoring received RETRY packet";
+    return true;
+  }
+
+  if (version_.UsesTls()) {
+    QUICHE_DCHECK(version_.HasLengthPrefixedConnectionIds()) << version_;
+    const size_t bytes_remaining = reader->BytesRemaining();
+    if (bytes_remaining <= kRetryIntegrityTagLength) {
+      set_detailed_error("Retry packet too short to parse integrity tag.");
+      return false;
+    }
+    const size_t retry_token_length =
+        bytes_remaining - kRetryIntegrityTagLength;
+    QUICHE_DCHECK_GT(retry_token_length, 0u);
+    absl::string_view retry_token;
+    if (!reader->ReadStringPiece(&retry_token, retry_token_length)) {
+      set_detailed_error("Failed to read retry token.");
+      return false;
+    }
+    absl::string_view retry_without_tag = reader->PreviouslyReadPayload();
+    absl::string_view integrity_tag = reader->ReadRemainingPayload();
+    QUICHE_DCHECK_EQ(integrity_tag.length(), kRetryIntegrityTagLength);
+    visitor_->OnRetryPacket(EmptyQuicConnectionId(),
+                            header.source_connection_id, retry_token,
+                            integrity_tag, retry_without_tag);
+    return true;
+  }
+
+  QuicConnectionId original_destination_connection_id;
+  if (version_.HasLengthPrefixedConnectionIds()) {
+    // Parse Original Destination Connection ID.
+    if (!reader->ReadLengthPrefixedConnectionId(
+            &original_destination_connection_id)) {
+      set_detailed_error("Unable to read Original Destination ConnectionId.");
+      return false;
+    }
+  } else {
+    // Parse Original Destination Connection ID Length.
+    uint8_t odcil = header.type_byte & 0xf;
+    if (odcil != 0) {
+      odcil += kConnectionIdLengthAdjustment;
+    }
+
+    // Parse Original Destination Connection ID.
+    if (!reader->ReadConnectionId(&original_destination_connection_id, odcil)) {
+      set_detailed_error("Unable to read Original Destination ConnectionId.");
+      return false;
+    }
+  }
+
+  if (!QuicUtils::IsConnectionIdValidForVersion(
+          original_destination_connection_id, transport_version())) {
+    set_detailed_error(
+        "Received Original Destination ConnectionId with invalid length.");
+    return false;
+  }
+
+  absl::string_view retry_token = reader->ReadRemainingPayload();
+  visitor_->OnRetryPacket(original_destination_connection_id,
+                          header.source_connection_id, retry_token,
+                          /*retry_integrity_tag=*/absl::string_view(),
+                          /*retry_without_tag=*/absl::string_view());
+  return true;
+}
+
+// Seeks the current packet to check for a coalesced packet at the end.
+// If the IETF length field only spans part of the outer packet,
+// then there is a coalesced packet after this one.
+void QuicFramer::MaybeProcessCoalescedPacket(
+    const QuicDataReader& encrypted_reader, uint64_t remaining_bytes_length,
+    const QuicPacketHeader& header) {
+  if (header.remaining_packet_length >= remaining_bytes_length) {
+    // There is no coalesced packet.
+    return;
+  }
+
+  absl::string_view remaining_data = encrypted_reader.PeekRemainingPayload();
+  QUICHE_DCHECK_EQ(remaining_data.length(), remaining_bytes_length);
+
+  const char* coalesced_data =
+      remaining_data.data() + header.remaining_packet_length;
+  uint64_t coalesced_data_length =
+      remaining_bytes_length - header.remaining_packet_length;
+  QuicDataReader coalesced_reader(coalesced_data, coalesced_data_length);
+
+  QuicPacketHeader coalesced_header;
+  if (!ProcessIetfPacketHeader(&coalesced_reader, &coalesced_header)) {
+    // Some implementations pad their INITIAL packets by sending random invalid
+    // data after the INITIAL, and that is allowed by the specification. If we
+    // fail to parse a subsequent coalesced packet, simply ignore it.
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Failed to parse received coalesced header of length "
+                    << coalesced_data_length
+                    << " with error: " << detailed_error_ << ": "
+                    << absl::BytesToHexString(absl::string_view(
+                           coalesced_data, coalesced_data_length))
+                    << " previous header was " << header;
+    return;
+  }
+
+  if (coalesced_header.destination_connection_id !=
+      header.destination_connection_id) {
+    // Drop coalesced packets with mismatched connection IDs.
+    QUIC_DLOG(INFO) << ENDPOINT << "Received mismatched coalesced header "
+                    << coalesced_header << " previous header was " << header;
+    QUIC_CODE_COUNT(
+        quic_received_coalesced_packets_with_mismatched_connection_id);
+    return;
+  }
+
+  QuicEncryptedPacket coalesced_packet(coalesced_data, coalesced_data_length,
+                                       /*owns_buffer=*/false);
+  visitor_->OnCoalescedPacket(coalesced_packet);
+}
+
+bool QuicFramer::MaybeProcessIetfLength(QuicDataReader* encrypted_reader,
+                                        QuicPacketHeader* header) {
+  if (!QuicVersionHasLongHeaderLengths(header->version.transport_version) ||
+      header->form != IETF_QUIC_LONG_HEADER_PACKET ||
+      (header->long_packet_type != INITIAL &&
+       header->long_packet_type != HANDSHAKE &&
+       header->long_packet_type != ZERO_RTT_PROTECTED)) {
+    return true;
+  }
+  header->length_length = encrypted_reader->PeekVarInt62Length();
+  if (!encrypted_reader->ReadVarInt62(&header->remaining_packet_length)) {
+    set_detailed_error("Unable to read long header payload length.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+  uint64_t remaining_bytes_length = encrypted_reader->BytesRemaining();
+  if (header->remaining_packet_length > remaining_bytes_length) {
+    set_detailed_error("Long header payload length longer than packet.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+
+  MaybeProcessCoalescedPacket(*encrypted_reader, remaining_bytes_length,
+                              *header);
+
+  if (!encrypted_reader->TruncateRemaining(header->remaining_packet_length)) {
+    set_detailed_error("Length TruncateRemaining failed.");
+    QUIC_BUG(quic_bug_10850_54) << "Length TruncateRemaining failed.";
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfDataPacket(QuicDataReader* encrypted_reader,
+                                       QuicPacketHeader* header,
+                                       const QuicEncryptedPacket& packet,
+                                       char* decrypted_buffer,
+                                       size_t buffer_length) {
+  QUICHE_DCHECK_NE(GOOGLE_QUIC_PACKET, header->form);
+  QUICHE_DCHECK(!header->has_possible_stateless_reset_token);
+  header->length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  header->remaining_packet_length = 0;
+  if (header->form == IETF_QUIC_SHORT_HEADER_PACKET &&
+      perspective_ == Perspective::IS_CLIENT) {
+    // Peek possible stateless reset token. Will only be used on decryption
+    // failure.
+    absl::string_view remaining = encrypted_reader->PeekRemainingPayload();
+    if (remaining.length() >= sizeof(header->possible_stateless_reset_token)) {
+      header->has_possible_stateless_reset_token = true;
+      memcpy(&header->possible_stateless_reset_token,
+             &remaining.data()[remaining.length() -
+                               sizeof(header->possible_stateless_reset_token)],
+             sizeof(header->possible_stateless_reset_token));
+    }
+  }
+
+  if (!MaybeProcessIetfLength(encrypted_reader, header)) {
+    return false;
+  }
+
+  absl::string_view associated_data;
+  std::vector<char> ad_storage;
+  QuicPacketNumber base_packet_number;
+  if (header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
+      header->long_packet_type != VERSION_NEGOTIATION) {
+    QUICHE_DCHECK(header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
+                  header->long_packet_type == INITIAL ||
+                  header->long_packet_type == HANDSHAKE ||
+                  header->long_packet_type == ZERO_RTT_PROTECTED);
+    // Process packet number.
+    if (supports_multiple_packet_number_spaces_) {
+      PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
+      if (pn_space == NUM_PACKET_NUMBER_SPACES) {
+        return RaiseError(QUIC_INVALID_PACKET_HEADER);
+      }
+      base_packet_number = largest_decrypted_packet_numbers_[pn_space];
+    } else {
+      base_packet_number = largest_packet_number_;
+    }
+    uint64_t full_packet_number;
+    bool hp_removal_failed = false;
+    if (version_.HasHeaderProtection()) {
+      if (!RemoveHeaderProtection(encrypted_reader, packet, header,
+                                  &full_packet_number, &ad_storage)) {
+        hp_removal_failed = true;
+      }
+      associated_data = absl::string_view(ad_storage.data(), ad_storage.size());
+    } else if (!ProcessAndCalculatePacketNumber(
+                   encrypted_reader, header->packet_number_length,
+                   base_packet_number, &full_packet_number)) {
+      set_detailed_error("Unable to read packet number.");
+      RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
+      return RaiseError(QUIC_INVALID_PACKET_HEADER);
+    }
+
+    if (hp_removal_failed ||
+        !IsValidFullPacketNumber(full_packet_number, version())) {
+      if (IsIetfStatelessResetPacket(*header)) {
+        // This is a stateless reset packet.
+        QuicIetfStatelessResetPacket packet(
+            *header, header->possible_stateless_reset_token);
+        visitor_->OnAuthenticatedIetfStatelessResetPacket(packet);
+        return true;
+      }
+      if (hp_removal_failed) {
+        const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
+        const bool has_decryption_key = decrypter_[decryption_level] != nullptr;
+        visitor_->OnUndecryptablePacket(
+            QuicEncryptedPacket(encrypted_reader->FullPayload()),
+            decryption_level, has_decryption_key);
+        RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
+        set_detailed_error(absl::StrCat(
+            "Unable to decrypt ", EncryptionLevelToString(decryption_level),
+            " header protection", has_decryption_key ? "" : " (missing key)",
+            "."));
+        return RaiseError(QUIC_DECRYPTION_FAILURE);
+      }
+      RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
+      set_detailed_error("packet numbers cannot be 0.");
+      return RaiseError(QUIC_INVALID_PACKET_HEADER);
+    }
+    header->packet_number = QuicPacketNumber(full_packet_number);
+  }
+
+  // A nonce should only present in SHLO from the server to the client when
+  // using QUIC crypto.
+  if (header->form == IETF_QUIC_LONG_HEADER_PACKET &&
+      header->long_packet_type == ZERO_RTT_PROTECTED &&
+      perspective_ == Perspective::IS_CLIENT &&
+      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+    if (!encrypted_reader->ReadBytes(
+            reinterpret_cast<uint8_t*>(last_nonce_.data()),
+            last_nonce_.size())) {
+      set_detailed_error("Unable to read nonce.");
+      RecordDroppedPacketReason(
+          DroppedPacketReason::INVALID_DIVERSIFICATION_NONCE);
+      return RaiseError(QUIC_INVALID_PACKET_HEADER);
+    }
+
+    header->nonce = &last_nonce_;
+  } else {
+    header->nonce = nullptr;
+  }
+
+  if (!visitor_->OnUnauthenticatedHeader(*header)) {
+    set_detailed_error(
+        "Visitor asked to stop processing of unauthenticated header.");
+    return false;
+  }
+
+  absl::string_view encrypted = encrypted_reader->ReadRemainingPayload();
+  if (!version_.HasHeaderProtection()) {
+    associated_data = GetAssociatedDataFromEncryptedPacket(
+        version_.transport_version, packet,
+        GetIncludedDestinationConnectionIdLength(*header),
+        GetIncludedSourceConnectionIdLength(*header), header->version_flag,
+        header->nonce != nullptr, header->packet_number_length,
+        header->retry_token_length_length, header->retry_token.length(),
+        header->length_length);
+  }
+
+  size_t decrypted_length = 0;
+  EncryptionLevel decrypted_level;
+  if (!DecryptPayload(packet.length(), encrypted, associated_data, *header,
+                      decrypted_buffer, buffer_length, &decrypted_length,
+                      &decrypted_level)) {
+    if (IsIetfStatelessResetPacket(*header)) {
+      // This is a stateless reset packet.
+      QuicIetfStatelessResetPacket packet(
+          *header, header->possible_stateless_reset_token);
+      visitor_->OnAuthenticatedIetfStatelessResetPacket(packet);
+      return true;
+    }
+    const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
+    const bool has_decryption_key = version_.KnowsWhichDecrypterToUse() &&
+                                    decrypter_[decryption_level] != nullptr;
+    visitor_->OnUndecryptablePacket(
+        QuicEncryptedPacket(encrypted_reader->FullPayload()), decryption_level,
+        has_decryption_key);
+    set_detailed_error(absl::StrCat(
+        "Unable to decrypt ", EncryptionLevelToString(decryption_level),
+        " payload with reconstructed packet number ",
+        header->packet_number.ToString(), " (largest decrypted was ",
+        base_packet_number.ToString(), ")",
+        has_decryption_key || !version_.KnowsWhichDecrypterToUse()
+            ? ""
+            : " (missing key)",
+        "."));
+    RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
+    return RaiseError(QUIC_DECRYPTION_FAILURE);
+  }
+  QuicDataReader reader(decrypted_buffer, decrypted_length);
+
+  // Update the largest packet number after we have decrypted the packet
+  // so we are confident is not attacker controlled.
+  if (supports_multiple_packet_number_spaces_) {
+    largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
+                                          decrypted_level)]
+        .UpdateMax(header->packet_number);
+  } else {
+    largest_packet_number_.UpdateMax(header->packet_number);
+  }
+
+  if (!visitor_->OnPacketHeader(*header)) {
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
+    // The visitor suppresses further processing of the packet.
+    return true;
+  }
+
+  if (packet.length() > kMaxIncomingPacketSize) {
+    set_detailed_error("Packet too large.");
+    return RaiseError(QUIC_PACKET_TOO_LARGE);
+  }
+
+  // Handle the payload.
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    current_received_frame_type_ = 0;
+    previously_received_frame_type_ = 0;
+    if (!ProcessIetfFrameData(&reader, *header, decrypted_level)) {
+      current_received_frame_type_ = 0;
+      previously_received_frame_type_ = 0;
+      QUICHE_DCHECK_NE(QUIC_NO_ERROR,
+                       error_);  // ProcessIetfFrameData sets the error.
+      QUICHE_DCHECK_NE("", detailed_error_);
+      QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
+                         << detailed_error_;
+      return false;
+    }
+    current_received_frame_type_ = 0;
+    previously_received_frame_type_ = 0;
+  } else {
+    if (!ProcessFrameData(&reader, *header)) {
+      QUICHE_DCHECK_NE(QUIC_NO_ERROR,
+                       error_);  // ProcessFrameData sets the error.
+      QUICHE_DCHECK_NE("", detailed_error_);
+      QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
+                         << detailed_error_;
+      return false;
+    }
+  }
+
+  visitor_->OnPacketComplete();
+  return true;
+}
+
+bool QuicFramer::ProcessDataPacket(QuicDataReader* encrypted_reader,
+                                   QuicPacketHeader* header,
+                                   const QuicEncryptedPacket& packet,
+                                   char* decrypted_buffer,
+                                   size_t buffer_length) {
+  if (!ProcessUnauthenticatedHeader(encrypted_reader, header)) {
+    QUICHE_DCHECK_NE("", detailed_error_);
+    QUIC_DVLOG(1)
+        << ENDPOINT
+        << "Unable to process packet header. Stopping parsing. Error: "
+        << detailed_error_;
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
+    return false;
+  }
+
+  absl::string_view encrypted = encrypted_reader->ReadRemainingPayload();
+  absl::string_view associated_data = GetAssociatedDataFromEncryptedPacket(
+      version_.transport_version, packet,
+      GetIncludedDestinationConnectionIdLength(*header),
+      GetIncludedSourceConnectionIdLength(*header), header->version_flag,
+      header->nonce != nullptr, header->packet_number_length,
+      header->retry_token_length_length, header->retry_token.length(),
+      header->length_length);
+
+  size_t decrypted_length = 0;
+  EncryptionLevel decrypted_level;
+  if (!DecryptPayload(packet.length(), encrypted, associated_data, *header,
+                      decrypted_buffer, buffer_length, &decrypted_length,
+                      &decrypted_level)) {
+    const EncryptionLevel decryption_level = decrypter_level_;
+    // This version uses trial decryption so we always report to our visitor
+    // that we are not certain we have the correct decryption key.
+    const bool has_decryption_key = false;
+    visitor_->OnUndecryptablePacket(
+        QuicEncryptedPacket(encrypted_reader->FullPayload()), decryption_level,
+        has_decryption_key);
+    RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
+    set_detailed_error(absl::StrCat("Unable to decrypt ",
+                                    EncryptionLevelToString(decryption_level),
+                                    " payload."));
+    return RaiseError(QUIC_DECRYPTION_FAILURE);
+  }
+
+  QuicDataReader reader(decrypted_buffer, decrypted_length);
+
+  // Update the largest packet number after we have decrypted the packet
+  // so we are confident is not attacker controlled.
+  if (supports_multiple_packet_number_spaces_) {
+    largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
+                                          decrypted_level)]
+        .UpdateMax(header->packet_number);
+  } else {
+    largest_packet_number_.UpdateMax(header->packet_number);
+  }
+
+  if (!visitor_->OnPacketHeader(*header)) {
+    // The visitor suppresses further processing of the packet.
+    return true;
+  }
+
+  if (packet.length() > kMaxIncomingPacketSize) {
+    set_detailed_error("Packet too large.");
+    return RaiseError(QUIC_PACKET_TOO_LARGE);
+  }
+
+  // Handle the payload.
+  if (!ProcessFrameData(&reader, *header)) {
+    QUICHE_DCHECK_NE(QUIC_NO_ERROR,
+                     error_);  // ProcessFrameData sets the error.
+    QUICHE_DCHECK_NE("", detailed_error_);
+    QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
+                       << detailed_error_;
+    return false;
+  }
+
+  visitor_->OnPacketComplete();
+  return true;
+}
+
+bool QuicFramer::ProcessPublicResetPacket(QuicDataReader* reader,
+                                          const QuicPacketHeader& header) {
+  QuicPublicResetPacket packet(
+      GetServerConnectionIdAsRecipient(header, perspective_));
+
+  std::unique_ptr<CryptoHandshakeMessage> reset(
+      CryptoFramer::ParseMessage(reader->ReadRemainingPayload()));
+  if (!reset) {
+    set_detailed_error("Unable to read reset message.");
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
+    return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
+  }
+  if (reset->tag() != kPRST) {
+    set_detailed_error("Incorrect message tag.");
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
+    return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
+  }
+
+  if (reset->GetUint64(kRNON, &packet.nonce_proof) != QUIC_NO_ERROR) {
+    set_detailed_error("Unable to read nonce proof.");
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
+    return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
+  }
+  // TODO(satyamshekhar): validate nonce to protect against DoS.
+
+  absl::string_view address;
+  if (reset->GetStringPiece(kCADR, &address)) {
+    QuicSocketAddressCoder address_coder;
+    if (address_coder.Decode(address.data(), address.length())) {
+      packet.client_address =
+          QuicSocketAddress(address_coder.ip(), address_coder.port());
+    }
+  }
+
+  absl::string_view endpoint_id;
+  if (perspective_ == Perspective::IS_CLIENT &&
+      reset->GetStringPiece(kEPID, &endpoint_id)) {
+    packet.endpoint_id = std::string(endpoint_id);
+    packet.endpoint_id += '\0';
+  }
+
+  visitor_->OnPublicResetPacket(packet);
+  return true;
+}
+
+bool QuicFramer::IsIetfStatelessResetPacket(
+    const QuicPacketHeader& header) const {
+  QUIC_BUG_IF(quic_bug_12975_3, header.has_possible_stateless_reset_token &&
+                                    perspective_ != Perspective::IS_CLIENT)
+      << "has_possible_stateless_reset_token can only be true at client side.";
+  return header.form == IETF_QUIC_SHORT_HEADER_PACKET &&
+         header.has_possible_stateless_reset_token &&
+         visitor_->IsValidStatelessResetToken(
+             header.possible_stateless_reset_token);
+}
+
+bool QuicFramer::HasEncrypterOfEncryptionLevel(EncryptionLevel level) const {
+  return encrypter_[level] != nullptr;
+}
+
+bool QuicFramer::HasDecrypterOfEncryptionLevel(EncryptionLevel level) const {
+  return decrypter_[level] != nullptr;
+}
+
+bool QuicFramer::HasAnEncrypterForSpace(PacketNumberSpace space) const {
+  switch (space) {
+    case INITIAL_DATA:
+      return HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL);
+    case HANDSHAKE_DATA:
+      return HasEncrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    case APPLICATION_DATA:
+      return HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT) ||
+             HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    case NUM_PACKET_NUMBER_SPACES:
+      break;
+  }
+  QUIC_BUG(quic_bug_10850_55)
+      << ENDPOINT
+      << "Try to send data of space: " << PacketNumberSpaceToString(space);
+  return false;
+}
+
+EncryptionLevel QuicFramer::GetEncryptionLevelToSendApplicationData() const {
+  if (!HasAnEncrypterForSpace(APPLICATION_DATA)) {
+    QUIC_BUG(quic_bug_12975_4)
+        << "Tried to get encryption level to send application data with no "
+           "encrypter available.";
+    return NUM_ENCRYPTION_LEVELS;
+  }
+  if (HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
+    return ENCRYPTION_FORWARD_SECURE;
+  }
+  QUICHE_DCHECK(HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT));
+  return ENCRYPTION_ZERO_RTT;
+}
+
+bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
+                                    QuicDataWriter* writer,
+                                    size_t* length_field_offset) {
+  if (version().HasIetfInvariantHeader()) {
+    return AppendIetfPacketHeader(header, writer, length_field_offset);
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Appending header: " << header;
+  uint8_t public_flags = 0;
+  if (header.reset_flag) {
+    public_flags |= PACKET_PUBLIC_FLAGS_RST;
+  }
+  if (header.version_flag) {
+    public_flags |= PACKET_PUBLIC_FLAGS_VERSION;
+  }
+
+  public_flags |= GetPacketNumberFlags(header.packet_number_length)
+                  << kPublicHeaderSequenceNumberShift;
+
+  if (header.nonce != nullptr) {
+    QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+    public_flags |= PACKET_PUBLIC_FLAGS_NONCE;
+  }
+
+  QuicConnectionId server_connection_id =
+      GetServerConnectionIdAsSender(header, perspective_);
+  QuicConnectionIdIncluded server_connection_id_included =
+      GetServerConnectionIdIncludedAsSender(header, perspective_);
+  QUICHE_DCHECK_EQ(CONNECTION_ID_ABSENT,
+                   GetClientConnectionIdIncludedAsSender(header, perspective_))
+      << ENDPOINT << ParsedQuicVersionToString(version_)
+      << " invalid header: " << header;
+
+  switch (server_connection_id_included) {
+    case CONNECTION_ID_ABSENT:
+      if (!writer->WriteUInt8(public_flags |
+                              PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) {
+        return false;
+      }
+      break;
+    case CONNECTION_ID_PRESENT:
+      QUIC_BUG_IF(quic_bug_12975_5,
+                  !QuicUtils::IsConnectionIdValidForVersion(
+                      server_connection_id, transport_version()))
+          << "AppendPacketHeader: attempted to use connection ID "
+          << server_connection_id << " which is invalid with version "
+          << version();
+
+      public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
+      if (perspective_ == Perspective::IS_CLIENT) {
+        public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD;
+      }
+      if (!writer->WriteUInt8(public_flags) ||
+          !writer->WriteConnectionId(server_connection_id)) {
+        return false;
+      }
+      break;
+  }
+  last_serialized_server_connection_id_ = server_connection_id;
+
+  if (header.version_flag) {
+    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+    QuicVersionLabel version_label = CreateQuicVersionLabel(version_);
+    if (!writer->WriteUInt32(version_label)) {
+      return false;
+    }
+
+    QUIC_DVLOG(1) << ENDPOINT << "label = '"
+                  << QuicVersionLabelToString(version_label) << "'";
+  }
+
+  if (header.nonce != nullptr &&
+      !writer->WriteBytes(header.nonce, kDiversificationNonceSize)) {
+    return false;
+  }
+
+  if (!AppendPacketNumber(header.packet_number_length, header.packet_number,
+                          writer)) {
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendIetfHeaderTypeByte(const QuicPacketHeader& header,
+                                          QuicDataWriter* writer) {
+  uint8_t type = 0;
+  if (header.version_flag) {
+    type = static_cast<uint8_t>(
+        FLAGS_LONG_HEADER | FLAGS_FIXED_BIT |
+        LongHeaderTypeToOnWireValue(header.long_packet_type, version_) |
+        PacketNumberLengthToOnWireValue(header.packet_number_length));
+  } else {
+    type = static_cast<uint8_t>(
+        FLAGS_FIXED_BIT | (current_key_phase_bit_ ? FLAGS_KEY_PHASE_BIT : 0) |
+        PacketNumberLengthToOnWireValue(header.packet_number_length));
+  }
+  return writer->WriteUInt8(type);
+}
+
+bool QuicFramer::AppendIetfPacketHeader(const QuicPacketHeader& header,
+                                        QuicDataWriter* writer,
+                                        size_t* length_field_offset) {
+  QUIC_DVLOG(1) << ENDPOINT << "Appending IETF header: " << header;
+  QuicConnectionId server_connection_id =
+      GetServerConnectionIdAsSender(header, perspective_);
+  QUIC_BUG_IF(quic_bug_12975_6, !QuicUtils::IsConnectionIdValidForVersion(
+                                    server_connection_id, transport_version()))
+      << "AppendIetfPacketHeader: attempted to use connection ID "
+      << server_connection_id << " which is invalid with version " << version();
+  if (!AppendIetfHeaderTypeByte(header, writer)) {
+    return false;
+  }
+
+  if (header.version_flag) {
+    QUICHE_DCHECK_NE(VERSION_NEGOTIATION, header.long_packet_type)
+        << "QuicFramer::AppendIetfPacketHeader does not support sending "
+           "version negotiation packets, use "
+           "QuicFramer::BuildVersionNegotiationPacket instead "
+        << header;
+    // Append version for long header.
+    QuicVersionLabel version_label = CreateQuicVersionLabel(version_);
+    if (!writer->WriteUInt32(version_label)) {
+      return false;
+    }
+  }
+
+  // Append connection ID.
+  if (!AppendIetfConnectionIds(
+          header.version_flag, version_.HasLengthPrefixedConnectionIds(),
+          header.destination_connection_id_included != CONNECTION_ID_ABSENT
+              ? header.destination_connection_id
+              : EmptyQuicConnectionId(),
+          header.source_connection_id_included != CONNECTION_ID_ABSENT
+              ? header.source_connection_id
+              : EmptyQuicConnectionId(),
+          writer)) {
+    return false;
+  }
+
+  last_serialized_server_connection_id_ = server_connection_id;
+  if (version_.SupportsClientConnectionIds()) {
+    last_serialized_client_connection_id_ =
+        GetClientConnectionIdAsSender(header, perspective_);
+  }
+
+  // TODO(b/141924462) Remove this QUIC_BUG once we do support sending RETRY.
+  QUIC_BUG_IF(quic_bug_12975_7,
+              header.version_flag && header.long_packet_type == RETRY)
+      << "Sending IETF RETRY packets is not currently supported " << header;
+
+  if (QuicVersionHasLongHeaderLengths(transport_version()) &&
+      header.version_flag) {
+    if (header.long_packet_type == INITIAL) {
+      QUICHE_DCHECK_NE(VARIABLE_LENGTH_INTEGER_LENGTH_0,
+                       header.retry_token_length_length)
+          << ENDPOINT << ParsedQuicVersionToString(version_)
+          << " bad retry token length length in header: " << header;
+      // Write retry token length.
+      if (!writer->WriteVarInt62(header.retry_token.length(),
+                                 header.retry_token_length_length)) {
+        return false;
+      }
+      // Write retry token.
+      if (!header.retry_token.empty() &&
+          !writer->WriteStringPiece(header.retry_token)) {
+        return false;
+      }
+    }
+    if (length_field_offset != nullptr) {
+      *length_field_offset = writer->length();
+    }
+    // Add fake length to reserve two bytes to add length in later.
+    writer->WriteVarInt62(256);
+  } else if (length_field_offset != nullptr) {
+    *length_field_offset = 0;
+  }
+
+  // Append packet number.
+  if (!AppendPacketNumber(header.packet_number_length, header.packet_number,
+                          writer)) {
+    return false;
+  }
+  last_written_packet_number_length_ = header.packet_number_length;
+
+  if (!header.version_flag) {
+    return true;
+  }
+
+  if (header.nonce != nullptr) {
+    QUICHE_DCHECK(header.version_flag);
+    QUICHE_DCHECK_EQ(ZERO_RTT_PROTECTED, header.long_packet_type);
+    QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+    if (!writer->WriteBytes(header.nonce, kDiversificationNonceSize)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+const QuicTime::Delta QuicFramer::CalculateTimestampFromWire(
+    uint32_t time_delta_us) {
+  // The new time_delta might have wrapped to the next epoch, or it
+  // might have reverse wrapped to the previous epoch, or it might
+  // remain in the same epoch. Select the time closest to the previous
+  // time.
+  //
+  // epoch_delta is the delta between epochs. A delta is 4 bytes of
+  // microseconds.
+  const uint64_t epoch_delta = UINT64_C(1) << 32;
+  uint64_t epoch = last_timestamp_.ToMicroseconds() & ~(epoch_delta - 1);
+  // Wrapping is safe here because a wrapped value will not be ClosestTo below.
+  uint64_t prev_epoch = epoch - epoch_delta;
+  uint64_t next_epoch = epoch + epoch_delta;
+
+  uint64_t time = ClosestTo(
+      last_timestamp_.ToMicroseconds(), epoch + time_delta_us,
+      ClosestTo(last_timestamp_.ToMicroseconds(), prev_epoch + time_delta_us,
+                next_epoch + time_delta_us));
+
+  return QuicTime::Delta::FromMicroseconds(time);
+}
+
+uint64_t QuicFramer::CalculatePacketNumberFromWire(
+    QuicPacketNumberLength packet_number_length,
+    QuicPacketNumber base_packet_number, uint64_t packet_number) const {
+  // The new packet number might have wrapped to the next epoch, or
+  // it might have reverse wrapped to the previous epoch, or it might
+  // remain in the same epoch.  Select the packet number closest to the
+  // next expected packet number, the previous packet number plus 1.
+
+  // epoch_delta is the delta between epochs the packet number was serialized
+  // with, so the correct value is likely the same epoch as the last sequence
+  // number or an adjacent epoch.
+  if (!base_packet_number.IsInitialized()) {
+    return packet_number;
+  }
+  const uint64_t epoch_delta = UINT64_C(1) << (8 * packet_number_length);
+  uint64_t next_packet_number = base_packet_number.ToUint64() + 1;
+  uint64_t epoch = base_packet_number.ToUint64() & ~(epoch_delta - 1);
+  uint64_t prev_epoch = epoch - epoch_delta;
+  uint64_t next_epoch = epoch + epoch_delta;
+
+  return ClosestTo(next_packet_number, epoch + packet_number,
+                   ClosestTo(next_packet_number, prev_epoch + packet_number,
+                             next_epoch + packet_number));
+}
+
+bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
+                                     bool packet_has_ietf_packet_header,
+                                     QuicPacketHeader* header) {
+  if (packet_has_ietf_packet_header) {
+    return ProcessIetfPacketHeader(reader, header);
+  }
+  uint8_t public_flags;
+  if (!reader->ReadBytes(&public_flags, 1)) {
+    set_detailed_error("Unable to read public flags.");
+    return false;
+  }
+
+  header->reset_flag = (public_flags & PACKET_PUBLIC_FLAGS_RST) != 0;
+  header->version_flag = (public_flags & PACKET_PUBLIC_FLAGS_VERSION) != 0;
+
+  if (validate_flags_ && !header->version_flag &&
+      public_flags > PACKET_PUBLIC_FLAGS_MAX) {
+    set_detailed_error("Illegal public flags value.");
+    return false;
+  }
+
+  if (header->reset_flag && header->version_flag) {
+    set_detailed_error("Got version flag in reset packet");
+    return false;
+  }
+
+  QuicConnectionId* header_connection_id = &header->destination_connection_id;
+  QuicConnectionIdIncluded* header_connection_id_included =
+      &header->destination_connection_id_included;
+  if (perspective_ == Perspective::IS_CLIENT) {
+    header_connection_id = &header->source_connection_id;
+    header_connection_id_included = &header->source_connection_id_included;
+  }
+  switch (public_flags & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) {
+    case PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID:
+      if (!reader->ReadConnectionId(header_connection_id,
+                                    kQuicDefaultConnectionIdLength)) {
+        set_detailed_error("Unable to read ConnectionId.");
+        return false;
+      }
+      *header_connection_id_included = CONNECTION_ID_PRESENT;
+      break;
+    case PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID:
+      *header_connection_id_included = CONNECTION_ID_ABSENT;
+      *header_connection_id = last_serialized_server_connection_id_;
+      break;
+  }
+
+  header->packet_number_length = ReadSequenceNumberLength(
+      public_flags >> kPublicHeaderSequenceNumberShift);
+
+  // Read the version only if the packet is from the client.
+  // version flag from the server means version negotiation packet.
+  if (header->version_flag && perspective_ == Perspective::IS_SERVER) {
+    QuicVersionLabel version_label;
+    if (!ProcessVersionLabel(reader, &version_label)) {
+      set_detailed_error("Unable to read protocol version.");
+      return false;
+    }
+    // If the version from the new packet is the same as the version of this
+    // framer, then the public flags should be set to something we understand.
+    // If not, this raises an error.
+    ParsedQuicVersion version = ParseQuicVersionLabel(version_label);
+    if (version == version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) {
+      set_detailed_error("Illegal public flags value.");
+      return false;
+    }
+    header->version = version;
+  }
+
+  // A nonce should only be present in packets from the server to the client,
+  // which are neither version negotiation nor public reset packets.
+  if (public_flags & PACKET_PUBLIC_FLAGS_NONCE &&
+      !(public_flags & PACKET_PUBLIC_FLAGS_VERSION) &&
+      !(public_flags & PACKET_PUBLIC_FLAGS_RST) &&
+      // The nonce flag from a client is ignored and is assumed to be an older
+      // client indicating an eight-byte connection ID.
+      perspective_ == Perspective::IS_CLIENT) {
+    if (!reader->ReadBytes(reinterpret_cast<uint8_t*>(last_nonce_.data()),
+                           last_nonce_.size())) {
+      set_detailed_error("Unable to read nonce.");
+      return false;
+    }
+    header->nonce = &last_nonce_;
+  } else {
+    header->nonce = nullptr;
+  }
+
+  return true;
+}
+
+// static
+QuicPacketNumberLength QuicFramer::GetMinPacketNumberLength(
+    QuicPacketNumber packet_number) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  if (packet_number < QuicPacketNumber(1 << (PACKET_1BYTE_PACKET_NUMBER * 8))) {
+    return PACKET_1BYTE_PACKET_NUMBER;
+  } else if (packet_number <
+             QuicPacketNumber(1 << (PACKET_2BYTE_PACKET_NUMBER * 8))) {
+    return PACKET_2BYTE_PACKET_NUMBER;
+  } else if (packet_number <
+             QuicPacketNumber(UINT64_C(1)
+                              << (PACKET_4BYTE_PACKET_NUMBER * 8))) {
+    return PACKET_4BYTE_PACKET_NUMBER;
+  } else {
+    return PACKET_6BYTE_PACKET_NUMBER;
+  }
+}
+
+// static
+uint8_t QuicFramer::GetPacketNumberFlags(
+    QuicPacketNumberLength packet_number_length) {
+  switch (packet_number_length) {
+    case PACKET_1BYTE_PACKET_NUMBER:
+      return PACKET_FLAGS_1BYTE_PACKET;
+    case PACKET_2BYTE_PACKET_NUMBER:
+      return PACKET_FLAGS_2BYTE_PACKET;
+    case PACKET_4BYTE_PACKET_NUMBER:
+      return PACKET_FLAGS_4BYTE_PACKET;
+    case PACKET_6BYTE_PACKET_NUMBER:
+    case PACKET_8BYTE_PACKET_NUMBER:
+      return PACKET_FLAGS_8BYTE_PACKET;
+    default:
+      QUIC_BUG(quic_bug_10850_56) << "Unreachable case statement.";
+      return PACKET_FLAGS_8BYTE_PACKET;
+  }
+}
+
+// static
+QuicFramer::AckFrameInfo QuicFramer::GetAckFrameInfo(
+    const QuicAckFrame& frame) {
+  AckFrameInfo new_ack_info;
+  if (frame.packets.Empty()) {
+    return new_ack_info;
+  }
+  // The first block is the last interval. It isn't encoded with the gap-length
+  // encoding, so skip it.
+  new_ack_info.first_block_length = frame.packets.LastIntervalLength();
+  auto itr = frame.packets.rbegin();
+  QuicPacketNumber previous_start = itr->min();
+  new_ack_info.max_block_length = itr->Length();
+  ++itr;
+
+  // Don't do any more work after getting information for 256 ACK blocks; any
+  // more can't be encoded anyway.
+  for (; itr != frame.packets.rend() &&
+         new_ack_info.num_ack_blocks < std::numeric_limits<uint8_t>::max();
+       previous_start = itr->min(), ++itr) {
+    const auto& interval = *itr;
+    const QuicPacketCount total_gap = previous_start - interval.max();
+    new_ack_info.num_ack_blocks +=
+        (total_gap + std::numeric_limits<uint8_t>::max() - 1) /
+        std::numeric_limits<uint8_t>::max();
+    new_ack_info.max_block_length =
+        std::max(new_ack_info.max_block_length, interval.Length());
+  }
+  return new_ack_info;
+}
+
+bool QuicFramer::ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
+                                              QuicPacketHeader* header) {
+  QuicPacketNumber base_packet_number;
+  if (supports_multiple_packet_number_spaces_) {
+    PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
+    if (pn_space == NUM_PACKET_NUMBER_SPACES) {
+      set_detailed_error("Unable to determine packet number space.");
+      return RaiseError(QUIC_INVALID_PACKET_HEADER);
+    }
+    base_packet_number = largest_decrypted_packet_numbers_[pn_space];
+  } else {
+    base_packet_number = largest_packet_number_;
+  }
+  uint64_t full_packet_number;
+  if (!ProcessAndCalculatePacketNumber(
+          encrypted_reader, header->packet_number_length, base_packet_number,
+          &full_packet_number)) {
+    set_detailed_error("Unable to read packet number.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+
+  if (!IsValidFullPacketNumber(full_packet_number, version())) {
+    set_detailed_error("packet numbers cannot be 0.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+  header->packet_number = QuicPacketNumber(full_packet_number);
+
+  if (!visitor_->OnUnauthenticatedHeader(*header)) {
+    set_detailed_error(
+        "Visitor asked to stop processing of unauthenticated header.");
+    return false;
+  }
+  // The function we are in is called because the framer believes that it is
+  // processing a packet that uses the non-IETF (i.e. Google QUIC) packet header
+  // type. Usually, the framer makes that decision based on the framer's
+  // version, but when the framer is used with Perspective::IS_SERVER, then
+  // before version negotiation is complete (specifically, before
+  // InferPacketHeaderTypeFromVersion is called), this decision is made based on
+  // the type byte of the packet.
+  //
+  // If the framer's version KnowsWhichDecrypterToUse, then that version expects
+  // to use the IETF packet header type. If that's the case and we're in this
+  // function, then the packet received is invalid: the framer was expecting an
+  // IETF packet header and didn't get one.
+  if (version().KnowsWhichDecrypterToUse()) {
+    set_detailed_error("Invalid public header type for expected version.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfHeaderTypeByte(QuicDataReader* reader,
+                                           QuicPacketHeader* header) {
+  uint8_t type;
+  if (!reader->ReadBytes(&type, 1)) {
+    set_detailed_error("Unable to read first byte.");
+    return false;
+  }
+  header->type_byte = type;
+  // Determine whether this is a long or short header.
+  header->form = GetIetfPacketHeaderFormat(type);
+  if (header->form == IETF_QUIC_LONG_HEADER_PACKET) {
+    // Version is always present in long headers.
+    header->version_flag = true;
+    // In versions that do not support client connection IDs, we mark the
+    // corresponding connection ID as absent.
+    header->destination_connection_id_included =
+        (perspective_ == Perspective::IS_SERVER ||
+         version_.SupportsClientConnectionIds())
+            ? CONNECTION_ID_PRESENT
+            : CONNECTION_ID_ABSENT;
+    header->source_connection_id_included =
+        (perspective_ == Perspective::IS_CLIENT ||
+         version_.SupportsClientConnectionIds())
+            ? CONNECTION_ID_PRESENT
+            : CONNECTION_ID_ABSENT;
+    // Read version tag.
+    QuicVersionLabel version_label;
+    if (!ProcessVersionLabel(reader, &version_label)) {
+      set_detailed_error("Unable to read protocol version.");
+      return false;
+    }
+    if (!version_label) {
+      // Version label is 0 indicating this is a version negotiation packet.
+      header->long_packet_type = VERSION_NEGOTIATION;
+    } else {
+      header->version = ParseQuicVersionLabel(version_label);
+      if (header->version.IsKnown()) {
+        if (!(type & FLAGS_FIXED_BIT)) {
+          set_detailed_error("Fixed bit is 0 in long header.");
+          return false;
+        }
+        header->long_packet_type = GetLongHeaderType(type, header->version);
+        switch (header->long_packet_type) {
+          case INVALID_PACKET_TYPE:
+            set_detailed_error("Illegal long header type value.");
+            return false;
+          case RETRY:
+            if (!version().SupportsRetry()) {
+              set_detailed_error("RETRY not supported in this version.");
+              return false;
+            }
+            if (perspective_ == Perspective::IS_SERVER) {
+              set_detailed_error("Client-initiated RETRY is invalid.");
+              return false;
+            }
+            break;
+          default:
+            if (!header->version.HasHeaderProtection()) {
+              header->packet_number_length =
+                  GetLongHeaderPacketNumberLength(type);
+            }
+            break;
+        }
+      }
+    }
+
+    QUIC_DVLOG(1) << ENDPOINT << "Received IETF long header: "
+                  << QuicUtils::QuicLongHeaderTypetoString(
+                         header->long_packet_type);
+    return true;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Received IETF short header";
+  // Version is not present in short headers.
+  header->version_flag = false;
+  // In versions that do not support client connection IDs, the client will not
+  // receive destination connection IDs.
+  header->destination_connection_id_included =
+      (perspective_ == Perspective::IS_SERVER ||
+       version_.SupportsClientConnectionIds())
+          ? CONNECTION_ID_PRESENT
+          : CONNECTION_ID_ABSENT;
+  header->source_connection_id_included = CONNECTION_ID_ABSENT;
+  if (!(type & FLAGS_FIXED_BIT)) {
+    set_detailed_error("Fixed bit is 0 in short header.");
+    return false;
+  }
+  if (!version_.HasHeaderProtection()) {
+    header->packet_number_length = GetShortHeaderPacketNumberLength(type);
+  }
+  QUIC_DVLOG(1) << "packet_number_length = " << header->packet_number_length;
+  return true;
+}
+
+// static
+bool QuicFramer::ProcessVersionLabel(QuicDataReader* reader,
+                                     QuicVersionLabel* version_label) {
+  if (!reader->ReadUInt32(version_label)) {
+    return false;
+  }
+  return true;
+}
+
+// static
+bool QuicFramer::ProcessAndValidateIetfConnectionIdLength(
+    QuicDataReader* reader, ParsedQuicVersion version, Perspective perspective,
+    bool should_update_expected_server_connection_id_length,
+    uint8_t* expected_server_connection_id_length,
+    uint8_t* destination_connection_id_length,
+    uint8_t* source_connection_id_length, std::string* detailed_error) {
+  uint8_t connection_id_lengths_byte;
+  if (!reader->ReadBytes(&connection_id_lengths_byte, 1)) {
+    *detailed_error = "Unable to read ConnectionId length.";
+    return false;
+  }
+  uint8_t dcil =
+      (connection_id_lengths_byte & kDestinationConnectionIdLengthMask) >> 4;
+  if (dcil != 0) {
+    dcil += kConnectionIdLengthAdjustment;
+  }
+  uint8_t scil = connection_id_lengths_byte & kSourceConnectionIdLengthMask;
+  if (scil != 0) {
+    scil += kConnectionIdLengthAdjustment;
+  }
+  if (should_update_expected_server_connection_id_length) {
+    uint8_t server_connection_id_length =
+        perspective == Perspective::IS_SERVER ? dcil : scil;
+    if (*expected_server_connection_id_length != server_connection_id_length) {
+      QUIC_DVLOG(1) << "Updating expected_server_connection_id_length: "
+                    << static_cast<int>(*expected_server_connection_id_length)
+                    << " -> " << static_cast<int>(server_connection_id_length);
+      *expected_server_connection_id_length = server_connection_id_length;
+    }
+  }
+  if (!should_update_expected_server_connection_id_length &&
+      (dcil != *destination_connection_id_length ||
+       scil != *source_connection_id_length) &&
+      version.IsKnown() && !version.AllowsVariableLengthConnectionIds()) {
+    QUIC_DVLOG(1) << "dcil: " << static_cast<uint32_t>(dcil)
+                  << ", scil: " << static_cast<uint32_t>(scil);
+    *detailed_error = "Invalid ConnectionId length.";
+    return false;
+  }
+  *destination_connection_id_length = dcil;
+  *source_connection_id_length = scil;
+  return true;
+}
+
+bool QuicFramer::ValidateReceivedConnectionIds(const QuicPacketHeader& header) {
+  bool skip_server_connection_id_validation =
+      perspective_ == Perspective::IS_CLIENT &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+  if (!skip_server_connection_id_validation &&
+      !QuicUtils::IsConnectionIdValidForVersion(
+          GetServerConnectionIdAsRecipient(header, perspective_),
+          transport_version())) {
+    set_detailed_error("Received server connection ID with invalid length.");
+    return false;
+  }
+
+  bool skip_client_connection_id_validation =
+      perspective_ == Perspective::IS_SERVER &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+  if (!skip_client_connection_id_validation &&
+      version_.SupportsClientConnectionIds() &&
+      !QuicUtils::IsConnectionIdValidForVersion(
+          GetClientConnectionIdAsRecipient(header, perspective_),
+          transport_version())) {
+    set_detailed_error("Received client connection ID with invalid length.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfPacketHeader(QuicDataReader* reader,
+                                         QuicPacketHeader* header) {
+  if (version_.HasLengthPrefixedConnectionIds()) {
+    uint8_t expected_destination_connection_id_length =
+        perspective_ == Perspective::IS_CLIENT
+            ? expected_client_connection_id_length_
+            : expected_server_connection_id_length_;
+    QuicVersionLabel version_label;
+    bool has_length_prefix;
+    std::string detailed_error;
+    QuicErrorCode parse_result = QuicFramer::ParsePublicHeader(
+        reader, expected_destination_connection_id_length,
+        version_.HasIetfInvariantHeader(), &header->type_byte, &header->form,
+        &header->version_flag, &has_length_prefix, &version_label,
+        &header->version, &header->destination_connection_id,
+        &header->source_connection_id, &header->long_packet_type,
+        &header->retry_token_length_length, &header->retry_token,
+        &detailed_error);
+    if (parse_result != QUIC_NO_ERROR) {
+      set_detailed_error(detailed_error);
+      return false;
+    }
+    header->destination_connection_id_included = CONNECTION_ID_PRESENT;
+    header->source_connection_id_included =
+        header->version_flag ? CONNECTION_ID_PRESENT : CONNECTION_ID_ABSENT;
+
+    if (!ValidateReceivedConnectionIds(*header)) {
+      return false;
+    }
+
+    if (header->version_flag &&
+        header->long_packet_type != VERSION_NEGOTIATION &&
+        !(header->type_byte & FLAGS_FIXED_BIT)) {
+      set_detailed_error("Fixed bit is 0 in long header.");
+      return false;
+    }
+    if (!header->version_flag && !(header->type_byte & FLAGS_FIXED_BIT)) {
+      set_detailed_error("Fixed bit is 0 in short header.");
+      return false;
+    }
+    if (!header->version_flag) {
+      if (!version_.HasHeaderProtection()) {
+        header->packet_number_length =
+            GetShortHeaderPacketNumberLength(header->type_byte);
+      }
+      return true;
+    }
+    if (header->long_packet_type == RETRY) {
+      if (!version().SupportsRetry()) {
+        set_detailed_error("RETRY not supported in this version.");
+        return false;
+      }
+      if (perspective_ == Perspective::IS_SERVER) {
+        set_detailed_error("Client-initiated RETRY is invalid.");
+        return false;
+      }
+      return true;
+    }
+    if (header->version.IsKnown() && !header->version.HasHeaderProtection()) {
+      header->packet_number_length =
+          GetLongHeaderPacketNumberLength(header->type_byte);
+    }
+
+    return true;
+  }
+
+  if (!ProcessIetfHeaderTypeByte(reader, header)) {
+    return false;
+  }
+
+  uint8_t destination_connection_id_length =
+      header->destination_connection_id_included == CONNECTION_ID_PRESENT
+          ? (perspective_ == Perspective::IS_SERVER
+                 ? expected_server_connection_id_length_
+                 : expected_client_connection_id_length_)
+          : 0;
+  uint8_t source_connection_id_length =
+      header->source_connection_id_included == CONNECTION_ID_PRESENT
+          ? (perspective_ == Perspective::IS_CLIENT
+                 ? expected_server_connection_id_length_
+                 : expected_client_connection_id_length_)
+          : 0;
+  if (header->form == IETF_QUIC_LONG_HEADER_PACKET) {
+    if (!ProcessAndValidateIetfConnectionIdLength(
+            reader, header->version, perspective_,
+            /*should_update_expected_server_connection_id_length=*/false,
+            &expected_server_connection_id_length_,
+            &destination_connection_id_length, &source_connection_id_length,
+            &detailed_error_)) {
+      return false;
+    }
+  }
+
+  // Read connection ID.
+  if (!reader->ReadConnectionId(&header->destination_connection_id,
+                                destination_connection_id_length)) {
+    set_detailed_error("Unable to read destination connection ID.");
+    return false;
+  }
+
+  if (!reader->ReadConnectionId(&header->source_connection_id,
+                                source_connection_id_length)) {
+    set_detailed_error("Unable to read source connection ID.");
+    return false;
+  }
+
+  if (header->source_connection_id_included == CONNECTION_ID_ABSENT) {
+    if (!header->source_connection_id.IsEmpty()) {
+      QUICHE_DCHECK(!version_.SupportsClientConnectionIds());
+      set_detailed_error("Client connection ID not supported in this version.");
+      return false;
+    }
+  }
+
+  return ValidateReceivedConnectionIds(*header);
+}
+
+bool QuicFramer::ProcessAndCalculatePacketNumber(
+    QuicDataReader* reader, QuicPacketNumberLength packet_number_length,
+    QuicPacketNumber base_packet_number, uint64_t* packet_number) {
+  uint64_t wire_packet_number;
+  if (!reader->ReadBytesToUInt64(packet_number_length, &wire_packet_number)) {
+    return false;
+  }
+
+  // TODO(ianswett): Explore the usefulness of trying multiple packet numbers
+  // in case the first guess is incorrect.
+  *packet_number = CalculatePacketNumberFromWire(
+      packet_number_length, base_packet_number, wire_packet_number);
+  return true;
+}
+
+bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
+                                  const QuicPacketHeader& header) {
+  QUICHE_DCHECK(!VersionHasIetfQuicFrames(version_.transport_version))
+      << "IETF QUIC Framing negotiated but attempting to process frames as "
+         "non-IETF QUIC.";
+  if (reader->IsDoneReading()) {
+    set_detailed_error("Packet has no frames.");
+    return RaiseError(QUIC_MISSING_PAYLOAD);
+  }
+  QUIC_DVLOG(2) << ENDPOINT << "Processing packet with header " << header;
+  while (!reader->IsDoneReading()) {
+    uint8_t frame_type;
+    if (!reader->ReadBytes(&frame_type, 1)) {
+      set_detailed_error("Unable to read frame type.");
+      return RaiseError(QUIC_INVALID_FRAME_DATA);
+    }
+    const uint8_t special_mask = version_.HasIetfInvariantHeader()
+                                     ? kQuicFrameTypeSpecialMask
+                                     : kQuicFrameTypeBrokenMask;
+    if (frame_type & special_mask) {
+      // Stream Frame
+      if (frame_type & kQuicFrameTypeStreamMask) {
+        QuicStreamFrame frame;
+        if (!ProcessStreamFrame(reader, frame_type, &frame)) {
+          return RaiseError(QUIC_INVALID_STREAM_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing stream frame " << frame;
+        if (!visitor_->OnStreamFrame(frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      // Ack Frame
+      if (frame_type & kQuicFrameTypeAckMask) {
+        if (!ProcessAckFrame(reader, frame_type)) {
+          return RaiseError(QUIC_INVALID_ACK_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing ACK frame";
+        continue;
+      }
+
+      // This was a special frame type that did not match any
+      // of the known ones. Error.
+      set_detailed_error("Illegal frame type.");
+      QUIC_DLOG(WARNING) << ENDPOINT << "Illegal frame type: "
+                         << static_cast<int>(frame_type);
+      return RaiseError(QUIC_INVALID_FRAME_DATA);
+    }
+
+    switch (frame_type) {
+      case PADDING_FRAME: {
+        QuicPaddingFrame frame;
+        ProcessPaddingFrame(reader, &frame);
+        QUIC_DVLOG(2) << ENDPOINT << "Processing padding frame " << frame;
+        if (!visitor_->OnPaddingFrame(frame)) {
+          QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case RST_STREAM_FRAME: {
+        QuicRstStreamFrame frame;
+        if (!ProcessRstStreamFrame(reader, &frame)) {
+          return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing reset stream frame " << frame;
+        if (!visitor_->OnRstStreamFrame(frame)) {
+          QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case CONNECTION_CLOSE_FRAME: {
+        QuicConnectionCloseFrame frame;
+        if (!ProcessConnectionCloseFrame(reader, &frame)) {
+          return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
+        }
+
+        QUIC_DVLOG(2) << ENDPOINT << "Processing connection close frame "
+                      << frame;
+        if (!visitor_->OnConnectionCloseFrame(frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case GOAWAY_FRAME: {
+        QuicGoAwayFrame goaway_frame;
+        if (!ProcessGoAwayFrame(reader, &goaway_frame)) {
+          return RaiseError(QUIC_INVALID_GOAWAY_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing go away frame "
+                      << goaway_frame;
+        if (!visitor_->OnGoAwayFrame(goaway_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case WINDOW_UPDATE_FRAME: {
+        QuicWindowUpdateFrame window_update_frame;
+        if (!ProcessWindowUpdateFrame(reader, &window_update_frame)) {
+          return RaiseError(QUIC_INVALID_WINDOW_UPDATE_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing window update frame "
+                      << window_update_frame;
+        if (!visitor_->OnWindowUpdateFrame(window_update_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case BLOCKED_FRAME: {
+        QuicBlockedFrame blocked_frame;
+        if (!ProcessBlockedFrame(reader, &blocked_frame)) {
+          return RaiseError(QUIC_INVALID_BLOCKED_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing blocked frame "
+                      << blocked_frame;
+        if (!visitor_->OnBlockedFrame(blocked_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case STOP_WAITING_FRAME: {
+        QuicStopWaitingFrame stop_waiting_frame;
+        if (!ProcessStopWaitingFrame(reader, header, &stop_waiting_frame)) {
+          return RaiseError(QUIC_INVALID_STOP_WAITING_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing stop waiting frame "
+                      << stop_waiting_frame;
+        if (!visitor_->OnStopWaitingFrame(stop_waiting_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+      case PING_FRAME: {
+        // Ping has no payload.
+        QuicPingFrame ping_frame;
+        if (!visitor_->OnPingFrame(ping_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing ping frame " << ping_frame;
+        continue;
+      }
+      case IETF_EXTENSION_MESSAGE_NO_LENGTH:
+        ABSL_FALLTHROUGH_INTENDED;
+      case IETF_EXTENSION_MESSAGE: {
+        QuicMessageFrame message_frame;
+        if (!ProcessMessageFrame(reader,
+                                 frame_type == IETF_EXTENSION_MESSAGE_NO_LENGTH,
+                                 &message_frame)) {
+          return RaiseError(QUIC_INVALID_MESSAGE_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing message frame "
+                      << message_frame;
+        if (!visitor_->OnMessageFrame(message_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        break;
+      }
+      case CRYPTO_FRAME: {
+        if (!QuicVersionUsesCryptoFrames(version_.transport_version)) {
+          set_detailed_error("Illegal frame type.");
+          return RaiseError(QUIC_INVALID_FRAME_DATA);
+        }
+        QuicCryptoFrame frame;
+        if (!ProcessCryptoFrame(reader, GetEncryptionLevel(header), &frame)) {
+          return RaiseError(QUIC_INVALID_FRAME_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing crypto frame " << frame;
+        if (!visitor_->OnCryptoFrame(frame)) {
+          QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        break;
+      }
+      case HANDSHAKE_DONE_FRAME: {
+        // HANDSHAKE_DONE has no payload.
+        QuicHandshakeDoneFrame handshake_done_frame;
+        QUIC_DVLOG(2) << ENDPOINT << "Processing handshake done frame "
+                      << handshake_done_frame;
+        if (!visitor_->OnHandshakeDoneFrame(handshake_done_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        break;
+      }
+
+      default:
+        set_detailed_error("Illegal frame type.");
+        QUIC_DLOG(WARNING) << ENDPOINT << "Illegal frame type: "
+                           << static_cast<int>(frame_type);
+        return RaiseError(QUIC_INVALID_FRAME_DATA);
+    }
+  }
+
+  return true;
+}
+
+// static
+bool QuicFramer::IsIetfFrameTypeExpectedForEncryptionLevel(
+    uint64_t frame_type, EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+    case ENCRYPTION_HANDSHAKE:
+      return frame_type == IETF_CRYPTO || frame_type == IETF_ACK ||
+             frame_type == IETF_ACK_ECN ||
+             frame_type == IETF_ACK_RECEIVE_TIMESTAMPS ||
+             frame_type == IETF_PING || frame_type == IETF_PADDING ||
+             frame_type == IETF_CONNECTION_CLOSE;
+    case ENCRYPTION_ZERO_RTT:
+      return !(frame_type == IETF_ACK || frame_type == IETF_ACK_ECN ||
+               frame_type == IETF_ACK_RECEIVE_TIMESTAMPS ||
+               frame_type == IETF_CRYPTO || frame_type == IETF_HANDSHAKE_DONE ||
+               frame_type == IETF_NEW_TOKEN ||
+               frame_type == IETF_PATH_RESPONSE ||
+               frame_type == IETF_RETIRE_CONNECTION_ID);
+    case ENCRYPTION_FORWARD_SECURE:
+      return true;
+    default:
+      QUIC_BUG(quic_bug_10850_57) << "Unknown encryption level: " << level;
+  }
+  return false;
+}
+
+bool QuicFramer::ProcessIetfFrameData(QuicDataReader* reader,
+                                      const QuicPacketHeader& header,
+                                      EncryptionLevel decrypted_level) {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version))
+      << "Attempt to process frames as IETF frames but version ("
+      << version_.transport_version << ") does not support IETF Framing.";
+
+  if (reader->IsDoneReading()) {
+    set_detailed_error("Packet has no frames.");
+    return RaiseError(QUIC_MISSING_PAYLOAD);
+  }
+
+  QUIC_DVLOG(2) << ENDPOINT << "Processing IETF packet with header " << header;
+  while (!reader->IsDoneReading()) {
+    uint64_t frame_type;
+    // Will be the number of bytes into which frame_type was encoded.
+    size_t encoded_bytes = reader->BytesRemaining();
+    if (!reader->ReadVarInt62(&frame_type)) {
+      set_detailed_error("Unable to read frame type.");
+      return RaiseError(QUIC_INVALID_FRAME_DATA);
+    }
+    if (!IsIetfFrameTypeExpectedForEncryptionLevel(frame_type,
+                                                   decrypted_level)) {
+      set_detailed_error(absl::StrCat(
+          "IETF frame type ",
+          QuicIetfFrameTypeString(static_cast<QuicIetfFrameType>(frame_type)),
+          " is unexpected at encryption level ",
+          EncryptionLevelToString(decrypted_level)));
+      return RaiseError(IETF_QUIC_PROTOCOL_VIOLATION);
+    }
+    previously_received_frame_type_ = current_received_frame_type_;
+    current_received_frame_type_ = frame_type;
+
+    // Is now the number of bytes into which the frame type was encoded.
+    encoded_bytes -= reader->BytesRemaining();
+
+    // Check that the frame type is minimally encoded.
+    if (encoded_bytes !=
+        static_cast<size_t>(QuicDataWriter::GetVarInt62Len(frame_type))) {
+      // The frame type was not minimally encoded.
+      set_detailed_error("Frame type not minimally encoded.");
+      return RaiseError(IETF_QUIC_PROTOCOL_VIOLATION);
+    }
+
+    if (IS_IETF_STREAM_FRAME(frame_type)) {
+      QuicStreamFrame frame;
+      if (!ProcessIetfStreamFrame(reader, frame_type, &frame)) {
+        return RaiseError(QUIC_INVALID_STREAM_DATA);
+      }
+      QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stream frame " << frame;
+      if (!visitor_->OnStreamFrame(frame)) {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "Visitor asked to stop further processing.";
+        // Returning true since there was no parsing error.
+        return true;
+      }
+    } else {
+      switch (frame_type) {
+        case IETF_PADDING: {
+          QuicPaddingFrame frame;
+          ProcessPaddingFrame(reader, &frame);
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF padding frame "
+                        << frame;
+          if (!visitor_->OnPaddingFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_RST_STREAM: {
+          QuicRstStreamFrame frame;
+          if (!ProcessIetfResetStreamFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF reset stream frame "
+                        << frame;
+          if (!visitor_->OnRstStreamFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_APPLICATION_CLOSE:
+        case IETF_CONNECTION_CLOSE: {
+          QuicConnectionCloseFrame frame;
+          if (!ProcessIetfConnectionCloseFrame(
+                  reader,
+                  (frame_type == IETF_CONNECTION_CLOSE)
+                      ? IETF_QUIC_TRANSPORT_CONNECTION_CLOSE
+                      : IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
+                  &frame)) {
+            return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF connection close frame "
+                        << frame;
+          if (!visitor_->OnConnectionCloseFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_MAX_DATA: {
+          QuicWindowUpdateFrame frame;
+          if (!ProcessMaxDataFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_MAX_DATA_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max data frame "
+                        << frame;
+          if (!visitor_->OnWindowUpdateFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_MAX_STREAM_DATA: {
+          QuicWindowUpdateFrame frame;
+          if (!ProcessMaxStreamDataFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max stream data frame "
+                        << frame;
+          if (!visitor_->OnWindowUpdateFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_MAX_STREAMS_BIDIRECTIONAL:
+        case IETF_MAX_STREAMS_UNIDIRECTIONAL: {
+          QuicMaxStreamsFrame frame;
+          if (!ProcessMaxStreamsFrame(reader, &frame, frame_type)) {
+            return RaiseError(QUIC_MAX_STREAMS_DATA);
+          }
+          QUIC_CODE_COUNT_N(quic_max_streams_received, 1, 2);
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max streams frame "
+                        << frame;
+          if (!visitor_->OnMaxStreamsFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_PING: {
+          // Ping has no payload.
+          QuicPingFrame ping_frame;
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ping frame "
+                        << ping_frame;
+          if (!visitor_->OnPingFrame(ping_frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_DATA_BLOCKED: {
+          QuicBlockedFrame frame;
+          if (!ProcessDataBlockedFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_BLOCKED_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF blocked frame "
+                        << frame;
+          if (!visitor_->OnBlockedFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_STREAM_DATA_BLOCKED: {
+          QuicBlockedFrame frame;
+          if (!ProcessStreamDataBlockedFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_STREAM_BLOCKED_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stream blocked frame "
+                        << frame;
+          if (!visitor_->OnBlockedFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_STREAMS_BLOCKED_UNIDIRECTIONAL:
+        case IETF_STREAMS_BLOCKED_BIDIRECTIONAL: {
+          QuicStreamsBlockedFrame frame;
+          if (!ProcessStreamsBlockedFrame(reader, &frame, frame_type)) {
+            return RaiseError(QUIC_STREAMS_BLOCKED_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF streams blocked frame "
+                        << frame;
+          if (!visitor_->OnStreamsBlockedFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_NEW_CONNECTION_ID: {
+          QuicNewConnectionIdFrame frame;
+          if (!ProcessNewConnectionIdFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_NEW_CONNECTION_ID_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT
+                        << "Processing IETF new connection ID frame " << frame;
+          if (!visitor_->OnNewConnectionIdFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_RETIRE_CONNECTION_ID: {
+          QuicRetireConnectionIdFrame frame;
+          if (!ProcessRetireConnectionIdFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT
+                        << "Processing IETF retire connection ID frame "
+                        << frame;
+          if (!visitor_->OnRetireConnectionIdFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_NEW_TOKEN: {
+          QuicNewTokenFrame frame;
+          if (!ProcessNewTokenFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_NEW_TOKEN);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF new token frame "
+                        << frame;
+          if (!visitor_->OnNewTokenFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_STOP_SENDING: {
+          QuicStopSendingFrame frame;
+          if (!ProcessStopSendingFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_STOP_SENDING_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stop sending frame "
+                        << frame;
+          if (!visitor_->OnStopSendingFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_ACK_RECEIVE_TIMESTAMPS:
+          if (!process_timestamps_) {
+            set_detailed_error("Unsupported frame type.");
+            QUIC_DLOG(WARNING)
+                << ENDPOINT << "IETF_ACK_RECEIVE_TIMESTAMPS not supported";
+            return RaiseError(QUIC_INVALID_FRAME_DATA);
+          }
+          ABSL_FALLTHROUGH_INTENDED;
+        case IETF_ACK_ECN:
+        case IETF_ACK: {
+          QuicAckFrame frame;
+          if (!ProcessIetfAckFrame(reader, frame_type, &frame)) {
+            return RaiseError(QUIC_INVALID_ACK_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ACK frame " << frame;
+          break;
+        }
+        case IETF_PATH_CHALLENGE: {
+          QuicPathChallengeFrame frame;
+          if (!ProcessPathChallengeFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_PATH_CHALLENGE_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF path challenge frame "
+                        << frame;
+          if (!visitor_->OnPathChallengeFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_PATH_RESPONSE: {
+          QuicPathResponseFrame frame;
+          if (!ProcessPathResponseFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_PATH_RESPONSE_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF path response frame "
+                        << frame;
+          if (!visitor_->OnPathResponseFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_EXTENSION_MESSAGE_NO_LENGTH_V99:
+          ABSL_FALLTHROUGH_INTENDED;
+        case IETF_EXTENSION_MESSAGE_V99: {
+          QuicMessageFrame message_frame;
+          if (!ProcessMessageFrame(
+                  reader, frame_type == IETF_EXTENSION_MESSAGE_NO_LENGTH_V99,
+                  &message_frame)) {
+            return RaiseError(QUIC_INVALID_MESSAGE_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF message frame "
+                        << message_frame;
+          if (!visitor_->OnMessageFrame(message_frame)) {
+            QUIC_DVLOG(1) << ENDPOINT
+                          << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_CRYPTO: {
+          QuicCryptoFrame frame;
+          if (!ProcessCryptoFrame(reader, GetEncryptionLevel(header), &frame)) {
+            return RaiseError(QUIC_INVALID_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF crypto frame " << frame;
+          if (!visitor_->OnCryptoFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_HANDSHAKE_DONE: {
+          // HANDSHAKE_DONE has no payload.
+          QuicHandshakeDoneFrame handshake_done_frame;
+          if (!visitor_->OnHandshakeDoneFrame(handshake_done_frame)) {
+            QUIC_DVLOG(1) << ENDPOINT
+                          << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing handshake done frame "
+                        << handshake_done_frame;
+          break;
+        }
+        case IETF_ACK_FREQUENCY: {
+          QuicAckFrequencyFrame frame;
+          if (!ProcessAckFrequencyFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ack frequency frame "
+                        << frame;
+          if (!visitor_->OnAckFrequencyFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        default:
+          set_detailed_error("Illegal frame type.");
+          QUIC_DLOG(WARNING)
+              << ENDPOINT
+              << "Illegal frame type: " << static_cast<int>(frame_type);
+          return RaiseError(QUIC_INVALID_FRAME_DATA);
+      }
+    }
+  }
+  return true;
+}
+
+namespace {
+// Create a mask that sets the last |num_bits| to 1 and the rest to 0.
+inline uint8_t GetMaskFromNumBits(uint8_t num_bits) {
+  return (1u << num_bits) - 1;
+}
+
+// Extract |num_bits| from |flags| offset by |offset|.
+uint8_t ExtractBits(uint8_t flags, uint8_t num_bits, uint8_t offset) {
+  return (flags >> offset) & GetMaskFromNumBits(num_bits);
+}
+
+// Extract the bit at position |offset| from |flags| as a bool.
+bool ExtractBit(uint8_t flags, uint8_t offset) {
+  return ((flags >> offset) & GetMaskFromNumBits(1)) != 0;
+}
+
+// Set |num_bits|, offset by |offset| to |val| in |flags|.
+void SetBits(uint8_t* flags, uint8_t val, uint8_t num_bits, uint8_t offset) {
+  QUICHE_DCHECK_LE(val, GetMaskFromNumBits(num_bits));
+  *flags |= val << offset;
+}
+
+// Set the bit at position |offset| to |val| in |flags|.
+void SetBit(uint8_t* flags, bool val, uint8_t offset) {
+  SetBits(flags, val ? 1 : 0, 1, offset);
+}
+}  // namespace
+
+bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader, uint8_t frame_type,
+                                    QuicStreamFrame* frame) {
+  uint8_t stream_flags = frame_type;
+
+  uint8_t stream_id_length = 0;
+  uint8_t offset_length = 4;
+  bool has_data_length = true;
+  stream_flags &= ~kQuicFrameTypeStreamMask;
+
+  // Read from right to left: StreamID, Offset, Data Length, Fin.
+  stream_id_length = (stream_flags & kQuicStreamIDLengthMask) + 1;
+  stream_flags >>= kQuicStreamIdShift;
+
+  offset_length = (stream_flags & kQuicStreamOffsetMask);
+  // There is no encoding for 1 byte, only 0 and 2 through 8.
+  if (offset_length > 0) {
+    offset_length += 1;
+  }
+  stream_flags >>= kQuicStreamShift;
+
+  has_data_length =
+      (stream_flags & kQuicStreamDataLengthMask) == kQuicStreamDataLengthMask;
+  stream_flags >>= kQuicStreamDataLengthShift;
+
+  frame->fin = (stream_flags & kQuicStreamFinMask) == kQuicStreamFinShift;
+
+  uint64_t stream_id;
+  if (!reader->ReadBytesToUInt64(stream_id_length, &stream_id)) {
+    set_detailed_error("Unable to read stream_id.");
+    return false;
+  }
+  frame->stream_id = static_cast<QuicStreamId>(stream_id);
+
+  if (!reader->ReadBytesToUInt64(offset_length, &frame->offset)) {
+    set_detailed_error("Unable to read offset.");
+    return false;
+  }
+
+  // TODO(ianswett): Don't use absl::string_view as an intermediary.
+  absl::string_view data;
+  if (has_data_length) {
+    if (!reader->ReadStringPiece16(&data)) {
+      set_detailed_error("Unable to read frame data.");
+      return false;
+    }
+  } else {
+    if (!reader->ReadStringPiece(&data, reader->BytesRemaining())) {
+      set_detailed_error("Unable to read frame data.");
+      return false;
+    }
+  }
+  frame->data_buffer = data.data();
+  frame->data_length = static_cast<uint16_t>(data.length());
+
+  return true;
+}
+
+bool QuicFramer::ProcessIetfStreamFrame(QuicDataReader* reader,
+                                        uint8_t frame_type,
+                                        QuicStreamFrame* frame) {
+  // Read stream id from the frame. It's always present.
+  if (!ReadUint32FromVarint62(reader, IETF_STREAM, &frame->stream_id)) {
+    return false;
+  }
+
+  // If we have a data offset, read it. If not, set to 0.
+  if (frame_type & IETF_STREAM_FRAME_OFF_BIT) {
+    if (!reader->ReadVarInt62(&frame->offset)) {
+      set_detailed_error("Unable to read stream data offset.");
+      return false;
+    }
+  } else {
+    // no offset in the frame, ensure it's 0 in the Frame.
+    frame->offset = 0;
+  }
+
+  // If we have a data length, read it. If not, set to 0.
+  if (frame_type & IETF_STREAM_FRAME_LEN_BIT) {
+    uint64_t length;
+    if (!reader->ReadVarInt62(&length)) {
+      set_detailed_error("Unable to read stream data length.");
+      return false;
+    }
+    if (length > std::numeric_limits<decltype(frame->data_length)>::max()) {
+      set_detailed_error("Stream data length is too large.");
+      return false;
+    }
+    frame->data_length = length;
+  } else {
+    // no length in the frame, it is the number of bytes remaining in the
+    // packet.
+    frame->data_length = reader->BytesRemaining();
+  }
+
+  if (frame_type & IETF_STREAM_FRAME_FIN_BIT) {
+    frame->fin = true;
+  } else {
+    frame->fin = false;
+  }
+
+  // TODO(ianswett): Don't use absl::string_view as an intermediary.
+  absl::string_view data;
+  if (!reader->ReadStringPiece(&data, frame->data_length)) {
+    set_detailed_error("Unable to read frame data.");
+    return false;
+  }
+  frame->data_buffer = data.data();
+  QUICHE_DCHECK_EQ(frame->data_length, data.length());
+
+  return true;
+}
+
+bool QuicFramer::ProcessCryptoFrame(QuicDataReader* reader,
+                                    EncryptionLevel encryption_level,
+                                    QuicCryptoFrame* frame) {
+  frame->level = encryption_level;
+  if (!reader->ReadVarInt62(&frame->offset)) {
+    set_detailed_error("Unable to read crypto data offset.");
+    return false;
+  }
+  uint64_t len;
+  if (!reader->ReadVarInt62(&len) ||
+      len > std::numeric_limits<QuicPacketLength>::max()) {
+    set_detailed_error("Invalid data length.");
+    return false;
+  }
+  frame->data_length = len;
+
+  // TODO(ianswett): Don't use absl::string_view as an intermediary.
+  absl::string_view data;
+  if (!reader->ReadStringPiece(&data, frame->data_length)) {
+    set_detailed_error("Unable to read frame data.");
+    return false;
+  }
+  frame->data_buffer = data.data();
+  return true;
+}
+
+bool QuicFramer::ProcessAckFrequencyFrame(QuicDataReader* reader,
+                                          QuicAckFrequencyFrame* frame) {
+  if (!reader->ReadVarInt62(&frame->sequence_number)) {
+    set_detailed_error("Unable to read sequence number.");
+    return false;
+  }
+
+  if (!reader->ReadVarInt62(&frame->packet_tolerance)) {
+    set_detailed_error("Unable to read packet tolerance.");
+    return false;
+  }
+  if (frame->packet_tolerance == 0) {
+    set_detailed_error("Invalid packet tolerance.");
+    return false;
+  }
+  uint64_t max_ack_delay_us;
+  if (!reader->ReadVarInt62(&max_ack_delay_us)) {
+    set_detailed_error("Unable to read max_ack_delay_us.");
+    return false;
+  }
+  constexpr uint64_t kMaxAckDelayUsBound = 1u << 24;
+  if (max_ack_delay_us > kMaxAckDelayUsBound) {
+    set_detailed_error("Invalid max_ack_delay_us.");
+    return false;
+  }
+  frame->max_ack_delay = QuicTime::Delta::FromMicroseconds(max_ack_delay_us);
+
+  uint8_t ignore_order;
+  if (!reader->ReadUInt8(&ignore_order)) {
+    set_detailed_error("Unable to read ignore_order.");
+    return false;
+  }
+  if (ignore_order > 1) {
+    set_detailed_error("Invalid ignore_order.");
+    return false;
+  }
+  frame->ignore_order = ignore_order;
+
+  return true;
+}
+
+bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type) {
+  const bool has_ack_blocks =
+      ExtractBit(frame_type, kQuicHasMultipleAckBlocksOffset);
+  uint8_t num_ack_blocks = 0;
+  uint8_t num_received_packets = 0;
+
+  // Determine the two lengths from the frame type: largest acked length,
+  // ack block length.
+  const QuicPacketNumberLength ack_block_length =
+      ReadAckPacketNumberLength(ExtractBits(
+          frame_type, kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset));
+  const QuicPacketNumberLength largest_acked_length =
+      ReadAckPacketNumberLength(ExtractBits(
+          frame_type, kQuicSequenceNumberLengthNumBits, kLargestAckedOffset));
+
+  uint64_t largest_acked;
+  if (!reader->ReadBytesToUInt64(largest_acked_length, &largest_acked)) {
+    set_detailed_error("Unable to read largest acked.");
+    return false;
+  }
+
+  if (largest_acked < first_sending_packet_number_.ToUint64()) {
+    // Connection always sends packet starting from kFirstSendingPacketNumber >
+    // 0, peer has observed an unsent packet.
+    set_detailed_error("Largest acked is 0.");
+    return false;
+  }
+
+  uint64_t ack_delay_time_us;
+  if (!reader->ReadUFloat16(&ack_delay_time_us)) {
+    set_detailed_error("Unable to read ack delay time.");
+    return false;
+  }
+
+  if (!visitor_->OnAckFrameStart(
+          QuicPacketNumber(largest_acked),
+          ack_delay_time_us == kUFloat16MaxValue
+              ? QuicTime::Delta::Infinite()
+              : QuicTime::Delta::FromMicroseconds(ack_delay_time_us))) {
+    // The visitor suppresses further processing of the packet. Although this is
+    // not a parsing error, returns false as this is in middle of processing an
+    // ack frame,
+    set_detailed_error("Visitor suppresses further processing of ack frame.");
+    return false;
+  }
+
+  if (has_ack_blocks && !reader->ReadUInt8(&num_ack_blocks)) {
+    set_detailed_error("Unable to read num of ack blocks.");
+    return false;
+  }
+
+  uint64_t first_block_length;
+  if (!reader->ReadBytesToUInt64(ack_block_length, &first_block_length)) {
+    set_detailed_error("Unable to read first ack block length.");
+    return false;
+  }
+
+  if (first_block_length == 0) {
+    set_detailed_error("First block length is zero.");
+    return false;
+  }
+  bool first_ack_block_underflow = first_block_length > largest_acked + 1;
+  if (first_block_length + first_sending_packet_number_.ToUint64() >
+      largest_acked + 1) {
+    first_ack_block_underflow = true;
+  }
+  if (first_ack_block_underflow) {
+    set_detailed_error(absl::StrCat("Underflow with first ack block length ",
+                                    first_block_length, " largest acked is ",
+                                    largest_acked, ".")
+                           .c_str());
+    return false;
+  }
+
+  uint64_t first_received = largest_acked + 1 - first_block_length;
+  if (!visitor_->OnAckRange(QuicPacketNumber(first_received),
+                            QuicPacketNumber(largest_acked + 1))) {
+    // The visitor suppresses further processing of the packet. Although
+    // this is not a parsing error, returns false as this is in middle
+    // of processing an ack frame,
+    set_detailed_error("Visitor suppresses further processing of ack frame.");
+    return false;
+  }
+
+  if (num_ack_blocks > 0) {
+    for (size_t i = 0; i < num_ack_blocks; ++i) {
+      uint8_t gap = 0;
+      if (!reader->ReadUInt8(&gap)) {
+        set_detailed_error("Unable to read gap to next ack block.");
+        return false;
+      }
+      uint64_t current_block_length;
+      if (!reader->ReadBytesToUInt64(ack_block_length, &current_block_length)) {
+        set_detailed_error("Unable to ack block length.");
+        return false;
+      }
+      bool ack_block_underflow = first_received < gap + current_block_length;
+      if (first_received < gap + current_block_length +
+                               first_sending_packet_number_.ToUint64()) {
+        ack_block_underflow = true;
+      }
+      if (ack_block_underflow) {
+        set_detailed_error(absl::StrCat("Underflow with ack block length ",
+                                        current_block_length,
+                                        ", end of block is ",
+                                        first_received - gap, ".")
+                               .c_str());
+        return false;
+      }
+
+      first_received -= (gap + current_block_length);
+      if (current_block_length > 0) {
+        if (!visitor_->OnAckRange(
+                QuicPacketNumber(first_received),
+                QuicPacketNumber(first_received) + current_block_length)) {
+          // The visitor suppresses further processing of the packet. Although
+          // this is not a parsing error, returns false as this is in middle
+          // of processing an ack frame,
+          set_detailed_error(
+              "Visitor suppresses further processing of ack frame.");
+          return false;
+        }
+      }
+    }
+  }
+
+  if (!reader->ReadUInt8(&num_received_packets)) {
+    set_detailed_error("Unable to read num received packets.");
+    return false;
+  }
+
+  if (!ProcessTimestampsInAckFrame(num_received_packets,
+                                   QuicPacketNumber(largest_acked), reader)) {
+    return false;
+  }
+
+  // Done processing the ACK frame.
+  if (!visitor_->OnAckFrameEnd(QuicPacketNumber(first_received))) {
+    set_detailed_error(
+        "Error occurs when visitor finishes processing the ACK frame.");
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::ProcessTimestampsInAckFrame(uint8_t num_received_packets,
+                                             QuicPacketNumber largest_acked,
+                                             QuicDataReader* reader) {
+  if (num_received_packets == 0) {
+    return true;
+  }
+  uint8_t delta_from_largest_observed;
+  if (!reader->ReadUInt8(&delta_from_largest_observed)) {
+    set_detailed_error("Unable to read sequence delta in received packets.");
+    return false;
+  }
+
+  if (largest_acked.ToUint64() <= delta_from_largest_observed) {
+    set_detailed_error(
+        absl::StrCat("delta_from_largest_observed too high: ",
+                     delta_from_largest_observed,
+                     ", largest_acked: ", largest_acked.ToUint64())
+            .c_str());
+    return false;
+  }
+
+  // Time delta from the framer creation.
+  uint32_t time_delta_us;
+  if (!reader->ReadUInt32(&time_delta_us)) {
+    set_detailed_error("Unable to read time delta in received packets.");
+    return false;
+  }
+
+  QuicPacketNumber seq_num = largest_acked - delta_from_largest_observed;
+  if (process_timestamps_) {
+    last_timestamp_ = CalculateTimestampFromWire(time_delta_us);
+
+    visitor_->OnAckTimestamp(seq_num, creation_time_ + last_timestamp_);
+  }
+
+  for (uint8_t i = 1; i < num_received_packets; ++i) {
+    if (!reader->ReadUInt8(&delta_from_largest_observed)) {
+      set_detailed_error("Unable to read sequence delta in received packets.");
+      return false;
+    }
+    if (largest_acked.ToUint64() <= delta_from_largest_observed) {
+      set_detailed_error(
+          absl::StrCat("delta_from_largest_observed too high: ",
+                       delta_from_largest_observed,
+                       ", largest_acked: ", largest_acked.ToUint64())
+              .c_str());
+      return false;
+    }
+    seq_num = largest_acked - delta_from_largest_observed;
+
+    // Time delta from the previous timestamp.
+    uint64_t incremental_time_delta_us;
+    if (!reader->ReadUFloat16(&incremental_time_delta_us)) {
+      set_detailed_error(
+          "Unable to read incremental time delta in received packets.");
+      return false;
+    }
+
+    if (process_timestamps_) {
+      last_timestamp_ = last_timestamp_ + QuicTime::Delta::FromMicroseconds(
+                                              incremental_time_delta_us);
+      visitor_->OnAckTimestamp(seq_num, creation_time_ + last_timestamp_);
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfAckFrame(QuicDataReader* reader,
+                                     uint64_t frame_type,
+                                     QuicAckFrame* ack_frame) {
+  uint64_t largest_acked;
+  if (!reader->ReadVarInt62(&largest_acked)) {
+    set_detailed_error("Unable to read largest acked.");
+    return false;
+  }
+  if (largest_acked < first_sending_packet_number_.ToUint64()) {
+    // Connection always sends packet starting from kFirstSendingPacketNumber >
+    // 0, peer has observed an unsent packet.
+    set_detailed_error("Largest acked is 0.");
+    return false;
+  }
+  ack_frame->largest_acked = static_cast<QuicPacketNumber>(largest_acked);
+  uint64_t ack_delay_time_in_us;
+  if (!reader->ReadVarInt62(&ack_delay_time_in_us)) {
+    set_detailed_error("Unable to read ack delay time.");
+    return false;
+  }
+
+  if (ack_delay_time_in_us >= (kVarInt62MaxValue >> peer_ack_delay_exponent_)) {
+    ack_frame->ack_delay_time = QuicTime::Delta::Infinite();
+  } else {
+    ack_delay_time_in_us = (ack_delay_time_in_us << peer_ack_delay_exponent_);
+    ack_frame->ack_delay_time =
+        QuicTime::Delta::FromMicroseconds(ack_delay_time_in_us);
+  }
+  if (!visitor_->OnAckFrameStart(QuicPacketNumber(largest_acked),
+                                 ack_frame->ack_delay_time)) {
+    // The visitor suppresses further processing of the packet. Although this is
+    // not a parsing error, returns false as this is in middle of processing an
+    // ACK frame.
+    set_detailed_error("Visitor suppresses further processing of ACK frame.");
+    return false;
+  }
+
+  // Get number of ACK blocks from the packet.
+  uint64_t ack_block_count;
+  if (!reader->ReadVarInt62(&ack_block_count)) {
+    set_detailed_error("Unable to read ack block count.");
+    return false;
+  }
+  // There always is a first ACK block, which is the (number of packets being
+  // acked)-1, up to and including the packet at largest_acked. Therefore if the
+  // value is 0, then only largest is acked. If it is 1, then largest-1,
+  // largest] are acked, etc
+  uint64_t ack_block_value;
+  if (!reader->ReadVarInt62(&ack_block_value)) {
+    set_detailed_error("Unable to read first ack block length.");
+    return false;
+  }
+  // Calculate the packets being acked in the first block.
+  //  +1 because AddRange implementation requires [low,high)
+  uint64_t block_high = largest_acked + 1;
+  uint64_t block_low = largest_acked - ack_block_value;
+
+  // ack_block_value is the number of packets preceding the
+  // largest_acked packet which are in the block being acked. Thus,
+  // its maximum value is largest_acked-1. Test this, reporting an
+  // error if the value is wrong.
+  if (ack_block_value + first_sending_packet_number_.ToUint64() >
+      largest_acked) {
+    set_detailed_error(absl::StrCat("Underflow with first ack block length ",
+                                    ack_block_value + 1, " largest acked is ",
+                                    largest_acked, ".")
+                           .c_str());
+    return false;
+  }
+
+  if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
+                            QuicPacketNumber(block_high))) {
+    // The visitor suppresses further processing of the packet. Although
+    // this is not a parsing error, returns false as this is in middle
+    // of processing an ACK frame.
+    set_detailed_error("Visitor suppresses further processing of ACK frame.");
+    return false;
+  }
+
+  while (ack_block_count != 0) {
+    uint64_t gap_block_value;
+    // Get the sizes of the gap and ack blocks,
+    if (!reader->ReadVarInt62(&gap_block_value)) {
+      set_detailed_error("Unable to read gap block value.");
+      return false;
+    }
+    // It's an error if the gap is larger than the space from packet
+    // number 0 to the start of the block that's just been acked, PLUS
+    // there must be space for at least 1 packet to be acked. For
+    // example, if block_low is 10 and gap_block_value is 9, it means
+    // the gap block is 10 packets long, leaving no room for a packet
+    // to be acked. Thus, gap_block_value+2 can not be larger than
+    // block_low.
+    // The test is written this way to detect wrap-arounds.
+    if ((gap_block_value + 2) > block_low) {
+      set_detailed_error(
+          absl::StrCat("Underflow with gap block length ", gap_block_value + 1,
+                       " previous ack block start is ", block_low, ".")
+              .c_str());
+      return false;
+    }
+
+    // Adjust block_high to be the top of the next ack block.
+    // There is a gap of |gap_block_value| packets between the bottom
+    // of ack block N and top of block N+1.  Note that gap_block_value
+    // is he size of the gap minus 1 (per the QUIC protocol), and
+    // block_high is the packet number of the first packet of the gap
+    // (per the implementation of OnAckRange/AddAckRange, below).
+    block_high = block_low - 1 - gap_block_value;
+
+    if (!reader->ReadVarInt62(&ack_block_value)) {
+      set_detailed_error("Unable to read ack block value.");
+      return false;
+    }
+    if (ack_block_value + first_sending_packet_number_.ToUint64() >
+        (block_high - 1)) {
+      set_detailed_error(
+          absl::StrCat("Underflow with ack block length ", ack_block_value + 1,
+                       " latest ack block end is ", block_high - 1, ".")
+              .c_str());
+      return false;
+    }
+    // Calculate the low end of the new nth ack block. The +1 is
+    // because the encoded value is the blocksize-1.
+    block_low = block_high - 1 - ack_block_value;
+    if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
+                              QuicPacketNumber(block_high))) {
+      // The visitor suppresses further processing of the packet. Although
+      // this is not a parsing error, returns false as this is in middle
+      // of processing an ACK frame.
+      set_detailed_error("Visitor suppresses further processing of ACK frame.");
+      return false;
+    }
+
+    // Another one done.
+    ack_block_count--;
+  }
+
+  if (frame_type == IETF_ACK_RECEIVE_TIMESTAMPS) {
+    QUICHE_DCHECK(process_timestamps_);
+    if (!ProcessIetfTimestampsInAckFrame(ack_frame->largest_acked, reader)) {
+      return false;
+    }
+  } else if (frame_type == IETF_ACK_ECN) {
+    ack_frame->ecn_counters_populated = true;
+    if (!reader->ReadVarInt62(&ack_frame->ect_0_count)) {
+      set_detailed_error("Unable to read ack ect_0_count.");
+      return false;
+    }
+    if (!reader->ReadVarInt62(&ack_frame->ect_1_count)) {
+      set_detailed_error("Unable to read ack ect_1_count.");
+      return false;
+    }
+    if (!reader->ReadVarInt62(&ack_frame->ecn_ce_count)) {
+      set_detailed_error("Unable to read ack ecn_ce_count.");
+      return false;
+    }
+  } else {
+    ack_frame->ecn_counters_populated = false;
+    ack_frame->ect_0_count = 0;
+    ack_frame->ect_1_count = 0;
+    ack_frame->ecn_ce_count = 0;
+  }
+  // TODO(fayang): Report ECN counts to visitor when they are actually used.
+  if (!visitor_->OnAckFrameEnd(QuicPacketNumber(block_low))) {
+    set_detailed_error(
+        "Error occurs when visitor finishes processing the ACK frame.");
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
+                                                 QuicDataReader* reader) {
+  uint64_t timestamp_range_count;
+  if (!reader->ReadVarInt62(&timestamp_range_count)) {
+    set_detailed_error("Unable to read receive timestamp range count.");
+    return false;
+  }
+  if (timestamp_range_count == 0) {
+    return true;
+  }
+
+  QuicPacketNumber packet_number = largest_acked;
+
+  // Iterate through all timestamp ranges, each of which represents a block of
+  // contiguous packets for which receive timestamps are being reported. Each
+  // range is of the form:
+  //
+  // Timestamp Range {
+  //    Gap (i),
+  //    Timestamp Delta Count (i),
+  //    Timestamp Delta (i) ...,
+  //  }
+  for (uint64_t i = 0; i < timestamp_range_count; i++) {
+    uint64_t gap;
+    if (!reader->ReadVarInt62(&gap)) {
+      set_detailed_error("Unable to read receive timestamp gap.");
+      return false;
+    }
+    if (packet_number.ToUint64() < gap) {
+      set_detailed_error("Receive timestamp gap too high.");
+      return false;
+    }
+    packet_number = packet_number - gap;
+    uint64_t timestamp_count;
+    if (!reader->ReadVarInt62(&timestamp_count)) {
+      set_detailed_error("Unable to read receive timestamp count.");
+      return false;
+    }
+    if (packet_number.ToUint64() < timestamp_count) {
+      set_detailed_error("Receive timestamp count too high.");
+      return false;
+    }
+    for (uint64_t j = 0; j < timestamp_count; j++) {
+      uint64_t timestamp_delta;
+      if (!reader->ReadVarInt62(&timestamp_delta)) {
+        set_detailed_error("Unable to read receive timestamp delta.");
+        return false;
+      }
+      // The first timestamp delta is relative to framer creation time; whereas
+      // subsequent deltas are relative to the previous delta in decreasing
+      // packet order.
+      timestamp_delta = timestamp_delta << receive_timestamps_exponent_;
+      if (i == 0 && j == 0) {
+        last_timestamp_ = QuicTime::Delta::FromMicroseconds(timestamp_delta);
+      } else {
+        last_timestamp_ = last_timestamp_ -
+                          QuicTime::Delta::FromMicroseconds(timestamp_delta);
+        if (last_timestamp_ < QuicTime::Delta::Zero()) {
+          set_detailed_error("Receive timestamp delta too high.");
+          return false;
+        }
+      }
+      visitor_->OnAckTimestamp(packet_number, creation_time_ + last_timestamp_);
+      packet_number--;
+    }
+    packet_number--;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessStopWaitingFrame(QuicDataReader* reader,
+                                         const QuicPacketHeader& header,
+                                         QuicStopWaitingFrame* stop_waiting) {
+  uint64_t least_unacked_delta;
+  if (!reader->ReadBytesToUInt64(header.packet_number_length,
+                                 &least_unacked_delta)) {
+    set_detailed_error("Unable to read least unacked delta.");
+    return false;
+  }
+  if (header.packet_number.ToUint64() <= least_unacked_delta) {
+    set_detailed_error("Invalid unacked delta.");
+    return false;
+  }
+  stop_waiting->least_unacked = header.packet_number - least_unacked_delta;
+
+  return true;
+}
+
+bool QuicFramer::ProcessRstStreamFrame(QuicDataReader* reader,
+                                       QuicRstStreamFrame* frame) {
+  if (!reader->ReadUInt32(&frame->stream_id)) {
+    set_detailed_error("Unable to read stream_id.");
+    return false;
+  }
+
+  if (!reader->ReadUInt64(&frame->byte_offset)) {
+    set_detailed_error("Unable to read rst stream sent byte offset.");
+    return false;
+  }
+
+  uint32_t error_code;
+  if (!reader->ReadUInt32(&error_code)) {
+    set_detailed_error("Unable to read rst stream error code.");
+    return false;
+  }
+
+  if (error_code >= QUIC_STREAM_LAST_ERROR) {
+    // Ignore invalid stream error code if any.
+    error_code = QUIC_STREAM_LAST_ERROR;
+  }
+
+  frame->error_code = static_cast<QuicRstStreamErrorCode>(error_code);
+
+  return true;
+}
+
+bool QuicFramer::ProcessConnectionCloseFrame(QuicDataReader* reader,
+                                             QuicConnectionCloseFrame* frame) {
+  uint32_t error_code;
+  frame->close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
+
+  if (!reader->ReadUInt32(&error_code)) {
+    set_detailed_error("Unable to read connection close error code.");
+    return false;
+  }
+
+  // For Google QUIC connection closes, |wire_error_code| and |quic_error_code|
+  // must have the same value.
+  frame->wire_error_code = error_code;
+  frame->quic_error_code = static_cast<QuicErrorCode>(error_code);
+
+  absl::string_view error_details;
+  if (!reader->ReadStringPiece16(&error_details)) {
+    set_detailed_error("Unable to read connection close error details.");
+    return false;
+  }
+  frame->error_details = std::string(error_details);
+
+  return true;
+}
+
+bool QuicFramer::ProcessGoAwayFrame(QuicDataReader* reader,
+                                    QuicGoAwayFrame* frame) {
+  uint32_t error_code;
+  if (!reader->ReadUInt32(&error_code)) {
+    set_detailed_error("Unable to read go away error code.");
+    return false;
+  }
+
+  frame->error_code = static_cast<QuicErrorCode>(error_code);
+
+  uint32_t stream_id;
+  if (!reader->ReadUInt32(&stream_id)) {
+    set_detailed_error("Unable to read last good stream id.");
+    return false;
+  }
+  frame->last_good_stream_id = static_cast<QuicStreamId>(stream_id);
+
+  absl::string_view reason_phrase;
+  if (!reader->ReadStringPiece16(&reason_phrase)) {
+    set_detailed_error("Unable to read goaway reason.");
+    return false;
+  }
+  frame->reason_phrase = std::string(reason_phrase);
+
+  return true;
+}
+
+bool QuicFramer::ProcessWindowUpdateFrame(QuicDataReader* reader,
+                                          QuicWindowUpdateFrame* frame) {
+  if (!reader->ReadUInt32(&frame->stream_id)) {
+    set_detailed_error("Unable to read stream_id.");
+    return false;
+  }
+
+  if (!reader->ReadUInt64(&frame->max_data)) {
+    set_detailed_error("Unable to read window byte_offset.");
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::ProcessBlockedFrame(QuicDataReader* reader,
+                                     QuicBlockedFrame* frame) {
+  QUICHE_DCHECK(!VersionHasIetfQuicFrames(version_.transport_version))
+      << "Attempt to process non-IETF QUIC frames in an IETF QUIC version.";
+
+  if (!reader->ReadUInt32(&frame->stream_id)) {
+    set_detailed_error("Unable to read stream_id.");
+    return false;
+  }
+
+  return true;
+}
+
+void QuicFramer::ProcessPaddingFrame(QuicDataReader* reader,
+                                     QuicPaddingFrame* frame) {
+  // Type byte has been read.
+  frame->num_padding_bytes = 1;
+  uint8_t next_byte;
+  while (!reader->IsDoneReading() && reader->PeekByte() == 0x00) {
+    reader->ReadBytes(&next_byte, 1);
+    QUICHE_DCHECK_EQ(0x00, next_byte);
+    ++frame->num_padding_bytes;
+  }
+}
+
+bool QuicFramer::ProcessMessageFrame(QuicDataReader* reader,
+                                     bool no_message_length,
+                                     QuicMessageFrame* frame) {
+  if (no_message_length) {
+    absl::string_view remaining(reader->ReadRemainingPayload());
+    frame->data = remaining.data();
+    frame->message_length = remaining.length();
+    return true;
+  }
+
+  uint64_t message_length;
+  if (!reader->ReadVarInt62(&message_length)) {
+    set_detailed_error("Unable to read message length");
+    return false;
+  }
+
+  absl::string_view message_piece;
+  if (!reader->ReadStringPiece(&message_piece, message_length)) {
+    set_detailed_error("Unable to read message data");
+    return false;
+  }
+
+  frame->data = message_piece.data();
+  frame->message_length = message_length;
+
+  return true;
+}
+
+// static
+absl::string_view QuicFramer::GetAssociatedDataFromEncryptedPacket(
+    QuicTransportVersion version, const QuicEncryptedPacket& encrypted,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length, bool includes_version,
+    bool includes_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    uint64_t retry_token_length,
+    QuicVariableLengthIntegerLength length_length) {
+  // TODO(ianswett): This is identical to QuicData::AssociatedData.
+  return absl::string_view(
+      encrypted.data(),
+      GetStartOfEncryptedData(version, destination_connection_id_length,
+                              source_connection_id_length, includes_version,
+                              includes_diversification_nonce,
+                              packet_number_length, retry_token_length_length,
+                              retry_token_length, length_length));
+}
+
+void QuicFramer::SetDecrypter(EncryptionLevel level,
+                              std::unique_ptr<QuicDecrypter> decrypter) {
+  QUICHE_DCHECK_EQ(alternative_decrypter_level_, NUM_ENCRYPTION_LEVELS);
+  QUICHE_DCHECK_GE(level, decrypter_level_);
+  QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Setting decrypter from level "
+                << decrypter_level_ << " to " << level;
+  decrypter_[decrypter_level_] = nullptr;
+  decrypter_[level] = std::move(decrypter);
+  decrypter_level_ = level;
+}
+
+void QuicFramer::SetAlternativeDecrypter(
+    EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
+    bool latch_once_used) {
+  QUICHE_DCHECK_NE(level, decrypter_level_);
+  QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Setting alternative decrypter from level "
+                << alternative_decrypter_level_ << " to " << level;
+  if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
+    decrypter_[alternative_decrypter_level_] = nullptr;
+  }
+  decrypter_[level] = std::move(decrypter);
+  alternative_decrypter_level_ = level;
+  alternative_decrypter_latch_ = latch_once_used;
+}
+
+void QuicFramer::InstallDecrypter(EncryptionLevel level,
+                                  std::unique_ptr<QuicDecrypter> decrypter) {
+  QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Installing decrypter at level " << level;
+  decrypter_[level] = std::move(decrypter);
+}
+
+void QuicFramer::RemoveDecrypter(EncryptionLevel level) {
+  QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Removing decrypter at level " << level;
+  decrypter_[level] = nullptr;
+}
+
+void QuicFramer::SetKeyUpdateSupportForConnection(bool enabled) {
+  QUIC_DVLOG(1) << ENDPOINT << "SetKeyUpdateSupportForConnection: " << enabled;
+  support_key_update_for_connection_ = enabled;
+}
+
+void QuicFramer::DiscardPreviousOneRttKeys() {
+  QUICHE_DCHECK(support_key_update_for_connection_);
+  QUIC_DVLOG(1) << ENDPOINT << "Discarding previous set of 1-RTT keys";
+  previous_decrypter_ = nullptr;
+}
+
+bool QuicFramer::DoKeyUpdate(KeyUpdateReason reason) {
+  QUICHE_DCHECK(support_key_update_for_connection_);
+  if (!next_decrypter_) {
+    // If key update is locally initiated, next decrypter might not be created
+    // yet.
+    next_decrypter_ = visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+  }
+  std::unique_ptr<QuicEncrypter> next_encrypter =
+      visitor_->CreateCurrentOneRttEncrypter();
+  if (!next_decrypter_ || !next_encrypter) {
+    QUIC_BUG(quic_bug_10850_58) << "Failed to create next crypters";
+    return false;
+  }
+  key_update_performed_ = true;
+  current_key_phase_bit_ = !current_key_phase_bit_;
+  QUIC_DLOG(INFO) << ENDPOINT << "DoKeyUpdate: new current_key_phase_bit_="
+                  << current_key_phase_bit_;
+  current_key_phase_first_received_packet_number_.Clear();
+  previous_decrypter_ = std::move(decrypter_[ENCRYPTION_FORWARD_SECURE]);
+  decrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_decrypter_);
+  encrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_encrypter);
+  switch (reason) {
+    case KeyUpdateReason::kInvalid:
+      QUIC_CODE_COUNT(quic_key_update_invalid);
+      break;
+    case KeyUpdateReason::kRemote:
+      QUIC_CODE_COUNT(quic_key_update_remote);
+      break;
+    case KeyUpdateReason::kLocalForTests:
+      QUIC_CODE_COUNT(quic_key_update_local_for_tests);
+      break;
+    case KeyUpdateReason::kLocalForInteropRunner:
+      QUIC_CODE_COUNT(quic_key_update_local_for_interop_runner);
+      break;
+    case KeyUpdateReason::kLocalAeadConfidentialityLimit:
+      QUIC_CODE_COUNT(quic_key_update_local_aead_confidentiality_limit);
+      break;
+    case KeyUpdateReason::kLocalKeyUpdateLimitOverride:
+      QUIC_CODE_COUNT(quic_key_update_local_limit_override);
+      break;
+  }
+  visitor_->OnKeyUpdate(reason);
+  return true;
+}
+
+QuicPacketCount QuicFramer::PotentialPeerKeyUpdateAttemptCount() const {
+  return potential_peer_key_update_attempt_count_;
+}
+
+const QuicDecrypter* QuicFramer::GetDecrypter(EncryptionLevel level) const {
+  QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
+  return decrypter_[level].get();
+}
+
+const QuicDecrypter* QuicFramer::decrypter() const {
+  return decrypter_[decrypter_level_].get();
+}
+
+const QuicDecrypter* QuicFramer::alternative_decrypter() const {
+  if (alternative_decrypter_level_ == NUM_ENCRYPTION_LEVELS) {
+    return nullptr;
+  }
+  return decrypter_[alternative_decrypter_level_].get();
+}
+
+void QuicFramer::SetEncrypter(EncryptionLevel level,
+                              std::unique_ptr<QuicEncrypter> encrypter) {
+  QUICHE_DCHECK_GE(level, 0);
+  QUICHE_DCHECK_LT(level, NUM_ENCRYPTION_LEVELS);
+  QUIC_DVLOG(1) << ENDPOINT << "Setting encrypter at level " << level;
+  encrypter_[level] = std::move(encrypter);
+}
+
+void QuicFramer::RemoveEncrypter(EncryptionLevel level) {
+  QUIC_DVLOG(1) << ENDPOINT << "Removing encrypter of " << level;
+  encrypter_[level] = nullptr;
+}
+
+void QuicFramer::SetInitialObfuscators(QuicConnectionId connection_id) {
+  CrypterPair crypters;
+  CryptoUtils::CreateInitialObfuscators(perspective_, version_, connection_id,
+                                        &crypters);
+  encrypter_[ENCRYPTION_INITIAL] = std::move(crypters.encrypter);
+  decrypter_[ENCRYPTION_INITIAL] = std::move(crypters.decrypter);
+}
+
+size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
+                                  QuicPacketNumber packet_number, size_t ad_len,
+                                  size_t total_len, size_t buffer_len,
+                                  char* buffer) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  if (encrypter_[level] == nullptr) {
+    QUIC_BUG(quic_bug_10850_59)
+        << ENDPOINT
+        << "Attempted to encrypt in place without encrypter at level " << level;
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+
+  size_t output_length = 0;
+  if (!encrypter_[level]->EncryptPacket(
+          packet_number.ToUint64(),
+          absl::string_view(buffer, ad_len),  // Associated data
+          absl::string_view(buffer + ad_len,
+                            total_len - ad_len),  // Plaintext
+          buffer + ad_len,                        // Destination buffer
+          &output_length, buffer_len - ad_len)) {
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+  if (version_.HasHeaderProtection() &&
+      !ApplyHeaderProtection(level, buffer, ad_len + output_length, ad_len)) {
+    QUIC_DLOG(ERROR) << "Applying header protection failed.";
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+
+  return ad_len + output_length;
+}
+
+namespace {
+
+const size_t kHPSampleLen = 16;
+
+constexpr bool IsLongHeader(uint8_t type_byte) {
+  return (type_byte & FLAGS_LONG_HEADER) != 0;
+}
+
+}  // namespace
+
+bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level, char* buffer,
+                                       size_t buffer_len, size_t ad_len) {
+  QuicDataReader buffer_reader(buffer, buffer_len);
+  QuicDataWriter buffer_writer(buffer_len, buffer);
+  // The sample starts 4 bytes after the start of the packet number.
+  if (ad_len < last_written_packet_number_length_) {
+    return false;
+  }
+  size_t pn_offset = ad_len - last_written_packet_number_length_;
+  // Sample the ciphertext and generate the mask to use for header protection.
+  size_t sample_offset = pn_offset + 4;
+  QuicDataReader sample_reader(buffer, buffer_len);
+  absl::string_view sample;
+  if (!sample_reader.Seek(sample_offset) ||
+      !sample_reader.ReadStringPiece(&sample, kHPSampleLen)) {
+    QUIC_BUG(quic_bug_10850_60)
+        << "Not enough bytes to sample: sample_offset " << sample_offset
+        << ", sample len: " << kHPSampleLen << ", buffer len: " << buffer_len;
+    return false;
+  }
+
+  if (encrypter_[level] == nullptr) {
+    QUIC_BUG(quic_bug_12975_8)
+        << ENDPOINT
+        << "Attempted to apply header protection without encrypter at level "
+        << level << " using " << version_;
+    return false;
+  }
+
+  std::string mask = encrypter_[level]->GenerateHeaderProtectionMask(sample);
+  if (mask.empty()) {
+    QUIC_BUG(quic_bug_10850_61) << "Unable to generate header protection mask.";
+    return false;
+  }
+  QuicDataReader mask_reader(mask.data(), mask.size());
+
+  // Apply the mask to the 4 or 5 least significant bits of the first byte.
+  uint8_t bitmask = 0x1f;
+  uint8_t type_byte;
+  if (!buffer_reader.ReadUInt8(&type_byte)) {
+    return false;
+  }
+  QuicLongHeaderType header_type;
+  if (IsLongHeader(type_byte)) {
+    bitmask = 0x0f;
+    header_type = GetLongHeaderType(type_byte, version_);
+    if (header_type == INVALID_PACKET_TYPE) {
+      return false;
+    }
+  }
+  uint8_t mask_byte;
+  if (!mask_reader.ReadUInt8(&mask_byte) ||
+      !buffer_writer.WriteUInt8(type_byte ^ (mask_byte & bitmask))) {
+    return false;
+  }
+
+  // Adjust |pn_offset| to account for the diversification nonce.
+  if (IsLongHeader(type_byte) && header_type == ZERO_RTT_PROTECTED &&
+      perspective_ == Perspective::IS_SERVER &&
+      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+    if (pn_offset <= kDiversificationNonceSize) {
+      QUIC_BUG(quic_bug_10850_62)
+          << "Expected diversification nonce, but not enough bytes";
+      return false;
+    }
+    pn_offset -= kDiversificationNonceSize;
+  }
+  // Advance the reader and writer to the packet number. Both the reader and
+  // writer have each read/written one byte.
+  if (!buffer_writer.Seek(pn_offset - 1) ||
+      !buffer_reader.Seek(pn_offset - 1)) {
+    return false;
+  }
+  // Apply the rest of the mask to the packet number.
+  for (size_t i = 0; i < last_written_packet_number_length_; ++i) {
+    uint8_t buffer_byte;
+    uint8_t mask_byte;
+    if (!mask_reader.ReadUInt8(&mask_byte) ||
+        !buffer_reader.ReadUInt8(&buffer_byte) ||
+        !buffer_writer.WriteUInt8(buffer_byte ^ mask_byte)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::RemoveHeaderProtection(QuicDataReader* reader,
+                                        const QuicEncryptedPacket& packet,
+                                        QuicPacketHeader* header,
+                                        uint64_t* full_packet_number,
+                                        std::vector<char>* associated_data) {
+  EncryptionLevel expected_decryption_level = GetEncryptionLevel(*header);
+  QuicDecrypter* decrypter = decrypter_[expected_decryption_level].get();
+  if (decrypter == nullptr) {
+    QUIC_DVLOG(1)
+        << ENDPOINT
+        << "No decrypter available for removing header protection at level "
+        << expected_decryption_level;
+    return false;
+  }
+
+  bool has_diversification_nonce =
+      header->form == IETF_QUIC_LONG_HEADER_PACKET &&
+      header->long_packet_type == ZERO_RTT_PROTECTED &&
+      perspective_ == Perspective::IS_CLIENT &&
+      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO;
+
+  // Read a sample from the ciphertext and compute the mask to use for header
+  // protection.
+  absl::string_view remaining_packet = reader->PeekRemainingPayload();
+  QuicDataReader sample_reader(remaining_packet);
+
+  // The sample starts 4 bytes after the start of the packet number.
+  absl::string_view pn;
+  if (!sample_reader.ReadStringPiece(&pn, 4)) {
+    QUIC_DVLOG(1) << "Not enough data to sample";
+    return false;
+  }
+  if (has_diversification_nonce) {
+    // In Google QUIC, the diversification nonce comes between the packet number
+    // and the sample.
+    if (!sample_reader.Seek(kDiversificationNonceSize)) {
+      QUIC_DVLOG(1) << "No diversification nonce to skip over";
+      return false;
+    }
+  }
+  std::string mask = decrypter->GenerateHeaderProtectionMask(&sample_reader);
+  QuicDataReader mask_reader(mask.data(), mask.size());
+  if (mask.empty()) {
+    QUIC_DVLOG(1) << "Failed to compute mask";
+    return false;
+  }
+
+  // Unmask the rest of the type byte.
+  uint8_t bitmask = 0x1f;
+  if (IsLongHeader(header->type_byte)) {
+    bitmask = 0x0f;
+  }
+  uint8_t mask_byte;
+  if (!mask_reader.ReadUInt8(&mask_byte)) {
+    QUIC_DVLOG(1) << "No first byte to read from mask";
+    return false;
+  }
+  header->type_byte ^= (mask_byte & bitmask);
+
+  // Compute the packet number length.
+  header->packet_number_length =
+      static_cast<QuicPacketNumberLength>((header->type_byte & 0x03) + 1);
+
+  char pn_buffer[IETF_MAX_PACKET_NUMBER_LENGTH] = {};
+  QuicDataWriter pn_writer(ABSL_ARRAYSIZE(pn_buffer), pn_buffer);
+
+  // Read the (protected) packet number from the reader and unmask the packet
+  // number.
+  for (size_t i = 0; i < header->packet_number_length; ++i) {
+    uint8_t protected_pn_byte, mask_byte;
+    if (!mask_reader.ReadUInt8(&mask_byte) ||
+        !reader->ReadUInt8(&protected_pn_byte) ||
+        !pn_writer.WriteUInt8(protected_pn_byte ^ mask_byte)) {
+      QUIC_DVLOG(1) << "Failed to unmask packet number";
+      return false;
+    }
+  }
+  QuicDataReader packet_number_reader(pn_writer.data(), pn_writer.length());
+  QuicPacketNumber base_packet_number;
+  if (supports_multiple_packet_number_spaces_) {
+    PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
+    if (pn_space == NUM_PACKET_NUMBER_SPACES) {
+      return false;
+    }
+    base_packet_number = largest_decrypted_packet_numbers_[pn_space];
+  } else {
+    base_packet_number = largest_packet_number_;
+  }
+  if (!ProcessAndCalculatePacketNumber(
+          &packet_number_reader, header->packet_number_length,
+          base_packet_number, full_packet_number)) {
+    return false;
+  }
+
+  // Get the associated data, and apply the same unmasking operations to it.
+  absl::string_view ad = GetAssociatedDataFromEncryptedPacket(
+      version_.transport_version, packet,
+      GetIncludedDestinationConnectionIdLength(*header),
+      GetIncludedSourceConnectionIdLength(*header), header->version_flag,
+      has_diversification_nonce, header->packet_number_length,
+      header->retry_token_length_length, header->retry_token.length(),
+      header->length_length);
+  *associated_data = std::vector<char>(ad.begin(), ad.end());
+  QuicDataWriter ad_writer(associated_data->size(), associated_data->data());
+
+  // Apply the unmasked type byte and packet number to |associated_data|.
+  if (!ad_writer.WriteUInt8(header->type_byte)) {
+    return false;
+  }
+  // Put the packet number at the end of the AD, or if there's a diversification
+  // nonce, before that (which is at the end of the AD).
+  size_t seek_len = ad_writer.remaining() - header->packet_number_length;
+  if (has_diversification_nonce) {
+    seek_len -= kDiversificationNonceSize;
+  }
+  if (!ad_writer.Seek(seek_len) ||
+      !ad_writer.WriteBytes(pn_writer.data(), pn_writer.length())) {
+    QUIC_DVLOG(1) << "Failed to apply unmasking operations to AD";
+    return false;
+  }
+
+  return true;
+}
+
+size_t QuicFramer::EncryptPayload(EncryptionLevel level,
+                                  QuicPacketNumber packet_number,
+                                  const QuicPacket& packet, char* buffer,
+                                  size_t buffer_len) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  if (encrypter_[level] == nullptr) {
+    QUIC_BUG(quic_bug_10850_63)
+        << ENDPOINT << "Attempted to encrypt without encrypter at level "
+        << level;
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+
+  absl::string_view associated_data =
+      packet.AssociatedData(version_.transport_version);
+  // Copy in the header, because the encrypter only populates the encrypted
+  // plaintext content.
+  const size_t ad_len = associated_data.length();
+  if (packet.length() < ad_len) {
+    QUIC_BUG(quic_bug_10850_64)
+        << ENDPOINT << "packet is shorter than associated data length. version:"
+        << version() << ", packet length:" << packet.length()
+        << ", associated data length:" << ad_len;
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+  memmove(buffer, associated_data.data(), ad_len);
+  // Encrypt the plaintext into the buffer.
+  size_t output_length = 0;
+  if (!encrypter_[level]->EncryptPacket(
+          packet_number.ToUint64(), associated_data,
+          packet.Plaintext(version_.transport_version), buffer + ad_len,
+          &output_length, buffer_len - ad_len)) {
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+  if (version_.HasHeaderProtection() &&
+      !ApplyHeaderProtection(level, buffer, ad_len + output_length, ad_len)) {
+    QUIC_DLOG(ERROR) << "Applying header protection failed.";
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+
+  return ad_len + output_length;
+}
+
+size_t QuicFramer::GetCiphertextSize(EncryptionLevel level,
+                                     size_t plaintext_size) const {
+  if (encrypter_[level] == nullptr) {
+    QUIC_BUG(quic_bug_10850_65)
+        << ENDPOINT
+        << "Attempted to get ciphertext size without encrypter at level "
+        << level << " using " << version_;
+    return plaintext_size;
+  }
+  return encrypter_[level]->GetCiphertextSize(plaintext_size);
+}
+
+size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) {
+  // In order to keep the code simple, we don't have the current encryption
+  // level to hand. Both the NullEncrypter and AES-GCM have a tag length of 12.
+  size_t min_plaintext_size = ciphertext_size;
+
+  for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; i++) {
+    if (encrypter_[i] != nullptr) {
+      size_t size = encrypter_[i]->GetMaxPlaintextSize(ciphertext_size);
+      if (size < min_plaintext_size) {
+        min_plaintext_size = size;
+      }
+    }
+  }
+
+  return min_plaintext_size;
+}
+
+QuicPacketCount QuicFramer::GetOneRttEncrypterConfidentialityLimit() const {
+  if (!encrypter_[ENCRYPTION_FORWARD_SECURE]) {
+    QUIC_BUG(quic_bug_10850_66) << "1-RTT encrypter not set";
+    return 0;
+  }
+  return encrypter_[ENCRYPTION_FORWARD_SECURE]->GetConfidentialityLimit();
+}
+
+bool QuicFramer::DecryptPayload(size_t udp_packet_length,
+                                absl::string_view encrypted,
+                                absl::string_view associated_data,
+                                const QuicPacketHeader& header,
+                                char* decrypted_buffer, size_t buffer_length,
+                                size_t* decrypted_length,
+                                EncryptionLevel* decrypted_level) {
+  if (!EncryptionLevelIsValid(decrypter_level_)) {
+    QUIC_BUG(quic_bug_10850_67)
+        << "Attempted to decrypt with bad decrypter_level_";
+    return false;
+  }
+  EncryptionLevel level = decrypter_level_;
+  QuicDecrypter* decrypter = decrypter_[level].get();
+  QuicDecrypter* alternative_decrypter = nullptr;
+  bool key_phase_parsed = false;
+  bool key_phase;
+  bool attempt_key_update = false;
+  if (version().KnowsWhichDecrypterToUse()) {
+    if (header.form == GOOGLE_QUIC_PACKET) {
+      QUIC_BUG(quic_bug_10850_68)
+          << "Attempted to decrypt GOOGLE_QUIC_PACKET with a version that "
+             "knows which decrypter to use";
+      return false;
+    }
+    level = GetEncryptionLevel(header);
+    if (!EncryptionLevelIsValid(level)) {
+      QUIC_BUG(quic_bug_10850_69) << "Attempted to decrypt with bad level";
+      return false;
+    }
+    decrypter = decrypter_[level].get();
+    if (decrypter == nullptr) {
+      return false;
+    }
+    if (level == ENCRYPTION_ZERO_RTT &&
+        perspective_ == Perspective::IS_CLIENT && header.nonce != nullptr) {
+      decrypter->SetDiversificationNonce(*header.nonce);
+    }
+    if (support_key_update_for_connection_ &&
+        header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+      QUICHE_DCHECK(version().UsesTls());
+      QUICHE_DCHECK_EQ(level, ENCRYPTION_FORWARD_SECURE);
+      key_phase = (header.type_byte & FLAGS_KEY_PHASE_BIT) != 0;
+      key_phase_parsed = true;
+      QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number
+                    << " received key_phase=" << key_phase
+                    << " current_key_phase_bit_=" << current_key_phase_bit_;
+      if (key_phase != current_key_phase_bit_) {
+        if ((current_key_phase_first_received_packet_number_.IsInitialized() &&
+             header.packet_number >
+                 current_key_phase_first_received_packet_number_) ||
+            (!current_key_phase_first_received_packet_number_.IsInitialized() &&
+             !key_update_performed_)) {
+          if (!next_decrypter_) {
+            next_decrypter_ =
+                visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+            if (!next_decrypter_) {
+              QUIC_BUG(quic_bug_10850_70) << "Failed to create next_decrypter";
+              return false;
+            }
+          }
+          QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number
+                        << " attempt_key_update=true";
+          attempt_key_update = true;
+          potential_peer_key_update_attempt_count_++;
+          decrypter = next_decrypter_.get();
+        } else {
+          if (previous_decrypter_) {
+            QUIC_DVLOG(1) << ENDPOINT
+                          << "trying previous_decrypter_ for packet "
+                          << header.packet_number;
+            decrypter = previous_decrypter_.get();
+          } else {
+            QUIC_DVLOG(1) << ENDPOINT << "dropping packet "
+                          << header.packet_number << " with old key phase";
+            return false;
+          }
+        }
+      }
+    }
+  } else if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
+    if (!EncryptionLevelIsValid(alternative_decrypter_level_)) {
+      QUIC_BUG(quic_bug_10850_71)
+          << "Attempted to decrypt with bad alternative_decrypter_level_";
+      return false;
+    }
+    alternative_decrypter = decrypter_[alternative_decrypter_level_].get();
+  }
+
+  if (decrypter == nullptr) {
+    QUIC_BUG(quic_bug_10850_72)
+        << "Attempting to decrypt without decrypter, encryption level:" << level
+        << " version:" << version();
+    return false;
+  }
+
+  bool success = decrypter->DecryptPacket(
+      header.packet_number.ToUint64(), associated_data, encrypted,
+      decrypted_buffer, decrypted_length, buffer_length);
+  if (success) {
+    visitor_->OnDecryptedPacket(udp_packet_length, level);
+    if (level == ENCRYPTION_ZERO_RTT &&
+        current_key_phase_first_received_packet_number_.IsInitialized() &&
+        header.packet_number >
+            current_key_phase_first_received_packet_number_) {
+      set_detailed_error(absl::StrCat(
+          "Decrypted a 0-RTT packet with a packet number ",
+          header.packet_number.ToString(),
+          " which is higher than a 1-RTT packet number ",
+          current_key_phase_first_received_packet_number_.ToString()));
+      return RaiseError(QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
+    }
+    *decrypted_level = level;
+    potential_peer_key_update_attempt_count_ = 0;
+    if (attempt_key_update) {
+      if (!DoKeyUpdate(KeyUpdateReason::kRemote)) {
+        set_detailed_error("Key update failed due to internal error");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      }
+      QUICHE_DCHECK_EQ(current_key_phase_bit_, key_phase);
+    }
+    if (key_phase_parsed &&
+        !current_key_phase_first_received_packet_number_.IsInitialized() &&
+        key_phase == current_key_phase_bit_) {
+      // Set packet number for current key phase if it hasn't been initialized
+      // yet. This is set outside of attempt_key_update since the key update
+      // may have been initiated locally, and in that case we don't know yet
+      // which packet number from the remote side to use until we receive a
+      // packet with that phase.
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "current_key_phase_first_received_packet_number_ = "
+                    << header.packet_number;
+      current_key_phase_first_received_packet_number_ = header.packet_number;
+      visitor_->OnDecryptedFirstPacketInKeyPhase();
+    }
+  } else if (alternative_decrypter != nullptr) {
+    if (header.nonce != nullptr) {
+      QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+      alternative_decrypter->SetDiversificationNonce(*header.nonce);
+    }
+    bool try_alternative_decryption = true;
+    if (alternative_decrypter_level_ == ENCRYPTION_ZERO_RTT) {
+      if (perspective_ == Perspective::IS_CLIENT) {
+        if (header.nonce == nullptr) {
+          // Can not use INITIAL decryption without a diversification nonce.
+          try_alternative_decryption = false;
+        }
+      } else {
+        QUICHE_DCHECK(header.nonce == nullptr);
+      }
+    }
+
+    if (try_alternative_decryption) {
+      success = alternative_decrypter->DecryptPacket(
+          header.packet_number.ToUint64(), associated_data, encrypted,
+          decrypted_buffer, decrypted_length, buffer_length);
+    }
+    if (success) {
+      visitor_->OnDecryptedPacket(udp_packet_length,
+                                  alternative_decrypter_level_);
+      *decrypted_level = decrypter_level_;
+      if (alternative_decrypter_latch_) {
+        if (!EncryptionLevelIsValid(alternative_decrypter_level_)) {
+          QUIC_BUG(quic_bug_10850_73)
+              << "Attempted to latch alternate decrypter with bad "
+                 "alternative_decrypter_level_";
+          return false;
+        }
+        // Switch to the alternative decrypter and latch so that we cannot
+        // switch back.
+        decrypter_level_ = alternative_decrypter_level_;
+        alternative_decrypter_level_ = NUM_ENCRYPTION_LEVELS;
+      } else {
+        // Switch the alternative decrypter so that we use it first next time.
+        EncryptionLevel level = alternative_decrypter_level_;
+        alternative_decrypter_level_ = decrypter_level_;
+        decrypter_level_ = level;
+      }
+    }
+  }
+
+  if (!success) {
+    QUIC_DVLOG(1) << ENDPOINT << "DecryptPacket failed for: " << header;
+    return false;
+  }
+
+  return true;
+}
+
+size_t QuicFramer::GetIetfAckFrameSize(const QuicAckFrame& frame) {
+  // Type byte, largest_acked, and delay_time are straight-forward.
+  size_t ack_frame_size = kQuicFrameTypeSize;
+  QuicPacketNumber largest_acked = LargestAcked(frame);
+  ack_frame_size += QuicDataWriter::GetVarInt62Len(largest_acked.ToUint64());
+  uint64_t ack_delay_time_us;
+  ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
+  ack_delay_time_us = ack_delay_time_us >> local_ack_delay_exponent_;
+  ack_frame_size += QuicDataWriter::GetVarInt62Len(ack_delay_time_us);
+
+  if (frame.packets.Empty() || frame.packets.Max() != largest_acked) {
+    QUIC_BUG(quic_bug_10850_74) << "Malformed ack frame";
+    // ACK frame serialization will fail and connection will be closed.
+    return ack_frame_size;
+  }
+
+  // Ack block count.
+  ack_frame_size +=
+      QuicDataWriter::GetVarInt62Len(frame.packets.NumIntervals() - 1);
+
+  // First Ack range.
+  auto iter = frame.packets.rbegin();
+  ack_frame_size += QuicDataWriter::GetVarInt62Len(iter->Length() - 1);
+  QuicPacketNumber previous_smallest = iter->min();
+  ++iter;
+
+  // Ack blocks.
+  for (; iter != frame.packets.rend(); ++iter) {
+    const uint64_t gap = previous_smallest - iter->max() - 1;
+    const uint64_t ack_range = iter->Length() - 1;
+    ack_frame_size += (QuicDataWriter::GetVarInt62Len(gap) +
+                       QuicDataWriter::GetVarInt62Len(ack_range));
+    previous_smallest = iter->min();
+  }
+
+  if (UseIetfAckWithReceiveTimestamp(frame)) {
+    ack_frame_size += GetIetfAckFrameTimestampSize(frame);
+  } else if (frame.ecn_counters_populated &&
+             (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
+    // ECN counts.
+    ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_0_count);
+    ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_1_count);
+    ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count);
+  }
+
+  return ack_frame_size;
+}
+
+size_t QuicFramer::GetIetfAckFrameTimestampSize(const QuicAckFrame& ack) {
+  QUICHE_DCHECK(!ack.received_packet_times.empty());
+  std::string detailed_error;
+  absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
+      GetAckTimestampRanges(ack, detailed_error);
+  if (!detailed_error.empty()) {
+    return 0;
+  }
+
+  int64_t size =
+      FrameAckTimestampRanges(ack, timestamp_ranges, /*writer=*/nullptr);
+  return std::max<int64_t>(0, size);
+}
+
+size_t QuicFramer::GetAckFrameSize(
+    const QuicAckFrame& ack, QuicPacketNumberLength /*packet_number_length*/) {
+  QUICHE_DCHECK(!ack.packets.Empty());
+  size_t ack_size = 0;
+
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return GetIetfAckFrameSize(ack);
+  }
+  AckFrameInfo ack_info = GetAckFrameInfo(ack);
+  QuicPacketNumberLength ack_block_length =
+      GetMinPacketNumberLength(QuicPacketNumber(ack_info.max_block_length));
+
+  ack_size = GetMinAckFrameSize(version_.transport_version, ack,
+                                local_ack_delay_exponent_,
+                                UseIetfAckWithReceiveTimestamp(ack));
+  // First ack block length.
+  ack_size += ack_block_length;
+  if (ack_info.num_ack_blocks != 0) {
+    ack_size += kNumberOfAckBlocksSize;
+    ack_size += std::min(ack_info.num_ack_blocks, kMaxAckBlocks) *
+                (ack_block_length + PACKET_1BYTE_PACKET_NUMBER);
+  }
+
+  // Include timestamps.
+  if (process_timestamps_) {
+    ack_size += GetAckFrameTimeStampSize(ack);
+  }
+
+  return ack_size;
+}
+
+size_t QuicFramer::GetAckFrameTimeStampSize(const QuicAckFrame& ack) {
+  if (ack.received_packet_times.empty()) {
+    return 0;
+  }
+
+  return kQuicNumTimestampsLength + kQuicFirstTimestampLength +
+         (kQuicTimestampLength + kQuicTimestampPacketNumberGapLength) *
+             (ack.received_packet_times.size() - 1);
+}
+
+size_t QuicFramer::ComputeFrameLength(
+    const QuicFrame& frame, bool last_frame_in_packet,
+    QuicPacketNumberLength packet_number_length) {
+  switch (frame.type) {
+    case STREAM_FRAME:
+      return GetMinStreamFrameSize(
+                 version_.transport_version, frame.stream_frame.stream_id,
+                 frame.stream_frame.offset, last_frame_in_packet,
+                 frame.stream_frame.data_length) +
+             frame.stream_frame.data_length;
+    case CRYPTO_FRAME:
+      return GetMinCryptoFrameSize(frame.crypto_frame->offset,
+                                   frame.crypto_frame->data_length) +
+             frame.crypto_frame->data_length;
+    case ACK_FRAME: {
+      return GetAckFrameSize(*frame.ack_frame, packet_number_length);
+    }
+    case STOP_WAITING_FRAME:
+      return GetStopWaitingFrameSize(packet_number_length);
+    case MTU_DISCOVERY_FRAME:
+      // MTU discovery frames are serialized as ping frames.
+      return kQuicFrameTypeSize;
+    case MESSAGE_FRAME:
+      return GetMessageFrameSize(version_.transport_version,
+                                 last_frame_in_packet,
+                                 frame.message_frame->message_length);
+    case PADDING_FRAME:
+      QUICHE_DCHECK(false);
+      return 0;
+    default:
+      return GetRetransmittableControlFrameSize(version_.transport_version,
+                                                frame);
+  }
+}
+
+bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
+                                bool last_frame_in_packet,
+                                QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return AppendIetfFrameType(frame, last_frame_in_packet, writer);
+  }
+  uint8_t type_byte = 0;
+  switch (frame.type) {
+    case STREAM_FRAME:
+      type_byte =
+          GetStreamFrameTypeByte(frame.stream_frame, last_frame_in_packet);
+      break;
+    case ACK_FRAME:
+      return true;
+    case MTU_DISCOVERY_FRAME:
+      type_byte = static_cast<uint8_t>(PING_FRAME);
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      set_detailed_error(
+          "Attempt to append NEW_CONNECTION_ID frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case RETIRE_CONNECTION_ID_FRAME:
+      set_detailed_error(
+          "Attempt to append RETIRE_CONNECTION_ID frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case NEW_TOKEN_FRAME:
+      set_detailed_error(
+          "Attempt to append NEW_TOKEN frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case MAX_STREAMS_FRAME:
+      set_detailed_error(
+          "Attempt to append MAX_STREAMS frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case STREAMS_BLOCKED_FRAME:
+      set_detailed_error(
+          "Attempt to append STREAMS_BLOCKED frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case PATH_RESPONSE_FRAME:
+      set_detailed_error(
+          "Attempt to append PATH_RESPONSE frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case PATH_CHALLENGE_FRAME:
+      set_detailed_error(
+          "Attempt to append PATH_CHALLENGE frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case STOP_SENDING_FRAME:
+      set_detailed_error(
+          "Attempt to append STOP_SENDING frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case MESSAGE_FRAME:
+      return true;
+
+    default:
+      type_byte = static_cast<uint8_t>(frame.type);
+      break;
+  }
+
+  return writer->WriteUInt8(type_byte);
+}
+
+bool QuicFramer::AppendIetfFrameType(const QuicFrame& frame,
+                                     bool last_frame_in_packet,
+                                     QuicDataWriter* writer) {
+  uint8_t type_byte = 0;
+  switch (frame.type) {
+    case PADDING_FRAME:
+      type_byte = IETF_PADDING;
+      break;
+    case RST_STREAM_FRAME:
+      type_byte = IETF_RST_STREAM;
+      break;
+    case CONNECTION_CLOSE_FRAME:
+      switch (frame.connection_close_frame->close_type) {
+        case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
+          type_byte = IETF_APPLICATION_CLOSE;
+          break;
+        case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
+          type_byte = IETF_CONNECTION_CLOSE;
+          break;
+        default:
+          set_detailed_error(absl::StrCat(
+              "Invalid QuicConnectionCloseFrame type: ",
+              static_cast<int>(frame.connection_close_frame->close_type)));
+          return RaiseError(QUIC_INTERNAL_ERROR);
+      }
+      break;
+    case GOAWAY_FRAME:
+      set_detailed_error(
+          "Attempt to create non-IETF QUIC GOAWAY frame in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case WINDOW_UPDATE_FRAME:
+      // Depending on whether there is a stream ID or not, will be either a
+      // MAX_STREAM_DATA frame or a MAX_DATA frame.
+      if (frame.window_update_frame.stream_id ==
+          QuicUtils::GetInvalidStreamId(transport_version())) {
+        type_byte = IETF_MAX_DATA;
+      } else {
+        type_byte = IETF_MAX_STREAM_DATA;
+      }
+      break;
+    case BLOCKED_FRAME:
+      if (frame.blocked_frame.stream_id ==
+          QuicUtils::GetInvalidStreamId(transport_version())) {
+        type_byte = IETF_DATA_BLOCKED;
+      } else {
+        type_byte = IETF_STREAM_DATA_BLOCKED;
+      }
+      break;
+    case STOP_WAITING_FRAME:
+      set_detailed_error(
+          "Attempt to append type byte of STOP WAITING frame in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case PING_FRAME:
+      type_byte = IETF_PING;
+      break;
+    case STREAM_FRAME:
+      type_byte =
+          GetStreamFrameTypeByte(frame.stream_frame, last_frame_in_packet);
+      break;
+    case ACK_FRAME:
+      // Do nothing here, AppendIetfAckFrameAndTypeByte() will put the type byte
+      // in the buffer.
+      return true;
+    case MTU_DISCOVERY_FRAME:
+      // The path MTU discovery frame is encoded as a PING frame on the wire.
+      type_byte = IETF_PING;
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      type_byte = IETF_NEW_CONNECTION_ID;
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      type_byte = IETF_RETIRE_CONNECTION_ID;
+      break;
+    case NEW_TOKEN_FRAME:
+      type_byte = IETF_NEW_TOKEN;
+      break;
+    case MAX_STREAMS_FRAME:
+      if (frame.max_streams_frame.unidirectional) {
+        type_byte = IETF_MAX_STREAMS_UNIDIRECTIONAL;
+      } else {
+        type_byte = IETF_MAX_STREAMS_BIDIRECTIONAL;
+      }
+      break;
+    case STREAMS_BLOCKED_FRAME:
+      if (frame.streams_blocked_frame.unidirectional) {
+        type_byte = IETF_STREAMS_BLOCKED_UNIDIRECTIONAL;
+      } else {
+        type_byte = IETF_STREAMS_BLOCKED_BIDIRECTIONAL;
+      }
+      break;
+    case PATH_RESPONSE_FRAME:
+      type_byte = IETF_PATH_RESPONSE;
+      break;
+    case PATH_CHALLENGE_FRAME:
+      type_byte = IETF_PATH_CHALLENGE;
+      break;
+    case STOP_SENDING_FRAME:
+      type_byte = IETF_STOP_SENDING;
+      break;
+    case MESSAGE_FRAME:
+      return true;
+    case CRYPTO_FRAME:
+      type_byte = IETF_CRYPTO;
+      break;
+    case HANDSHAKE_DONE_FRAME:
+      type_byte = IETF_HANDSHAKE_DONE;
+      break;
+    case ACK_FREQUENCY_FRAME:
+      type_byte = IETF_ACK_FREQUENCY;
+      break;
+    default:
+      QUIC_BUG(quic_bug_10850_75)
+          << "Attempt to generate a frame type for an unsupported value: "
+          << frame.type;
+      return false;
+  }
+  return writer->WriteVarInt62(type_byte);
+}
+
+// static
+bool QuicFramer::AppendPacketNumber(QuicPacketNumberLength packet_number_length,
+                                    QuicPacketNumber packet_number,
+                                    QuicDataWriter* writer) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  if (!IsValidPacketNumberLength(packet_number_length)) {
+    QUIC_BUG(quic_bug_10850_76)
+        << "Invalid packet_number_length: " << packet_number_length;
+    return false;
+  }
+  return writer->WriteBytesToUInt64(packet_number_length,
+                                    packet_number.ToUint64());
+}
+
+// static
+bool QuicFramer::AppendStreamId(size_t stream_id_length, QuicStreamId stream_id,
+                                QuicDataWriter* writer) {
+  if (stream_id_length == 0 || stream_id_length > 4) {
+    QUIC_BUG(quic_bug_10850_77)
+        << "Invalid stream_id_length: " << stream_id_length;
+    return false;
+  }
+  return writer->WriteBytesToUInt64(stream_id_length, stream_id);
+}
+
+// static
+bool QuicFramer::AppendStreamOffset(size_t offset_length,
+                                    QuicStreamOffset offset,
+                                    QuicDataWriter* writer) {
+  if (offset_length == 1 || offset_length > 8) {
+    QUIC_BUG(quic_bug_10850_78)
+        << "Invalid stream_offset_length: " << offset_length;
+    return false;
+  }
+
+  return writer->WriteBytesToUInt64(offset_length, offset);
+}
+
+// static
+bool QuicFramer::AppendAckBlock(uint8_t gap,
+                                QuicPacketNumberLength length_length,
+                                uint64_t length, QuicDataWriter* writer) {
+  if (length == 0) {
+    if (!IsValidPacketNumberLength(length_length)) {
+      QUIC_BUG(quic_bug_10850_79)
+          << "Invalid packet_number_length: " << length_length;
+      return false;
+    }
+    return writer->WriteUInt8(gap) &&
+           writer->WriteBytesToUInt64(length_length, length);
+  }
+  return writer->WriteUInt8(gap) &&
+         AppendPacketNumber(length_length, QuicPacketNumber(length), writer);
+}
+
+bool QuicFramer::AppendStreamFrame(const QuicStreamFrame& frame,
+                                   bool no_stream_frame_length,
+                                   QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return AppendIetfStreamFrame(frame, no_stream_frame_length, writer);
+  }
+  if (!AppendStreamId(GetStreamIdSize(frame.stream_id), frame.stream_id,
+                      writer)) {
+    QUIC_BUG(quic_bug_10850_80) << "Writing stream id size failed.";
+    return false;
+  }
+  if (!AppendStreamOffset(GetStreamOffsetSize(frame.offset), frame.offset,
+                          writer)) {
+    QUIC_BUG(quic_bug_10850_81) << "Writing offset size failed.";
+    return false;
+  }
+  if (!no_stream_frame_length) {
+    static_assert(
+        std::numeric_limits<decltype(frame.data_length)>::max() <=
+            std::numeric_limits<uint16_t>::max(),
+        "If frame.data_length can hold more than a uint16_t than we need to "
+        "check that frame.data_length <= std::numeric_limits<uint16_t>::max()");
+    if (!writer->WriteUInt16(static_cast<uint16_t>(frame.data_length))) {
+      QUIC_BUG(quic_bug_10850_82) << "Writing stream frame length failed";
+      return false;
+    }
+  }
+
+  if (data_producer_ != nullptr) {
+    QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
+    if (frame.data_length == 0) {
+      return true;
+    }
+    if (data_producer_->WriteStreamData(frame.stream_id, frame.offset,
+                                        frame.data_length,
+                                        writer) != WRITE_SUCCESS) {
+      QUIC_BUG(quic_bug_10850_83) << "Writing frame data failed.";
+      return false;
+    }
+    return true;
+  }
+
+  if (!writer->WriteBytes(frame.data_buffer, frame.data_length)) {
+    QUIC_BUG(quic_bug_10850_84) << "Writing frame data failed.";
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendNewTokenFrame(const QuicNewTokenFrame& frame,
+                                     QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.token.length()))) {
+    set_detailed_error("Writing token length failed.");
+    return false;
+  }
+  if (!writer->WriteBytes(frame.token.data(), frame.token.length())) {
+    set_detailed_error("Writing token buffer failed.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessNewTokenFrame(QuicDataReader* reader,
+                                      QuicNewTokenFrame* frame) {
+  uint64_t length;
+  if (!reader->ReadVarInt62(&length)) {
+    set_detailed_error("Unable to read new token length.");
+    return false;
+  }
+  if (length > kMaxNewTokenTokenLength) {
+    set_detailed_error("Token length larger than maximum.");
+    return false;
+  }
+
+  // TODO(ianswett): Don't use absl::string_view as an intermediary.
+  absl::string_view data;
+  if (!reader->ReadStringPiece(&data, length)) {
+    set_detailed_error("Unable to read new token data.");
+    return false;
+  }
+  frame->token = std::string(data);
+  return true;
+}
+
+// Add a new ietf-format stream frame.
+// Bits controlling whether there is a frame-length and frame-offset
+// are in the QuicStreamFrame.
+bool QuicFramer::AppendIetfStreamFrame(const QuicStreamFrame& frame,
+                                       bool last_frame_in_packet,
+                                       QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
+    set_detailed_error("Writing stream id failed.");
+    return false;
+  }
+
+  if (frame.offset != 0) {
+    if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.offset))) {
+      set_detailed_error("Writing data offset failed.");
+      return false;
+    }
+  }
+
+  if (!last_frame_in_packet) {
+    if (!writer->WriteVarInt62(frame.data_length)) {
+      set_detailed_error("Writing data length failed.");
+      return false;
+    }
+  }
+
+  if (frame.data_length == 0) {
+    return true;
+  }
+  if (data_producer_ == nullptr) {
+    if (!writer->WriteBytes(frame.data_buffer, frame.data_length)) {
+      set_detailed_error("Writing frame data failed.");
+      return false;
+    }
+  } else {
+    QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
+
+    if (data_producer_->WriteStreamData(frame.stream_id, frame.offset,
+                                        frame.data_length,
+                                        writer) != WRITE_SUCCESS) {
+      set_detailed_error("Writing frame data from producer failed.");
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::AppendCryptoFrame(const QuicCryptoFrame& frame,
+                                   QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.offset))) {
+    set_detailed_error("Writing data offset failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.data_length))) {
+    set_detailed_error("Writing data length failed.");
+    return false;
+  }
+  if (data_producer_ == nullptr) {
+    if (frame.data_buffer == nullptr ||
+        !writer->WriteBytes(frame.data_buffer, frame.data_length)) {
+      set_detailed_error("Writing frame data failed.");
+      return false;
+    }
+  } else {
+    QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
+    if (!data_producer_->WriteCryptoData(frame.level, frame.offset,
+                                         frame.data_length, writer)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
+                                         QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.sequence_number)) {
+    set_detailed_error("Writing sequence number failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(frame.packet_tolerance)) {
+    set_detailed_error("Writing packet tolerance failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(
+          static_cast<uint64_t>(frame.max_ack_delay.ToMicroseconds()))) {
+    set_detailed_error("Writing max_ack_delay_us failed.");
+    return false;
+  }
+  if (!writer->WriteUInt8(static_cast<uint8_t>(frame.ignore_order))) {
+    set_detailed_error("Writing ignore_order failed.");
+    return false;
+  }
+
+  return true;
+}
+
+void QuicFramer::set_version(const ParsedQuicVersion version) {
+  QUICHE_DCHECK(IsSupportedVersion(version))
+      << ParsedQuicVersionToString(version);
+  version_ = version;
+}
+
+bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
+                                           QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return AppendIetfAckFrameAndTypeByte(frame, writer);
+  }
+
+  const AckFrameInfo new_ack_info = GetAckFrameInfo(frame);
+  QuicPacketNumber largest_acked = LargestAcked(frame);
+  QuicPacketNumberLength largest_acked_length =
+      GetMinPacketNumberLength(largest_acked);
+  QuicPacketNumberLength ack_block_length =
+      GetMinPacketNumberLength(QuicPacketNumber(new_ack_info.max_block_length));
+  // Calculate available bytes for timestamps and ack blocks.
+  int32_t available_timestamp_and_ack_block_bytes =
+      writer->capacity() - writer->length() - ack_block_length -
+      GetMinAckFrameSize(version_.transport_version, frame,
+                         local_ack_delay_exponent_,
+                         UseIetfAckWithReceiveTimestamp(frame)) -
+      (new_ack_info.num_ack_blocks != 0 ? kNumberOfAckBlocksSize : 0);
+  QUICHE_DCHECK_LE(0, available_timestamp_and_ack_block_bytes);
+
+  uint8_t type_byte = 0;
+  SetBit(&type_byte, new_ack_info.num_ack_blocks != 0,
+         kQuicHasMultipleAckBlocksOffset);
+
+  SetBits(&type_byte, GetPacketNumberFlags(largest_acked_length),
+          kQuicSequenceNumberLengthNumBits, kLargestAckedOffset);
+
+  SetBits(&type_byte, GetPacketNumberFlags(ack_block_length),
+          kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset);
+
+  type_byte |= kQuicFrameTypeAckMask;
+
+  if (!writer->WriteUInt8(type_byte)) {
+    return false;
+  }
+
+  size_t max_num_ack_blocks = available_timestamp_and_ack_block_bytes /
+                              (ack_block_length + PACKET_1BYTE_PACKET_NUMBER);
+
+  // Number of ack blocks.
+  size_t num_ack_blocks =
+      std::min(new_ack_info.num_ack_blocks, max_num_ack_blocks);
+  if (num_ack_blocks > std::numeric_limits<uint8_t>::max()) {
+    num_ack_blocks = std::numeric_limits<uint8_t>::max();
+  }
+
+  // Largest acked.
+  if (!AppendPacketNumber(largest_acked_length, largest_acked, writer)) {
+    return false;
+  }
+
+  // Largest acked delta time.
+  uint64_t ack_delay_time_us = kUFloat16MaxValue;
+  if (!frame.ack_delay_time.IsInfinite()) {
+    QUICHE_DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
+    ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
+  }
+  if (!writer->WriteUFloat16(ack_delay_time_us)) {
+    return false;
+  }
+
+  if (num_ack_blocks > 0) {
+    if (!writer->WriteBytes(&num_ack_blocks, 1)) {
+      return false;
+    }
+  }
+
+  // First ack block length.
+  if (!AppendPacketNumber(ack_block_length,
+                          QuicPacketNumber(new_ack_info.first_block_length),
+                          writer)) {
+    return false;
+  }
+
+  // Ack blocks.
+  if (num_ack_blocks > 0) {
+    size_t num_ack_blocks_written = 0;
+    // Append, in descending order from the largest ACKed packet, a series of
+    // ACK blocks that represents the successfully acknoweldged packets. Each
+    // appended gap/block length represents a descending delta from the previous
+    // block. i.e.:
+    // |--- length ---|--- gap ---|--- length ---|--- gap ---|--- largest ---|
+    // For gaps larger than can be represented by a single encoded gap, a 0
+    // length gap of the maximum is used, i.e.:
+    // |--- length ---|--- gap ---|- 0 -|--- gap ---|--- largest ---|
+    auto itr = frame.packets.rbegin();
+    QuicPacketNumber previous_start = itr->min();
+    ++itr;
+
+    for (;
+         itr != frame.packets.rend() && num_ack_blocks_written < num_ack_blocks;
+         previous_start = itr->min(), ++itr) {
+      const auto& interval = *itr;
+      const uint64_t total_gap = previous_start - interval.max();
+      const size_t num_encoded_gaps =
+          (total_gap + std::numeric_limits<uint8_t>::max() - 1) /
+          std::numeric_limits<uint8_t>::max();
+
+      // Append empty ACK blocks because the gap is longer than a single gap.
+      for (size_t i = 1;
+           i < num_encoded_gaps && num_ack_blocks_written < num_ack_blocks;
+           ++i) {
+        if (!AppendAckBlock(std::numeric_limits<uint8_t>::max(),
+                            ack_block_length, 0, writer)) {
+          return false;
+        }
+        ++num_ack_blocks_written;
+      }
+      if (num_ack_blocks_written >= num_ack_blocks) {
+        if (QUIC_PREDICT_FALSE(num_ack_blocks_written != num_ack_blocks)) {
+          QUIC_BUG(quic_bug_10850_85)
+              << "Wrote " << num_ack_blocks_written << ", expected to write "
+              << num_ack_blocks;
+        }
+        break;
+      }
+
+      const uint8_t last_gap =
+          total_gap -
+          (num_encoded_gaps - 1) * std::numeric_limits<uint8_t>::max();
+      // Append the final ACK block with a non-empty size.
+      if (!AppendAckBlock(last_gap, ack_block_length, interval.Length(),
+                          writer)) {
+        return false;
+      }
+      ++num_ack_blocks_written;
+    }
+    QUICHE_DCHECK_EQ(num_ack_blocks, num_ack_blocks_written);
+  }
+  // Timestamps.
+  // If we don't process timestamps or if we don't have enough available space
+  // to append all the timestamps, don't append any of them.
+  if (process_timestamps_ && writer->capacity() - writer->length() >=
+                                 GetAckFrameTimeStampSize(frame)) {
+    if (!AppendTimestampsToAckFrame(frame, writer)) {
+      return false;
+    }
+  } else {
+    uint8_t num_received_packets = 0;
+    if (!writer->WriteBytes(&num_received_packets, 1)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendTimestampsToAckFrame(const QuicAckFrame& frame,
+                                            QuicDataWriter* writer) {
+  QUICHE_DCHECK_GE(std::numeric_limits<uint8_t>::max(),
+                   frame.received_packet_times.size());
+  // num_received_packets is only 1 byte.
+  if (frame.received_packet_times.size() >
+      std::numeric_limits<uint8_t>::max()) {
+    return false;
+  }
+
+  uint8_t num_received_packets = frame.received_packet_times.size();
+  if (!writer->WriteBytes(&num_received_packets, 1)) {
+    return false;
+  }
+  if (num_received_packets == 0) {
+    return true;
+  }
+
+  auto it = frame.received_packet_times.begin();
+  QuicPacketNumber packet_number = it->first;
+  uint64_t delta_from_largest_observed = LargestAcked(frame) - packet_number;
+
+  QUICHE_DCHECK_GE(std::numeric_limits<uint8_t>::max(),
+                   delta_from_largest_observed);
+  if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) {
+    return false;
+  }
+
+  if (!writer->WriteUInt8(delta_from_largest_observed)) {
+    return false;
+  }
+
+  // Use the lowest 4 bytes of the time delta from the creation_time_.
+  const uint64_t time_epoch_delta_us = UINT64_C(1) << 32;
+  uint32_t time_delta_us =
+      static_cast<uint32_t>((it->second - creation_time_).ToMicroseconds() &
+                            (time_epoch_delta_us - 1));
+  if (!writer->WriteUInt32(time_delta_us)) {
+    return false;
+  }
+
+  QuicTime prev_time = it->second;
+
+  for (++it; it != frame.received_packet_times.end(); ++it) {
+    packet_number = it->first;
+    delta_from_largest_observed = LargestAcked(frame) - packet_number;
+
+    if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) {
+      return false;
+    }
+
+    if (!writer->WriteUInt8(delta_from_largest_observed)) {
+      return false;
+    }
+
+    uint64_t frame_time_delta_us = (it->second - prev_time).ToMicroseconds();
+    prev_time = it->second;
+    if (!writer->WriteUFloat16(frame_time_delta_us)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+absl::InlinedVector<QuicFramer::AckTimestampRange, 2>
+QuicFramer::GetAckTimestampRanges(const QuicAckFrame& frame,
+                                  std::string& detailed_error) const {
+  detailed_error = "";
+  if (frame.received_packet_times.empty()) {
+    return {};
+  }
+
+  absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges;
+
+  for (size_t r = 0; r < std::min<size_t>(max_receive_timestamps_per_ack_,
+                                          frame.received_packet_times.size());
+       ++r) {
+    const size_t i = frame.received_packet_times.size() - 1 - r;
+    const QuicPacketNumber packet_number = frame.received_packet_times[i].first;
+    const QuicTime receive_timestamp = frame.received_packet_times[i].second;
+
+    if (timestamp_ranges.empty()) {
+      if (receive_timestamp < creation_time_ ||
+          LargestAcked(frame) < packet_number) {
+        detailed_error =
+            "The first packet is either received earlier than framer creation "
+            "time, or larger than largest acked packet.";
+        QUIC_BUG(quic_framer_ack_ts_first_packet_bad)
+            << detailed_error << " receive_timestamp:" << receive_timestamp
+            << ", framer_creation_time:" << creation_time_
+            << ", packet_number:" << packet_number
+            << ", largest_acked:" << LargestAcked(frame);
+        return {};
+      }
+      timestamp_ranges.push_back(AckTimestampRange());
+      timestamp_ranges.back().gap = LargestAcked(frame) - packet_number;
+      timestamp_ranges.back().range_begin = i;
+      timestamp_ranges.back().range_end = i;
+      continue;
+    }
+
+    const size_t prev_i = timestamp_ranges.back().range_end;
+    const QuicPacketNumber prev_packet_number =
+        frame.received_packet_times[prev_i].first;
+    const QuicTime prev_receive_timestamp =
+        frame.received_packet_times[prev_i].second;
+
+    QUIC_DVLOG(3) << "prev_packet_number:" << prev_packet_number
+                  << ", packet_number:" << packet_number;
+    if (prev_receive_timestamp < receive_timestamp ||
+        prev_packet_number <= packet_number) {
+      detailed_error = "Packet number and/or receive time not in order.";
+      QUIC_BUG(quic_framer_ack_ts_packet_out_of_order)
+          << detailed_error << " packet_number:" << packet_number
+          << ", receive_timestamp:" << receive_timestamp
+          << ", prev_packet_number:" << prev_packet_number
+          << ", prev_receive_timestamp:" << prev_receive_timestamp;
+      return {};
+    }
+
+    if (prev_packet_number == packet_number + 1) {
+      timestamp_ranges.back().range_end = i;
+    } else {
+      timestamp_ranges.push_back(AckTimestampRange());
+      timestamp_ranges.back().gap = prev_packet_number - 2 - packet_number;
+      timestamp_ranges.back().range_begin = i;
+      timestamp_ranges.back().range_end = i;
+    }
+  }
+
+  return timestamp_ranges;
+}
+
+int64_t QuicFramer::FrameAckTimestampRanges(
+    const QuicAckFrame& frame,
+    const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
+    QuicDataWriter* writer) const {
+  int64_t size = 0;
+  auto maybe_write_var_int62 = [&](uint64_t value) {
+    size += QuicDataWriter::GetVarInt62Len(value);
+    if (writer != nullptr && !writer->WriteVarInt62(value)) {
+      return false;
+    }
+    return true;
+  };
+
+  if (!maybe_write_var_int62(timestamp_ranges.size())) {
+    return -1;
+  }
+
+  // |effective_prev_time| is the exponent-encoded timestamp of the previous
+  // packet.
+  absl::optional<QuicTime> effective_prev_time;
+  for (const AckTimestampRange& range : timestamp_ranges) {
+    QUIC_DVLOG(3) << "Range: gap:" << range.gap << ", beg:" << range.range_begin
+                  << ", end:" << range.range_end;
+    if (!maybe_write_var_int62(range.gap)) {
+      return -1;
+    }
+
+    if (!maybe_write_var_int62(range.range_begin - range.range_end + 1)) {
+      return -1;
+    }
+
+    for (int64_t i = range.range_begin; i >= range.range_end; --i) {
+      const QuicTime receive_timestamp = frame.received_packet_times[i].second;
+      uint64_t time_delta;
+      if (effective_prev_time.has_value()) {
+        time_delta =
+            (*effective_prev_time - receive_timestamp).ToMicroseconds();
+        QUIC_DVLOG(3) << "time_delta:" << time_delta
+                      << ", exponent:" << receive_timestamps_exponent_
+                      << ", effective_prev_time:" << *effective_prev_time
+                      << ", recv_time:" << receive_timestamp;
+        time_delta = time_delta >> receive_timestamps_exponent_;
+        effective_prev_time = effective_prev_time.value() -
+                              QuicTime::Delta::FromMicroseconds(
+                                  time_delta << receive_timestamps_exponent_);
+      } else {
+        // The first delta is from framer creation to the current receive
+        // timestamp (forward in time), whereas in the common case subsequent
+        // deltas move backwards in time.
+        time_delta = (receive_timestamp - creation_time_).ToMicroseconds();
+        QUIC_DVLOG(3) << "First time_delta:" << time_delta
+                      << ", exponent:" << receive_timestamps_exponent_
+                      << ", recv_time:" << receive_timestamp
+                      << ", creation_time:" << creation_time_;
+        // Round up the first exponent-encoded time delta so that the next
+        // receive timestamp is guaranteed to be decreasing.
+        time_delta = ((time_delta - 1) >> receive_timestamps_exponent_) + 1;
+        effective_prev_time =
+            creation_time_ + QuicTime::Delta::FromMicroseconds(
+                                 time_delta << receive_timestamps_exponent_);
+      }
+
+      if (!maybe_write_var_int62(time_delta)) {
+        return -1;
+      }
+    }
+  }
+
+  return size;
+}
+
+bool QuicFramer::AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
+                                                QuicDataWriter* writer) {
+  QUICHE_DCHECK(!frame.received_packet_times.empty());
+  std::string detailed_error;
+  const absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
+      GetAckTimestampRanges(frame, detailed_error);
+  if (!detailed_error.empty()) {
+    set_detailed_error(std::move(detailed_error));
+    return false;
+  }
+
+  // Compute the size first using a null writer.
+  int64_t size =
+      FrameAckTimestampRanges(frame, timestamp_ranges, /*writer=*/nullptr);
+  if (size > static_cast<int64_t>(writer->capacity() - writer->length())) {
+    QUIC_DVLOG(1) << "Insufficient room to write IETF ack receive timestamps. "
+                     "size_remain:"
+                  << (writer->capacity() - writer->length())
+                  << ", size_needed:" << size;
+    // Write a Timestamp Range Count of 0.
+    return writer->WriteVarInt62(0);
+  }
+
+  return FrameAckTimestampRanges(frame, timestamp_ranges, writer) > 0;
+}
+
+bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
+                                        const QuicStopWaitingFrame& frame,
+                                        QuicDataWriter* writer) {
+  QUICHE_DCHECK(!version_.HasIetfInvariantHeader());
+  QUICHE_DCHECK(frame.least_unacked.IsInitialized());
+  QUICHE_DCHECK_GE(header.packet_number, frame.least_unacked);
+  const uint64_t least_unacked_delta =
+      header.packet_number - frame.least_unacked;
+  const uint64_t length_shift = header.packet_number_length * 8;
+
+  if (least_unacked_delta >> length_shift > 0) {
+    QUIC_BUG(quic_bug_10850_86)
+        << "packet_number_length " << header.packet_number_length
+        << " is too small for least_unacked_delta: " << least_unacked_delta
+        << " packet_number:" << header.packet_number
+        << " least_unacked:" << frame.least_unacked
+        << " version:" << version_.transport_version;
+    return false;
+  }
+  if (least_unacked_delta == 0) {
+    return writer->WriteBytesToUInt64(header.packet_number_length,
+                                      least_unacked_delta);
+  }
+  if (!AppendPacketNumber(header.packet_number_length,
+                          QuicPacketNumber(least_unacked_delta), writer)) {
+    QUIC_BUG(quic_bug_10850_87)
+        << " seq failed: " << header.packet_number_length;
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
+                                               QuicDataWriter* writer) {
+  uint8_t type = IETF_ACK;
+  uint64_t ecn_size = 0;
+  if (UseIetfAckWithReceiveTimestamp(frame)) {
+    type = IETF_ACK_RECEIVE_TIMESTAMPS;
+  } else if (frame.ecn_counters_populated &&
+             (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
+    // Change frame type to ACK_ECN if any ECN count is available.
+    type = IETF_ACK_ECN;
+    ecn_size = (QuicDataWriter::GetVarInt62Len(frame.ect_0_count) +
+                QuicDataWriter::GetVarInt62Len(frame.ect_1_count) +
+                QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count));
+  }
+
+  if (!writer->WriteVarInt62(type)) {
+    set_detailed_error("No room for frame-type");
+    return false;
+  }
+
+  QuicPacketNumber largest_acked = LargestAcked(frame);
+  if (!writer->WriteVarInt62(largest_acked.ToUint64())) {
+    set_detailed_error("No room for largest-acked in ack frame");
+    return false;
+  }
+
+  uint64_t ack_delay_time_us = kVarInt62MaxValue;
+  if (!frame.ack_delay_time.IsInfinite()) {
+    QUICHE_DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
+    ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
+    ack_delay_time_us = ack_delay_time_us >> local_ack_delay_exponent_;
+  }
+
+  if (!writer->WriteVarInt62(ack_delay_time_us)) {
+    set_detailed_error("No room for ack-delay in ack frame");
+    return false;
+  }
+
+  if (frame.packets.Empty() || frame.packets.Max() != largest_acked) {
+    QUIC_BUG(quic_bug_10850_88) << "Malformed ack frame: " << frame;
+    set_detailed_error("Malformed ack frame");
+    return false;
+  }
+
+  // Latch ack_block_count for potential truncation.
+  const uint64_t ack_block_count = frame.packets.NumIntervals() - 1;
+  QuicDataWriter count_writer(QuicDataWriter::GetVarInt62Len(ack_block_count),
+                              writer->data() + writer->length());
+  if (!writer->WriteVarInt62(ack_block_count)) {
+    set_detailed_error("No room for ack block count in ack frame");
+    return false;
+  }
+  auto iter = frame.packets.rbegin();
+  if (!writer->WriteVarInt62(iter->Length() - 1)) {
+    set_detailed_error("No room for first ack block in ack frame");
+    return false;
+  }
+  QuicPacketNumber previous_smallest = iter->min();
+  ++iter;
+  // Append remaining ACK blocks.
+  uint64_t appended_ack_blocks = 0;
+  for (; iter != frame.packets.rend(); ++iter) {
+    const uint64_t gap = previous_smallest - iter->max() - 1;
+    const uint64_t ack_range = iter->Length() - 1;
+
+    if (type == IETF_ACK_RECEIVE_TIMESTAMPS &&
+        writer->remaining() <
+            static_cast<size_t>(QuicDataWriter::GetVarInt62Len(gap) +
+                                QuicDataWriter::GetVarInt62Len(ack_range) +
+                                QuicDataWriter::GetVarInt62Len(0))) {
+      // If we write this ACK range we won't have space for a timestamp range
+      // count of 0.
+      break;
+    } else if (writer->remaining() < ecn_size ||
+               writer->remaining() - ecn_size <
+                   static_cast<size_t>(
+                       QuicDataWriter::GetVarInt62Len(gap) +
+                       QuicDataWriter::GetVarInt62Len(ack_range))) {
+      // ACK range does not fit, truncate it.
+      break;
+    }
+    const bool success =
+        writer->WriteVarInt62(gap) && writer->WriteVarInt62(ack_range);
+    QUICHE_DCHECK(success);
+    previous_smallest = iter->min();
+    ++appended_ack_blocks;
+  }
+
+  if (appended_ack_blocks < ack_block_count) {
+    // Truncation is needed, rewrite the ack block count.
+    if (QuicDataWriter::GetVarInt62Len(appended_ack_blocks) !=
+            QuicDataWriter::GetVarInt62Len(ack_block_count) ||
+        !count_writer.WriteVarInt62(appended_ack_blocks)) {
+      // This should never happen as ack_block_count is limited by
+      // max_ack_ranges_.
+      QUIC_BUG(quic_bug_10850_89)
+          << "Ack frame truncation fails. ack_block_count: " << ack_block_count
+          << ", appended count: " << appended_ack_blocks;
+      set_detailed_error("ACK frame truncation fails");
+      return false;
+    }
+    QUIC_DLOG(INFO) << ENDPOINT << "ACK ranges get truncated from "
+                    << ack_block_count << " to " << appended_ack_blocks;
+  }
+
+  if (type == IETF_ACK_ECN) {
+    // Encode the ECN counts.
+    if (!writer->WriteVarInt62(frame.ect_0_count)) {
+      set_detailed_error("No room for ect_0_count in ack frame");
+      return false;
+    }
+    if (!writer->WriteVarInt62(frame.ect_1_count)) {
+      set_detailed_error("No room for ect_1_count in ack frame");
+      return false;
+    }
+    if (!writer->WriteVarInt62(frame.ecn_ce_count)) {
+      set_detailed_error("No room for ecn_ce_count in ack frame");
+      return false;
+    }
+  }
+
+  if (type == IETF_ACK_RECEIVE_TIMESTAMPS) {
+    if (!AppendIetfTimestampsToAckFrame(frame, writer)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendRstStreamFrame(const QuicRstStreamFrame& frame,
+                                      QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return AppendIetfResetStreamFrame(frame, writer);
+  }
+  if (!writer->WriteUInt32(frame.stream_id)) {
+    return false;
+  }
+
+  if (!writer->WriteUInt64(frame.byte_offset)) {
+    return false;
+  }
+
+  uint32_t error_code = static_cast<uint32_t>(frame.error_code);
+  if (!writer->WriteUInt32(error_code)) {
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendConnectionCloseFrame(
+    const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return AppendIetfConnectionCloseFrame(frame, writer);
+  }
+  uint32_t error_code = static_cast<uint32_t>(frame.wire_error_code);
+  if (!writer->WriteUInt32(error_code)) {
+    return false;
+  }
+  if (!writer->WriteStringPiece16(TruncateErrorString(frame.error_details))) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendGoAwayFrame(const QuicGoAwayFrame& frame,
+                                   QuicDataWriter* writer) {
+  uint32_t error_code = static_cast<uint32_t>(frame.error_code);
+  if (!writer->WriteUInt32(error_code)) {
+    return false;
+  }
+  uint32_t stream_id = static_cast<uint32_t>(frame.last_good_stream_id);
+  if (!writer->WriteUInt32(stream_id)) {
+    return false;
+  }
+  if (!writer->WriteStringPiece16(TruncateErrorString(frame.reason_phrase))) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
+                                         QuicDataWriter* writer) {
+  uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
+  if (!writer->WriteUInt32(stream_id)) {
+    return false;
+  }
+  if (!writer->WriteUInt64(frame.max_data)) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendBlockedFrame(const QuicBlockedFrame& frame,
+                                    QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    if (frame.stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+      return AppendDataBlockedFrame(frame, writer);
+    }
+    return AppendStreamDataBlockedFrame(frame, writer);
+  }
+  uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
+  if (!writer->WriteUInt32(stream_id)) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendPaddingFrame(const QuicPaddingFrame& frame,
+                                    QuicDataWriter* writer) {
+  if (frame.num_padding_bytes == 0) {
+    return false;
+  }
+  if (frame.num_padding_bytes < 0) {
+    QUIC_BUG_IF(quic_bug_12975_9, frame.num_padding_bytes != -1);
+    writer->WritePadding();
+    return true;
+  }
+  // Please note, num_padding_bytes includes type byte which has been written.
+  return writer->WritePaddingBytes(frame.num_padding_bytes - 1);
+}
+
+bool QuicFramer::AppendMessageFrameAndTypeByte(const QuicMessageFrame& frame,
+                                               bool last_frame_in_packet,
+                                               QuicDataWriter* writer) {
+  uint8_t type_byte;
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    type_byte = last_frame_in_packet ? IETF_EXTENSION_MESSAGE_NO_LENGTH_V99
+                                     : IETF_EXTENSION_MESSAGE_V99;
+  } else {
+    type_byte = last_frame_in_packet ? IETF_EXTENSION_MESSAGE_NO_LENGTH
+                                     : IETF_EXTENSION_MESSAGE;
+  }
+  if (!writer->WriteUInt8(type_byte)) {
+    return false;
+  }
+  if (!last_frame_in_packet && !writer->WriteVarInt62(frame.message_length)) {
+    return false;
+  }
+  for (const auto& slice : frame.message_data) {
+    if (!writer->WriteBytes(slice.data(), slice.length())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::RaiseError(QuicErrorCode error) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Error: " << QuicErrorCodeToString(error)
+                  << " detail: " << detailed_error_;
+  set_error(error);
+  if (visitor_) {
+    visitor_->OnError(this);
+  }
+  return false;
+}
+
+bool QuicFramer::IsVersionNegotiation(
+    const QuicPacketHeader& header, bool packet_has_ietf_packet_header) const {
+  if (!packet_has_ietf_packet_header &&
+      perspective_ == Perspective::IS_CLIENT) {
+    return header.version_flag;
+  }
+  if (header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+    return false;
+  }
+  return header.long_packet_type == VERSION_NEGOTIATION;
+}
+
+bool QuicFramer::AppendIetfConnectionCloseFrame(
+    const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
+  if (frame.close_type != IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
+      frame.close_type != IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
+    QUIC_BUG(quic_bug_10850_90)
+        << "Invalid close_type for writing IETF CONNECTION CLOSE.";
+    set_detailed_error("Invalid close_type for writing IETF CONNECTION CLOSE.");
+    return false;
+  }
+
+  if (!writer->WriteVarInt62(frame.wire_error_code)) {
+    set_detailed_error("Can not write connection close frame error code");
+    return false;
+  }
+
+  if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+    // Write the frame-type of the frame causing the error only
+    // if it's a CONNECTION_CLOSE/Transport.
+    if (!writer->WriteVarInt62(frame.transport_close_frame_type)) {
+      set_detailed_error("Writing frame type failed.");
+      return false;
+    }
+  }
+
+  // There may be additional error information available in the extracted error
+  // code. Encode the error information in the reason phrase and serialize the
+  // result.
+  std::string final_error_string =
+      GenerateErrorString(frame.error_details, frame.quic_error_code);
+  if (!writer->WriteStringPieceVarInt62(
+          TruncateErrorString(final_error_string))) {
+    set_detailed_error("Can not write connection close phrase");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfConnectionCloseFrame(
+    QuicDataReader* reader, QuicConnectionCloseType type,
+    QuicConnectionCloseFrame* frame) {
+  frame->close_type = type;
+
+  uint64_t error_code;
+  if (!reader->ReadVarInt62(&error_code)) {
+    set_detailed_error("Unable to read connection close error code.");
+    return false;
+  }
+
+  frame->wire_error_code = error_code;
+
+  if (type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+    // The frame-type of the frame causing the error is present only
+    // if it's a CONNECTION_CLOSE/Transport.
+    if (!reader->ReadVarInt62(&frame->transport_close_frame_type)) {
+      set_detailed_error("Unable to read connection close frame type.");
+      return false;
+    }
+  }
+
+  uint64_t phrase_length;
+  if (!reader->ReadVarInt62(&phrase_length)) {
+    set_detailed_error("Unable to read connection close error details.");
+    return false;
+  }
+
+  absl::string_view phrase;
+  if (!reader->ReadStringPiece(&phrase, static_cast<size_t>(phrase_length))) {
+    set_detailed_error("Unable to read connection close error details.");
+    return false;
+  }
+  frame->error_details = std::string(phrase);
+
+  // The frame may have an extracted error code in it. Look for it and
+  // extract it. If it's not present, MaybeExtract will return
+  // QUIC_IETF_GQUIC_ERROR_MISSING.
+  MaybeExtractQuicErrorCode(frame);
+  return true;
+}
+
+// IETF Quic Path Challenge/Response frames.
+bool QuicFramer::ProcessPathChallengeFrame(QuicDataReader* reader,
+                                           QuicPathChallengeFrame* frame) {
+  if (!reader->ReadBytes(frame->data_buffer.data(),
+                         frame->data_buffer.size())) {
+    set_detailed_error("Can not read path challenge data.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessPathResponseFrame(QuicDataReader* reader,
+                                          QuicPathResponseFrame* frame) {
+  if (!reader->ReadBytes(frame->data_buffer.data(),
+                         frame->data_buffer.size())) {
+    set_detailed_error("Can not read path response data.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendPathChallengeFrame(const QuicPathChallengeFrame& frame,
+                                          QuicDataWriter* writer) {
+  if (!writer->WriteBytes(frame.data_buffer.data(), frame.data_buffer.size())) {
+    set_detailed_error("Writing Path Challenge data failed.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendPathResponseFrame(const QuicPathResponseFrame& frame,
+                                         QuicDataWriter* writer) {
+  if (!writer->WriteBytes(frame.data_buffer.data(), frame.data_buffer.size())) {
+    set_detailed_error("Writing Path Response data failed.");
+    return false;
+  }
+  return true;
+}
+
+// Add a new ietf-format stream reset frame.
+// General format is
+//    stream id
+//    application error code
+//    final offset
+bool QuicFramer::AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
+                                            QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
+    set_detailed_error("Writing reset-stream stream id failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.ietf_error_code))) {
+    set_detailed_error("Writing reset-stream error code failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.byte_offset))) {
+    set_detailed_error("Writing reset-stream final-offset failed.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfResetStreamFrame(QuicDataReader* reader,
+                                             QuicRstStreamFrame* frame) {
+  // Get Stream ID from frame. ReadVarIntStreamID returns false
+  // if either A) there is a read error or B) the resulting value of
+  // the Stream ID is larger than the maximum allowed value.
+  if (!ReadUint32FromVarint62(reader, IETF_RST_STREAM, &frame->stream_id)) {
+    return false;
+  }
+
+  if (!reader->ReadVarInt62(&frame->ietf_error_code)) {
+    set_detailed_error("Unable to read rst stream error code.");
+    return false;
+  }
+
+  frame->error_code =
+      IetfResetStreamErrorCodeToRstStreamErrorCode(frame->ietf_error_code);
+
+  if (!reader->ReadVarInt62(&frame->byte_offset)) {
+    set_detailed_error("Unable to read rst stream sent byte offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessStopSendingFrame(
+    QuicDataReader* reader, QuicStopSendingFrame* stop_sending_frame) {
+  if (!ReadUint32FromVarint62(reader, IETF_STOP_SENDING,
+                              &stop_sending_frame->stream_id)) {
+    return false;
+  }
+
+  if (!reader->ReadVarInt62(&stop_sending_frame->ietf_error_code)) {
+    set_detailed_error("Unable to read stop sending application error code.");
+    return false;
+  }
+
+  stop_sending_frame->error_code = IetfResetStreamErrorCodeToRstStreamErrorCode(
+      stop_sending_frame->ietf_error_code);
+  return true;
+}
+
+bool QuicFramer::AppendStopSendingFrame(
+    const QuicStopSendingFrame& stop_sending_frame, QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(stop_sending_frame.stream_id)) {
+    set_detailed_error("Can not write stop sending stream id");
+    return false;
+  }
+  if (!writer->WriteVarInt62(
+          static_cast<uint64_t>(stop_sending_frame.ietf_error_code))) {
+    set_detailed_error("Can not write application error code");
+    return false;
+  }
+  return true;
+}
+
+// Append/process IETF-Format MAX_DATA Frame
+bool QuicFramer::AppendMaxDataFrame(const QuicWindowUpdateFrame& frame,
+                                    QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.max_data)) {
+    set_detailed_error("Can not write MAX_DATA byte-offset");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessMaxDataFrame(QuicDataReader* reader,
+                                     QuicWindowUpdateFrame* frame) {
+  frame->stream_id = QuicUtils::GetInvalidStreamId(transport_version());
+  if (!reader->ReadVarInt62(&frame->max_data)) {
+    set_detailed_error("Can not read MAX_DATA byte-offset");
+    return false;
+  }
+  return true;
+}
+
+// Append/process IETF-Format MAX_STREAM_DATA Frame
+bool QuicFramer::AppendMaxStreamDataFrame(const QuicWindowUpdateFrame& frame,
+                                          QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.stream_id)) {
+    set_detailed_error("Can not write MAX_STREAM_DATA stream id");
+    return false;
+  }
+  if (!writer->WriteVarInt62(frame.max_data)) {
+    set_detailed_error("Can not write MAX_STREAM_DATA byte-offset");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessMaxStreamDataFrame(QuicDataReader* reader,
+                                           QuicWindowUpdateFrame* frame) {
+  if (!ReadUint32FromVarint62(reader, IETF_MAX_STREAM_DATA,
+                              &frame->stream_id)) {
+    return false;
+  }
+  if (!reader->ReadVarInt62(&frame->max_data)) {
+    set_detailed_error("Can not read MAX_STREAM_DATA byte-count");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendMaxStreamsFrame(const QuicMaxStreamsFrame& frame,
+                                       QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.stream_count)) {
+    set_detailed_error("Can not write MAX_STREAMS stream count");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessMaxStreamsFrame(QuicDataReader* reader,
+                                        QuicMaxStreamsFrame* frame,
+                                        uint64_t frame_type) {
+  if (!ReadUint32FromVarint62(reader,
+                              static_cast<QuicIetfFrameType>(frame_type),
+                              &frame->stream_count)) {
+    return false;
+  }
+  frame->unidirectional = (frame_type == IETF_MAX_STREAMS_UNIDIRECTIONAL);
+  return true;
+}
+
+bool QuicFramer::AppendDataBlockedFrame(const QuicBlockedFrame& frame,
+                                        QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.offset)) {
+    set_detailed_error("Can not write blocked offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessDataBlockedFrame(QuicDataReader* reader,
+                                         QuicBlockedFrame* frame) {
+  // Indicates that it is a BLOCKED frame (as opposed to STREAM_BLOCKED).
+  frame->stream_id = QuicUtils::GetInvalidStreamId(transport_version());
+  if (!reader->ReadVarInt62(&frame->offset)) {
+    set_detailed_error("Can not read blocked offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendStreamDataBlockedFrame(const QuicBlockedFrame& frame,
+                                              QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.stream_id)) {
+    set_detailed_error("Can not write stream blocked stream id.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(frame.offset)) {
+    set_detailed_error("Can not write stream blocked offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessStreamDataBlockedFrame(QuicDataReader* reader,
+                                               QuicBlockedFrame* frame) {
+  if (!ReadUint32FromVarint62(reader, IETF_STREAM_DATA_BLOCKED,
+                              &frame->stream_id)) {
+    return false;
+  }
+  if (!reader->ReadVarInt62(&frame->offset)) {
+    set_detailed_error("Can not read stream blocked offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
+                                           QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.stream_count)) {
+    set_detailed_error("Can not write STREAMS_BLOCKED stream count");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessStreamsBlockedFrame(QuicDataReader* reader,
+                                            QuicStreamsBlockedFrame* frame,
+                                            uint64_t frame_type) {
+  if (!ReadUint32FromVarint62(reader,
+                              static_cast<QuicIetfFrameType>(frame_type),
+                              &frame->stream_count)) {
+    return false;
+  }
+  if (frame->stream_count > QuicUtils::GetMaxStreamCount()) {
+    // If stream count is such that the resulting stream ID would exceed our
+    // implementation limit, generate an error.
+    set_detailed_error(
+        "STREAMS_BLOCKED stream count exceeds implementation limit.");
+    return false;
+  }
+  frame->unidirectional = (frame_type == IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
+  return true;
+}
+
+bool QuicFramer::AppendNewConnectionIdFrame(
+    const QuicNewConnectionIdFrame& frame, QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.sequence_number)) {
+    set_detailed_error("Can not write New Connection ID sequence number");
+    return false;
+  }
+  if (!writer->WriteVarInt62(frame.retire_prior_to)) {
+    set_detailed_error("Can not write New Connection ID retire_prior_to");
+    return false;
+  }
+  if (!writer->WriteLengthPrefixedConnectionId(frame.connection_id)) {
+    set_detailed_error("Can not write New Connection ID frame connection ID");
+    return false;
+  }
+
+  if (!writer->WriteBytes(
+          static_cast<const void*>(&frame.stateless_reset_token),
+          sizeof(frame.stateless_reset_token))) {
+    set_detailed_error("Can not write New Connection ID Reset Token");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessNewConnectionIdFrame(QuicDataReader* reader,
+                                             QuicNewConnectionIdFrame* frame) {
+  if (!reader->ReadVarInt62(&frame->sequence_number)) {
+    set_detailed_error(
+        "Unable to read new connection ID frame sequence number.");
+    return false;
+  }
+
+  if (!reader->ReadVarInt62(&frame->retire_prior_to)) {
+    set_detailed_error(
+        "Unable to read new connection ID frame retire_prior_to.");
+    return false;
+  }
+  if (frame->retire_prior_to > frame->sequence_number) {
+    set_detailed_error("Retire_prior_to > sequence_number.");
+    return false;
+  }
+
+  if (!reader->ReadLengthPrefixedConnectionId(&frame->connection_id)) {
+    set_detailed_error("Unable to read new connection ID frame connection id.");
+    return false;
+  }
+
+  if (!QuicUtils::IsConnectionIdValidForVersion(frame->connection_id,
+                                                transport_version())) {
+    set_detailed_error("Invalid new connection ID length for version.");
+    return false;
+  }
+
+  if (!reader->ReadBytes(&frame->stateless_reset_token,
+                         sizeof(frame->stateless_reset_token))) {
+    set_detailed_error("Can not read new connection ID frame reset token.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendRetireConnectionIdFrame(
+    const QuicRetireConnectionIdFrame& frame, QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.sequence_number)) {
+    set_detailed_error("Can not write Retire Connection ID sequence number");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessRetireConnectionIdFrame(
+    QuicDataReader* reader, QuicRetireConnectionIdFrame* frame) {
+  if (!reader->ReadVarInt62(&frame->sequence_number)) {
+    set_detailed_error(
+        "Unable to read retire connection ID frame sequence number.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ReadUint32FromVarint62(QuicDataReader* reader,
+                                        QuicIetfFrameType type,
+                                        QuicStreamId* id) {
+  uint64_t temp_uint64;
+  if (!reader->ReadVarInt62(&temp_uint64)) {
+    set_detailed_error("Unable to read " + QuicIetfFrameTypeString(type) +
+                       " frame stream id/count.");
+    return false;
+  }
+  if (temp_uint64 > kMaxQuicStreamId) {
+    set_detailed_error("Stream id/count of " + QuicIetfFrameTypeString(type) +
+                       "frame is too large.");
+    return false;
+  }
+  *id = static_cast<uint32_t>(temp_uint64);
+  return true;
+}
+
+uint8_t QuicFramer::GetStreamFrameTypeByte(const QuicStreamFrame& frame,
+                                           bool last_frame_in_packet) const {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return GetIetfStreamFrameTypeByte(frame, last_frame_in_packet);
+  }
+  uint8_t type_byte = 0;
+  // Fin bit.
+  type_byte |= frame.fin ? kQuicStreamFinMask : 0;
+
+  // Data Length bit.
+  type_byte <<= kQuicStreamDataLengthShift;
+  type_byte |= last_frame_in_packet ? 0 : kQuicStreamDataLengthMask;
+
+  // Offset 3 bits.
+  type_byte <<= kQuicStreamShift;
+  const size_t offset_len = GetStreamOffsetSize(frame.offset);
+  if (offset_len > 0) {
+    type_byte |= offset_len - 1;
+  }
+
+  // stream id 2 bits.
+  type_byte <<= kQuicStreamIdShift;
+  type_byte |= GetStreamIdSize(frame.stream_id) - 1;
+  type_byte |= kQuicFrameTypeStreamMask;  // Set Stream Frame Type to 1.
+
+  return type_byte;
+}
+
+uint8_t QuicFramer::GetIetfStreamFrameTypeByte(
+    const QuicStreamFrame& frame, bool last_frame_in_packet) const {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
+  uint8_t type_byte = IETF_STREAM;
+  if (!last_frame_in_packet) {
+    type_byte |= IETF_STREAM_FRAME_LEN_BIT;
+  }
+  if (frame.offset != 0) {
+    type_byte |= IETF_STREAM_FRAME_OFF_BIT;
+  }
+  if (frame.fin) {
+    type_byte |= IETF_STREAM_FRAME_FIN_BIT;
+  }
+  return type_byte;
+}
+
+void QuicFramer::InferPacketHeaderTypeFromVersion() {
+  // This function should only be called when server connection negotiates the
+  // version.
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_SERVER);
+  QUICHE_DCHECK(!infer_packet_header_type_from_version_);
+  infer_packet_header_type_from_version_ = true;
+}
+
+void QuicFramer::EnableMultiplePacketNumberSpacesSupport() {
+  if (supports_multiple_packet_number_spaces_) {
+    QUIC_BUG(quic_bug_10850_91)
+        << "Multiple packet number spaces has already been enabled";
+    return;
+  }
+  if (largest_packet_number_.IsInitialized()) {
+    QUIC_BUG(quic_bug_10850_92)
+        << "Try to enable multiple packet number spaces support after any "
+           "packet has been received.";
+    return;
+  }
+
+  supports_multiple_packet_number_spaces_ = true;
+}
+
+// static
+QuicErrorCode QuicFramer::ParsePublicHeaderDispatcher(
+    const QuicEncryptedPacket& packet,
+    uint8_t expected_destination_connection_id_length,
+    PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
+    bool* version_present, bool* has_length_prefix,
+    QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
+    QuicConnectionId* destination_connection_id,
+    QuicConnectionId* source_connection_id,
+    absl::optional<absl::string_view>* retry_token,
+    std::string* detailed_error) {
+  QuicDataReader reader(packet.data(), packet.length());
+  if (reader.IsDoneReading()) {
+    *detailed_error = "Unable to read first byte.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+  const uint8_t first_byte = reader.PeekByte();
+  if ((first_byte & FLAGS_LONG_HEADER) == 0 &&
+      (first_byte & FLAGS_FIXED_BIT) == 0 &&
+      (first_byte & FLAGS_DEMULTIPLEXING_BIT) == 0) {
+    // All versions of Google QUIC up to and including Q043 set
+    // FLAGS_DEMULTIPLEXING_BIT to one on all client-to-server packets. Q044
+    // and Q045 were never default-enabled in production. All subsequent
+    // versions of Google QUIC (starting with Q046) require FLAGS_FIXED_BIT to
+    // be set to one on all packets. All versions of IETF QUIC (since
+    // draft-ietf-quic-transport-17 which was earlier than the first IETF QUIC
+    // version that was deployed in production by any implementation) also
+    // require FLAGS_FIXED_BIT to be set to one on all packets. If a packet
+    // has the FLAGS_LONG_HEADER bit set to one, it could be a first flight
+    // from an unknown future version that allows the other two bits to be set
+    // to zero. Based on this, packets that have all three of those bits set
+    // to zero are known to be invalid.
+    *detailed_error = "Invalid flags.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+  const bool ietf_format = QuicUtils::IsIetfPacketHeader(first_byte);
+  uint8_t unused_first_byte;
+  QuicVariableLengthIntegerLength retry_token_length_length;
+  absl::string_view maybe_retry_token;
+  QuicErrorCode error_code = ParsePublicHeader(
+      &reader, expected_destination_connection_id_length, ietf_format,
+      &unused_first_byte, format, version_present, has_length_prefix,
+      version_label, parsed_version, destination_connection_id,
+      source_connection_id, long_packet_type, &retry_token_length_length,
+      &maybe_retry_token, detailed_error);
+  if (retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+    *retry_token = maybe_retry_token;
+  } else {
+    retry_token->reset();
+  }
+  return error_code;
+}
+
+// static
+QuicErrorCode QuicFramer::ParsePublicHeaderGoogleQuic(
+    QuicDataReader* reader, uint8_t* first_byte, PacketHeaderFormat* format,
+    bool* version_present, QuicVersionLabel* version_label,
+    ParsedQuicVersion* parsed_version,
+    QuicConnectionId* destination_connection_id, std::string* detailed_error) {
+  *format = GOOGLE_QUIC_PACKET;
+  *version_present = (*first_byte & PACKET_PUBLIC_FLAGS_VERSION) != 0;
+  uint8_t destination_connection_id_length = 0;
+  if ((*first_byte & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) != 0) {
+    destination_connection_id_length = kQuicDefaultConnectionIdLength;
+  }
+  if (!reader->ReadConnectionId(destination_connection_id,
+                                destination_connection_id_length)) {
+    *detailed_error = "Unable to read ConnectionId.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+  if (*version_present) {
+    if (!ProcessVersionLabel(reader, version_label)) {
+      *detailed_error = "Unable to read protocol version.";
+      return QUIC_INVALID_PACKET_HEADER;
+    }
+    *parsed_version = ParseQuicVersionLabel(*version_label);
+  }
+  return QUIC_NO_ERROR;
+}
+
+namespace {
+
+const QuicVersionLabel kProxVersionLabel = 0x50524F58;  // "PROX"
+
+inline bool PacketHasLengthPrefixedConnectionIds(
+    const QuicDataReader& reader, ParsedQuicVersion parsed_version,
+    QuicVersionLabel version_label, uint8_t first_byte) {
+  if (parsed_version.IsKnown()) {
+    return parsed_version.HasLengthPrefixedConnectionIds();
+  }
+
+  // Received unsupported version, check known old unsupported versions.
+  if (QuicVersionLabelUses4BitConnectionIdLength(version_label)) {
+    return false;
+  }
+
+  // Received unknown version, check connection ID length byte.
+  if (reader.IsDoneReading()) {
+    // This check is required to safely peek the connection ID length byte.
+    return true;
+  }
+  const uint8_t connection_id_length_byte = reader.PeekByte();
+
+  // Check for packets produced by older versions of
+  // QuicFramer::WriteClientVersionNegotiationProbePacket
+  if (first_byte == 0xc0 && (connection_id_length_byte & 0x0f) == 0 &&
+      connection_id_length_byte >= 0x50 && version_label == 0xcabadaba) {
+    return false;
+  }
+
+  // Check for munged packets with version tag PROX.
+  if ((connection_id_length_byte & 0x0f) == 0 &&
+      connection_id_length_byte >= 0x20 && version_label == kProxVersionLabel) {
+    return false;
+  }
+
+  return true;
+}
+
+inline bool ParseLongHeaderConnectionIds(
+    QuicDataReader& reader, bool has_length_prefix,
+    QuicVersionLabel version_label, QuicConnectionId& destination_connection_id,
+    QuicConnectionId& source_connection_id, std::string& detailed_error) {
+  if (has_length_prefix) {
+    if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) {
+      detailed_error = "Unable to read destination connection ID.";
+      return false;
+    }
+    if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) {
+      if (version_label == kProxVersionLabel) {
+        // The "PROX" version does not follow the length-prefixed invariants,
+        // and can therefore attempt to read a payload byte and interpret it
+        // as the source connection ID length, which could fail to parse.
+        // In that scenario we keep the source connection ID empty but mark
+        // parsing as successful.
+        return true;
+      }
+      detailed_error = "Unable to read source connection ID.";
+      return false;
+    }
+  } else {
+    // Parse connection ID lengths.
+    uint8_t connection_id_lengths_byte;
+    if (!reader.ReadUInt8(&connection_id_lengths_byte)) {
+      detailed_error = "Unable to read connection ID lengths.";
+      return false;
+    }
+    uint8_t destination_connection_id_length =
+        (connection_id_lengths_byte & kDestinationConnectionIdLengthMask) >> 4;
+    if (destination_connection_id_length != 0) {
+      destination_connection_id_length += kConnectionIdLengthAdjustment;
+    }
+    uint8_t source_connection_id_length =
+        connection_id_lengths_byte & kSourceConnectionIdLengthMask;
+    if (source_connection_id_length != 0) {
+      source_connection_id_length += kConnectionIdLengthAdjustment;
+    }
+
+    // Read destination connection ID.
+    if (!reader.ReadConnectionId(&destination_connection_id,
+                                 destination_connection_id_length)) {
+      detailed_error = "Unable to read destination connection ID.";
+      return false;
+    }
+
+    // Read source connection ID.
+    if (!reader.ReadConnectionId(&source_connection_id,
+                                 source_connection_id_length)) {
+      detailed_error = "Unable to read source connection ID.";
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace
+
+// static
+QuicErrorCode QuicFramer::ParsePublicHeader(
+    QuicDataReader* reader, uint8_t expected_destination_connection_id_length,
+    bool ietf_format, uint8_t* first_byte, PacketHeaderFormat* format,
+    bool* version_present, bool* has_length_prefix,
+    QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
+    QuicConnectionId* destination_connection_id,
+    QuicConnectionId* source_connection_id,
+    QuicLongHeaderType* long_packet_type,
+    QuicVariableLengthIntegerLength* retry_token_length_length,
+    absl::string_view* retry_token, std::string* detailed_error) {
+  *version_present = false;
+  *has_length_prefix = false;
+  *version_label = 0;
+  *parsed_version = UnsupportedQuicVersion();
+  *source_connection_id = EmptyQuicConnectionId();
+  *long_packet_type = INVALID_PACKET_TYPE;
+  *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  *retry_token = absl::string_view();
+  *detailed_error = "";
+
+  if (!reader->ReadUInt8(first_byte)) {
+    *detailed_error = "Unable to read first byte.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  if (!ietf_format) {
+    return ParsePublicHeaderGoogleQuic(
+        reader, first_byte, format, version_present, version_label,
+        parsed_version, destination_connection_id, detailed_error);
+  }
+
+  *format = GetIetfPacketHeaderFormat(*first_byte);
+
+  if (*format == IETF_QUIC_SHORT_HEADER_PACKET) {
+    // Read destination connection ID using
+    // expected_destination_connection_id_length to determine its length.
+    if (!reader->ReadConnectionId(destination_connection_id,
+                                  expected_destination_connection_id_length)) {
+      *detailed_error = "Unable to read destination connection ID.";
+      return QUIC_INVALID_PACKET_HEADER;
+    }
+    return QUIC_NO_ERROR;
+  }
+
+  QUICHE_DCHECK_EQ(IETF_QUIC_LONG_HEADER_PACKET, *format);
+  *version_present = true;
+  if (!ProcessVersionLabel(reader, version_label)) {
+    *detailed_error = "Unable to read protocol version.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  if (*version_label == 0) {
+    *long_packet_type = VERSION_NEGOTIATION;
+  }
+
+  // Parse version.
+  *parsed_version = ParseQuicVersionLabel(*version_label);
+
+  // Figure out which IETF QUIC invariants this packet follows.
+  *has_length_prefix = PacketHasLengthPrefixedConnectionIds(
+      *reader, *parsed_version, *version_label, *first_byte);
+
+  // Parse connection IDs.
+  if (!ParseLongHeaderConnectionIds(*reader, *has_length_prefix, *version_label,
+                                    *destination_connection_id,
+                                    *source_connection_id, *detailed_error)) {
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  if (!parsed_version->IsKnown()) {
+    // Skip parsing of long packet type and retry token for unknown versions.
+    return QUIC_NO_ERROR;
+  }
+
+  // Parse long packet type.
+  *long_packet_type = GetLongHeaderType(*first_byte, *parsed_version);
+
+  switch (*long_packet_type) {
+    case INVALID_PACKET_TYPE:
+      *detailed_error = "Unable to parse long packet type.";
+      return QUIC_INVALID_PACKET_HEADER;
+    case INITIAL:
+      if (!parsed_version->SupportsRetry()) {
+        // Retry token is only present on initial packets for some versions.
+        return QUIC_NO_ERROR;
+      }
+      break;
+    default:
+      return QUIC_NO_ERROR;
+  }
+
+  *retry_token_length_length = reader->PeekVarInt62Length();
+  uint64_t retry_token_length;
+  if (!reader->ReadVarInt62(&retry_token_length)) {
+    *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+    *detailed_error = "Unable to read retry token length.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  if (!reader->ReadStringPiece(retry_token, retry_token_length)) {
+    *detailed_error = "Unable to read retry token.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+// static
+bool QuicFramer::WriteClientVersionNegotiationProbePacket(
+    char* packet_bytes, QuicByteCount packet_length,
+    const char* destination_connection_id_bytes,
+    uint8_t destination_connection_id_length) {
+  if (packet_bytes == nullptr) {
+    QUIC_BUG(quic_bug_10850_93) << "Invalid packet_bytes";
+    return false;
+  }
+  if (packet_length < kMinPacketSizeForVersionNegotiation ||
+      packet_length > 65535) {
+    QUIC_BUG(quic_bug_10850_94) << "Invalid packet_length";
+    return false;
+  }
+  if (destination_connection_id_length > kQuicMaxConnectionId4BitLength ||
+      destination_connection_id_length < kQuicDefaultConnectionIdLength) {
+    QUIC_BUG(quic_bug_10850_95) << "Invalid connection_id_length";
+    return false;
+  }
+  // clang-format off
+  const unsigned char packet_start_bytes[] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version, part of the IETF space reserved for negotiation.
+    // This intentionally differs from QuicVersionReservedForNegotiation()
+    // to allow differentiating them over the wire.
+    0xca, 0xba, 0xda, 0xda,
+  };
+  // clang-format on
+  static_assert(sizeof(packet_start_bytes) == 5, "bad packet_start_bytes size");
+  QuicDataWriter writer(packet_length, packet_bytes);
+  if (!writer.WriteBytes(packet_start_bytes, sizeof(packet_start_bytes))) {
+    QUIC_BUG(quic_bug_10850_96) << "Failed to write packet start";
+    return false;
+  }
+
+  QuicConnectionId destination_connection_id(destination_connection_id_bytes,
+                                             destination_connection_id_length);
+  if (!AppendIetfConnectionIds(
+          /*version_flag=*/true, /*use_length_prefix=*/true,
+          destination_connection_id, EmptyQuicConnectionId(), &writer)) {
+    QUIC_BUG(quic_bug_10850_97) << "Failed to write connection IDs";
+    return false;
+  }
+  // Add 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
+  // not parse with any known version. The zeroes make sure that packet numbers,
+  // retry token lengths and payload lengths are parsed as zero, and if the
+  // zeroes are treated as padding frames, 0xff is known to not parse as a
+  // valid frame type.
+  if (!writer.WriteUInt64(0) ||
+      !writer.WriteUInt64(std::numeric_limits<uint64_t>::max())) {
+    QUIC_BUG(quic_bug_10850_98) << "Failed to write 18 bytes";
+    return false;
+  }
+  // Make sure the polite greeting below is padded to a 16-byte boundary to
+  // make it easier to read in tcpdump.
+  while (writer.length() % 16 != 0) {
+    if (!writer.WriteUInt8(0)) {
+      QUIC_BUG(quic_bug_10850_99) << "Failed to write padding byte";
+      return false;
+    }
+  }
+  // Add a polite greeting in case a human sees this in tcpdump.
+  static const char polite_greeting[] =
+      "This packet only exists to trigger IETF QUIC version negotiation. "
+      "Please respond with a Version Negotiation packet indicating what "
+      "versions you support. Thank you and have a nice day.";
+  if (!writer.WriteBytes(polite_greeting, sizeof(polite_greeting))) {
+    QUIC_BUG(quic_bug_10850_100) << "Failed to write polite greeting";
+    return false;
+  }
+  // Fill the rest of the packet with zeroes.
+  writer.WritePadding();
+  QUICHE_DCHECK_EQ(0u, writer.remaining());
+  return true;
+}
+
+// static
+bool QuicFramer::ParseServerVersionNegotiationProbeResponse(
+    const char* packet_bytes, QuicByteCount packet_length,
+    char* source_connection_id_bytes, uint8_t* source_connection_id_length_out,
+    std::string* detailed_error) {
+  if (detailed_error == nullptr) {
+    QUIC_BUG(quic_bug_10850_101) << "Invalid error_details";
+    return false;
+  }
+  *detailed_error = "";
+  if (packet_bytes == nullptr) {
+    *detailed_error = "Invalid packet_bytes";
+    return false;
+  }
+  if (packet_length < 6) {
+    *detailed_error = "Invalid packet_length";
+    return false;
+  }
+  if (source_connection_id_bytes == nullptr) {
+    *detailed_error = "Invalid source_connection_id_bytes";
+    return false;
+  }
+  if (source_connection_id_length_out == nullptr) {
+    *detailed_error = "Invalid source_connection_id_length_out";
+    return false;
+  }
+  QuicDataReader reader(packet_bytes, packet_length);
+  uint8_t type_byte = 0;
+  if (!reader.ReadUInt8(&type_byte)) {
+    *detailed_error = "Failed to read type byte";
+    return false;
+  }
+  if ((type_byte & 0x80) == 0) {
+    *detailed_error = "Packet does not have long header";
+    return false;
+  }
+  uint32_t version = 0;
+  if (!reader.ReadUInt32(&version)) {
+    *detailed_error = "Failed to read version";
+    return false;
+  }
+  if (version != 0) {
+    *detailed_error = "Packet is not a version negotiation packet";
+    return false;
+  }
+
+  QuicConnectionId destination_connection_id, source_connection_id;
+  if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) {
+    *detailed_error = "Failed to read destination connection ID";
+    return false;
+  }
+  if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) {
+    *detailed_error = "Failed to read source connection ID";
+    return false;
+  }
+
+  if (destination_connection_id.length() != 0) {
+    *detailed_error = "Received unexpected destination connection ID length";
+    return false;
+  }
+  if (*source_connection_id_length_out < source_connection_id.length()) {
+    *detailed_error =
+        absl::StrCat("*source_connection_id_length_out too small ",
+                     static_cast<int>(*source_connection_id_length_out), " < ",
+                     static_cast<int>(source_connection_id.length()));
+    return false;
+  }
+
+  memcpy(source_connection_id_bytes, source_connection_id.data(),
+         source_connection_id.length());
+  *source_connection_id_length_out = source_connection_id.length();
+
+  return true;
+}
+
+// Look for and parse the error code from the "<quic_error_code>:" text that
+// may be present at the start of the CONNECTION_CLOSE error details string.
+// This text, inserted by the peer if it's using Google's QUIC implementation,
+// contains additional error information that narrows down the exact error.  If
+// the string is not found, or is not properly formed, it returns
+// ErrorCode::QUIC_IETF_GQUIC_ERROR_MISSING
+void MaybeExtractQuicErrorCode(QuicConnectionCloseFrame* frame) {
+  std::vector<absl::string_view> ed = absl::StrSplit(frame->error_details, ':');
+  uint64_t extracted_error_code;
+  if (ed.size() < 2 || !quiche::QuicheTextUtils::IsAllDigits(ed[0]) ||
+      !absl::SimpleAtoi(ed[0], &extracted_error_code)) {
+    if (frame->close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
+        frame->wire_error_code == NO_IETF_QUIC_ERROR) {
+      frame->quic_error_code = QUIC_NO_ERROR;
+    } else {
+      frame->quic_error_code = QUIC_IETF_GQUIC_ERROR_MISSING;
+    }
+    return;
+  }
+  // Return the error code (numeric) and the error details string without the
+  // error code prefix. Note that Split returns everything up to, but not
+  // including, the split character, so the length of ed[0] is just the number
+  // of digits in the error number. In removing the prefix, 1 is added to the
+  // length to account for the :
+  absl::string_view x = absl::string_view(frame->error_details);
+  x.remove_prefix(ed[0].length() + 1);
+  frame->error_details = std::string(x);
+  frame->quic_error_code = static_cast<QuicErrorCode>(extracted_error_code);
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_framer.h b/quiche/quic/core/quic_framer.h
new file mode 100644
index 0000000..de03169
--- /dev/null
+++ b/quiche/quic/core/quic_framer.h
@@ -0,0 +1,1265 @@
+// 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_FRAMER_H_
+#define QUICHE_QUIC_CORE_QUIC_FRAMER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicFramerPeer;
+}  // namespace test
+
+class QuicDataReader;
+class QuicDataWriter;
+class QuicFramer;
+class QuicStreamFrameDataProducer;
+
+// Number of bytes reserved for the frame type preceding each frame.
+const size_t kQuicFrameTypeSize = 1;
+// Number of bytes reserved for error code.
+const size_t kQuicErrorCodeSize = 4;
+// Number of bytes reserved to denote the length of error details field.
+const size_t kQuicErrorDetailsLengthSize = 2;
+
+// Maximum number of bytes reserved for stream id.
+const size_t kQuicMaxStreamIdSize = 4;
+// Maximum number of bytes reserved for byte offset in stream frame.
+const size_t kQuicMaxStreamOffsetSize = 8;
+// Number of bytes reserved to store payload length in stream frame.
+const size_t kQuicStreamPayloadLengthSize = 2;
+// Number of bytes to reserve for IQ Error codes (for the Connection Close,
+// Application Close, and Reset Stream frames).
+const size_t kQuicIetfQuicErrorCodeSize = 2;
+// Minimum size of the IETF QUIC Error Phrase's length field
+const size_t kIetfQuicMinErrorPhraseLengthSize = 1;
+
+// Size in bytes reserved for the delta time of the largest observed
+// packet number in ack frames.
+const size_t kQuicDeltaTimeLargestObservedSize = 2;
+// Size in bytes reserved for the number of received packets with timestamps.
+const size_t kQuicNumTimestampsSize = 1;
+// Size in bytes reserved for the number of missing packets in ack frames.
+const size_t kNumberOfNackRangesSize = 1;
+// Size in bytes reserved for the number of ack blocks in ack frames.
+const size_t kNumberOfAckBlocksSize = 1;
+// Maximum number of missing packet ranges that can fit within an ack frame.
+const size_t kMaxNackRanges = (1 << (kNumberOfNackRangesSize * 8)) - 1;
+// Maximum number of ack blocks that can fit within an ack frame.
+const size_t kMaxAckBlocks = (1 << (kNumberOfAckBlocksSize * 8)) - 1;
+
+// This class receives callbacks from the framer when packets
+// are processed.
+class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface {
+ public:
+  virtual ~QuicFramerVisitorInterface() {}
+
+  // Called if an error is detected in the QUIC protocol.
+  virtual void OnError(QuicFramer* framer) = 0;
+
+  // Called only when |perspective_| is IS_SERVER and the framer gets a
+  // packet with version flag true and the version on the packet doesn't match
+  // |quic_version_|. The visitor should return true after it updates the
+  // version of the |framer_| to |received_version| or false to stop processing
+  // this packet.
+  virtual bool OnProtocolVersionMismatch(
+      ParsedQuicVersion received_version) = 0;
+
+  // Called when a new packet has been received, before it
+  // has been validated or processed.
+  virtual void OnPacket() = 0;
+
+  // Called when a public reset packet has been parsed but has not yet
+  // been validated.
+  virtual void OnPublicResetPacket(const QuicPublicResetPacket& packet) = 0;
+
+  // Called only when |perspective_| is IS_CLIENT and a version negotiation
+  // packet has been parsed.
+  virtual void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& packet) = 0;
+
+  // Called only when |perspective_| is IS_CLIENT and a retry packet has been
+  // parsed. |new_connection_id| contains the value of the Source Connection
+  // ID field, and |retry_token| contains the value of the Retry Token field.
+  // On versions where UsesTls() is false,
+  // |original_connection_id| contains the value of the Original Destination
+  // Connection ID field, and both |retry_integrity_tag| and
+  // |retry_without_tag| are empty.
+  // On versions where UsesTls() is true,
+  // |original_connection_id| is empty, |retry_integrity_tag| contains the
+  // value of the Retry Integrity Tag field, and |retry_without_tag| contains
+  // the entire RETRY packet except the Retry Integrity Tag field.
+  virtual void OnRetryPacket(QuicConnectionId original_connection_id,
+                             QuicConnectionId new_connection_id,
+                             absl::string_view retry_token,
+                             absl::string_view retry_integrity_tag,
+                             absl::string_view retry_without_tag) = 0;
+
+  // Called when all fields except packet number has been parsed, but has not
+  // been authenticated. If it returns false, framing for this packet will
+  // cease.
+  virtual bool OnUnauthenticatedPublicHeader(
+      const QuicPacketHeader& header) = 0;
+
+  // Called when the unauthenticated portion of the header has been parsed.
+  // If OnUnauthenticatedHeader returns false, framing for this packet will
+  // cease.
+  virtual bool OnUnauthenticatedHeader(const QuicPacketHeader& header) = 0;
+
+  // Called when a packet has been decrypted. |length| is the packet length,
+  // and |level| is the encryption level of the packet.
+  virtual void OnDecryptedPacket(size_t length, EncryptionLevel level) = 0;
+
+  // Called when the complete header of a packet had been parsed.
+  // If OnPacketHeader returns false, framing for this packet will cease.
+  virtual bool OnPacketHeader(const QuicPacketHeader& header) = 0;
+
+  // Called when the packet being processed contains multiple IETF QUIC packets,
+  // which is due to there being more data after what is covered by the length
+  // field. |packet| contains the remaining data which can be processed.
+  // Note that this is called when the framer parses the length field, before
+  // it attempts to decrypt the first payload. It is the visitor's
+  // responsibility to buffer the packet and call ProcessPacket on it
+  // after the framer is done parsing the current payload. |packet| does not
+  // own its internal buffer, the visitor should make a copy of it.
+  virtual void OnCoalescedPacket(const QuicEncryptedPacket& packet) = 0;
+
+  // Called when the packet being processed failed to decrypt.
+  // |has_decryption_key| indicates whether the framer knew which decryption
+  // key to use for this packet and already had a suitable key.
+  virtual void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                                     EncryptionLevel decryption_level,
+                                     bool has_decryption_key) = 0;
+
+  // Called when a StreamFrame has been parsed.
+  virtual bool OnStreamFrame(const QuicStreamFrame& frame) = 0;
+
+  // Called when a CRYPTO frame has been parsed.
+  virtual bool OnCryptoFrame(const QuicCryptoFrame& frame) = 0;
+
+  // Called when largest acked of an AckFrame has been parsed.
+  virtual bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                               QuicTime::Delta ack_delay_time) = 0;
+
+  // Called when ack range [start, end) of an AckFrame has been parsed.
+  virtual bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) = 0;
+
+  // Called when a timestamp in the AckFrame has been parsed.
+  virtual bool OnAckTimestamp(QuicPacketNumber packet_number,
+                              QuicTime timestamp) = 0;
+
+  // Called after the last ack range in an AckFrame has been parsed.
+  // |start| is the starting value of the last ack range.
+  virtual bool OnAckFrameEnd(QuicPacketNumber start) = 0;
+
+  // Called when a StopWaitingFrame has been parsed.
+  virtual bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) = 0;
+
+  // Called when a QuicPaddingFrame has been parsed.
+  virtual bool OnPaddingFrame(const QuicPaddingFrame& frame) = 0;
+
+  // Called when a PingFrame has been parsed.
+  virtual bool OnPingFrame(const QuicPingFrame& frame) = 0;
+
+  // Called when a RstStreamFrame has been parsed.
+  virtual bool OnRstStreamFrame(const QuicRstStreamFrame& frame) = 0;
+
+  // Called when a ConnectionCloseFrame, of any type, has been parsed.
+  virtual bool OnConnectionCloseFrame(
+      const QuicConnectionCloseFrame& frame) = 0;
+
+  // Called when a StopSendingFrame has been parsed.
+  virtual bool OnStopSendingFrame(const QuicStopSendingFrame& frame) = 0;
+
+  // Called when a PathChallengeFrame has been parsed.
+  virtual bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) = 0;
+
+  // Called when a PathResponseFrame has been parsed.
+  virtual bool OnPathResponseFrame(const QuicPathResponseFrame& frame) = 0;
+
+  // Called when a GoAwayFrame has been parsed.
+  virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) = 0;
+
+  // Called when a WindowUpdateFrame has been parsed.
+  virtual bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) = 0;
+
+  // Called when a BlockedFrame has been parsed.
+  virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) = 0;
+
+  // Called when a NewConnectionIdFrame has been parsed.
+  virtual bool OnNewConnectionIdFrame(
+      const QuicNewConnectionIdFrame& frame) = 0;
+
+  // Called when a RetireConnectionIdFrame has been parsed.
+  virtual bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) = 0;
+
+  // Called when a NewTokenFrame has been parsed.
+  virtual bool OnNewTokenFrame(const QuicNewTokenFrame& frame) = 0;
+
+  // Called when a message frame has been parsed.
+  virtual bool OnMessageFrame(const QuicMessageFrame& frame) = 0;
+
+  // Called when a handshake done frame has been parsed.
+  virtual bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) = 0;
+
+  // Called when an AckFrequencyFrame has been parsed.
+  virtual bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) = 0;
+
+  // Called when a packet has been completely processed.
+  virtual void OnPacketComplete() = 0;
+
+  // Called to check whether |token| is a valid stateless reset token.
+  virtual bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const = 0;
+
+  // Called when an IETF stateless reset packet has been parsed and validated
+  // with the stateless reset token.
+  virtual void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& packet) = 0;
+
+  // Called when an IETF MaxStreams frame has been parsed.
+  virtual bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) = 0;
+
+  // Called when an IETF StreamsBlocked frame has been parsed.
+  virtual bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) = 0;
+
+  // Called when a Key Phase Update has been initiated. This is called for both
+  // locally and peer initiated key updates. If the key update was locally
+  // initiated, this does not indicate the peer has received the key update yet.
+  virtual void OnKeyUpdate(KeyUpdateReason reason) = 0;
+
+  // Called on the first decrypted packet in each key phase (including the
+  // first key phase.)
+  virtual void OnDecryptedFirstPacketInKeyPhase() = 0;
+
+  // Called when the framer needs to generate a decrypter for the next key
+  // phase. Each call should generate the key for phase n+1.
+  virtual std::unique_ptr<QuicDecrypter>
+  AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
+
+  // Called when the framer needs to generate an encrypter. The key corresponds
+  // to the key phase of the last decrypter returned by
+  // AdvanceKeysAndCreateCurrentOneRttDecrypter().
+  virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
+};
+
+// Class for parsing and constructing QUIC packets.  It has a
+// QuicFramerVisitorInterface that is called when packets are parsed.
+class QUIC_EXPORT_PRIVATE QuicFramer {
+ public:
+  // Constructs a new framer that installs a kNULL QuicEncrypter and
+  // QuicDecrypter for level ENCRYPTION_INITIAL. |supported_versions| specifies
+  // the list of supported QUIC versions. |quic_version_| is set to the maximum
+  // version in |supported_versions|.
+  QuicFramer(const ParsedQuicVersionVector& supported_versions,
+             QuicTime creation_time,
+             Perspective perspective,
+             uint8_t expected_server_connection_id_length);
+  QuicFramer(const QuicFramer&) = delete;
+  QuicFramer& operator=(const QuicFramer&) = delete;
+
+  virtual ~QuicFramer();
+
+  // Returns true if |version| is a supported transport version.
+  bool IsSupportedTransportVersion(const QuicTransportVersion version) const;
+
+  // Returns true if |version| is a supported protocol version.
+  bool IsSupportedVersion(const ParsedQuicVersion version) const;
+
+  // Set callbacks to be called from the framer.  A visitor must be set, or
+  // else the framer will likely crash.  It is acceptable for the visitor
+  // to do nothing.  If this is called multiple times, only the last visitor
+  // will be used.
+  void set_visitor(QuicFramerVisitorInterface* visitor) { visitor_ = visitor; }
+
+  const ParsedQuicVersionVector& supported_versions() const {
+    return supported_versions_;
+  }
+
+  QuicTransportVersion transport_version() const {
+    return version_.transport_version;
+  }
+
+  ParsedQuicVersion version() const { return version_; }
+
+  void set_version(const ParsedQuicVersion version);
+
+  // Does not QUICHE_DCHECK for supported version. Used by tests to set
+  // unsupported version to trigger version negotiation.
+  void set_version_for_tests(const ParsedQuicVersion version) {
+    version_ = version;
+  }
+
+  QuicErrorCode error() const { return error_; }
+
+  // Allows enabling or disabling of timestamp processing and serialization.
+  // TODO(ianswett): Remove the const once timestamps are negotiated via
+  // transport params.
+  void set_process_timestamps(bool process_timestamps) const {
+    process_timestamps_ = process_timestamps;
+  }
+
+  // Sets the max number of receive timestamps to send per ACK frame.
+  // TODO(wub): Remove the const once timestamps are negotiated via
+  // transport params.
+  void set_max_receive_timestamps_per_ack(uint32_t max_timestamps) const {
+    max_receive_timestamps_per_ack_ = max_timestamps;
+  }
+
+  // Sets the exponent to use when writing/reading ACK receive timestamps.
+  void set_receive_timestamps_exponent(uint32_t exponent) const {
+    receive_timestamps_exponent_ = exponent;
+  }
+
+  // Pass a UDP packet into the framer for parsing.
+  // Return true if the packet was processed successfully. |packet| must be a
+  // single, complete UDP packet (not a frame of a packet).  This packet
+  // might be null padded past the end of the payload, which will be correctly
+  // ignored.
+  bool ProcessPacket(const QuicEncryptedPacket& packet);
+
+  // Whether we are in the middle of a call to this->ProcessPacket.
+  bool is_processing_packet() const { return is_processing_packet_; }
+
+  // Largest size in bytes of all stream frame fields without the payload.
+  static size_t GetMinStreamFrameSize(QuicTransportVersion version,
+                                      QuicStreamId stream_id,
+                                      QuicStreamOffset offset,
+                                      bool last_frame_in_packet,
+                                      size_t data_length);
+  // Returns the overhead of framing a CRYPTO frame with the specific offset and
+  // data length provided, but not counting the size of the data payload.
+  static size_t GetMinCryptoFrameSize(QuicStreamOffset offset,
+                                      QuicPacketLength data_length);
+  static size_t GetMessageFrameSize(QuicTransportVersion version,
+                                    bool last_frame_in_packet,
+                                    QuicByteCount length);
+  // Size in bytes of all ack frame fields without the missing packets or ack
+  // blocks.
+  static size_t GetMinAckFrameSize(QuicTransportVersion version,
+                                   const QuicAckFrame& ack_frame,
+                                   uint32_t local_ack_delay_exponent,
+                                   bool use_ietf_ack_with_receive_timestamp);
+  // Size in bytes of a stop waiting frame.
+  static size_t GetStopWaitingFrameSize(
+      QuicPacketNumberLength packet_number_length);
+  // Size in bytes of all reset stream frame fields.
+  static size_t GetRstStreamFrameSize(QuicTransportVersion version,
+                                      const QuicRstStreamFrame& frame);
+  // Size in bytes of all ack frenquency frame fields.
+  static size_t GetAckFrequencyFrameSize(const QuicAckFrequencyFrame& frame);
+  // Size in bytes of all connection close frame fields, including the error
+  // details.
+  static size_t GetConnectionCloseFrameSize(
+      QuicTransportVersion version,
+      const QuicConnectionCloseFrame& frame);
+  // Size in bytes of all GoAway frame fields without the reason phrase.
+  static size_t GetMinGoAwayFrameSize();
+  // Size in bytes of all WindowUpdate frame fields.
+  // For version 99, determines whether a MAX DATA or MAX STREAM DATA frame will
+  // be generated and calculates the appropriate size.
+  static size_t GetWindowUpdateFrameSize(QuicTransportVersion version,
+                                         const QuicWindowUpdateFrame& frame);
+  // Size in bytes of all MaxStreams frame fields.
+  static size_t GetMaxStreamsFrameSize(QuicTransportVersion version,
+                                       const QuicMaxStreamsFrame& frame);
+  // Size in bytes of all StreamsBlocked frame fields.
+  static size_t GetStreamsBlockedFrameSize(
+      QuicTransportVersion version,
+      const QuicStreamsBlockedFrame& frame);
+  // Size in bytes of all Blocked frame fields.
+  static size_t GetBlockedFrameSize(QuicTransportVersion version,
+                                    const QuicBlockedFrame& frame);
+  // Size in bytes of PathChallenge frame.
+  static size_t GetPathChallengeFrameSize(const QuicPathChallengeFrame& frame);
+  // Size in bytes of PathResponse frame.
+  static size_t GetPathResponseFrameSize(const QuicPathResponseFrame& frame);
+  // Size in bytes required to serialize the stream id.
+  static size_t GetStreamIdSize(QuicStreamId stream_id);
+  // Size in bytes required to serialize the stream offset.
+  static size_t GetStreamOffsetSize(QuicStreamOffset offset);
+  // Size in bytes for a serialized new connection id frame
+  static size_t GetNewConnectionIdFrameSize(
+      const QuicNewConnectionIdFrame& frame);
+
+  // Size in bytes for a serialized retire connection id frame
+  static size_t GetRetireConnectionIdFrameSize(
+      const QuicRetireConnectionIdFrame& frame);
+
+  // Size in bytes for a serialized new token frame
+  static size_t GetNewTokenFrameSize(const QuicNewTokenFrame& frame);
+
+  // Size in bytes required for a serialized stop sending frame.
+  static size_t GetStopSendingFrameSize(const QuicStopSendingFrame& frame);
+
+  // Size in bytes required for a serialized retransmittable control |frame|.
+  static size_t GetRetransmittableControlFrameSize(QuicTransportVersion version,
+                                                   const QuicFrame& frame);
+
+  // Returns the number of bytes added to the packet for the specified frame,
+  // and 0 if the frame doesn't fit.  Includes the header size for the first
+  // frame.
+  size_t GetSerializedFrameLength(const QuicFrame& frame,
+                                  size_t free_bytes,
+                                  bool first_frame_in_packet,
+                                  bool last_frame_in_packet,
+                                  QuicPacketNumberLength packet_number_length);
+
+  // Returns the associated data from the encrypted packet |encrypted| as a
+  // stringpiece.
+  static absl::string_view GetAssociatedDataFromEncryptedPacket(
+      QuicTransportVersion version,
+      const QuicEncryptedPacket& encrypted,
+      QuicConnectionIdLength destination_connection_id_length,
+      QuicConnectionIdLength source_connection_id_length,
+      bool includes_version,
+      bool includes_diversification_nonce,
+      QuicPacketNumberLength packet_number_length,
+      QuicVariableLengthIntegerLength retry_token_length_length,
+      uint64_t retry_token_length,
+      QuicVariableLengthIntegerLength length_length);
+
+  // Parses the unencrypted fields in a QUIC header using |reader| as input,
+  // stores the result in the other parameters.
+  // |expected_destination_connection_id_length| is only used for short headers.
+  static QuicErrorCode ParsePublicHeader(
+      QuicDataReader* reader,
+      uint8_t expected_destination_connection_id_length,
+      bool ietf_format,
+      uint8_t* first_byte,
+      PacketHeaderFormat* format,
+      bool* version_present,
+      bool* has_length_prefix,
+      QuicVersionLabel* version_label,
+      ParsedQuicVersion* parsed_version,
+      QuicConnectionId* destination_connection_id,
+      QuicConnectionId* source_connection_id,
+      QuicLongHeaderType* long_packet_type,
+      QuicVariableLengthIntegerLength* retry_token_length_length,
+      absl::string_view* retry_token,
+      std::string* detailed_error);
+
+  // Parses the unencrypted fields in |packet| and stores them in the other
+  // parameters. This can only be called on the server.
+  // |expected_destination_connection_id_length| is only used for short headers.
+  static QuicErrorCode ParsePublicHeaderDispatcher(
+      const QuicEncryptedPacket& packet,
+      uint8_t expected_destination_connection_id_length,
+      PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
+      bool* version_present, bool* has_length_prefix,
+      QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
+      QuicConnectionId* destination_connection_id,
+      QuicConnectionId* source_connection_id,
+      absl::optional<absl::string_view>* retry_token,
+      std::string* detailed_error);
+
+  // Serializes a packet containing |frames| into |buffer|.
+  // Returns the length of the packet, which must not be longer than
+  // |packet_length|.  Returns 0 if it fails to serialize.
+  size_t BuildDataPacket(const QuicPacketHeader& header,
+                         const QuicFrames& frames,
+                         char* buffer,
+                         size_t packet_length,
+                         EncryptionLevel level);
+
+  // Returns a new public reset packet.
+  static std::unique_ptr<QuicEncryptedPacket> BuildPublicResetPacket(
+      const QuicPublicResetPacket& packet);
+
+  // Returns the minimal stateless reset packet length.
+  static size_t GetMinStatelessResetPacketLength();
+
+  // Returns a new IETF stateless reset packet.
+  static std::unique_ptr<QuicEncryptedPacket> BuildIetfStatelessResetPacket(
+      QuicConnectionId connection_id,
+      size_t received_packet_length,
+      StatelessResetToken stateless_reset_token);
+
+  // Returns a new version negotiation packet.
+  static std::unique_ptr<QuicEncryptedPacket> BuildVersionNegotiationPacket(
+      QuicConnectionId server_connection_id,
+      QuicConnectionId client_connection_id,
+      bool ietf_quic,
+      bool use_length_prefix,
+      const ParsedQuicVersionVector& versions);
+
+  // Returns a new IETF version negotiation packet.
+  static std::unique_ptr<QuicEncryptedPacket> BuildIetfVersionNegotiationPacket(
+      bool use_length_prefix,
+      QuicConnectionId server_connection_id,
+      QuicConnectionId client_connection_id,
+      const ParsedQuicVersionVector& versions);
+
+  // If header.version_flag is set, the version in the
+  // packet will be set -- but it will be set from version_ not
+  // header.versions.
+  bool AppendPacketHeader(const QuicPacketHeader& header,
+                          QuicDataWriter* writer,
+                          size_t* length_field_offset);
+  bool AppendIetfHeaderTypeByte(const QuicPacketHeader& header,
+                                QuicDataWriter* writer);
+  bool AppendIetfPacketHeader(const QuicPacketHeader& header,
+                              QuicDataWriter* writer,
+                              size_t* length_field_offset);
+  bool WriteIetfLongHeaderLength(const QuicPacketHeader& header,
+                                 QuicDataWriter* writer,
+                                 size_t length_field_offset,
+                                 EncryptionLevel level);
+  bool AppendTypeByte(const QuicFrame& frame,
+                      bool last_frame_in_packet,
+                      QuicDataWriter* writer);
+  bool AppendIetfFrameType(const QuicFrame& frame,
+                           bool last_frame_in_packet,
+                           QuicDataWriter* writer);
+  size_t AppendIetfFrames(const QuicFrames& frames, QuicDataWriter* writer);
+  bool AppendStreamFrame(const QuicStreamFrame& frame,
+                         bool no_stream_frame_length, QuicDataWriter* writer);
+  bool AppendCryptoFrame(const QuicCryptoFrame& frame, QuicDataWriter* writer);
+  bool AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
+                               QuicDataWriter* writer);
+
+  // SetDecrypter sets the primary decrypter, replacing any that already exists.
+  // If an alternative decrypter is in place then the function QUICHE_DCHECKs.
+  // This is intended for cases where one knows that future packets will be
+  // using the new decrypter and the previous decrypter is now obsolete. |level|
+  // indicates the encryption level of the new decrypter.
+  void SetDecrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicDecrypter> decrypter);
+
+  // SetAlternativeDecrypter sets a decrypter that may be used to decrypt
+  // future packets. |level| indicates the encryption level of the decrypter. If
+  // |latch_once_used| is true, then the first time that the decrypter is
+  // successful it will replace the primary decrypter.  Otherwise both
+  // decrypters will remain active and the primary decrypter will be the one
+  // last used.
+  void SetAlternativeDecrypter(EncryptionLevel level,
+                               std::unique_ptr<QuicDecrypter> decrypter,
+                               bool latch_once_used);
+
+  void InstallDecrypter(EncryptionLevel level,
+                        std::unique_ptr<QuicDecrypter> decrypter);
+  void RemoveDecrypter(EncryptionLevel level);
+
+  // Enables key update support.
+  void SetKeyUpdateSupportForConnection(bool enabled);
+  // Discard the decrypter for the previous key phase.
+  void DiscardPreviousOneRttKeys();
+  // Update the key phase.
+  bool DoKeyUpdate(KeyUpdateReason reason);
+  // Returns the count of packets received that appeared to attempt a key
+  // update but failed decryption which have been received since the last
+  // successfully decrypted packet.
+  QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const;
+
+  const QuicDecrypter* GetDecrypter(EncryptionLevel level) const;
+  const QuicDecrypter* decrypter() const;
+  const QuicDecrypter* alternative_decrypter() const;
+
+  // Changes the encrypter used for level |level| to |encrypter|.
+  void SetEncrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicEncrypter> encrypter);
+
+  // Called to remove encrypter of encryption |level|.
+  void RemoveEncrypter(EncryptionLevel level);
+
+  // Sets the encrypter and decrypter for the ENCRYPTION_INITIAL level.
+  void SetInitialObfuscators(QuicConnectionId connection_id);
+
+  // Encrypts a payload in |buffer|.  |ad_len| is the length of the associated
+  // data. |total_len| is the length of the associated data plus plaintext.
+  // |buffer_len| is the full length of the allocated buffer.
+  size_t EncryptInPlace(EncryptionLevel level,
+                        QuicPacketNumber packet_number,
+                        size_t ad_len,
+                        size_t total_len,
+                        size_t buffer_len,
+                        char* buffer);
+
+  // Returns the length of the data encrypted into |buffer| if |buffer_len| is
+  // long enough, and otherwise 0.
+  size_t EncryptPayload(EncryptionLevel level,
+                        QuicPacketNumber packet_number,
+                        const QuicPacket& packet,
+                        char* buffer,
+                        size_t buffer_len);
+
+  // Returns the length of the ciphertext that would be generated by encrypting
+  // to plaintext of size |plaintext_size| at the given level.
+  size_t GetCiphertextSize(EncryptionLevel level, size_t plaintext_size) const;
+
+  // Returns the maximum length of plaintext that can be encrypted
+  // to ciphertext no larger than |ciphertext_size|.
+  size_t GetMaxPlaintextSize(size_t ciphertext_size);
+
+  // Returns the maximum number of packets that can be safely encrypted with
+  // the active AEAD. 1-RTT keys must be set before calling this method.
+  QuicPacketCount GetOneRttEncrypterConfidentialityLimit() const;
+
+  const std::string& detailed_error() { return detailed_error_; }
+
+  // The minimum packet number length required to represent |packet_number|.
+  static QuicPacketNumberLength GetMinPacketNumberLength(
+      QuicPacketNumber packet_number);
+
+  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+    supported_versions_ = versions;
+    version_ = versions[0];
+  }
+
+  // Tell framer to infer packet header type from version_.
+  void InferPacketHeaderTypeFromVersion();
+
+  // Returns true if |header| is considered as an stateless reset packet.
+  bool IsIetfStatelessResetPacket(const QuicPacketHeader& header) const;
+
+  // Returns true if encrypter of |level| is available.
+  bool HasEncrypterOfEncryptionLevel(EncryptionLevel level) const;
+  // Returns true if decrypter of |level| is available.
+  bool HasDecrypterOfEncryptionLevel(EncryptionLevel level) const;
+
+  // Returns true if an encrypter of |space| is available.
+  bool HasAnEncrypterForSpace(PacketNumberSpace space) const;
+
+  // Returns the encryption level to send application data. This should be only
+  // called with available encrypter for application data.
+  EncryptionLevel GetEncryptionLevelToSendApplicationData() const;
+
+  void set_validate_flags(bool value) { validate_flags_ = value; }
+
+  Perspective perspective() const { return perspective_; }
+
+  QuicStreamFrameDataProducer* data_producer() const { return data_producer_; }
+
+  void set_data_producer(QuicStreamFrameDataProducer* data_producer) {
+    data_producer_ = data_producer;
+  }
+
+  QuicTime creation_time() const { return creation_time_; }
+
+  QuicPacketNumber first_sending_packet_number() const {
+    return first_sending_packet_number_;
+  }
+
+  uint64_t current_received_frame_type() const {
+    return current_received_frame_type_;
+  }
+
+  uint64_t previously_received_frame_type() const {
+    return previously_received_frame_type_;
+  }
+
+  // The connection ID length the framer expects on incoming IETF short headers
+  // on the server.
+  uint8_t GetExpectedServerConnectionIdLength() {
+    return expected_server_connection_id_length_;
+  }
+
+  // Change the expected destination connection ID length for short headers on
+  // the client.
+  void SetExpectedClientConnectionIdLength(
+      uint8_t expected_client_connection_id_length) {
+    expected_client_connection_id_length_ =
+        expected_client_connection_id_length;
+  }
+
+  void EnableMultiplePacketNumberSpacesSupport();
+
+  // Writes an array of bytes that, if sent as a UDP datagram, will trigger
+  // IETF QUIC Version Negotiation on servers. The bytes will be written to
+  // |packet_bytes|, which must point to |packet_length| bytes of memory.
+  // |packet_length| must be in the range [1200, 65535].
+  // |destination_connection_id_bytes| will be sent as the destination
+  // connection ID, and must point to |destination_connection_id_length| bytes
+  // of memory. |destination_connection_id_length| must be in the range [8,18].
+  // When targeting Google servers, it is recommended to use a
+  // |destination_connection_id_length| of 8.
+  static bool WriteClientVersionNegotiationProbePacket(
+      char* packet_bytes,
+      QuicByteCount packet_length,
+      const char* destination_connection_id_bytes,
+      uint8_t destination_connection_id_length);
+
+  // Parses a packet which a QUIC server sent in response to a packet sent by
+  // WriteClientVersionNegotiationProbePacket. |packet_bytes| must point to
+  // |packet_length| bytes in memory which represent the response.
+  // |packet_length| must be greater or equal to 6. This method will fill in
+  // |source_connection_id_bytes| which must point to at least
+  // |*source_connection_id_length_out| bytes in memory.
+  // |*source_connection_id_length_out| must be at least 18.
+  // |*source_connection_id_length_out| will contain the length of the received
+  // source connection ID, which on success will match the contents of the
+  // destination connection ID passed in to
+  // WriteClientVersionNegotiationProbePacket. In the case of a failure,
+  // |detailed_error| will be filled in with an explanation of what failed.
+  static bool ParseServerVersionNegotiationProbeResponse(
+      const char* packet_bytes,
+      QuicByteCount packet_length,
+      char* source_connection_id_bytes,
+      uint8_t* source_connection_id_length_out,
+      std::string* detailed_error);
+
+  void set_local_ack_delay_exponent(uint32_t exponent) {
+    local_ack_delay_exponent_ = exponent;
+  }
+  uint32_t local_ack_delay_exponent() const {
+    return local_ack_delay_exponent_;
+  }
+
+  void set_peer_ack_delay_exponent(uint32_t exponent) {
+    peer_ack_delay_exponent_ = exponent;
+  }
+  uint32_t peer_ack_delay_exponent() const { return peer_ack_delay_exponent_; }
+
+  void set_drop_incoming_retry_packets(bool drop_incoming_retry_packets) {
+    drop_incoming_retry_packets_ = drop_incoming_retry_packets;
+  }
+
+ private:
+  friend class test::QuicFramerPeer;
+
+  using NackRangeMap = std::map<QuicPacketNumber, uint8_t>;
+
+  // AckTimestampRange is a data structure derived from a QuicAckFrame. It is
+  // used to serialize timestamps in a IETF_ACK_RECEIVE_TIMESTAMPS frame.
+  struct QUIC_EXPORT_PRIVATE AckTimestampRange {
+    QuicPacketCount gap;
+    // |range_begin| and |range_end| are index(es) in
+    // QuicAckFrame.received_packet_times, representing a continuous range of
+    // packet numbers in descending order. |range_begin| >= |range_end|.
+    int64_t range_begin;  // Inclusive
+    int64_t range_end;    // Inclusive
+  };
+  absl::InlinedVector<AckTimestampRange, 2> GetAckTimestampRanges(
+      const QuicAckFrame& frame, std::string& detailed_error) const;
+  int64_t FrameAckTimestampRanges(
+      const QuicAckFrame& frame,
+      const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
+      QuicDataWriter* writer) const;
+
+  struct QUIC_EXPORT_PRIVATE AckFrameInfo {
+    AckFrameInfo();
+    AckFrameInfo(const AckFrameInfo& other);
+    ~AckFrameInfo();
+
+    // The maximum ack block length.
+    QuicPacketCount max_block_length;
+    // Length of first ack block.
+    QuicPacketCount first_block_length;
+    // Number of ACK blocks needed for the ACK frame.
+    size_t num_ack_blocks;
+  };
+
+  // Applies header protection to an IETF QUIC packet header in |buffer| using
+  // the encrypter for level |level|. The buffer has |buffer_len| bytes of data,
+  // with the first protected packet bytes starting at |ad_len|.
+  bool ApplyHeaderProtection(EncryptionLevel level,
+                             char* buffer,
+                             size_t buffer_len,
+                             size_t ad_len);
+
+  // Removes header protection from an IETF QUIC packet header.
+  //
+  // The packet number from the header is read from |reader|, where the packet
+  // number is the next contents in |reader|. |reader| is only advanced by the
+  // length of the packet number, but it is also used to peek the sample needed
+  // for removing header protection.
+  //
+  // Properties needed for removing header protection are read from |header|.
+  // The packet number length and type byte are written to |header|.
+  //
+  // The packet number, after removing header protection and decoding it, is
+  // written to |full_packet_number|. Finally, the header, with header
+  // protection removed, is written to |associated_data| to be used in packet
+  // decryption. |packet| is used in computing the asociated data.
+  bool RemoveHeaderProtection(QuicDataReader* reader,
+                              const QuicEncryptedPacket& packet,
+                              QuicPacketHeader* header,
+                              uint64_t* full_packet_number,
+                              std::vector<char>* associated_data);
+
+  bool ProcessDataPacket(QuicDataReader* reader,
+                         QuicPacketHeader* header,
+                         const QuicEncryptedPacket& packet,
+                         char* decrypted_buffer,
+                         size_t buffer_length);
+
+  bool ProcessIetfDataPacket(QuicDataReader* encrypted_reader,
+                             QuicPacketHeader* header,
+                             const QuicEncryptedPacket& packet,
+                             char* decrypted_buffer,
+                             size_t buffer_length);
+
+  bool ProcessPublicResetPacket(QuicDataReader* reader,
+                                const QuicPacketHeader& header);
+
+  bool ProcessVersionNegotiationPacket(QuicDataReader* reader,
+                                       const QuicPacketHeader& header);
+
+  bool ProcessRetryPacket(QuicDataReader* reader,
+                          const QuicPacketHeader& header);
+
+  void MaybeProcessCoalescedPacket(const QuicDataReader& encrypted_reader,
+                                   uint64_t remaining_bytes_length,
+                                   const QuicPacketHeader& header);
+
+  bool MaybeProcessIetfLength(QuicDataReader* encrypted_reader,
+                              QuicPacketHeader* header);
+
+  bool ProcessPublicHeader(QuicDataReader* reader,
+                           bool packet_has_ietf_packet_header,
+                           QuicPacketHeader* header);
+
+  // Processes the unauthenticated portion of the header into |header| from
+  // the current QuicDataReader.  Returns true on success, false on failure.
+  bool ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
+                                    QuicPacketHeader* header);
+
+  // Processes the version label in the packet header.
+  static bool ProcessVersionLabel(QuicDataReader* reader,
+                                  QuicVersionLabel* version_label);
+
+  // Validates and updates |destination_connection_id_length| and
+  // |source_connection_id_length|. When
+  // |should_update_expected_server_connection_id_length| is true, length
+  // validation is disabled and |expected_server_connection_id_length| is set
+  // to the appropriate length.
+  // TODO(b/133873272) refactor this method.
+  static bool ProcessAndValidateIetfConnectionIdLength(
+      QuicDataReader* reader,
+      ParsedQuicVersion version,
+      Perspective perspective,
+      bool should_update_expected_server_connection_id_length,
+      uint8_t* expected_server_connection_id_length,
+      uint8_t* destination_connection_id_length,
+      uint8_t* source_connection_id_length,
+      std::string* detailed_error);
+
+  bool ProcessIetfHeaderTypeByte(QuicDataReader* reader,
+                                 QuicPacketHeader* header);
+  bool ProcessIetfPacketHeader(QuicDataReader* reader,
+                               QuicPacketHeader* header);
+
+  // First processes possibly truncated packet number. Calculates the full
+  // packet number from the truncated one and the last seen packet number, and
+  // stores it to |packet_number|.
+  bool ProcessAndCalculatePacketNumber(
+      QuicDataReader* reader,
+      QuicPacketNumberLength packet_number_length,
+      QuicPacketNumber base_packet_number,
+      uint64_t* packet_number);
+  bool ProcessFrameData(QuicDataReader* reader, const QuicPacketHeader& header);
+
+  static bool IsIetfFrameTypeExpectedForEncryptionLevel(uint64_t frame_type,
+                                                        EncryptionLevel level);
+
+  bool ProcessIetfFrameData(QuicDataReader* reader,
+                            const QuicPacketHeader& header,
+                            EncryptionLevel decrypted_level);
+  bool ProcessStreamFrame(QuicDataReader* reader,
+                          uint8_t frame_type,
+                          QuicStreamFrame* frame);
+  bool ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type);
+  bool ProcessTimestampsInAckFrame(uint8_t num_received_packets,
+                                   QuicPacketNumber largest_acked,
+                                   QuicDataReader* reader);
+  bool ProcessIetfAckFrame(QuicDataReader* reader,
+                           uint64_t frame_type,
+                           QuicAckFrame* ack_frame);
+  bool ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
+                                       QuicDataReader* reader);
+  bool ProcessStopWaitingFrame(QuicDataReader* reader,
+                               const QuicPacketHeader& header,
+                               QuicStopWaitingFrame* stop_waiting);
+  bool ProcessRstStreamFrame(QuicDataReader* reader, QuicRstStreamFrame* frame);
+  bool ProcessConnectionCloseFrame(QuicDataReader* reader,
+                                   QuicConnectionCloseFrame* frame);
+  bool ProcessGoAwayFrame(QuicDataReader* reader, QuicGoAwayFrame* frame);
+  bool ProcessWindowUpdateFrame(QuicDataReader* reader,
+                                QuicWindowUpdateFrame* frame);
+  bool ProcessBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame);
+  void ProcessPaddingFrame(QuicDataReader* reader, QuicPaddingFrame* frame);
+  bool ProcessMessageFrame(QuicDataReader* reader,
+                           bool no_message_length,
+                           QuicMessageFrame* frame);
+
+  bool DecryptPayload(size_t udp_packet_length,
+                      absl::string_view encrypted,
+                      absl::string_view associated_data,
+                      const QuicPacketHeader& header,
+                      char* decrypted_buffer,
+                      size_t buffer_length,
+                      size_t* decrypted_length,
+                      EncryptionLevel* decrypted_level);
+
+  // Returns the full packet number from the truncated
+  // wire format version and the last seen packet number.
+  uint64_t CalculatePacketNumberFromWire(
+      QuicPacketNumberLength packet_number_length,
+      QuicPacketNumber base_packet_number,
+      uint64_t packet_number) const;
+
+  // Returns the QuicTime::Delta corresponding to the time from when the framer
+  // was created.
+  const QuicTime::Delta CalculateTimestampFromWire(uint32_t time_delta_us);
+
+  // Computes the wire size in bytes of time stamps in |ack|.
+  size_t GetAckFrameTimeStampSize(const QuicAckFrame& ack);
+  size_t GetIetfAckFrameTimestampSize(const QuicAckFrame& ack);
+
+  // Computes the wire size in bytes of the |ack| frame.
+  size_t GetAckFrameSize(const QuicAckFrame& ack,
+                         QuicPacketNumberLength packet_number_length);
+  // Computes the wire-size, in bytes, of the |frame| ack frame, for IETF Quic.
+  size_t GetIetfAckFrameSize(const QuicAckFrame& frame);
+
+  // Computes the wire size in bytes of the |ack| frame.
+  size_t GetAckFrameSize(const QuicAckFrame& ack);
+
+  // Computes the wire size in bytes of the payload of |frame|.
+  size_t ComputeFrameLength(const QuicFrame& frame,
+                            bool last_frame_in_packet,
+                            QuicPacketNumberLength packet_number_length);
+
+  static bool AppendPacketNumber(QuicPacketNumberLength packet_number_length,
+                                 QuicPacketNumber packet_number,
+                                 QuicDataWriter* writer);
+  static bool AppendStreamId(size_t stream_id_length,
+                             QuicStreamId stream_id,
+                             QuicDataWriter* writer);
+  static bool AppendStreamOffset(size_t offset_length,
+                                 QuicStreamOffset offset,
+                                 QuicDataWriter* writer);
+
+  // Appends a single ACK block to |writer| and returns true if the block was
+  // successfully appended.
+  static bool AppendAckBlock(uint8_t gap,
+                             QuicPacketNumberLength length_length,
+                             uint64_t length,
+                             QuicDataWriter* writer);
+
+  static uint8_t GetPacketNumberFlags(
+      QuicPacketNumberLength packet_number_length);
+
+  static AckFrameInfo GetAckFrameInfo(const QuicAckFrame& frame);
+
+  static QuicErrorCode ParsePublicHeaderGoogleQuic(
+      QuicDataReader* reader,
+      uint8_t* first_byte,
+      PacketHeaderFormat* format,
+      bool* version_present,
+      QuicVersionLabel* version_label,
+      ParsedQuicVersion* parsed_version,
+      QuicConnectionId* destination_connection_id,
+      std::string* detailed_error);
+
+  bool ValidateReceivedConnectionIds(const QuicPacketHeader& header);
+
+  // The Append* methods attempt to write the provided header or frame using the
+  // |writer|, and return true if successful.
+
+  bool AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
+                                 QuicDataWriter* writer);
+  bool AppendTimestampsToAckFrame(const QuicAckFrame& frame,
+                                  QuicDataWriter* writer);
+
+  // Append IETF format ACK frame.
+  //
+  // AppendIetfAckFrameAndTypeByte adds the IETF type byte and the body
+  // of the frame.
+  bool AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
+                                     QuicDataWriter* writer);
+  bool AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
+                                      QuicDataWriter* writer);
+
+  bool AppendStopWaitingFrame(const QuicPacketHeader& header,
+                              const QuicStopWaitingFrame& frame,
+                              QuicDataWriter* writer);
+  bool AppendRstStreamFrame(const QuicRstStreamFrame& frame,
+                            QuicDataWriter* writer);
+  bool AppendConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
+                                  QuicDataWriter* writer);
+  bool AppendGoAwayFrame(const QuicGoAwayFrame& frame, QuicDataWriter* writer);
+  bool AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
+                               QuicDataWriter* writer);
+  bool AppendBlockedFrame(const QuicBlockedFrame& frame,
+                          QuicDataWriter* writer);
+  bool AppendPaddingFrame(const QuicPaddingFrame& frame,
+                          QuicDataWriter* writer);
+  bool AppendMessageFrameAndTypeByte(const QuicMessageFrame& frame,
+                                     bool last_frame_in_packet,
+                                     QuicDataWriter* writer);
+
+  // IETF frame processing methods.
+  bool ProcessIetfStreamFrame(QuicDataReader* reader,
+                              uint8_t frame_type,
+                              QuicStreamFrame* frame);
+  bool ProcessIetfConnectionCloseFrame(QuicDataReader* reader,
+                                       QuicConnectionCloseType type,
+                                       QuicConnectionCloseFrame* frame);
+  bool ProcessPathChallengeFrame(QuicDataReader* reader,
+                                 QuicPathChallengeFrame* frame);
+  bool ProcessPathResponseFrame(QuicDataReader* reader,
+                                QuicPathResponseFrame* frame);
+  bool ProcessIetfResetStreamFrame(QuicDataReader* reader,
+                                   QuicRstStreamFrame* frame);
+  bool ProcessStopSendingFrame(QuicDataReader* reader,
+                               QuicStopSendingFrame* stop_sending_frame);
+  bool ProcessCryptoFrame(QuicDataReader* reader,
+                          EncryptionLevel encryption_level,
+                          QuicCryptoFrame* frame);
+  bool ProcessAckFrequencyFrame(QuicDataReader* reader,
+                                QuicAckFrequencyFrame* frame);
+  // IETF frame appending methods.  All methods append the type byte as well.
+  bool AppendIetfStreamFrame(const QuicStreamFrame& frame,
+                             bool last_frame_in_packet,
+                             QuicDataWriter* writer);
+  bool AppendIetfConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
+                                      QuicDataWriter* writer);
+  bool AppendPathChallengeFrame(const QuicPathChallengeFrame& frame,
+                                QuicDataWriter* writer);
+  bool AppendPathResponseFrame(const QuicPathResponseFrame& frame,
+                               QuicDataWriter* writer);
+  bool AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
+                                  QuicDataWriter* writer);
+  bool AppendStopSendingFrame(const QuicStopSendingFrame& stop_sending_frame,
+                              QuicDataWriter* writer);
+
+  // Append/consume IETF-Format MAX_DATA and MAX_STREAM_DATA frames
+  bool AppendMaxDataFrame(const QuicWindowUpdateFrame& frame,
+                          QuicDataWriter* writer);
+  bool AppendMaxStreamDataFrame(const QuicWindowUpdateFrame& frame,
+                                QuicDataWriter* writer);
+  bool ProcessMaxDataFrame(QuicDataReader* reader,
+                           QuicWindowUpdateFrame* frame);
+  bool ProcessMaxStreamDataFrame(QuicDataReader* reader,
+                                 QuicWindowUpdateFrame* frame);
+
+  bool AppendMaxStreamsFrame(const QuicMaxStreamsFrame& frame,
+                             QuicDataWriter* writer);
+  bool ProcessMaxStreamsFrame(QuicDataReader* reader,
+                              QuicMaxStreamsFrame* frame,
+                              uint64_t frame_type);
+
+  bool AppendDataBlockedFrame(const QuicBlockedFrame& frame,
+                              QuicDataWriter* writer);
+  bool ProcessDataBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame);
+
+  bool AppendStreamDataBlockedFrame(const QuicBlockedFrame& frame,
+                                    QuicDataWriter* writer);
+  bool ProcessStreamDataBlockedFrame(QuicDataReader* reader,
+                                     QuicBlockedFrame* frame);
+
+  bool AppendStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
+                                 QuicDataWriter* writer);
+  bool ProcessStreamsBlockedFrame(QuicDataReader* reader,
+                                  QuicStreamsBlockedFrame* frame,
+                                  uint64_t frame_type);
+
+  bool AppendNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame,
+                                  QuicDataWriter* writer);
+  bool ProcessNewConnectionIdFrame(QuicDataReader* reader,
+                                   QuicNewConnectionIdFrame* frame);
+  bool AppendRetireConnectionIdFrame(const QuicRetireConnectionIdFrame& frame,
+                                     QuicDataWriter* writer);
+  bool ProcessRetireConnectionIdFrame(QuicDataReader* reader,
+                                      QuicRetireConnectionIdFrame* frame);
+
+  bool AppendNewTokenFrame(const QuicNewTokenFrame& frame,
+                           QuicDataWriter* writer);
+  bool ProcessNewTokenFrame(QuicDataReader* reader, QuicNewTokenFrame* frame);
+
+  bool RaiseError(QuicErrorCode error);
+
+  // Returns true if |header| indicates a version negotiation packet.
+  bool IsVersionNegotiation(const QuicPacketHeader& header,
+                            bool packet_has_ietf_packet_header) const;
+
+  // Calculates and returns type byte of stream frame.
+  uint8_t GetStreamFrameTypeByte(const QuicStreamFrame& frame,
+                                 bool last_frame_in_packet) const;
+  uint8_t GetIetfStreamFrameTypeByte(const QuicStreamFrame& frame,
+                                     bool last_frame_in_packet) const;
+
+  void set_error(QuicErrorCode error) { error_ = error; }
+
+  void set_detailed_error(const char* error) { detailed_error_ = error; }
+  void set_detailed_error(std::string error) { detailed_error_ = error; }
+
+  // Returns false if the reading fails.
+  bool ReadUint32FromVarint62(QuicDataReader* reader,
+                              QuicIetfFrameType type,
+                              QuicStreamId* id);
+
+  bool ProcessPacketInternal(const QuicEncryptedPacket& packet);
+
+  // Determine whether the given QuicAckFrame should be serialized with a
+  // IETF_ACK_RECEIVE_TIMESTAMPS frame type.
+  bool UseIetfAckWithReceiveTimestamp(const QuicAckFrame& frame) const {
+    return VersionHasIetfQuicFrames(version_.transport_version) &&
+           process_timestamps_ &&
+           std::min<uint64_t>(max_receive_timestamps_per_ack_,
+                              frame.received_packet_times.size()) > 0;
+  }
+
+  std::string detailed_error_;
+  QuicFramerVisitorInterface* visitor_;
+  QuicErrorCode error_;
+  // Updated by ProcessPacketHeader when it succeeds decrypting a larger packet.
+  QuicPacketNumber largest_packet_number_;
+  // Largest successfully decrypted packet number per packet number space. Only
+  // used when supports_multiple_packet_number_spaces_ is true.
+  QuicPacketNumber largest_decrypted_packet_numbers_[NUM_PACKET_NUMBER_SPACES];
+  // Last server connection ID seen on the wire.
+  QuicConnectionId last_serialized_server_connection_id_;
+  // Last client connection ID seen on the wire.
+  QuicConnectionId last_serialized_client_connection_id_;
+  // Version of the protocol being used.
+  ParsedQuicVersion version_;
+  // This vector contains QUIC versions which we currently support.
+  // This should be ordered such that the highest supported version is the first
+  // element, with subsequent elements in descending order (versions can be
+  // skipped as necessary).
+  ParsedQuicVersionVector supported_versions_;
+  // Decrypters used to decrypt packets during parsing.
+  std::unique_ptr<QuicDecrypter> decrypter_[NUM_ENCRYPTION_LEVELS];
+  // The encryption level of the primary decrypter to use in |decrypter_|.
+  EncryptionLevel decrypter_level_;
+  // The encryption level of the alternative decrypter to use in |decrypter_|.
+  // When set to NUM_ENCRYPTION_LEVELS, indicates that there is no alternative
+  // decrypter.
+  EncryptionLevel alternative_decrypter_level_;
+  // |alternative_decrypter_latch_| is true if, when the decrypter at
+  // |alternative_decrypter_level_| successfully decrypts a packet, we should
+  // install it as the only decrypter.
+  bool alternative_decrypter_latch_;
+  // Encrypters used to encrypt packets via EncryptPayload().
+  std::unique_ptr<QuicEncrypter> encrypter_[NUM_ENCRYPTION_LEVELS];
+  // Tracks if the framer is being used by the entity that received the
+  // connection or the entity that initiated it.
+  Perspective perspective_;
+  // If false, skip validation that the public flags are set to legal values.
+  bool validate_flags_;
+  // The diversification nonce from the last received packet.
+  DiversificationNonce last_nonce_;
+  // If true, send and process timestamps in the ACK frame.
+  // TODO(ianswett): Remove the mutables once set_process_timestamps and
+  // set_receive_timestamp_exponent_ aren't const.
+  mutable bool process_timestamps_;
+  // The max number of receive timestamps to send per ACK frame.
+  mutable uint32_t max_receive_timestamps_per_ack_;
+  // The exponent to use when writing/reading ACK receive timestamps.
+  mutable uint32_t receive_timestamps_exponent_;
+  // The creation time of the connection, used to calculate timestamps.
+  QuicTime creation_time_;
+  // The last timestamp received if process_timestamps_ is true.
+  QuicTime::Delta last_timestamp_;
+
+  // Whether IETF QUIC Key Update is supported on this connection.
+  bool support_key_update_for_connection_;
+  // The value of the current key phase bit, which is toggled when the keys are
+  // changed.
+  bool current_key_phase_bit_;
+  // Whether we have performed a key update at least once.
+  bool key_update_performed_ = false;
+  // Tracks the first packet received in the current key phase. Will be
+  // uninitialized before the first one-RTT packet has been received or after a
+  // locally initiated key update but before the first packet from the peer in
+  // the new key phase is received.
+  QuicPacketNumber current_key_phase_first_received_packet_number_;
+  // Counts the number of packets received that might have been failed key
+  // update attempts. Reset to zero every time a packet is successfully
+  // decrypted.
+  QuicPacketCount potential_peer_key_update_attempt_count_;
+  // Decrypter for the previous key phase. Will be null if in the first key
+  // phase or previous keys have been discarded.
+  std::unique_ptr<QuicDecrypter> previous_decrypter_;
+  // Decrypter for the next key phase. May be null if next keys haven't been
+  // generated yet.
+  std::unique_ptr<QuicDecrypter> next_decrypter_;
+
+  // If this is a framer of a connection, this is the packet number of first
+  // sending packet. If this is a framer of a framer of dispatcher, this is the
+  // packet number of sent packets (for those which have packet number).
+  const QuicPacketNumber first_sending_packet_number_;
+
+  // If not null, framer asks data_producer_ to write stream frame data. Not
+  // owned. TODO(fayang): Consider add data producer to framer's constructor.
+  QuicStreamFrameDataProducer* data_producer_;
+
+  // Whether we are in the middle of a call to this->ProcessPacket.
+  bool is_processing_packet_ = false;
+
+  // If true, framer infers packet header type (IETF/GQUIC) from version_.
+  // Otherwise, framer infers packet header type from first byte of a received
+  // packet.
+  bool infer_packet_header_type_from_version_;
+
+  // IETF short headers contain a destination connection ID but do not
+  // encode its length. These variables contains the length we expect to read.
+  // This is also used to validate the long header destination connection ID
+  // lengths in older versions of QUIC.
+  uint8_t expected_server_connection_id_length_;
+  uint8_t expected_client_connection_id_length_;
+
+  // Indicates whether this framer supports multiple packet number spaces.
+  bool supports_multiple_packet_number_spaces_;
+
+  // Indicates whether received RETRY packets should be dropped.
+  bool drop_incoming_retry_packets_ = false;
+
+  // The length in bytes of the last packet number written to an IETF-framed
+  // packet.
+  size_t last_written_packet_number_length_;
+
+  // The amount to shift the ack timestamp in ACK frames. The default is 3.
+  // Local_ is the amount this node shifts timestamps in ACK frames it
+  // generates. it is sent to the peer in a transport parameter negotiation.
+  // Peer_ is the amount the peer shifts timestamps when it sends ACK frames to
+  // this node. This node "unshifts" by this amount. The value is received from
+  // the peer in the transport parameter negotiation. IETF QUIC only.
+  uint32_t peer_ack_delay_exponent_;
+  uint32_t local_ack_delay_exponent_;
+
+  // The type of received IETF frame currently being processed.  0 when not
+  // processing a frame or when processing Google QUIC frames.  Used to populate
+  // the Transport Connection Close when there is an error during frame
+  // processing.
+  uint64_t current_received_frame_type_;
+
+  // TODO(haoyuewang) Remove this debug utility.
+  // The type of the IETF frame preceding the frame currently being processed. 0
+  // when not processing a frame or only 1 frame has been processed.
+  uint64_t previously_received_frame_type_;
+};
+
+// Look for and parse the error code from the "<quic_error_code>:" text that
+// may be present at the start of the CONNECTION_CLOSE error details string.
+// This text, inserted by the peer if it's using Google's QUIC implementation,
+// contains additional error information that narrows down the exact error. The
+// extracted error code and (possibly updated) error_details string are returned
+// in |*frame|. If an error code is not found in the error details, then
+// frame->quic_error_code is set to
+// QuicErrorCode::QUIC_IETF_GQUIC_ERROR_MISSING.  If there is an error code in
+// the string then it is removed from the string.
+QUIC_EXPORT_PRIVATE void MaybeExtractQuicErrorCode(
+    QuicConnectionCloseFrame* frame);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_FRAMER_H_
diff --git a/quiche/quic/core/quic_framer_test.cc b/quiche/quic/core/quic_framer_test.cc
new file mode 100644
index 0000000..76bbe4a
--- /dev/null
+++ b/quiche/quic/core/quic_framer_test.cc
@@ -0,0 +1,16373 @@
+// 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 "quiche/quic/core/quic_framer.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_data_producer.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using testing::_;
+using testing::ContainerEq;
+using testing::Return;
+
+namespace quic {
+namespace test {
+namespace {
+
+const uint64_t kEpoch = UINT64_C(1) << 32;
+const uint64_t kMask = kEpoch - 1;
+
+const StatelessResetToken kTestStatelessResetToken{
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
+
+// Use fields in which each byte is distinct to ensure that every byte is
+// framed correctly. The values are otherwise arbitrary.
+QuicConnectionId FramerTestConnectionId() {
+  return TestConnectionId(UINT64_C(0xFEDCBA9876543210));
+}
+
+QuicConnectionId FramerTestConnectionIdPlusOne() {
+  return TestConnectionId(UINT64_C(0xFEDCBA9876543211));
+}
+
+QuicConnectionId FramerTestConnectionIdNineBytes() {
+  uint8_t connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
+                                    0x54, 0x32, 0x10, 0x42};
+  return QuicConnectionId(reinterpret_cast<char*>(connection_id_bytes),
+                          sizeof(connection_id_bytes));
+}
+
+const QuicPacketNumber kPacketNumber = QuicPacketNumber(UINT64_C(0x12345678));
+const QuicPacketNumber kSmallLargestObserved =
+    QuicPacketNumber(UINT16_C(0x1234));
+const QuicPacketNumber kSmallMissingPacket = QuicPacketNumber(UINT16_C(0x1233));
+const QuicPacketNumber kLeastUnacked = QuicPacketNumber(UINT64_C(0x012345670));
+const QuicStreamId kStreamId = UINT64_C(0x01020304);
+// Note that the high 4 bits of the stream offset must be less than 0x40
+// in order to ensure that the value can be encoded using VarInt62 encoding.
+const QuicStreamOffset kStreamOffset = UINT64_C(0x3A98FEDC32107654);
+const QuicPublicResetNonceProof kNonceProof = UINT64_C(0xABCDEF0123456789);
+
+// In testing that we can ack the full range of packets...
+// This is the largest packet number that can be represented in IETF QUIC
+// varint62 format.
+const QuicPacketNumber kLargestIetfLargestObserved =
+    QuicPacketNumber(UINT64_C(0x3fffffffffffffff));
+// Encodings for the two bits in a VarInt62 that
+// describe the length of the VarInt61. For binary packet
+// formats in this file, the convention is to code the
+// first byte as
+//   kVarInt62FourBytes + 0x<value_in_that_byte>
+const uint8_t kVarInt62OneByte = 0x00;
+const uint8_t kVarInt62TwoBytes = 0x40;
+const uint8_t kVarInt62FourBytes = 0x80;
+const uint8_t kVarInt62EightBytes = 0xc0;
+
+class TestEncrypter : public QuicEncrypter {
+ public:
+  ~TestEncrypter() override {}
+  bool SetKey(absl::string_view /*key*/) override { return true; }
+  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
+    return true;
+  }
+  bool SetIV(absl::string_view /*iv*/) override { return true; }
+  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
+    return true;
+  }
+  bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
+                     absl::string_view plaintext, char* output,
+                     size_t* output_length,
+                     size_t /*max_output_length*/) override {
+    packet_number_ = QuicPacketNumber(packet_number);
+    associated_data_ = std::string(associated_data);
+    plaintext_ = std::string(plaintext);
+    memcpy(output, plaintext.data(), plaintext.length());
+    *output_length = plaintext.length();
+    return true;
+  }
+  std::string GenerateHeaderProtectionMask(
+      absl::string_view /*sample*/) override {
+    return std::string(5, 0);
+  }
+  size_t GetKeySize() const override { return 0; }
+  size_t GetNoncePrefixSize() const override { return 0; }
+  size_t GetIVSize() const override { return 0; }
+  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
+    return ciphertext_size;
+  }
+  size_t GetCiphertextSize(size_t plaintext_size) const override {
+    return plaintext_size;
+  }
+  QuicPacketCount GetConfidentialityLimit() const override {
+    return std::numeric_limits<QuicPacketCount>::max();
+  }
+  absl::string_view GetKey() const override { return absl::string_view(); }
+  absl::string_view GetNoncePrefix() const override {
+    return absl::string_view();
+  }
+
+  QuicPacketNumber packet_number_;
+  std::string associated_data_;
+  std::string plaintext_;
+};
+
+class TestDecrypter : public QuicDecrypter {
+ public:
+  ~TestDecrypter() override {}
+  bool SetKey(absl::string_view /*key*/) override { return true; }
+  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
+    return true;
+  }
+  bool SetIV(absl::string_view /*iv*/) override { return true; }
+  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
+    return true;
+  }
+  bool SetPreliminaryKey(absl::string_view /*key*/) override {
+    QUIC_BUG(quic_bug_10486_1) << "should not be called";
+    return false;
+  }
+  bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
+    return true;
+  }
+  bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
+                     absl::string_view ciphertext, char* output,
+                     size_t* output_length,
+                     size_t /*max_output_length*/) override {
+    packet_number_ = QuicPacketNumber(packet_number);
+    associated_data_ = std::string(associated_data);
+    ciphertext_ = std::string(ciphertext);
+    memcpy(output, ciphertext.data(), ciphertext.length());
+    *output_length = ciphertext.length();
+    return true;
+  }
+  std::string GenerateHeaderProtectionMask(
+      QuicDataReader* /*sample_reader*/) override {
+    return std::string(5, 0);
+  }
+  size_t GetKeySize() const override { return 0; }
+  size_t GetNoncePrefixSize() const override { return 0; }
+  size_t GetIVSize() const override { return 0; }
+  absl::string_view GetKey() const override { return absl::string_view(); }
+  absl::string_view GetNoncePrefix() const override {
+    return absl::string_view();
+  }
+  // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
+  uint32_t cipher_id() const override { return 0xFFFFFFF2; }
+  QuicPacketCount GetIntegrityLimit() const override {
+    return std::numeric_limits<QuicPacketCount>::max();
+  }
+  QuicPacketNumber packet_number_;
+  std::string associated_data_;
+  std::string ciphertext_;
+};
+
+std::unique_ptr<QuicEncryptedPacket> EncryptPacketWithTagAndPhase(
+    const QuicPacket& packet, uint8_t tag, bool phase) {
+  std::string packet_data = std::string(packet.AsStringPiece());
+  if (phase) {
+    packet_data[0] |= FLAGS_KEY_PHASE_BIT;
+  } else {
+    packet_data[0] &= ~FLAGS_KEY_PHASE_BIT;
+  }
+
+  TaggingEncrypter crypter(tag);
+  const size_t packet_size = crypter.GetCiphertextSize(packet_data.size());
+  char* buffer = new char[packet_size];
+  size_t buf_len = 0;
+  if (!crypter.EncryptPacket(0, absl::string_view(), packet_data, buffer,
+                             &buf_len, packet_size)) {
+    delete[] buffer;
+    return nullptr;
+  }
+
+  return std::make_unique<QuicEncryptedPacket>(buffer, buf_len,
+                                               /*owns_buffer=*/true);
+}
+
+class TestQuicVisitor : public QuicFramerVisitorInterface {
+ public:
+  TestQuicVisitor()
+      : error_count_(0),
+        version_mismatch_(0),
+        packet_count_(0),
+        frame_count_(0),
+        complete_packets_(0),
+        derive_next_key_count_(0),
+        decrypted_first_packet_in_key_phase_count_(0),
+        accept_packet_(true),
+        accept_public_header_(true) {}
+
+  ~TestQuicVisitor() override {}
+
+  void OnError(QuicFramer* f) override {
+    QUIC_DLOG(INFO) << "QuicFramer Error: " << QuicErrorCodeToString(f->error())
+                    << " (" << f->error() << ")";
+    ++error_count_;
+  }
+
+  void OnPacket() override {}
+
+  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
+    public_reset_packet_ = std::make_unique<QuicPublicResetPacket>((packet));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& packet) override {
+    version_negotiation_packet_ =
+        std::make_unique<QuicVersionNegotiationPacket>((packet));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  void OnRetryPacket(QuicConnectionId original_connection_id,
+                     QuicConnectionId new_connection_id,
+                     absl::string_view retry_token,
+                     absl::string_view retry_integrity_tag,
+                     absl::string_view retry_without_tag) override {
+    on_retry_packet_called_ = true;
+    retry_original_connection_id_ =
+        std::make_unique<QuicConnectionId>(original_connection_id);
+    retry_new_connection_id_ =
+        std::make_unique<QuicConnectionId>(new_connection_id);
+    retry_token_ = std::make_unique<std::string>(std::string(retry_token));
+    retry_token_integrity_tag_ =
+        std::make_unique<std::string>(std::string(retry_integrity_tag));
+    retry_without_tag_ =
+        std::make_unique<std::string>(std::string(retry_without_tag));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
+    QUIC_DLOG(INFO) << "QuicFramer Version Mismatch, version: "
+                    << received_version;
+    ++version_mismatch_;
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return false;
+  }
+
+  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override {
+    header_ = std::make_unique<QuicPacketHeader>((header));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return accept_public_header_;
+  }
+
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return true;
+  }
+
+  void OnDecryptedPacket(size_t /*length*/,
+                         EncryptionLevel /*level*/) override {
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  bool OnPacketHeader(const QuicPacketHeader& header) override {
+    ++packet_count_;
+    header_ = std::make_unique<QuicPacketHeader>((header));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return accept_packet_;
+  }
+
+  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {
+    coalesced_packets_.push_back(packet.Clone());
+  }
+
+  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                             EncryptionLevel decryption_level,
+                             bool has_decryption_key) override {
+    undecryptable_packets_.push_back(packet.Clone());
+    undecryptable_decryption_levels_.push_back(decryption_level);
+    undecryptable_has_decryption_keys_.push_back(has_decryption_key);
+  }
+
+  bool OnStreamFrame(const QuicStreamFrame& frame) override {
+    ++frame_count_;
+    // Save a copy of the data so it is valid after the packet is processed.
+    std::string* string_data =
+        new std::string(frame.data_buffer, frame.data_length);
+    stream_data_.push_back(absl::WrapUnique(string_data));
+    stream_frames_.push_back(std::make_unique<QuicStreamFrame>(
+        frame.stream_id, frame.fin, frame.offset, *string_data));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      // Low order bits of type encode flags, ignore them for this test.
+      EXPECT_TRUE(IS_IETF_STREAM_FRAME(framer_->current_received_frame_type()));
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
+    ++frame_count_;
+    // Save a copy of the data so it is valid after the packet is processed.
+    std::string* string_data =
+        new std::string(frame.data_buffer, frame.data_length);
+    crypto_data_.push_back(absl::WrapUnique(string_data));
+    crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>(
+        frame.level, frame.offset, *string_data));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_EQ(IETF_CRYPTO, framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time) override {
+    ++frame_count_;
+    QuicAckFrame ack_frame;
+    ack_frame.largest_acked = largest_acked;
+    ack_frame.ack_delay_time = ack_delay_time;
+    ack_frames_.push_back(std::make_unique<QuicAckFrame>(ack_frame));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
+                  IETF_ACK_ECN == framer_->current_received_frame_type() ||
+                  IETF_ACK_RECEIVE_TIMESTAMPS ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
+    QUICHE_DCHECK(!ack_frames_.empty());
+    ack_frames_[ack_frames_.size() - 1]->packets.AddRange(start, end);
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
+                  IETF_ACK_ECN == framer_->current_received_frame_type() ||
+                  IETF_ACK_RECEIVE_TIMESTAMPS ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnAckTimestamp(QuicPacketNumber packet_number,
+                      QuicTime timestamp) override {
+    ack_frames_[ack_frames_.size() - 1]->received_packet_times.push_back(
+        std::make_pair(packet_number, timestamp));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
+                  IETF_ACK_ECN == framer_->current_received_frame_type() ||
+                  IETF_ACK_RECEIVE_TIMESTAMPS ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
+
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
+    ++frame_count_;
+    stop_waiting_frames_.push_back(
+        std::make_unique<QuicStopWaitingFrame>(frame));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
+    padding_frames_.push_back(std::make_unique<QuicPaddingFrame>(frame));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_EQ(IETF_PADDING, framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnPingFrame(const QuicPingFrame& frame) override {
+    ++frame_count_;
+    ping_frames_.push_back(std::make_unique<QuicPingFrame>(frame));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_EQ(IETF_PING, framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnMessageFrame(const QuicMessageFrame& frame) override {
+    ++frame_count_;
+    message_frames_.push_back(
+        std::make_unique<QuicMessageFrame>(frame.data, frame.message_length));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 ==
+                      framer_->current_received_frame_type() ||
+                  IETF_EXTENSION_MESSAGE_V99 ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
+    ++frame_count_;
+    handshake_done_frames_.push_back(
+        std::make_unique<QuicHandshakeDoneFrame>(frame));
+    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_EQ(IETF_HANDSHAKE_DONE, framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
+    ++frame_count_;
+    ack_frequency_frames_.emplace_back(
+        std::make_unique<QuicAckFrequencyFrame>(frame));
+    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_EQ(IETF_ACK_FREQUENCY, framer_->current_received_frame_type());
+    return true;
+  }
+
+  void OnPacketComplete() override { ++complete_packets_; }
+
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
+    rst_stream_frame_ = frame;
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_EQ(IETF_RST_STREAM, framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
+    connection_close_frame_ = frame;
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_NE(GOOGLE_QUIC_CONNECTION_CLOSE, frame.close_type);
+      if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+        EXPECT_EQ(IETF_CONNECTION_CLOSE,
+                  framer_->current_received_frame_type());
+      } else {
+        EXPECT_EQ(IETF_APPLICATION_CLOSE,
+                  framer_->current_received_frame_type());
+      }
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
+    stop_sending_frame_ = frame;
+    EXPECT_EQ(IETF_STOP_SENDING, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
+    path_challenge_frame_ = frame;
+    EXPECT_EQ(IETF_PATH_CHALLENGE, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
+    path_response_frame_ = frame;
+    EXPECT_EQ(IETF_PATH_RESPONSE, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
+    goaway_frame_ = frame;
+    EXPECT_FALSE(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
+    max_streams_frame_ = frame;
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_TRUE(IETF_MAX_STREAMS_UNIDIRECTIONAL ==
+                    framer_->current_received_frame_type() ||
+                IETF_MAX_STREAMS_BIDIRECTIONAL ==
+                    framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
+    streams_blocked_frame_ = frame;
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_TRUE(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL ==
+                    framer_->current_received_frame_type() ||
+                IETF_STREAMS_BLOCKED_BIDIRECTIONAL ==
+                    framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
+    window_update_frame_ = frame;
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_MAX_DATA == framer_->current_received_frame_type() ||
+                  IETF_MAX_STREAM_DATA ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
+    blocked_frame_ = frame;
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_DATA_BLOCKED == framer_->current_received_frame_type() ||
+                  IETF_STREAM_DATA_BLOCKED ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
+    new_connection_id_ = frame;
+    EXPECT_EQ(IETF_NEW_CONNECTION_ID, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) override {
+    EXPECT_EQ(IETF_RETIRE_CONNECTION_ID,
+              framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    retire_connection_id_ = frame;
+    return true;
+  }
+
+  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
+    new_token_ = frame;
+    EXPECT_EQ(IETF_NEW_TOKEN, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const override {
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return token == kTestStatelessResetToken;
+  }
+
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& packet) override {
+    stateless_reset_packet_ =
+        std::make_unique<QuicIetfStatelessResetPacket>(packet);
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  void OnKeyUpdate(KeyUpdateReason reason) override {
+    key_update_reasons_.push_back(reason);
+  }
+
+  void OnDecryptedFirstPacketInKeyPhase() override {
+    decrypted_first_packet_in_key_phase_count_++;
+  }
+
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    derive_next_key_count_++;
+    return std::make_unique<StrictTaggingDecrypter>(derive_next_key_count_);
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return std::make_unique<TaggingEncrypter>(derive_next_key_count_);
+  }
+
+  void set_framer(QuicFramer* framer) {
+    framer_ = framer;
+    transport_version_ = framer->transport_version();
+  }
+
+  size_t key_update_count() const { return key_update_reasons_.size(); }
+
+  // Counters from the visitor_ callbacks.
+  int error_count_;
+  int version_mismatch_;
+  int packet_count_;
+  int frame_count_;
+  int complete_packets_;
+  std::vector<KeyUpdateReason> key_update_reasons_;
+  int derive_next_key_count_;
+  int decrypted_first_packet_in_key_phase_count_;
+  bool accept_packet_;
+  bool accept_public_header_;
+
+  std::unique_ptr<QuicPacketHeader> header_;
+  std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
+  std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
+  std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
+  std::unique_ptr<QuicConnectionId> retry_original_connection_id_;
+  std::unique_ptr<QuicConnectionId> retry_new_connection_id_;
+  std::unique_ptr<std::string> retry_token_;
+  std::unique_ptr<std::string> retry_token_integrity_tag_;
+  std::unique_ptr<std::string> retry_without_tag_;
+  bool on_retry_packet_called_ = false;
+  std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_;
+  std::vector<std::unique_ptr<QuicCryptoFrame>> crypto_frames_;
+  std::vector<std::unique_ptr<QuicAckFrame>> ack_frames_;
+  std::vector<std::unique_ptr<QuicStopWaitingFrame>> stop_waiting_frames_;
+  std::vector<std::unique_ptr<QuicPaddingFrame>> padding_frames_;
+  std::vector<std::unique_ptr<QuicPingFrame>> ping_frames_;
+  std::vector<std::unique_ptr<QuicMessageFrame>> message_frames_;
+  std::vector<std::unique_ptr<QuicHandshakeDoneFrame>> handshake_done_frames_;
+  std::vector<std::unique_ptr<QuicAckFrequencyFrame>> ack_frequency_frames_;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> coalesced_packets_;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> undecryptable_packets_;
+  std::vector<EncryptionLevel> undecryptable_decryption_levels_;
+  std::vector<bool> undecryptable_has_decryption_keys_;
+  QuicRstStreamFrame rst_stream_frame_;
+  QuicConnectionCloseFrame connection_close_frame_;
+  QuicStopSendingFrame stop_sending_frame_;
+  QuicGoAwayFrame goaway_frame_;
+  QuicPathChallengeFrame path_challenge_frame_;
+  QuicPathResponseFrame path_response_frame_;
+  QuicWindowUpdateFrame window_update_frame_;
+  QuicBlockedFrame blocked_frame_;
+  QuicStreamsBlockedFrame streams_blocked_frame_;
+  QuicMaxStreamsFrame max_streams_frame_;
+  QuicNewConnectionIdFrame new_connection_id_;
+  QuicRetireConnectionIdFrame retire_connection_id_;
+  QuicNewTokenFrame new_token_;
+  std::vector<std::unique_ptr<std::string>> stream_data_;
+  std::vector<std::unique_ptr<std::string>> crypto_data_;
+  QuicTransportVersion transport_version_;
+  QuicFramer* framer_;
+};
+
+// Simple struct for defining a packet's content, and associated
+// parse error.
+struct PacketFragment {
+  std::string error_if_missing;
+  std::vector<unsigned char> fragment;
+};
+
+using PacketFragments = std::vector<struct PacketFragment>;
+
+class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicFramerTest()
+      : encrypter_(new test::TestEncrypter()),
+        decrypter_(new test::TestDecrypter()),
+        version_(GetParam()),
+        start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)),
+        framer_(AllSupportedVersions(), start_, Perspective::IS_SERVER,
+                kQuicDefaultConnectionIdLength) {
+    framer_.set_version(version_);
+    if (framer_.version().KnowsWhichDecrypterToUse()) {
+      framer_.InstallDecrypter(ENCRYPTION_INITIAL,
+                               std::unique_ptr<QuicDecrypter>(decrypter_));
+    } else {
+      framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                           std::unique_ptr<QuicDecrypter>(decrypter_));
+    }
+    framer_.SetEncrypter(ENCRYPTION_INITIAL,
+                         std::unique_ptr<QuicEncrypter>(encrypter_));
+
+    framer_.set_visitor(&visitor_);
+    framer_.InferPacketHeaderTypeFromVersion();
+    visitor_.set_framer(&framer_);
+  }
+
+  void SetDecrypterLevel(EncryptionLevel level) {
+    if (!framer_.version().KnowsWhichDecrypterToUse()) {
+      return;
+    }
+    decrypter_ = new TestDecrypter();
+    framer_.InstallDecrypter(level, std::unique_ptr<QuicDecrypter>(decrypter_));
+  }
+
+  // Helper function to get unsigned char representation of the handshake
+  // protocol byte at position |pos| of the current QUIC version number.
+  unsigned char GetQuicVersionByte(int pos) {
+    return (CreateQuicVersionLabel(version_) >> 8 * (3 - pos)) & 0xff;
+  }
+
+  // Helper functions to take a v1 long header packet and make it v2. These are
+  // not needed for short header packets, but if sent, this function will exit
+  // cleanly. It needs to be called twice for coalesced packets (see references
+  // to length_of_first_coalesced_packet below for examples of how to do this).
+  inline void ReviseFirstByteByVersion(unsigned char packet_ietf[]) {
+    if (version_.UsesV2PacketTypes() && (packet_ietf[0] >= 0x80)) {
+      packet_ietf[0] = (packet_ietf[0] + 0x10) | 0xc0;
+    }
+  }
+  inline void ReviseFirstByteByVersion(PacketFragments& packet_ietf) {
+    ReviseFirstByteByVersion(&packet_ietf[0].fragment[0]);
+  }
+
+  bool CheckEncryption(QuicPacketNumber packet_number, QuicPacket* packet) {
+    if (packet_number != encrypter_->packet_number_) {
+      QUIC_LOG(ERROR) << "Encrypted incorrect packet number.  expected "
+                      << packet_number
+                      << " actual: " << encrypter_->packet_number_;
+      return false;
+    }
+    if (packet->AssociatedData(framer_.transport_version()) !=
+        encrypter_->associated_data_) {
+      QUIC_LOG(ERROR) << "Encrypted incorrect associated data.  expected "
+                      << packet->AssociatedData(framer_.transport_version())
+                      << " actual: " << encrypter_->associated_data_;
+      return false;
+    }
+    if (packet->Plaintext(framer_.transport_version()) !=
+        encrypter_->plaintext_) {
+      QUIC_LOG(ERROR) << "Encrypted incorrect plaintext data.  expected "
+                      << packet->Plaintext(framer_.transport_version())
+                      << " actual: " << encrypter_->plaintext_;
+      return false;
+    }
+    return true;
+  }
+
+  bool CheckDecryption(const QuicEncryptedPacket& encrypted,
+                       bool includes_version,
+                       bool includes_diversification_nonce,
+                       QuicConnectionIdLength destination_connection_id_length,
+                       QuicConnectionIdLength source_connection_id_length) {
+    return CheckDecryption(
+        encrypted, includes_version, includes_diversification_nonce,
+        destination_connection_id_length, source_connection_id_length,
+        VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  }
+
+  bool CheckDecryption(
+      const QuicEncryptedPacket& encrypted, bool includes_version,
+      bool includes_diversification_nonce,
+      QuicConnectionIdLength destination_connection_id_length,
+      QuicConnectionIdLength source_connection_id_length,
+      QuicVariableLengthIntegerLength retry_token_length_length,
+      size_t retry_token_length,
+      QuicVariableLengthIntegerLength length_length) {
+    if (visitor_.header_->packet_number != decrypter_->packet_number_) {
+      QUIC_LOG(ERROR) << "Decrypted incorrect packet number.  expected "
+                      << visitor_.header_->packet_number
+                      << " actual: " << decrypter_->packet_number_;
+      return false;
+    }
+    absl::string_view associated_data =
+        QuicFramer::GetAssociatedDataFromEncryptedPacket(
+            framer_.transport_version(), encrypted,
+            destination_connection_id_length, source_connection_id_length,
+            includes_version, includes_diversification_nonce,
+            PACKET_4BYTE_PACKET_NUMBER, retry_token_length_length,
+            retry_token_length, length_length);
+    if (associated_data != decrypter_->associated_data_) {
+      QUIC_LOG(ERROR) << "Decrypted incorrect associated data.  expected "
+                      << absl::BytesToHexString(associated_data) << " actual: "
+                      << absl::BytesToHexString(decrypter_->associated_data_);
+      return false;
+    }
+    absl::string_view ciphertext(
+        encrypted.AsStringPiece().substr(GetStartOfEncryptedData(
+            framer_.transport_version(), destination_connection_id_length,
+            source_connection_id_length, includes_version,
+            includes_diversification_nonce, PACKET_4BYTE_PACKET_NUMBER,
+            retry_token_length_length, retry_token_length, length_length)));
+    if (ciphertext != decrypter_->ciphertext_) {
+      QUIC_LOG(ERROR) << "Decrypted incorrect ciphertext data.  expected "
+                      << absl::BytesToHexString(ciphertext) << " actual: "
+                      << absl::BytesToHexString(decrypter_->ciphertext_)
+                      << " associated data: "
+                      << absl::BytesToHexString(associated_data);
+      return false;
+    }
+    return true;
+  }
+
+  char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); }
+
+  // Creates a new QuicEncryptedPacket by concatenating the various
+  // packet fragments in |fragments|.
+  std::unique_ptr<QuicEncryptedPacket> AssemblePacketFromFragments(
+      const PacketFragments& fragments) {
+    char* buffer = new char[kMaxOutgoingPacketSize + 1];
+    size_t len = 0;
+    for (const auto& fragment : fragments) {
+      memcpy(buffer + len, fragment.fragment.data(), fragment.fragment.size());
+      len += fragment.fragment.size();
+    }
+    return std::make_unique<QuicEncryptedPacket>(buffer, len, true);
+  }
+
+  void CheckFramingBoundaries(const PacketFragments& fragments,
+                              QuicErrorCode error_code) {
+    std::unique_ptr<QuicEncryptedPacket> packet(
+        AssemblePacketFromFragments(fragments));
+    // Check all the various prefixes of |packet| for the expected
+    // parse error and error code.
+    for (size_t i = 0; i < packet->length(); ++i) {
+      std::string expected_error;
+      size_t len = 0;
+      for (const auto& fragment : fragments) {
+        len += fragment.fragment.size();
+        if (i < len) {
+          expected_error = fragment.error_if_missing;
+          break;
+        }
+      }
+
+      if (expected_error.empty()) continue;
+
+      CheckProcessingFails(*packet, i, expected_error, error_code);
+    }
+  }
+
+  void CheckProcessingFails(const QuicEncryptedPacket& packet, size_t len,
+                            std::string expected_error,
+                            QuicErrorCode error_code) {
+    QuicEncryptedPacket encrypted(packet.data(), len, false);
+    EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len;
+    EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len;
+    EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
+  }
+
+  void CheckProcessingFails(unsigned char* packet, size_t len,
+                            std::string expected_error,
+                            QuicErrorCode error_code) {
+    QuicEncryptedPacket encrypted(AsChars(packet), len, false);
+    EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len;
+    EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len;
+    EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
+  }
+
+  // Checks if the supplied string matches data in the supplied StreamFrame.
+  void CheckStreamFrameData(std::string str, QuicStreamFrame* frame) {
+    EXPECT_EQ(str, std::string(frame->data_buffer, frame->data_length));
+  }
+
+  void CheckCalculatePacketNumber(uint64_t expected_packet_number,
+                                  QuicPacketNumber last_packet_number) {
+    uint64_t wire_packet_number = expected_packet_number & kMask;
+    EXPECT_EQ(expected_packet_number,
+              QuicFramerPeer::CalculatePacketNumberFromWire(
+                  &framer_, PACKET_4BYTE_PACKET_NUMBER, last_packet_number,
+                  wire_packet_number))
+        << "last_packet_number: " << last_packet_number
+        << " wire_packet_number: " << wire_packet_number;
+  }
+
+  std::unique_ptr<QuicPacket> BuildDataPacket(const QuicPacketHeader& header,
+                                              const QuicFrames& frames) {
+    return BuildUnsizedDataPacket(&framer_, header, frames);
+  }
+
+  std::unique_ptr<QuicPacket> BuildDataPacket(const QuicPacketHeader& header,
+                                              const QuicFrames& frames,
+                                              size_t packet_size) {
+    return BuildUnsizedDataPacket(&framer_, header, frames, packet_size);
+  }
+
+  // N starts at 1.
+  QuicStreamId GetNthStreamid(QuicTransportVersion transport_version,
+                              Perspective perspective, bool bidirectional,
+                              int n) {
+    if (bidirectional) {
+      return QuicUtils::GetFirstBidirectionalStreamId(transport_version,
+                                                      perspective) +
+             ((n - 1) * QuicUtils::StreamIdDelta(transport_version));
+    }
+    // Unidirectional
+    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version,
+                                                     perspective) +
+           ((n - 1) * QuicUtils::StreamIdDelta(transport_version));
+  }
+
+  QuicTime CreationTimePlus(uint64_t offset_us) {
+    return framer_.creation_time() +
+           QuicTime::Delta::FromMicroseconds(offset_us);
+  }
+
+  test::TestEncrypter* encrypter_;
+  test::TestDecrypter* decrypter_;
+  ParsedQuicVersion version_;
+  QuicTime start_;
+  QuicFramer framer_;
+  test::TestQuicVisitor visitor_;
+  quiche::SimpleBufferAllocator allocator_;
+};
+
+// Multiple test cases of QuicFramerTest use byte arrays to define packets for
+// testing, and these byte arrays contain the QUIC version. This macro explodes
+// the 32-bit version into four bytes in network order. Since it uses methods of
+// QuicFramerTest, it is only valid to use this in a QuicFramerTest.
+#define QUIC_VERSION_BYTES                                             \
+  GetQuicVersionByte(0), GetQuicVersionByte(1), GetQuicVersionByte(2), \
+      GetQuicVersionByte(3)
+
+// Run all framer tests with all supported versions of QUIC.
+INSTANTIATE_TEST_SUITE_P(QuicFramerTests, QuicFramerTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) {
+  // A few quick manual sanity checks.
+  CheckCalculatePacketNumber(UINT64_C(1), QuicPacketNumber());
+  CheckCalculatePacketNumber(kEpoch + 1, QuicPacketNumber(kMask));
+  CheckCalculatePacketNumber(kEpoch, QuicPacketNumber(kMask));
+  for (uint64_t j = 0; j < 10; j++) {
+    CheckCalculatePacketNumber(j, QuicPacketNumber());
+    CheckCalculatePacketNumber(kEpoch - 1 - j, QuicPacketNumber());
+  }
+
+  // Cases where the last number was close to the start of the range.
+  for (QuicPacketNumber last = QuicPacketNumber(1); last < QuicPacketNumber(10);
+       last++) {
+    // Small numbers should not wrap (even if they're out of order).
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(j, last);
+    }
+
+    // Large numbers should not wrap either (because we're near 0 already).
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(kEpoch - 1 - j, last);
+    }
+  }
+}
+
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochEnd) {
+  // Cases where the last number was close to the end of the range
+  for (uint64_t i = 0; i < 10; i++) {
+    QuicPacketNumber last = QuicPacketNumber(kEpoch - i);
+
+    // Small numbers should wrap.
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(kEpoch + j, last);
+    }
+
+    // Large numbers should not (even if they're out of order).
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(kEpoch - 1 - j, last);
+    }
+  }
+}
+
+// Next check where we're in a non-zero epoch to verify we handle
+// reverse wrapping, too.
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearPrevEpoch) {
+  const uint64_t prev_epoch = 1 * kEpoch;
+  const uint64_t cur_epoch = 2 * kEpoch;
+  // Cases where the last number was close to the start of the range
+  for (uint64_t i = 0; i < 10; i++) {
+    QuicPacketNumber last = QuicPacketNumber(cur_epoch + i);
+    // Small number should not wrap (even if they're out of order).
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(cur_epoch + j, last);
+    }
+
+    // But large numbers should reverse wrap.
+    for (uint64_t j = 0; j < 10; j++) {
+      uint64_t num = kEpoch - 1 - j;
+      CheckCalculatePacketNumber(prev_epoch + num, last);
+    }
+  }
+}
+
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextEpoch) {
+  const uint64_t cur_epoch = 2 * kEpoch;
+  const uint64_t next_epoch = 3 * kEpoch;
+  // Cases where the last number was close to the end of the range
+  for (uint64_t i = 0; i < 10; i++) {
+    QuicPacketNumber last = QuicPacketNumber(next_epoch - 1 - i);
+
+    // Small numbers should wrap.
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(next_epoch + j, last);
+    }
+
+    // but large numbers should not (even if they're out of order).
+    for (uint64_t j = 0; j < 10; j++) {
+      uint64_t num = kEpoch - 1 - j;
+      CheckCalculatePacketNumber(cur_epoch + num, last);
+    }
+  }
+}
+
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextMax) {
+  const uint64_t max_number = std::numeric_limits<uint64_t>::max();
+  const uint64_t max_epoch = max_number & ~kMask;
+
+  // Cases where the last number was close to the end of the range
+  for (uint64_t i = 0; i < 10; i++) {
+    // Subtract 1, because the expected next packet number is 1 more than the
+    // last packet number.
+    QuicPacketNumber last = QuicPacketNumber(max_number - i - 1);
+
+    // Small numbers should not wrap, because they have nowhere to go.
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(max_epoch + j, last);
+    }
+
+    // Large numbers should not wrap either.
+    for (uint64_t j = 0; j < 10; j++) {
+      uint64_t num = kEpoch - 1 - j;
+      CheckCalculatePacketNumber(max_epoch + num, last);
+    }
+  }
+}
+
+TEST_P(QuicFramerTest, EmptyPacket) {
+  char packet[] = {0x00};
+  QuicEncryptedPacket encrypted(packet, 0, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+}
+
+TEST_P(QuicFramerTest, LargePacket) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[kMaxIncomingPacketSize + 1] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78, 0x56, 0x34, 0x12,
+    // private flags
+    0x00,
+  };
+  unsigned char packet46[kMaxIncomingPacketSize + 1] = {
+    // type (short header 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78, 0x56, 0x34, 0x12,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  const size_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+
+  memset(p + header_size, 0, kMaxIncomingPacketSize - header_size);
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  ASSERT_TRUE(visitor_.header_.get());
+  // Make sure we've parsed the packet header, so we can send an error.
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  // Make sure the correct error is propagated.
+  EXPECT_THAT(framer_.error(), IsError(QUIC_PACKET_TOO_LARGE));
+  EXPECT_EQ("Packet too large.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, PacketHeader) {
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"Unable to read public flags.",
+       {0x28}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments = packet;
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+
+  PacketHeaderFormat format;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_flag;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  QuicVersionLabel version_label;
+  std::string detailed_error;
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+      *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_flag, &use_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_FALSE(use_length_prefix);
+  EXPECT_THAT(error_code, IsQuicNoError());
+  EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
+  EXPECT_FALSE(version_flag);
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+}
+
+TEST_P(QuicFramerTest, LongPacketHeader) {
+  // clang-format off
+  PacketFragments packet46 = {
+    // type (long header with packet type ZERO_RTT)
+    {"Unable to read first byte.",
+     {0xD3}},
+    // version tag
+    {"Unable to read protocol version.",
+     {QUIC_VERSION_BYTES}},
+    // connection_id length
+    {"Unable to read ConnectionId length.",
+     {0x50}},
+    // connection_id
+    {"Unable to read destination connection ID.",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"Unable to read packet number.",
+     {0x12, 0x34, 0x56, 0x78}},
+  };
+  // clang-format on
+
+  if (!framer_.version().HasIetfInvariantHeader() ||
+      QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet46));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_TRUE(visitor_.header_->version_flag);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(packet46, QUIC_INVALID_PACKET_HEADER);
+
+  PacketHeaderFormat format;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_flag;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  QuicVersionLabel version_label;
+  std::string detailed_error;
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+      *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_flag, &use_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_THAT(error_code, IsQuicNoError());
+  EXPECT_EQ("", detailed_error);
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_FALSE(use_length_prefix);
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+  EXPECT_TRUE(version_flag);
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+}
+
+TEST_P(QuicFramerTest, LongPacketHeaderWithBothConnectionIds) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type ZERO_RTT_PROTECTED and
+    // 4-byte packet number)
+    0xD3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x55,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type ZERO_RTT_PROTECTED and
+    // 4-byte packet number)
+    0xD3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_flag = false;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  QuicVersionLabel version_label = 0;
+  std::string detailed_error = "";
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_flag, &use_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_THAT(error_code, IsQuicNoError());
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_EQ(framer_.version().HasLengthPrefixedConnectionIds(),
+            use_length_prefix);
+  EXPECT_EQ("", detailed_error);
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+  EXPECT_TRUE(version_flag);
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(FramerTestConnectionIdPlusOne(), source_connection_id);
+}
+
+TEST_P(QuicFramerTest, AllZeroPacketParsingFails) {
+  unsigned char packet[1200] = {};
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_flag = false;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  QuicVersionLabel version_label = 0;
+  std::string detailed_error = "";
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_flag, &use_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_EQ(error_code, QUIC_INVALID_PACKET_HEADER);
+  EXPECT_EQ(detailed_error, "Invalid flags.");
+}
+
+TEST_P(QuicFramerTest, ParsePublicHeader) {
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (version included, 8-byte connection ID,
+    // 4-byte packet number)
+    0x29,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // version
+    QUIC_VERSION_BYTES,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // padding frame
+    0x00,
+  };
+  unsigned char packet46[] = {
+      // public flags (long header with packet type HANDSHAKE and
+      // 4-byte packet number)
+      0xE3,
+      // version
+      QUIC_VERSION_BYTES,
+      // connection ID lengths
+      0x50,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // long header packet length
+      0x05,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // padding frame
+      0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x00,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_length = ABSL_ARRAYSIZE(packet46);
+  }
+
+  uint8_t first_byte = 0x33;
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  bool version_present = false, has_length_prefix = false;
+  QuicVersionLabel version_label = 0;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
+                   source_connection_id = EmptyQuicConnectionId();
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  QuicVariableLengthIntegerLength retry_token_length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_4;
+  absl::string_view retry_token;
+  std::string detailed_error = "foobar";
+
+  QuicDataReader reader(AsChars(p), p_length);
+  const QuicErrorCode parse_error = QuicFramer::ParsePublicHeader(
+      &reader, kQuicDefaultConnectionIdLength,
+      /*ietf_format=*/
+      framer_.version().HasIetfInvariantHeader(), &first_byte, &format,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &long_packet_type,
+      &retry_token_length_length, &retry_token, &detailed_error);
+  EXPECT_THAT(parse_error, IsQuicNoError());
+  EXPECT_EQ("", detailed_error);
+  EXPECT_EQ(p[0], first_byte);
+  EXPECT_TRUE(version_present);
+  EXPECT_EQ(framer_.version().HasLengthPrefixedConnectionIds(),
+            has_length_prefix);
+  EXPECT_EQ(CreateQuicVersionLabel(framer_.version()), version_label);
+  EXPECT_EQ(framer_.version(), parsed_version);
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+  EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
+  EXPECT_EQ(absl::string_view(), retry_token);
+  if (framer_.version().HasIetfInvariantHeader()) {
+    EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+    EXPECT_EQ(HANDSHAKE, long_packet_type);
+  } else {
+    EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
+  }
+}
+
+TEST_P(QuicFramerTest, ParsePublicHeaderProxBadSourceConnectionIdLength) {
+  if (!framer_.version().HasLengthPrefixedConnectionIds()) {
+    return;
+  }
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    'P', 'R', 'O', 'X',
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length (bogus)
+    0xEE,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+
+  uint8_t first_byte = 0x33;
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  bool version_present = false, has_length_prefix = false;
+  QuicVersionLabel version_label = 0;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
+                   source_connection_id = EmptyQuicConnectionId();
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  QuicVariableLengthIntegerLength retry_token_length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_4;
+  absl::string_view retry_token;
+  std::string detailed_error = "foobar";
+
+  QuicDataReader reader(AsChars(p), p_length);
+  const QuicErrorCode parse_error = QuicFramer::ParsePublicHeader(
+      &reader, kQuicDefaultConnectionIdLength,
+      /*ietf_format=*/true, &first_byte, &format, &version_present,
+      &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &long_packet_type,
+      &retry_token_length_length, &retry_token, &detailed_error);
+  EXPECT_THAT(parse_error, IsQuicNoError());
+  EXPECT_EQ("", detailed_error);
+  EXPECT_EQ(p[0], first_byte);
+  EXPECT_TRUE(version_present);
+  EXPECT_TRUE(has_length_prefix);
+  EXPECT_EQ(0x50524F58u, version_label);  // "PROX"
+  EXPECT_EQ(UnsupportedQuicVersion(), parsed_version);
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+  EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
+  EXPECT_EQ(absl::string_view(), retry_token);
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+}
+
+TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToClient) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
+                                                      TestConnectionId(0x33));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  framer_.SetExpectedClientConnectionIdLength(kQuicDefaultConnectionIdLength);
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x13, 0x37, 0x42, 0x33,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_EQ("", framer_.detailed_error());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+}
+
+// In short header packets from client to server, the client connection ID
+// is omitted, but the framer adds it to the header struct using its
+// last serialized client connection ID. This test ensures that this
+// mechanism behaves as expected.
+TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToServer) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLastSerializedClientConnectionId(&framer_,
+                                                      TestConnectionId(0x33));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x13, 0x37, 0x42, 0x33,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_EQ("", framer_.detailed_error());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
+                                                      FramerTestConnectionId());
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (0 byte connection_id)
+      {"Unable to read public flags.",
+       {0x20}},
+      // connection_id
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet46 = {
+        // type (short header, 4 byte packet number)
+        {"Unable to read first byte.",
+         {0x43}},
+        // connection_id
+        // packet number
+        {"Unable to read packet number.",
+         {0x12, 0x34, 0x56, 0x78}},
+   };
+
+  PacketFragments packet_hp = {
+        // type (short header, 4 byte packet number)
+        {"Unable to read first byte.",
+         {0x43}},
+        // connection_id
+        // packet number
+        {"",
+         {0x12, 0x34, 0x56, 0x78}},
+   };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (0 byte connection_id)
+      {"Unable to read public flags.",
+       {0x29}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // version tag
+      {"Unable to read protocol version.",
+       {QUIC_VERSION_BYTES}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet46 = {
+      // type (long header with packet type ZERO_RTT_PROTECTED and 4 bytes
+      // packet number)
+      {"Unable to read first byte.",
+       {0xD3}},
+      // version tag
+      {"Unable to read protocol version.",
+       {QUIC_VERSION_BYTES}},
+      // connection_id length
+      {"Unable to read ConnectionId length.",
+       {0x50}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet49 = {
+      // type (long header with packet type ZERO_RTT_PROTECTED and 4 bytes
+      // packet number)
+      {"Unable to read first byte.",
+       {0xD3}},
+      // version tag
+      {"Unable to read protocol version.",
+       {QUIC_VERSION_BYTES}},
+      // destination connection ID length
+      {"Unable to read destination connection ID.",
+       {0x08}},
+      // destination connection ID
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // source connection ID length
+      {"Unable to read source connection ID.",
+       {0x00}},
+      // long header packet length
+      {"Unable to read long header payload length.",
+       {0x04}},
+      // packet number
+      {"Long header payload length longer than packet.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+  // clang-format on
+
+  ReviseFirstByteByVersion(packet49);
+  PacketFragments& fragments =
+      framer_.version().HasLongHeaderLengths()
+          ? packet49
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_TRUE(visitor_.header_->version_flag);
+  EXPECT_EQ(GetParam(), visitor_.header_->version);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id and 4 byte packet number)
+      {"Unable to read public flags.",
+       {0x28}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"Unable to read first byte.",
+       {0x43}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet_hp = {
+      // type (short header, 4 byte packet number)
+      {"Unable to read first byte.",
+       {0x43}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id and 2 byte packet number)
+      {"Unable to read public flags.",
+       {0x18}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x56, 0x78}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 2 byte packet number)
+      {"Unable to read first byte.",
+       {0x41}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x56, 0x78}},
+  };
+
+  PacketFragments packet_hp = {
+      // type (short header, 2 byte packet number)
+      {"Unable to read first byte.",
+       {0x41}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x56, 0x78}},
+      // padding
+      {"", {0x00, 0x00}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsQuicNoError());
+  } else {
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  }
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id and 1 byte packet number)
+      {"Unable to read public flags.",
+       {0x08}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x78}},
+  };
+
+  PacketFragments packet46 = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read first byte.",
+       {0x40}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x78}},
+  };
+
+  PacketFragments packet_hp = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read first byte.",
+       {0x40}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x78}},
+      // padding
+      {"", {0x00, 0x00, 0x00}},
+  };
+
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsQuicNoError());
+  } else {
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  }
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketNumberDecreasesThenIncreases) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // Test the case when a packet is received from the past and future packet
+  // numbers are still calculated relative to the largest received packet.
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber - 2;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  QuicEncryptedPacket encrypted(data->data(), data->length(), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber - 2, visitor_.header_->packet_number);
+
+  // Receive a 1 byte packet number.
+  header.packet_number = kPacketNumber;
+  header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  QuicEncryptedPacket encrypted1(data->data(), data->length(), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted1));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  // Process a 2 byte packet number 256 packets ago.
+  header.packet_number = kPacketNumber - 256;
+  header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  QuicEncryptedPacket encrypted2(data->data(), data->length(), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted2));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber - 256, visitor_.header_->packet_number);
+
+  // Process another 1 byte packet number and ensure it works.
+  header.packet_number = kPacketNumber - 1;
+  header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  QuicEncryptedPacket encrypted3(data->data(), data->length(), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted3));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber - 1, visitor_.header_->packet_number);
+}
+
+TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags: includes nonce flag
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // nonce
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[] = {
+    // type: Long header with packet type ZERO_RTT_PROTECTED and 1 byte packet
+    // number.
+    0xD0,
+    // version tag
+    QUIC_VERSION_BYTES,
+    // connection_id length
+    0x05,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78,
+    // nonce
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+
+    // frame type (padding)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet49[] = {
+    // type: Long header with packet type ZERO_RTT_PROTECTED and 1 byte packet
+    // number.
+    0xD0,
+    // version tag
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x00,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x26,
+    // packet number
+    0x78,
+    // nonce
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+
+    // frame type (padding)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  if (framer_.version().handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
+    return;
+  }
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_size = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  ASSERT_TRUE(visitor_.header_->nonce != nullptr);
+  for (char i = 0; i < 32; ++i) {
+    EXPECT_EQ(i, (*visitor_.header_->nonce)[static_cast<size_t>(i)]);
+  }
+  EXPECT_EQ(1u, visitor_.padding_frames_.size());
+  EXPECT_EQ(5, visitor_.padding_frames_[0]->num_padding_bytes);
+}
+
+TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id, version flag and an unknown flag)
+    0x29,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // version tag
+    'Q', '0', '0', '0',
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
+    0xD3,
+    // version tag
+    'Q', '0', '0', '0',
+    // connection_id length
+    0x50,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet49[] = {
+    // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
+    0xD3,
+    // version tag
+    'Q', '0', '0', '0',
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x00,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_size = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(0, visitor_.frame_count_);
+  EXPECT_EQ(1, visitor_.version_mismatch_);
+}
+
+TEST_P(QuicFramerTest, PaddingFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
+    0x08 | 0x01 | 0x02 | 0x04,
+
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    kVarInt62OneByte + 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  EXPECT_EQ(2u, visitor_.padding_frames_.size());
+  EXPECT_EQ(2, visitor_.padding_frames_[0]->num_padding_bytes);
+  EXPECT_EQ(2, visitor_.padding_frames_[1]->num_padding_bytes);
+  EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+}
+
+TEST_P(QuicFramerTest, StreamFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFF}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFF}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
+      {"",
+       { 0x08 | 0x01 | 0x02 | 0x04 }},
+      // stream id
+      {"Unable to read IETF_STREAM frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read stream data offset.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Unable to read stream data length.",
+       {kVarInt62OneByte + 0x0c}},
+      // data
+      {"Unable to read frame data.",
+       { 'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
+}
+
+// Test an empty (no data) stream frame.
+TEST_P(QuicFramerTest, EmptyStreamFrame) {
+  // Only the IETF QUIC spec explicitly says that empty
+  // stream frames are supported.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
+      {"",
+       { 0x08 | 0x01 | 0x02 | 0x04 }},
+      // stream id
+      {"Unable to read IETF_STREAM frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read stream data offset.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Unable to read stream data length.",
+       {kVarInt62OneByte + 0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  EXPECT_EQ(visitor_.stream_frames_[0].get()->data_length, 0u);
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, MissingDiversificationNonce) {
+  if (framer_.version().handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
+    // TLS does not use diversification nonces.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  decrypter_ = new test::TestDecrypter();
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_INITIAL,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+                             std::unique_ptr<QuicDecrypter>(decrypter_));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 Perspective::IS_CLIENT));
+    framer_.SetAlternativeDecrypter(
+        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+  }
+
+  // clang-format off
+  unsigned char packet[] = {
+        // public flags (8 byte connection_id)
+        0x28,
+        // connection_id
+        0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+        // packet number
+        0x12, 0x34, 0x56, 0x78,
+        // padding frame
+        0x00,
+    };
+
+  unsigned char packet46[] = {
+        // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
+        0xD3,
+        // version tag
+        QUIC_VERSION_BYTES,
+        // connection_id length
+        0x05,
+        // connection_id
+        0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+        // packet number
+        0x12, 0x34, 0x56, 0x78,
+        // padding frame
+        0x00,
+    };
+
+  unsigned char packet49[] = {
+        // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
+        0xD3,
+        // version tag
+        QUIC_VERSION_BYTES,
+        // destination connection ID length
+        0x00,
+        // source connection ID length
+        0x08,
+        // source connection ID
+        0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+        // IETF long header payload length
+        0x05,
+        // packet number
+        0x12, 0x34, 0x56, 0x78,
+        // padding frame
+        0x00,
+    };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_length = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+    EXPECT_EQ("Unable to decrypt ENCRYPTION_ZERO_RTT header protection.",
+              framer_.detailed_error());
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    // Cannot read diversification nonce.
+    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+    EXPECT_EQ("Unable to read nonce.", framer_.detailed_error());
+  } else {
+    EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+  }
+}
+
+TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
+  if (framer_.version().HasIetfInvariantHeader()) {
+    // This test is nonsensical for IETF Quic.
+    return;
+  }
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFE}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments = packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFD}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (stream frame with fin)
+       {"",
+        {0xFD}},
+       // stream id
+       {"Unable to read stream_id.",
+        {0x03, 0x04}},
+       // offset
+       {"Unable to read offset.",
+        {0x3A, 0x98, 0xFE, 0xDC,
+         0x32, 0x10, 0x76, 0x54}},
+       {"Unable to read frame data.",
+        {
+          // data length
+          0x00, 0x0c,
+          // data
+          'h',  'e',  'l',  'l',
+          'o',  ' ',  'w',  'o',
+          'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_STREAM frame with LEN, FIN, and OFFSET bits set)
+      {"",
+       {0x08 | 0x01 | 0x02 | 0x04}},
+      // stream id
+      {"Unable to read IETF_STREAM frame stream id/count.",
+       {kVarInt62TwoBytes + 0x03, 0x04}},
+      // offset
+      {"Unable to read stream data offset.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Unable to read stream data length.",
+       {kVarInt62OneByte + 0x0c}},
+      // data
+      {"Unable to read frame data.",
+       { 'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  // Stream ID should be the last 2 bytes of kStreamId.
+  EXPECT_EQ(0x0000FFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFC}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFC}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_STREAM frame with LEN, FIN, and OFFSET bits set)
+      {"",
+       {0x08 | 0x01 | 0x02 | 0x04}},
+      // stream id
+      {"Unable to read IETF_STREAM frame stream id/count.",
+       {kVarInt62OneByte + 0x04}},
+      // offset
+      {"Unable to read stream data offset.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Unable to read stream data length.",
+       {kVarInt62OneByte + 0x0c}},
+      // data
+      {"Unable to read frame data.",
+       { 'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  // Stream ID should be the last 1 byte of kStreamId.
+  EXPECT_EQ(0x000000FF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, StreamFrameWithVersion) {
+  // If IETF frames are in use then we must also have the IETF
+  // header invariants.
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    QUICHE_DCHECK(framer_.version().HasIetfInvariantHeader());
+  }
+
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (version, 8 byte connection_id)
+      {"",
+       {0x29}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // version tag
+      {"",
+       {QUIC_VERSION_BYTES}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFE}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet46 = {
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      {"",
+       {0xD3}},
+      // version tag
+      {"",
+       {QUIC_VERSION_BYTES}},
+      // connection_id length
+      {"",
+       {0x50}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFE}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet49 = {
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      {"",
+       {0xD3}},
+      // version tag
+      {"",
+       {QUIC_VERSION_BYTES}},
+      // destination connection ID length
+      {"",
+       {0x08}},
+      // destination connection ID
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // source connection ID length
+      {"",
+       {0x00}},
+      // long header packet length
+      {"",
+       {0x1E}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFE}},
+      // stream id
+      {"Long header payload length longer than packet.",
+       {0x02, 0x03, 0x04}},
+      // offset
+      {"Long header payload length longer than packet.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Long header payload length longer than packet.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      {"",
+       {0xD3}},
+      // version tag
+      {"",
+       {QUIC_VERSION_BYTES}},
+      // destination connection ID length
+      {"",
+       {0x08}},
+      // destination connection ID
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // source connection ID length
+      {"",
+       {0x00}},
+      // long header packet length
+      {"",
+       {0x1E}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      {"",
+       {0x08 | 0x01 | 0x02 | 0x04}},
+      // stream id
+      {"Long header payload length longer than packet.",
+       {kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04}},
+      // offset
+      {"Long header payload length longer than packet.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Long header payload length longer than packet.",
+       {kVarInt62OneByte + 0x0c}},
+      // data
+      {"Long header payload length longer than packet.",
+       { 'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  QuicVariableLengthIntegerLength retry_token_length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  size_t retry_token_length = 0;
+  QuicVariableLengthIntegerLength length_length =
+      QuicVersionHasLongHeaderLengths(framer_.transport_version())
+          ? VARIABLE_LENGTH_INTEGER_LENGTH_1
+          : VARIABLE_LENGTH_INTEGER_LENGTH_0;
+
+  ReviseFirstByteByVersion(packet_ietf);
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasLongHeaderLengths()
+                 ? packet49
+                 : (framer_.version().HasIetfInvariantHeader() ? packet46
+                                                               : packet));
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID,
+      retry_token_length_length, retry_token_length, length_length));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, framer_.version().HasLongHeaderLengths()
+                                        ? QUIC_INVALID_PACKET_HEADER
+                                        : QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, RejectPacket) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  visitor_.accept_packet_ = false;
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x28,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (stream frame with fin)
+      0xFF,
+      // stream id
+      0x01, 0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (STREAM Frame with FIN, LEN, and OFFSET bits set)
+      0x10 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+  QuicEncryptedPacket encrypted(AsChars(p),
+                                framer_.version().HasIetfInvariantHeader()
+                                    ? ABSL_ARRAYSIZE(packet46)
+                                    : ABSL_ARRAYSIZE(packet),
+                                false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(0u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+}
+
+TEST_P(QuicFramerTest, RejectPublicHeader) {
+  visitor_.accept_public_header_ = false;
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 1 byte packet number)
+    0x40,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x01,
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(
+      framer_.version().HasIetfInvariantHeader() ? AsChars(packet46)
+                                                 : AsChars(packet),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet),
+      false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_FALSE(visitor_.header_->packet_number.IsInitialized());
+}
+
+TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x2C}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       {0x45}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x12, 0x34}},
+      // num timestamps.
+      {"Unable to read num received packets.",
+       {0x00}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short packet, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       {0x45}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x12, 0x34}},
+      // num timestamps.
+      {"Unable to read num received packets.",
+       {0x00}}
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short packet, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK)
+       // (one ack block, 2 byte largest observed, 2 byte block length)
+       // IETF-Quic ignores the bit-fields in the ack type, all of
+       // that information is encoded elsewhere in the frame.
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62TwoBytes  + 0x12, 0x34}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+      // Ack block count (0 -- no blocks after the first)
+      {"Unable to read ack block count.",
+       {kVarInt62OneByte + 0x00}},
+       // first ack block length - 1.
+       // IETF Quic defines the ack block's value as the "number of
+       // packets that preceed the largest packet number in the block"
+       // which for the 1st ack block is the largest acked field,
+       // above. This means that if we are acking just packet 0x1234
+       // then the 1st ack block will be 0.
+       {"Unable to read first ack block length.",
+        {kVarInt62TwoBytes + 0x12, 0x33}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(kSmallLargestObserved, LargestAcked(frame));
+  ASSERT_EQ(4660u, frame.packets.NumPacketsSlow());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
+}
+
+// This test checks that the ack frame processor correctly identifies
+// and handles the case where the first ack block is larger than the
+// largest_acked packet.
+TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x2C}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       {0x45}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x88, 0x88}},
+      // num timestamps.
+      {"Underflow with first ack block length 34952 largest acked is 4660.",
+       {0x00}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       {0x45}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x88, 0x88}},
+      // num timestamps.
+      {"Underflow with first ack block length 34952 largest acked is 4660.",
+       {0x00}}
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62TwoBytes  + 0x12, 0x34}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (0 -- no blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0x00}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62TwoBytes + 0x28, 0x88}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
+}
+
+// This test checks that the ack frame processor correctly identifies
+// and handles the case where the third ack block's gap is larger than the
+// available space in the ack range.
+TEST_P(QuicFramerTest, ThirdAckBlockUnderflowGap) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62OneByte  + 63}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (2 -- 2 blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0x02}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62OneByte + 13}},  // Ack 14 packets, range 50..63 (inclusive)
+
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 9}},  // Gap 10 packets, 40..49 (inclusive)
+       {"Unable to read ack block value.",
+        {kVarInt62OneByte + 9}},  // Ack 10 packets, 30..39 (inclusive)
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 29}},  // A gap of 30 packets (0..29 inclusive)
+                                   // should be too big, leaving no room
+                                   // for the ack.
+       {"Underflow with gap block length 30 previous ack block start is 30.",
+        {kVarInt62OneByte + 10}},  // Don't care
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(
+      framer_.detailed_error(),
+      "Underflow with gap block length 30 previous ack block start is 30.");
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
+}
+
+// This test checks that the ack frame processor correctly identifies
+// and handles the case where the third ack block's length is larger than the
+// available space in the ack range.
+TEST_P(QuicFramerTest, ThirdAckBlockUnderflowAck) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62OneByte  + 63}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (2 -- 2 blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0x02}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62OneByte + 13}},  // only 50 packet numbers "left"
+
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 10}},  // Only 40 packet numbers left
+       {"Unable to read ack block value.",
+        {kVarInt62OneByte + 10}},  // only 30 packet numbers left.
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 1}},  // Gap is OK, 29 packet numbers left
+      {"Unable to read ack block value.",
+        {kVarInt62OneByte + 30}},  // Use up all 30, should be an error
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(framer_.detailed_error(),
+            "Underflow with ack block length 31 latest ack block end is 25.");
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
+}
+
+// Tests a variety of ack block wrap scenarios. For example, if the
+// N-1th block causes packet 0 to be acked, then a gap would wrap
+// around to 0x3fffffff ffffffff... Make sure we detect this
+// condition.
+TEST_P(QuicFramerTest, AckBlockUnderflowGapWrap) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62OneByte  + 10}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (1 -- 1 blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 1}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62OneByte + 9}},  // Ack packets 1..10 (inclusive)
+
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 1}},  // Gap of 2 packets (-1...0), should wrap
+       {"Underflow with gap block length 2 previous ack block start is 1.",
+        {kVarInt62OneByte + 9}},  // irrelevant
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(framer_.detailed_error(),
+            "Underflow with gap block length 2 previous ack block start is 1.");
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
+}
+
+// As AckBlockUnderflowGapWrap, but in this test, it's the ack
+// component of the ack-block that causes the wrap, not the gap.
+TEST_P(QuicFramerTest, AckBlockUnderflowAckWrap) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62OneByte  + 10}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (1 -- 1 blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 1}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62OneByte + 6}},  // Ack packets 4..10 (inclusive)
+
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 1}},  // Gap of 2 packets (2..3)
+       {"Unable to read ack block value.",
+        {kVarInt62OneByte + 9}},  // Should wrap.
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(framer_.detailed_error(),
+            "Underflow with ack block length 10 latest ack block end is 1.");
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
+}
+
+// An ack block that acks the entire range, 1...0x3fffffffffffffff
+TEST_P(QuicFramerTest, AckBlockAcksEverything) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62EightBytes  + 0x3f, 0xff, 0xff, 0xff,
+         0xff, 0xff, 0xff, 0xff}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count No additional blocks
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62EightBytes  + 0x3f, 0xff, 0xff, 0xff,
+         0xff, 0xff, 0xff, 0xfe}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.ack_frames_.size());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(1u, frame.packets.NumIntervals());
+  EXPECT_EQ(kLargestIetfLargestObserved, LargestAcked(frame));
+  EXPECT_EQ(kLargestIetfLargestObserved.ToUint64(),
+            frame.packets.NumPacketsSlow());
+}
+
+// This test looks for a malformed ack where
+//  - There is a largest-acked value (that is, the frame is acking
+//    something,
+//  - But the length of the first ack block is 0 saying that no frames
+//    are being acked with the largest-acked value or there are no
+//    additional ack blocks.
+//
+TEST_P(QuicFramerTest, AckFrameFirstAckBlockLengthZero) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Not applicable to version 99 -- first ack block contains the
+    // number of packets that preceed the largest_acked packet.
+    // A value of 0 means no packets preceed --- that the block's
+    // length is 1. Therefore the condition that this test checks can
+    // not arise.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       { 0x2C }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (ack frame)
+      // (more than one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       { 0x65 }},
+      // largest acked
+      {"Unable to read largest acked.",
+       { 0x12, 0x34 }},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       { 0x00, 0x00 }},
+      // num ack blocks ranges.
+      {"Unable to read num of ack blocks.",
+       { 0x01 }},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       { 0x00, 0x00 }},
+      // gap to next block.
+      { "First block length is zero.",
+        { 0x01 }},
+      // ack block length.
+      { "First block length is zero.",
+        { 0x0e, 0xaf }},
+      // Number of timestamps.
+      { "First block length is zero.",
+        { 0x00 }},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (ack frame)
+      // (more than one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       { 0x65 }},
+      // largest acked
+      {"Unable to read largest acked.",
+       { 0x12, 0x34 }},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       { 0x00, 0x00 }},
+      // num ack blocks ranges.
+      {"Unable to read num of ack blocks.",
+       { 0x01 }},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       { 0x00, 0x00 }},
+      // gap to next block.
+      { "First block length is zero.",
+        { 0x01 }},
+      // ack block length.
+      { "First block length is zero.",
+        { 0x0e, 0xaf }},
+      // Number of timestamps.
+      { "First block length is zero.",
+        { 0x00 }},
+  };
+
+  // clang-format on
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_ACK_DATA));
+
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
+}
+
+TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x2C}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 4 byte largest observed, 2 byte block length)
+      {"",
+       {0x49}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34, 0x56, 0x78}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x12, 0x34}},
+      // num timestamps.
+      {"Unable to read num received packets.",
+       {0x00}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x56, 0x78, 0x9A, 0xBC}},
+      // frame type (ack frame)
+      // (one ack block, 4 byte largest observed, 2 byte block length)
+      {"",
+       {0x49}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34, 0x56, 0x78}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x12, 0x34}},
+      // num timestamps.
+      {"Unable to read num received packets.",
+       {0x00}}
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x56, 0x78, 0x9A, 0xBC}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62FourBytes  + 0x12, 0x34, 0x56, 0x78}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Number of ack blocks after first
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0x00}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62TwoBytes  + 0x12, 0x33}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(kPacketNumber, LargestAcked(frame));
+  ASSERT_EQ(4660u, frame.packets.NumPacketsSlow());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
+}
+
+// Tests ability to handle multiple ackblocks after the first ack
+// block. Non-version-99 tests include multiple timestamps as well.
+TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       { 0x2C }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (ack frame)
+      // (more than one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       { 0x65 }},
+      // largest acked
+      {"Unable to read largest acked.",
+       { 0x12, 0x34 }},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       { 0x00, 0x00 }},
+      // num ack blocks ranges.
+      {"Unable to read num of ack blocks.",
+       { 0x04 }},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       { 0x00, 0x01 }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x01 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x0e, 0xaf }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0xff }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x00, 0x00 }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x91 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x01, 0xea }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x05 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x00, 0x04 }},
+      // Number of timestamps.
+      { "Unable to read num received packets.",
+        { 0x02 }},
+      // Delta from largest observed.
+      { "Unable to read sequence delta in received packets.",
+        { 0x01 }},
+      // Delta time.
+      { "Unable to read time delta in received packets.",
+        { 0x76, 0x54, 0x32, 0x10 }},
+      // Delta from largest observed.
+      { "Unable to read sequence delta in received packets.",
+        { 0x02 }},
+      // Delta time.
+      { "Unable to read incremental time delta in received packets.",
+        { 0x32, 0x10 }},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (ack frame)
+      // (more than one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       { 0x65 }},
+      // largest acked
+      {"Unable to read largest acked.",
+       { 0x12, 0x34 }},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       { 0x00, 0x00 }},
+      // num ack blocks ranges.
+      {"Unable to read num of ack blocks.",
+       { 0x04 }},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       { 0x00, 0x01 }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x01 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x0e, 0xaf }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0xff }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x00, 0x00 }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x91 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x01, 0xea }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x05 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x00, 0x04 }},
+      // Number of timestamps.
+      { "Unable to read num received packets.",
+        { 0x02 }},
+      // Delta from largest observed.
+      { "Unable to read sequence delta in received packets.",
+        { 0x01 }},
+      // Delta time.
+      { "Unable to read time delta in received packets.",
+        { 0x76, 0x54, 0x32, 0x10 }},
+      // Delta from largest observed.
+      { "Unable to read sequence delta in received packets.",
+        { 0x02 }},
+      // Delta time.
+      { "Unable to read incremental time delta in received packets.",
+        { 0x32, 0x10 }},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x03 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Additional ACK Block #1
+       // gap to next block.
+       { "Unable to read gap block value.",
+         { kVarInt62OneByte + 0x00 }},   // gap of 1 packet
+       // ack block length.
+       { "Unable to read ack block value.",
+         { kVarInt62TwoBytes + 0x0e, 0xae }},   // 3759
+
+       // pre-version-99 test includes an ack block of 0 length. this
+       // can not happen in version 99. ergo the second block is not
+       // present in the v99 test and the gap length of the next block
+       // is the sum of the two gaps in the pre-version-99 tests.
+       // Additional ACK Block #2
+       // gap to next block.
+       { "Unable to read gap block value.",
+         { kVarInt62TwoBytes + 0x01, 0x8f }},  // Gap is 400 (0x190) pkts
+       // ack block length.
+       { "Unable to read ack block value.",
+         { kVarInt62TwoBytes + 0x01, 0xe9 }},  // block is 389 (x1ea) pkts
+
+       // Additional ACK Block #3
+       // gap to next block.
+       { "Unable to read gap block value.",
+         { kVarInt62OneByte + 0x04 }},   // Gap is 5 packets.
+       // ack block length.
+       { "Unable to read ack block value.",
+         { kVarInt62OneByte + 0x03 }},   // block is 3 packets.
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62FourBytes + 0x36, 0x54, 0x32, 0x10 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x32, 0x10 }},
+  };
+
+  // clang-format on
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(kSmallLargestObserved, LargestAcked(frame));
+  ASSERT_EQ(4254u, frame.packets.NumPacketsSlow());
+  EXPECT_EQ(4u, frame.packets.NumIntervals());
+  EXPECT_EQ(2u, frame.received_packet_times.size());
+}
+
+TEST_P(QuicFramerTest, AckFrameMultipleReceiveTimestampRanges) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x03 }},
+
+       // Timestamp range 1 (three packets).
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x03 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62FourBytes + 0x29, 0xff, 0xff, 0xff}},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x11, 0x11 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x01}},
+
+       // Timestamp range 2 (one packet).
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x05 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x10, 0x00 }},
+
+       // Timestamp range 3 (two packets).
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x08 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x10 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x01, 0x00 }},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  // Timestamp Range 1.
+                  {LargestAcked(frame) - 2, CreationTimePlus(0x29ffffff)},
+                  {LargestAcked(frame) - 3, CreationTimePlus(0x29ffeeee)},
+                  {LargestAcked(frame) - 4, CreationTimePlus(0x29ffeeed)},
+                  // Timestamp Range 2.
+                  {LargestAcked(frame) - 11, CreationTimePlus(0x29ffdeed)},
+                  // Timestamp Range 3.
+                  {LargestAcked(frame) - 21, CreationTimePlus(0x29ffdedd)},
+                  {LargestAcked(frame) - 22, CreationTimePlus(0x29ffdddd)},
+              }));
+}
+
+TEST_P(QuicFramerTest, AckFrameReceiveTimestampWithExponent) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x00 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x03 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x29, 0xff}},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x11, 0x11 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x01}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_receive_timestamps_exponent(3);
+  framer_.set_process_timestamps(true);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  // Timestamp Range 1.
+                  {LargestAcked(frame), CreationTimePlus(0x29ff << 3)},
+                  {LargestAcked(frame) - 1, CreationTimePlus(0x18ee << 3)},
+                  {LargestAcked(frame) - 2, CreationTimePlus(0x18ed << 3)},
+              }));
+}
+
+TEST_P(QuicFramerTest, AckFrameReceiveTimestampGapTooHigh) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x79 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x29, 0xff}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "Receive timestamp gap too high."));
+}
+
+TEST_P(QuicFramerTest, AckFrameReceiveTimestampCountTooHigh) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x0a}},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x0b}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "Receive timestamp delta too high."));
+}
+
+TEST_P(QuicFramerTest, AckFrameReceiveTimestampDeltaTooHigh) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x29, 0xff}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "Receive timestamp count too high."));
+}
+
+TEST_P(QuicFramerTest, AckFrameTimeStampDeltaTooHigh) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x28,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 1 byte largest observed, 1 byte block length)
+      0x40,
+      // largest acked
+      0x01,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x01,
+      // num timestamps.
+      0x01,
+      // Delta from largest observed.
+      0x01,
+      // Delta time.
+      0x10, 0x32, 0x54, 0x76,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 1 byte largest observed, 1 byte block length)
+      0x40,
+      // largest acked
+      0x01,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x01,
+      // num timestamps.
+      0x01,
+      // Delta from largest observed.
+      0x01,
+      // Delta time.
+      0x10, 0x32, 0x54, 0x76,
+  };
+  // clang-format on
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // ACK Timestamp is not a feature of IETF QUIC.
+    return;
+  }
+  QuicEncryptedPacket encrypted(
+      AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
+      ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "delta_from_largest_observed too high"));
+}
+
+TEST_P(QuicFramerTest, AckFrameTimeStampSecondDeltaTooHigh) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x28,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 1 byte largest observed, 1 byte block length)
+      0x40,
+      // largest acked
+      0x03,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x03,
+      // num timestamps.
+      0x02,
+      // Delta from largest observed.
+      0x01,
+      // Delta time.
+      0x10, 0x32, 0x54, 0x76,
+      // Delta from largest observed.
+      0x03,
+      // Delta time.
+      0x10, 0x32,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 1 byte largest observed, 1 byte block length)
+      0x40,
+      // largest acked
+      0x03,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x03,
+      // num timestamps.
+      0x02,
+      // Delta from largest observed.
+      0x01,
+      // Delta time.
+      0x10, 0x32, 0x54, 0x76,
+      // Delta from largest observed.
+      0x03,
+      // Delta time.
+      0x10, 0x32,
+  };
+  // clang-format on
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // ACK Timestamp is not a feature of IETF QUIC.
+    return;
+  }
+  QuicEncryptedPacket encrypted(
+      AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
+      ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "delta_from_largest_observed too high"));
+}
+
+TEST_P(QuicFramerTest, NewStopWaitingFrame) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    // The Stop Waiting frame is not in IETF QUIC
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x2C}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stop waiting frame)
+      {"",
+       {0x06}},
+      // least packet number awaiting an ack, delta from packet number.
+      {"Unable to read least unacked delta.",
+        {0x00, 0x00, 0x00, 0x08}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stop waiting frame)
+      {"",
+       {0x06}},
+      // least packet number awaiting an ack, delta from packet number.
+      {"Unable to read least unacked delta.",
+        {0x00, 0x00, 0x00, 0x08}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.stop_waiting_frames_.size());
+  const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0];
+  EXPECT_EQ(kLeastUnacked, frame.least_unacked);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STOP_WAITING_DATA);
+}
+
+TEST_P(QuicFramerTest, InvalidNewStopWaitingFrame) {
+  // The Stop Waiting frame is not in IETF QUIC
+  if (VersionHasIetfQuicFrames(version_.transport_version) &&
+      framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // frame type (stop waiting frame)
+    0x06,
+    // least packet number awaiting an ack, delta from packet number.
+    0x13, 0x34, 0x56, 0x78,
+    0x9A, 0xA8,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // frame type (stop waiting frame)
+    0x06,
+    // least packet number awaiting an ack, delta from packet number.
+    0x57, 0x78, 0x9A, 0xA8,
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(
+      AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet),
+      false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_STOP_WAITING_DATA));
+  EXPECT_EQ("Invalid unacked delta.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, RstStreamFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (rst stream frame)
+      {"",
+       {0x01}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // sent byte offset
+      {"Unable to read rst stream sent byte offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // error code QUIC_STREAM_CANCELLED
+      {"Unable to read rst stream error code.",
+       {0x00, 0x00, 0x00, 0x06}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (rst stream frame)
+      {"",
+       {0x01}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // sent byte offset
+      {"Unable to read rst stream sent byte offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // error code QUIC_STREAM_CANCELLED
+      {"Unable to read rst stream error code.",
+       {0x00, 0x00, 0x00, 0x06}}
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_RST_STREAM frame)
+      {"",
+       {0x04}},
+      // stream id
+      {"Unable to read IETF_RST_STREAM frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // application error code H3_REQUEST_CANCELLED gets translated to
+      // QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED.
+      {"Unable to read rst stream error code.",
+       {kVarInt62TwoBytes + 0x01, 0x0c}},
+      // Final Offset
+      {"Unable to read rst stream sent byte offset.",
+       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.rst_stream_frame_.stream_id);
+  EXPECT_EQ(QUIC_STREAM_CANCELLED, visitor_.rst_stream_frame_.error_code);
+  EXPECT_EQ(kStreamOffset, visitor_.rst_stream_frame_.byte_offset);
+  CheckFramingBoundaries(fragments, QUIC_INVALID_RST_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, ConnectionCloseFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (connection close frame)
+      {"",
+       {0x02}},
+      // error code
+      {"Unable to read connection close error code.",
+       {0x00, 0x00, 0x00, 0x11}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (connection close frame)
+      {"",
+       {0x02}},
+      // error code
+      {"Unable to read connection close error code.",
+       {0x00, 0x00, 0x00, 0x11}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF Transport CONNECTION_CLOSE frame)
+      {"",
+       {0x1c}},
+      // error code
+      {"Unable to read connection close error code.",
+       {kVarInt62TwoBytes + 0x00, 0x11}},
+      {"Unable to read connection close frame type.",
+       {kVarInt62TwoBytes + 0x12, 0x34 }},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         kVarInt62OneByte + 0x11,
+         // error details with QuicErrorCode serialized
+         '1',  '1',  '5',  ':',
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0x11u, static_cast<unsigned>(
+                       visitor_.connection_close_frame_.wire_error_code));
+  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(0x1234u,
+              visitor_.connection_close_frame_.transport_close_frame_type);
+    EXPECT_EQ(115u, visitor_.connection_close_frame_.quic_error_code);
+  } else {
+    // For Google QUIC frame, |quic_error_code| and |wire_error_code| has the
+    // same value.
+    EXPECT_EQ(0x11u, static_cast<unsigned>(
+                         visitor_.connection_close_frame_.quic_error_code));
+  }
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+TEST_P(QuicFramerTest, ConnectionCloseFrameWithUnknownErrorCode) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (connection close frame)
+      {"",
+       {0x02}},
+      // error code larger than QUIC_LAST_ERROR
+      {"Unable to read connection close error code.",
+       {0x00, 0x00, 0xC0, 0xDE}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (connection close frame)
+      {"",
+       {0x02}},
+      // error code larger than QUIC_LAST_ERROR
+      {"Unable to read connection close error code.",
+       {0x00, 0x00, 0xC0, 0xDE}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF Transport CONNECTION_CLOSE frame)
+      {"",
+       {0x1c}},
+      // error code
+      {"Unable to read connection close error code.",
+       {kVarInt62FourBytes + 0x00, 0x00, 0xC0, 0xDE}},
+      {"Unable to read connection close frame type.",
+       {kVarInt62TwoBytes + 0x12, 0x34 }},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         kVarInt62OneByte + 0x11,
+         // error details with QuicErrorCode larger than QUIC_LAST_ERROR
+         '8',  '4',  '9',  ':',
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(0x1234u,
+              visitor_.connection_close_frame_.transport_close_frame_type);
+    EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.wire_error_code);
+    EXPECT_EQ(849u, visitor_.connection_close_frame_.quic_error_code);
+  } else {
+    // For Google QUIC frame, |quic_error_code| and |wire_error_code| has the
+    // same value.
+    EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.wire_error_code);
+    EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.quic_error_code);
+  }
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+// As above, but checks that for Google-QUIC, if there happens
+// to be an ErrorCode string at the start of the details, it is
+// NOT extracted/parsed/folded/spindled/and/mutilated.
+TEST_P(QuicFramerTest, ConnectionCloseFrameWithExtractedInfoIgnoreGCuic) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+    // public flags (8 byte connection_id)
+    {"",
+     {0x28}},
+    // connection_id
+    {"",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"",
+     {0x12, 0x34, 0x56, 0x78}},
+    // frame type (connection close frame)
+    {"",
+     {0x02}},
+    // error code
+    {"Unable to read connection close error code.",
+     {0x00, 0x00, 0x00, 0x11}},
+    {"Unable to read connection close error details.",
+     {
+       // error details length
+       0x0, 0x13,
+       // error details
+      '1',  '7',  '7',  '6',
+      '7',  ':',  'b',  'e',
+      'c',  'a',  'u',  's',
+      'e',  ' ',  'I',  ' ',
+      'c',  'a',  'n'}
+    }
+  };
+
+  PacketFragments packet46 = {
+    // type (short header, 4 byte packet number)
+    {"",
+     {0x43}},
+    // connection_id
+    {"",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"",
+     {0x12, 0x34, 0x56, 0x78}},
+    // frame type (connection close frame)
+    {"",
+     {0x02}},
+    // error code
+    {"Unable to read connection close error code.",
+     {0x00, 0x00, 0x00, 0x11}},
+    {"Unable to read connection close error details.",
+     {
+       // error details length
+       0x0, 0x13,
+       // error details
+      '1',  '7',  '7',  '6',
+      '7',  ':',  'b',  'e',
+      'c',  'a',  'u',  's',
+      'e',  ' ',  'I',  ' ',
+      'c',  'a',  'n'}
+    }
+  };
+
+  PacketFragments packet_ietf = {
+    // type (short header, 4 byte packet number)
+    {"",
+     {0x43}},
+    // connection_id
+    {"",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"",
+     {0x12, 0x34, 0x56, 0x78}},
+    // frame type (IETF Transport CONNECTION_CLOSE frame)
+    {"",
+     {0x1c}},
+    // error code
+    {"Unable to read connection close error code.",
+     {kVarInt62OneByte + 0x11}},
+    {"Unable to read connection close frame type.",
+     {kVarInt62TwoBytes + 0x12, 0x34 }},
+    {"Unable to read connection close error details.",
+     {
+       // error details length
+       kVarInt62OneByte + 0x13,
+       // error details
+      '1',  '7',  '7',  '6',
+      '7',  ':',  'b',  'e',
+      'c',  'a',  'u',  's',
+      'e',  ' ',  'I',  ' ',
+      'c',  'a',  'n'}
+    }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0x11u, static_cast<unsigned>(
+                       visitor_.connection_close_frame_.wire_error_code));
+
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(0x1234u,
+              visitor_.connection_close_frame_.transport_close_frame_type);
+    EXPECT_EQ(17767u, visitor_.connection_close_frame_.quic_error_code);
+    EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+  } else {
+    EXPECT_EQ(0x11u, visitor_.connection_close_frame_.quic_error_code);
+    // Error code is not prepended in GQUIC, so it is not removed and should
+    // remain in the reason phrase.
+    EXPECT_EQ("17767:because I can",
+              visitor_.connection_close_frame_.error_details);
+  }
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+// Test the CONNECTION_CLOSE/Application variant.
+TEST_P(QuicFramerTest, ApplicationCloseFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_CONNECTION_CLOSE/Application frame)
+      {"",
+       {0x1d}},
+      // error code
+      {"Unable to read connection close error code.",
+       {kVarInt62TwoBytes + 0x00, 0x11}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         kVarInt62OneByte + 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
+            visitor_.connection_close_frame_.close_type);
+  EXPECT_EQ(122u, visitor_.connection_close_frame_.quic_error_code);
+  EXPECT_EQ(0x11u, visitor_.connection_close_frame_.wire_error_code);
+  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+// Check that we can extract an error code from an application close.
+TEST_P(QuicFramerTest, ApplicationCloseFrameExtract) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_CONNECTION_CLOSE/Application frame)
+      {"",
+       {0x1d}},
+      // error code
+      {"Unable to read connection close error code.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read connection close error details.",
+       {
+       // error details length
+       kVarInt62OneByte + 0x13,
+       // error details
+       '1',  '7',  '7',  '6',
+       '7',  ':',  'b',  'e',
+       'c',  'a',  'u',  's',
+       'e',  ' ',  'I',  ' ',
+       'c',  'a',  'n'}
+      }
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
+            visitor_.connection_close_frame_.close_type);
+  EXPECT_EQ(17767u, visitor_.connection_close_frame_.quic_error_code);
+  EXPECT_EQ(0x11u, visitor_.connection_close_frame_.wire_error_code);
+  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+TEST_P(QuicFramerTest, GoAwayFrame) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is not in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (go away frame)
+      {"",
+       {0x03}},
+      // error code
+      {"Unable to read go away error code.",
+       {0x00, 0x00, 0x00, 0x09}},
+      // stream id
+      {"Unable to read last good stream id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // stream id
+      {"Unable to read goaway reason.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (go away frame)
+      {"",
+       {0x03}},
+      // error code
+      {"Unable to read go away error code.",
+       {0x00, 0x00, 0x00, 0x09}},
+      // stream id
+      {"Unable to read last good stream id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // stream id
+      {"Unable to read goaway reason.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id);
+  EXPECT_EQ(0x9u, visitor_.goaway_frame_.error_code);
+  EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_GOAWAY_DATA);
+}
+
+TEST_P(QuicFramerTest, GoAwayFrameWithUnknownErrorCode) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is not in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (go away frame)
+      {"",
+       {0x03}},
+      // error code larger than QUIC_LAST_ERROR
+      {"Unable to read go away error code.",
+       {0x00, 0x00, 0xC0, 0xDE}},
+      // stream id
+      {"Unable to read last good stream id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // stream id
+      {"Unable to read goaway reason.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (go away frame)
+      {"",
+       {0x03}},
+      // error code larger than QUIC_LAST_ERROR
+      {"Unable to read go away error code.",
+       {0x00, 0x00, 0xC0, 0xDE}},
+      // stream id
+      {"Unable to read last good stream id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // stream id
+      {"Unable to read goaway reason.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id);
+  EXPECT_EQ(0xC0DE, visitor_.goaway_frame_.error_code);
+  EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_GOAWAY_DATA);
+}
+
+TEST_P(QuicFramerTest, WindowUpdateFrame) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is not in IETF QUIC, see MaxDataFrame and MaxStreamDataFrame
+    // for IETF QUIC equivalents.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (window update frame)
+      {"",
+       {0x04}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // byte offset
+      {"Unable to read window byte_offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (window update frame)
+      {"",
+       {0x04}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // byte offset
+      {"Unable to read window byte_offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+  };
+
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id);
+  EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_WINDOW_UPDATE_DATA);
+}
+
+TEST_P(QuicFramerTest, MaxDataFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is available only in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_MAX_DATA frame)
+      {"",
+       {0x10}},
+      // byte offset
+      {"Can not read MAX_DATA byte-offset",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(QuicUtils::GetInvalidStreamId(framer_.transport_version()),
+            visitor_.window_update_frame_.stream_id);
+  EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MAX_DATA_FRAME_DATA);
+}
+
+TEST_P(QuicFramerTest, MaxStreamDataFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame available only in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_MAX_STREAM_DATA frame)
+      {"",
+       {0x11}},
+      // stream id
+      {"Unable to read IETF_MAX_STREAM_DATA frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // byte offset
+      {"Can not read MAX_STREAM_DATA byte-count",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id);
+  EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
+}
+
+TEST_P(QuicFramerTest, BlockedFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (blocked frame)
+      {"",
+       {0x05}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (blocked frame)
+      {"",
+       {0x05}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_STREAM_BLOCKED frame)
+      {"",
+       {0x15}},
+      // stream id
+      {"Unable to read IETF_STREAM_DATA_BLOCKED frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // Offset
+      {"Can not read stream blocked offset.",
+       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
+  } else {
+    EXPECT_EQ(0u, visitor_.blocked_frame_.offset);
+  }
+  EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id);
+
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_BLOCKED_DATA);
+  } else {
+    CheckFramingBoundaries(fragments, QUIC_INVALID_BLOCKED_DATA);
+  }
+}
+
+TEST_P(QuicFramerTest, PingFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+     // public flags (8 byte connection_id)
+     0x28,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // frame type (ping frame)
+     0x07,
+    };
+
+  unsigned char packet46[] = {
+     // type (short header, 4 byte packet number)
+     0x43,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // frame type
+     0x07,
+    };
+
+  unsigned char packet_ietf[] = {
+     // type (short header, 4 byte packet number)
+     0x43,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // frame type (IETF_PING frame)
+     0x01,
+    };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(
+      AsChars(VersionHasIetfQuicFrames(framer_.transport_version())
+                  ? packet_ietf
+                  : (framer_.version().HasIetfInvariantHeader() ? packet46
+                                                                : packet)),
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? ABSL_ARRAYSIZE(packet_ietf)
+          : (framer_.version().HasIetfInvariantHeader()
+                 ? ABSL_ARRAYSIZE(packet46)
+                 : ABSL_ARRAYSIZE(packet)),
+      false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(1u, visitor_.ping_frames_.size());
+
+  // No need to check the PING frame boundaries because it has no payload.
+}
+
+TEST_P(QuicFramerTest, HandshakeDoneFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+     // type (short header, 4 byte packet number)
+     0x43,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // frame type (Handshake done frame)
+     0x1e,
+    };
+  // clang-format on
+
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(1u, visitor_.handshake_done_frames_.size());
+}
+
+TEST_P(QuicFramerTest, ParseAckFrequencyFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+     // type (short header, 4 byte packet number)
+     0x43,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // ack frequency frame type (which needs two bytes as it is > 0x3F)
+     0x40, 0xAF,
+     // sequence_number
+     0x11,
+     // packet_tolerance
+     0x02,
+     // max_ack_delay_us = 2'5000 us
+     0x80, 0x00, 0x61, 0xA8,
+     // ignore_order
+     0x01
+  };
+  // clang-format on
+
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.ack_frequency_frames_.size());
+  const auto& frame = visitor_.ack_frequency_frames_.front();
+  EXPECT_EQ(17u, frame->sequence_number);
+  EXPECT_EQ(2u, frame->packet_tolerance);
+  EXPECT_EQ(2'5000u, frame->max_ack_delay.ToMicroseconds());
+  EXPECT_EQ(true, frame->ignore_order);
+}
+
+TEST_P(QuicFramerTest, MessageFrame) {
+  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet46 = {
+       // type (short header, 4 byte packet number)
+       {"",
+        {0x43}},
+       // connection_id
+       {"",
+        {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+       // packet number
+       {"",
+        {0x12, 0x34, 0x56, 0x78}},
+       // message frame type.
+       {"",
+        { 0x21 }},
+       // message length
+       {"Unable to read message length",
+        {0x07}},
+       // message data
+       {"Unable to read message data",
+        {'m', 'e', 's', 's', 'a', 'g', 'e'}},
+        // message frame no length.
+        {"",
+         { 0x20 }},
+        // message data
+        {{},
+         {'m', 'e', 's', 's', 'a', 'g', 'e', '2'}},
+   };
+  PacketFragments packet_ietf = {
+       // type (short header, 4 byte packet number)
+       {"",
+        {0x43}},
+       // connection_id
+       {"",
+        {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+       // packet number
+       {"",
+        {0x12, 0x34, 0x56, 0x78}},
+       // message frame type.
+       {"",
+        { 0x31 }},
+       // message length
+       {"Unable to read message length",
+        {0x07}},
+       // message data
+       {"Unable to read message data",
+        {'m', 'e', 's', 's', 'a', 'g', 'e'}},
+        // message frame no length.
+        {"",
+         { 0x30 }},
+        // message data
+        {{},
+         {'m', 'e', 's', 's', 'a', 'g', 'e', '2'}},
+   };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    encrypted = AssemblePacketFromFragments(packet_ietf);
+  } else {
+    encrypted = AssemblePacketFromFragments(packet46);
+  }
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(2u, visitor_.message_frames_.size());
+  EXPECT_EQ(7u, visitor_.message_frames_[0]->message_length);
+  EXPECT_EQ(8u, visitor_.message_frames_[1]->message_length);
+
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MESSAGE_DATA);
+  } else {
+    CheckFramingBoundaries(packet46, QUIC_INVALID_MESSAGE_DATA);
+  }
+}
+
+TEST_P(QuicFramerTest, PublicResetPacketV33) {
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (public reset, 8 byte connection_id)
+      {"",
+       {0x0A}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      {"Unable to read reset message.",
+       {
+         // message tag (kPRST)
+         'P', 'R', 'S', 'T',
+         // num_entries (2) + padding
+         0x02, 0x00, 0x00, 0x00,
+         // tag kRNON
+         'R', 'N', 'O', 'N',
+         // end offset 8
+         0x08, 0x00, 0x00, 0x00,
+         // tag kRSEQ
+         'R', 'S', 'E', 'Q',
+         // end offset 16
+         0x10, 0x00, 0x00, 0x00,
+         // nonce proof
+         0x89, 0x67, 0x45, 0x23,
+         0x01, 0xEF, 0xCD, 0xAB,
+         // rejected packet number
+         0xBC, 0x9A, 0x78, 0x56,
+         0x34, 0x12, 0x00, 0x00,
+       }
+      }
+  };
+  // clang-format on
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.public_reset_packet_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.public_reset_packet_->connection_id);
+  EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
+  EXPECT_EQ(
+      IpAddressFamily::IP_UNSPEC,
+      visitor_.public_reset_packet_->client_address.host().address_family());
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
+}
+
+TEST_P(QuicFramerTest, PublicResetPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (public reset, 8 byte connection_id)
+      {"",
+       {0x0E}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      {"Unable to read reset message.",
+       {
+         // message tag (kPRST)
+         'P', 'R', 'S', 'T',
+         // num_entries (2) + padding
+         0x02, 0x00, 0x00, 0x00,
+         // tag kRNON
+         'R', 'N', 'O', 'N',
+         // end offset 8
+         0x08, 0x00, 0x00, 0x00,
+         // tag kRSEQ
+         'R', 'S', 'E', 'Q',
+         // end offset 16
+         0x10, 0x00, 0x00, 0x00,
+         // nonce proof
+         0x89, 0x67, 0x45, 0x23,
+         0x01, 0xEF, 0xCD, 0xAB,
+         // rejected packet number
+         0xBC, 0x9A, 0x78, 0x56,
+         0x34, 0x12, 0x00, 0x00,
+       }
+      }
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.public_reset_packet_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.public_reset_packet_->connection_id);
+  EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
+  EXPECT_EQ(
+      IpAddressFamily::IP_UNSPEC,
+      visitor_.public_reset_packet_->client_address.host().address_family());
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
+}
+
+TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) {
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (public reset, 8 byte connection_id)
+    0x0A,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // message tag (kPRST)
+    'P', 'R', 'S', 'T',
+    // num_entries (2) + padding
+    0x02, 0x00, 0x00, 0x00,
+    // tag kRNON
+    'R', 'N', 'O', 'N',
+    // end offset 8
+    0x08, 0x00, 0x00, 0x00,
+    // tag kRSEQ
+    'R', 'S', 'E', 'Q',
+    // end offset 16
+    0x10, 0x00, 0x00, 0x00,
+    // nonce proof
+    0x89, 0x67, 0x45, 0x23,
+    0x01, 0xEF, 0xCD, 0xAB,
+    // rejected packet number
+    0xBC, 0x9A, 0x78, 0x56,
+    0x34, 0x12, 0x00, 0x00,
+    // trailing junk
+    'j', 'u', 'n', 'k',
+  };
+  // clang-format on
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  ASSERT_THAT(framer_.error(), IsError(QUIC_INVALID_PUBLIC_RST_PACKET));
+  EXPECT_EQ("Unable to read reset message.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (public reset, 8 byte connection_id)
+      {"",
+       {0x0A}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      {"Unable to read reset message.",
+       {
+         // message tag (kPRST)
+         'P', 'R', 'S', 'T',
+         // num_entries (2) + padding
+         0x03, 0x00, 0x00, 0x00,
+         // tag kRNON
+         'R', 'N', 'O', 'N',
+         // end offset 8
+         0x08, 0x00, 0x00, 0x00,
+         // tag kRSEQ
+         'R', 'S', 'E', 'Q',
+         // end offset 16
+         0x10, 0x00, 0x00, 0x00,
+         // tag kCADR
+         'C', 'A', 'D', 'R',
+         // end offset 24
+         0x18, 0x00, 0x00, 0x00,
+         // nonce proof
+         0x89, 0x67, 0x45, 0x23,
+         0x01, 0xEF, 0xCD, 0xAB,
+         // rejected packet number
+         0xBC, 0x9A, 0x78, 0x56,
+         0x34, 0x12, 0x00, 0x00,
+         // client address: 4.31.198.44:443
+         0x02, 0x00,
+         0x04, 0x1F, 0xC6, 0x2C,
+         0xBB, 0x01,
+       }
+      }
+  };
+  // clang-format on
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.public_reset_packet_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.public_reset_packet_->connection_id);
+  EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
+  EXPECT_EQ("4.31.198.44",
+            visitor_.public_reset_packet_->client_address.host().ToString());
+  EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port());
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
+}
+
+TEST_P(QuicFramerTest, IetfStatelessResetPacket) {
+  // clang-format off
+  unsigned char packet[] = {
+      // type (short packet, 1 byte packet number)
+      0x50,
+      // Random bytes
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      // stateless reset token
+      0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+      0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+  };
+  // clang-format on
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
+                                                      TestConnectionId(0x33));
+  decrypter_ = new test::TestDecrypter();
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_INITIAL,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+                             std::unique_ptr<QuicDecrypter>(decrypter_));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 Perspective::IS_CLIENT));
+    framer_.SetAlternativeDecrypter(
+        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+  }
+  // This packet cannot be decrypted because diversification nonce is missing.
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.stateless_reset_packet_.get());
+  EXPECT_EQ(kTestStatelessResetToken,
+            visitor_.stateless_reset_packet_->stateless_reset_token);
+}
+
+TEST_P(QuicFramerTest, IetfStatelessResetPacketInvalidStatelessResetToken) {
+  // clang-format off
+  unsigned char packet[] = {
+      // type (short packet, 1 byte packet number)
+      0x50,
+      // Random bytes
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      // stateless reset token
+      0xB6, 0x69, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
+                                                      TestConnectionId(0x33));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  decrypter_ = new test::TestDecrypter();
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_INITIAL,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+                             std::unique_ptr<QuicDecrypter>(decrypter_));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 Perspective::IS_CLIENT));
+    framer_.SetAlternativeDecrypter(
+        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+  }
+  // This packet cannot be decrypted because diversification nonce is missing.
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+  ASSERT_FALSE(visitor_.stateless_reset_packet_);
+}
+
+TEST_P(QuicFramerTest, VersionNegotiationPacketClient) {
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (version, 8 byte connection_id)
+      {"",
+       {0x29}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // version tag
+      {"Unable to read supported version in negotiation.",
+       {QUIC_VERSION_BYTES,
+        'Q', '2', '.', '0'}},
+  };
+
+  PacketFragments packet46 = {
+      // type (long header)
+      {"",
+       {0x8F}},
+      // version tag
+      {"",
+       {0x00, 0x00, 0x00, 0x00}},
+      {"",
+       {0x05}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // Supported versions
+      {"Unable to read supported version in negotiation.",
+       {QUIC_VERSION_BYTES,
+        'Q', '2', '.', '0'}},
+  };
+
+  PacketFragments packet49 = {
+      // type (long header)
+      {"",
+       {0x8F}},
+      // version tag
+      {"",
+       {0x00, 0x00, 0x00, 0x00}},
+      {"",
+       {0x08}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      {"",
+       {0x00}},
+      // Supported versions
+      {"Unable to read supported version in negotiation.",
+       {QUIC_VERSION_BYTES,
+        'Q', '2', '.', '0'}},
+  };
+  // clang-format on
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  PacketFragments& fragments =
+      framer_.version().HasLongHeaderLengths()     ? packet49
+      : framer_.version().HasIetfInvariantHeader() ? packet46
+                                                   : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.version_negotiation_packet_.get());
+  EXPECT_EQ(1u, visitor_.version_negotiation_packet_->versions.size());
+  EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
+
+  // Remove the last version from the packet so that every truncated
+  // version of the packet is invalid, otherwise checking boundaries
+  // is annoyingly complicated.
+  for (size_t i = 0; i < 4; ++i) {
+    fragments.back().fragment.pop_back();
+  }
+  CheckFramingBoundaries(fragments, QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+}
+
+TEST_P(QuicFramerTest, VersionNegotiationPacketServer) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (long header with all ignored bits set)
+      0xFF,
+      // version
+      0x00, 0x00, 0x00, 0x00,
+      // connection ID lengths
+      0x50,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // supported versions
+      QUIC_VERSION_BYTES,
+      'Q', '2', '.', '0',
+  };
+  unsigned char packet2[] = {
+      // public flags (long header with all ignored bits set)
+      0xFF,
+      // version
+      0x00, 0x00, 0x00, 0x00,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // source connection ID length
+      0x00,
+      // supported versions
+      QUIC_VERSION_BYTES,
+      'Q', '2', '.', '0',
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLengthPrefixedConnectionIds()) {
+    p = packet2;
+    p_length = ABSL_ARRAYSIZE(packet2);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(),
+              IsError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET));
+  EXPECT_EQ("Server received version negotiation packet.",
+            framer_.detailed_error());
+  EXPECT_FALSE(visitor_.version_negotiation_packet_.get());
+}
+
+TEST_P(QuicFramerTest, OldVersionNegotiationPacket) {
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (version, 8 byte connection_id)
+      {"",
+       {0x2D}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // version tag
+      {"Unable to read supported version in negotiation.",
+       {QUIC_VERSION_BYTES,
+        'Q', '2', '.', '0'}},
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.version_negotiation_packet_.get());
+  EXPECT_EQ(1u, visitor_.version_negotiation_packet_->versions.size());
+  EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
+
+  // Remove the last version from the packet so that every truncated
+  // version of the packet is invalid, otherwise checking boundaries
+  // is annoyingly complicated.
+  for (size_t i = 0; i < 4; ++i) {
+    packet.back().fragment.pop_back();
+  }
+  CheckFramingBoundaries(packet, QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+}
+
+TEST_P(QuicFramerTest, ParseIetfRetryPacket) {
+  if (!framer_.version().SupportsRetry()) {
+    return;
+  }
+  // IETF RETRY is only sent from client to server.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (long header with packet type RETRY and ODCIL=8)
+      0xF5,
+      // version
+      QUIC_VERSION_BYTES,
+      // connection ID lengths
+      0x05,
+      // source connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // original destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // retry token
+      'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
+      ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
+  };
+  unsigned char packet49[] = {
+      // public flags (long header with packet type RETRY)
+      0xF0,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x00,
+      // source connection ID length
+      0x08,
+      // source connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // original destination connection ID length
+      0x08,
+      // original destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // retry token
+      'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
+      ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
+  };
+  unsigned char packet_with_tag[] = {
+      // public flags (long header with packet type RETRY)
+      0xF0,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x00,
+      // source connection ID length
+      0x08,
+      // source connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // retry token
+      'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
+      ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
+      // retry token integrity tag
+      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().UsesTls()) {
+    ReviseFirstByteByVersion(packet_with_tag);
+    p = packet_with_tag;
+    p_length = ABSL_ARRAYSIZE(packet_with_tag);
+  } else if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_TRUE(visitor_.on_retry_packet_called_);
+  ASSERT_TRUE(visitor_.retry_new_connection_id_.get());
+  ASSERT_TRUE(visitor_.retry_token_.get());
+
+  if (framer_.version().UsesTls()) {
+    ASSERT_TRUE(visitor_.retry_token_integrity_tag_.get());
+    static const unsigned char expected_integrity_tag[16] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    };
+    quiche::test::CompareCharArraysWithHexError(
+        "retry integrity tag", visitor_.retry_token_integrity_tag_->data(),
+        visitor_.retry_token_integrity_tag_->length(),
+        reinterpret_cast<const char*>(expected_integrity_tag),
+        ABSL_ARRAYSIZE(expected_integrity_tag));
+    ASSERT_TRUE(visitor_.retry_without_tag_.get());
+    quiche::test::CompareCharArraysWithHexError(
+        "retry without tag", visitor_.retry_without_tag_->data(),
+        visitor_.retry_without_tag_->length(),
+        reinterpret_cast<const char*>(packet_with_tag), 35);
+  } else {
+    ASSERT_TRUE(visitor_.retry_original_connection_id_.get());
+    EXPECT_EQ(FramerTestConnectionId(),
+              *visitor_.retry_original_connection_id_.get());
+  }
+
+  EXPECT_EQ(FramerTestConnectionIdPlusOne(),
+            *visitor_.retry_new_connection_id_.get());
+  EXPECT_EQ("Hello this is RETRY!", *visitor_.retry_token_.get());
+
+  // IETF RETRY is only sent from client to server, the rest of this test
+  // ensures that the server correctly drops them without acting on them.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Reset our visitor state to default settings.
+  visitor_.retry_original_connection_id_.reset();
+  visitor_.retry_new_connection_id_.reset();
+  visitor_.retry_token_.reset();
+  visitor_.retry_token_integrity_tag_.reset();
+  visitor_.retry_without_tag_.reset();
+  visitor_.on_retry_packet_called_ = false;
+
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  EXPECT_EQ("Client-initiated RETRY is invalid.", framer_.detailed_error());
+
+  EXPECT_FALSE(visitor_.on_retry_packet_called_);
+  EXPECT_FALSE(visitor_.retry_new_connection_id_.get());
+  EXPECT_FALSE(visitor_.retry_token_.get());
+  EXPECT_FALSE(visitor_.retry_token_integrity_tag_.get());
+  EXPECT_FALSE(visitor_.retry_without_tag_.get());
+}
+
+TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // clang-format off
+  unsigned char packet[kMaxOutgoingPacketSize] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[kMaxOutgoingPacketSize] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  uint64_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
+                               absl::string_view("hello world!"));
+  QuicPaddingFrame padding_frame(2);
+  QuicFrames frames = {QuicFrame(padding_frame), QuicFrame(stream_frame),
+                       QuicFrame(padding_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (IETF_STREAM with FIN, LEN, and OFFSET bits set)
+    0x08 | 0x01 | 0x02 | 0x04,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    kVarInt62OneByte + 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // clang-format off
+  unsigned char packet[kMaxOutgoingPacketSize] = {
+    // public flags (8 byte connection_id and 4 byte packet number)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[kMaxOutgoingPacketSize] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  uint64_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // clang-format off
+  unsigned char packet[kMaxOutgoingPacketSize] = {
+    // public flags (8 byte connection_id and 2 byte packet number)
+    0x1C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[kMaxOutgoingPacketSize] = {
+    // type (short header, 2 byte packet number)
+    0x41,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
+    // type (short header, 2 byte packet number)
+    0x41,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  uint64_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_2BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // clang-format off
+  unsigned char packet[kMaxOutgoingPacketSize] = {
+    // public flags (8 byte connection_id and 1 byte packet number)
+    0x0C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[kMaxOutgoingPacketSize] = {
+    // type (short header, 1 byte packet number)
+    0x40,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
+    // type (short header, 1 byte packet number)
+    0x40,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  uint64_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildStreamFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
+                               absl::string_view("hello world!"));
+
+  QuicFrames frames = {QuicFrame(stream_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stream frame with fin and no length)
+    0xDF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stream frame with fin and no length)
+    0xDF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAM frame with FIN and OFFSET, no length)
+    0x08 | 0x01 | 0x04,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = true;
+  if (framer_.version().HasIetfInvariantHeader()) {
+    header.long_packet_type = ZERO_RTT_PROTECTED;
+  }
+  header.packet_number = kPacketNumber;
+  if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
+                               absl::string_view("hello world!"));
+  QuicFrames frames = {QuicFrame(stream_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (version, 8 byte connection_id)
+      0x2D,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // version tag
+      QUIC_VERSION_BYTES,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (stream frame with fin and no length)
+      0xDF,
+      // stream id
+      0x01, 0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data
+      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
+  };
+
+  unsigned char packet46[] = {
+      // type (long header with packet type ZERO_RTT_PROTECTED)
+      0xD3,
+      // version tag
+      QUIC_VERSION_BYTES,
+      // connection_id length
+      0x50,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (stream frame with fin and no length)
+      0xDF,
+      // stream id
+      0x01, 0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data
+      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
+  };
+
+  unsigned char packet49[] = {
+      // type (long header with packet type ZERO_RTT_PROTECTED)
+      0xD3,
+      // version tag
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // length
+      0x40, 0x1D,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (stream frame with fin and no length)
+      0xDF,
+      // stream id
+      0x01, 0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data
+      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
+  };
+
+  unsigned char packet_ietf[] = {
+      // type (long header with packet type ZERO_RTT_PROTECTED)
+      0xD3,
+      // version tag
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // length
+      0x40, 0x1D,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (IETF_STREAM frame with fin and offset, no length)
+      0x08 | 0x01 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data
+      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
+  };
+  // clang-format on
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    ReviseFirstByteByVersion(packet_ietf);
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_size = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildCryptoFramePacket) {
+  if (!QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  SimpleDataProducer data_producer;
+  framer_.set_data_producer(&data_producer);
+
+  absl::string_view crypto_frame_contents("hello world!");
+  QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, kStreamOffset,
+                               crypto_frame_contents.length());
+  data_producer.SaveCryptoData(ENCRYPTION_INITIAL, kStreamOffset,
+                               crypto_frame_contents);
+
+  QuicFrames frames = {QuicFrame(&crypto_frame)};
+
+  // clang-format off
+  unsigned char packet48[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (QuicFrameType CRYPTO_FRAME)
+    0x08,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // length
+    kVarInt62OneByte + 12,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_CRYPTO frame)
+    0x06,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // length
+    kVarInt62OneByte + 12,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+  // clang-format on
+
+  unsigned char* packet = packet48;
+  size_t packet_size = ABSL_ARRAYSIZE(packet48);
+  if (framer_.version().HasIetfQuicFrames()) {
+    packet = packet_ietf;
+    packet_size = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError("constructed packet",
+                                              data->data(), data->length(),
+                                              AsChars(packet), packet_size);
+}
+
+TEST_P(QuicFramerTest, CryptoFrame) {
+  if (!QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+    // CRYPTO frames aren't supported prior to v48.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet48 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (QuicFrameType CRYPTO_FRAME)
+      {"",
+       {0x08}},
+      // offset
+      {"",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Invalid data length.",
+       {kVarInt62OneByte + 12}},
+      // data
+      {"Unable to read frame data.",
+       {'h',  'e',  'l',  'l',
+        'o',  ' ',  'w',  'o',
+        'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_CRYPTO frame)
+      {"",
+       {0x06}},
+      // offset
+      {"",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Invalid data length.",
+       {kVarInt62OneByte + 12}},
+      // data
+      {"Unable to read frame data.",
+       {'h',  'e',  'l',  'l',
+        'o',  ' ',  'w',  'o',
+        'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfQuicFrames() ? packet_ietf : packet48;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+  ASSERT_EQ(1u, visitor_.crypto_frames_.size());
+  QuicCryptoFrame* frame = visitor_.crypto_frames_[0].get();
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, frame->level);
+  EXPECT_EQ(kStreamOffset, frame->offset);
+  EXPECT_EQ("hello world!",
+            std::string(frame->data_buffer, frame->data_length));
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_FRAME_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
+  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (version, 8 byte connection_id)
+      0x0D,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // supported versions
+      0xDA, 0x5A, 0x3A, 0x3A,
+      QUIC_VERSION_BYTES,
+  };
+  unsigned char packet46[] = {
+      // type (long header)
+      0xC0,
+      // version tag
+      0x00, 0x00, 0x00, 0x00,
+      // connection_id length
+      0x05,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // supported versions
+      0xDA, 0x5A, 0x3A, 0x3A,
+      QUIC_VERSION_BYTES,
+  };
+  unsigned char packet49[] = {
+      // type (long header)
+      0xC0,
+      // version tag
+      0x00, 0x00, 0x00, 0x00,
+      // destination connection ID length
+      0x00,
+      // source connection ID length
+      0x08,
+      // source connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // supported versions
+      0xDA, 0x5A, 0x3A, 0x3A,
+      QUIC_VERSION_BYTES,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_size = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicConnectionId connection_id = FramerTestConnectionId();
+  std::unique_ptr<QuicEncryptedPacket> data(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id, EmptyQuicConnectionId(),
+          framer_.version().HasIetfInvariantHeader(),
+          framer_.version().HasLengthPrefixedConnectionIds(),
+          SupportedVersions(GetParam())));
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildVersionNegotiationPacketWithClientConnectionId) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+
+  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
+
+  // clang-format off
+  unsigned char packet[] = {
+      // type (long header)
+      0xC0,
+      // version tag
+      0x00, 0x00, 0x00, 0x00,
+      // client/destination connection ID
+      0x08,
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // server/source connection ID
+      0x08,
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // supported versions
+      0xDA, 0x5A, 0x3A, 0x3A,
+      QUIC_VERSION_BYTES,
+  };
+  // clang-format on
+
+  QuicConnectionId server_connection_id = FramerTestConnectionId();
+  QuicConnectionId client_connection_id = FramerTestConnectionIdPlusOne();
+  std::unique_ptr<QuicEncryptedPacket> data(
+      QuicFramer::BuildVersionNegotiationPacket(
+          server_connection_id, client_connection_id, true, true,
+          SupportedVersions(GetParam())));
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x2C,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 2 byte largest observed, 2 byte block length)
+      0x45,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x12, 0x34,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 2 byte largest observed, 2 byte block length)
+      0x45,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x12, 0x34,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (IETF_ACK frame)
+      0x02,
+      // largest acked
+      kVarInt62TwoBytes + 0x12, 0x34,
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // Number of additional ack blocks.
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x12, 0x33,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameMultipleRanges) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      // Timestamp Range 3.
+      {kSmallLargestObserved - 22, CreationTimePlus(0x29ffdddd)},
+      {kSmallLargestObserved - 21, CreationTimePlus(0x29ffdedd)},
+      // Timestamp Range 2.
+      {kSmallLargestObserved - 11, CreationTimePlus(0x29ffdeed)},
+      // Timestamp Range 1.
+      {kSmallLargestObserved - 4, CreationTimePlus(0x29ffeeed)},
+      {kSmallLargestObserved - 3, CreationTimePlus(0x29ffeeee)},
+      {kSmallLargestObserved - 2, CreationTimePlus(0x29ffffff)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE,
+      0xDC,
+      0xBA,
+      0x98,
+      0x76,
+      0x54,
+      0x32,
+      0x10,
+      // packet number
+      0x12,
+      0x34,
+      0x56,
+      0x78,
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      0x22,
+      // largest acked
+      kVarInt62TwoBytes + 0x12,
+      0x34,  // = 4660
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // number of additional ack blocks
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x12,
+      0x33,
+
+      // Receive Timestamps.
+
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x03,
+
+      // Timestamp range 1 (three packets).
+      // Gap
+      kVarInt62OneByte + 0x02,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x03,
+      // Timestamp Delta
+      kVarInt62FourBytes + 0x29,
+      0xff,
+      0xff,
+      0xff,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x11,
+      0x11,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x01,
+
+      // Timestamp range 2 (one packet).
+      // Gap
+      kVarInt62OneByte + 0x05,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x01,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x10,
+      0x00,
+
+      // Timestamp range 3 (two packets).
+      // Gap
+      kVarInt62OneByte + 0x08,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x02,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x10,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x01,
+      0x00,
+  };
+  // clang-format on
+
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameExceedsMaxTimestamps) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      // Timestamp Range 3 (not included because max receive timestamps = 4).
+      {kSmallLargestObserved - 20, CreationTimePlus(0x29ffdddd)},
+      // Timestamp Range 2.
+      {kSmallLargestObserved - 10, CreationTimePlus(0x29ffdedd)},
+      {kSmallLargestObserved - 9, CreationTimePlus(0x29ffdeed)},
+      // Timestamp Range 1.
+      {kSmallLargestObserved - 2, CreationTimePlus(0x29ffeeed)},
+      {kSmallLargestObserved - 1, CreationTimePlus(0x29ffeeee)},
+      {kSmallLargestObserved, CreationTimePlus(0x29ffffff)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE,
+      0xDC,
+      0xBA,
+      0x98,
+      0x76,
+      0x54,
+      0x32,
+      0x10,
+      // packet number
+      0x12,
+      0x34,
+      0x56,
+      0x78,
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      0x22,
+      // largest acked
+      kVarInt62TwoBytes + 0x12,
+      0x34,  // = 4660
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // number of additional ack blocks
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x12,
+      0x33,
+
+      // Receive Timestamps.
+
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x02,
+
+      // Timestamp range 1 (three packets).
+      // Gap
+      kVarInt62OneByte + 0x00,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x03,
+      // Timestamp Delta
+      kVarInt62FourBytes + 0x29,
+      0xff,
+      0xff,
+      0xff,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x11,
+      0x11,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x01,
+
+      // Timestamp range 2 (one packet).
+      // Gap
+      kVarInt62OneByte + 0x05,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x01,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x10,
+      0x00,
+  };
+  // clang-format on
+
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(4);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameWithExponentEncoding) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      // Timestamp Range 2.
+      {kSmallLargestObserved - 12, CreationTimePlus((0x06c00 << 3) + 0x03)},
+      {kSmallLargestObserved - 11, CreationTimePlus((0x28e00 << 3) + 0x00)},
+      // Timestamp Range 1.
+      {kSmallLargestObserved - 5, CreationTimePlus((0x29f00 << 3) + 0x00)},
+      {kSmallLargestObserved - 4, CreationTimePlus((0x29f00 << 3) + 0x01)},
+      {kSmallLargestObserved - 3, CreationTimePlus((0x29f00 << 3) + 0x02)},
+      {kSmallLargestObserved - 2, CreationTimePlus((0x29f00 << 3) + 0x03)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE,
+      0xDC,
+      0xBA,
+      0x98,
+      0x76,
+      0x54,
+      0x32,
+      0x10,
+      // packet number
+      0x12,
+      0x34,
+      0x56,
+      0x78,
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      0x22,
+      // largest acked
+      kVarInt62TwoBytes + 0x12,
+      0x34,  // = 4660
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // number of additional ack blocks
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x12,
+      0x33,
+
+      // Receive Timestamps.
+
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x02,
+
+      // Timestamp range 1 (three packets).
+      // Gap
+      kVarInt62OneByte + 0x02,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x04,
+      // Timestamp Delta
+      kVarInt62FourBytes + 0x00,
+      0x02,
+      0x9f,
+      0x01,  // round up
+      // Timestamp Delta
+      kVarInt62OneByte + 0x00,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x00,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x01,
+
+      // Timestamp range 2 (one packet).
+      // Gap
+      kVarInt62OneByte + 0x04,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x02,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x11,
+      0x00,
+      // Timestamp Delta
+      kVarInt62FourBytes + 0x00,
+      0x02,
+      0x21,
+      0xff,
+  };
+  // clang-format on
+
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildAndProcessAckReceiveTimestampsWithMultipleRanges) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
+      {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
+      {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
+      {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
+      {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+      {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+      {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
+                  {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+                  {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+                  {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
+                  {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
+                  {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
+                  {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
+              }));
+}
+
+TEST_P(QuicFramerTest,
+       BuildAndProcessAckReceiveTimestampsExceedsMaxTimestamps) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(2);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
+      {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
+      {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
+      {kSmallLargestObserved - 5, CreationTimePlus(0xabcdea125)},
+      {kSmallLargestObserved - 3, CreationTimePlus(0xabcded124)},
+      {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+      {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+                  {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+              }));
+}
+
+TEST_P(QuicFramerTest,
+       BuildAndProcessAckReceiveTimestampsWithExponentNoTruncation) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
+      {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
+      {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
+      {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
+                  {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
+                  {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
+                  {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
+              }));
+}
+
+TEST_P(QuicFramerTest,
+       BuildAndProcessAckReceiveTimestampsWithExponentTruncation) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 10, CreationTimePlus((0x1001 << 3) + 1)},
+      {kSmallLargestObserved - 9, CreationTimePlus((0x2995 << 3) - 1)},
+      {kSmallLargestObserved - 8, CreationTimePlus((0x2995 << 3) + 0)},
+      {kSmallLargestObserved - 7, CreationTimePlus((0x2995 << 3) + 1)},
+      {kSmallLargestObserved - 6, CreationTimePlus((0x2995 << 3) + 2)},
+      {kSmallLargestObserved - 3, CreationTimePlus((0x2995 << 3) + 3)},
+      {kSmallLargestObserved - 2, CreationTimePlus((0x2995 << 3) + 4)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved - 2, CreationTimePlus(0x2996 << 3)},
+                  {kSmallLargestObserved - 3, CreationTimePlus(0x2996 << 3)},
+                  {kSmallLargestObserved - 6, CreationTimePlus(0x2996 << 3)},
+                  {kSmallLargestObserved - 7, CreationTimePlus(0x2996 << 3)},
+                  {kSmallLargestObserved - 8, CreationTimePlus(0x2995 << 3)},
+                  {kSmallLargestObserved - 9, CreationTimePlus(0x2995 << 3)},
+                  {kSmallLargestObserved - 10, CreationTimePlus(0x1002 << 3)},
+              }));
+}
+
+TEST_P(QuicFramerTest, AckReceiveTimestamps) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
+                  {kSmallLargestObserved - 3, CreationTimePlus(0x29ff << 3)},
+                  {kSmallLargestObserved - 4, CreationTimePlus(0x29ff << 3)},
+                  {kSmallLargestObserved - 5, CreationTimePlus(0x29ff << 3)},
+              }));
+}
+
+TEST_P(QuicFramerTest, AckReceiveTimestampsPacketOutOfOrder) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+
+  // The packet numbers below are out of order, this is impossible because we
+  // don't record out of order packets in received_packet_times. The test is
+  // intended to ensure this error is raised when it happens.
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  EXPECT_QUIC_BUG(BuildDataPacket(header, frames),
+                  "Packet number and/or receive time not in order.");
+}
+
+// If there's insufficient room for IETF ack receive timestamps, don't write any
+// timestamp ranges.
+TEST_P(QuicFramerTest, IetfAckReceiveTimestampsTruncate) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8192);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  for (QuicPacketNumber i(1); i <= kSmallLargestObserved; i += 2) {
+    ack_frame.received_packet_times.push_back(
+        {i, CreationTimePlus((0x29ff << 3))});
+  }
+
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_TRUE(frame.received_packet_times.empty());
+}
+
+// If there are too many ack ranges, they will be truncated to make room for a
+// timestamp range count of 0.
+TEST_P(QuicFramerTest, IetfAckReceiveTimestampsAckRangeTruncation) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame;
+  // Create a packet with just the ack.
+  ack_frame = MakeAckFrameWithGaps(/*gap_size=*/0xffffffff,
+                                   /*max_num_gaps=*/200,
+                                   /*largest_acked=*/kMaxIetfVarInt);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {QuicPacketNumber(kMaxIetfVarInt) - 2, CreationTimePlus((0x29ff << 3))},
+  };
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+  // Build an ACK packet.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+            LargestAcked(processed_ack_frame));
+  // Verify ACK ranges in the frame gets truncated.
+  ASSERT_LT(processed_ack_frame.packets.NumPacketsSlow(),
+            ack_frame.packets.NumIntervals());
+  EXPECT_EQ(158u, processed_ack_frame.packets.NumPacketsSlow());
+  EXPECT_LT(processed_ack_frame.packets.NumIntervals(),
+            ack_frame.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+            processed_ack_frame.packets.Max());
+  // But the receive timestamps are not truncated because they are small.
+  EXPECT_FALSE(processed_ack_frame.received_packet_times.empty());
+}
+
+TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kPacketNumber);
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x2C,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 4 byte largest observed, 4 byte block length)
+      0x4A,
+      // largest acked
+      0x12, 0x34, 0x56, 0x78,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x12, 0x34, 0x56, 0x78,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 4 byte largest observed, 4 byte block length)
+      0x4A,
+      // largest acked
+      0x12, 0x34, 0x56, 0x78,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x12, 0x34, 0x56, 0x78,
+      // num timestamps.
+      0x00,
+  };
+
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (IETF_ACK frame)
+      0x02,
+      // largest acked
+      kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // Nr. of additional ack blocks
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
+                    {QuicPacketNumber(10), QuicPacketNumber(500)},
+                    {QuicPacketNumber(900), kSmallMissingPacket},
+                    {kSmallMissingPacket + 1, kSmallLargestObserved + 1}});
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x2C,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (has ack blocks, 2 byte largest observed, 2 byte block length)
+      0x65,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // num ack blocks ranges.
+      0x04,
+      // first ack block length.
+      0x00, 0x01,
+      // gap to next block.
+      0x01,
+      // ack block length.
+      0x0e, 0xaf,
+      // gap to next block.
+      0xff,
+      // ack block length.
+      0x00, 0x00,
+      // gap to next block.
+      0x91,
+      // ack block length.
+      0x01, 0xea,
+      // gap to next block.
+      0x05,
+      // ack block length.
+      0x00, 0x04,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (has ack blocks, 2 byte largest observed, 2 byte block length)
+      0x65,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // num ack blocks ranges.
+      0x04,
+      // first ack block length.
+      0x00, 0x01,
+      // gap to next block.
+      0x01,
+      // ack block length.
+      0x0e, 0xaf,
+      // gap to next block.
+      0xff,
+      // ack block length.
+      0x00, 0x00,
+      // gap to next block.
+      0x91,
+      // ack block length.
+      0x01, 0xea,
+      // gap to next block.
+      0x05,
+      // ack block length.
+      0x00, 0x04,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (IETF_ACK frame)
+      0x02,
+      // largest acked
+      kVarInt62TwoBytes + 0x12, 0x34,
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // num additional ack blocks.
+      kVarInt62OneByte + 0x03,
+      // first ack block length.
+      kVarInt62OneByte + 0x00,
+
+      // gap to next block.
+      kVarInt62OneByte + 0x00,
+      // ack block length.
+      kVarInt62TwoBytes + 0x0e, 0xae,
+
+      // gap to next block.
+      kVarInt62TwoBytes + 0x01, 0x8f,
+      // ack block length.
+      kVarInt62TwoBytes + 0x01, 0xe9,
+
+      // gap to next block.
+      kVarInt62OneByte + 0x04,
+      // ack block length.
+      kVarInt62OneByte + 0x03,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObservedto make this test finished in a short time.
+  QuicAckFrame ack_frame;
+  ack_frame.largest_acked = kSmallLargestObserved;
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  // 300 ack blocks.
+  for (size_t i = 2; i < 2 * 300; i += 2) {
+    ack_frame.packets.Add(QuicPacketNumber(i));
+  }
+  ack_frame.packets.AddRange(QuicPacketNumber(600), kSmallLargestObserved + 1);
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x2C,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (ack frame)
+      // (has ack blocks, 2 byte largest observed, 2 byte block length)
+      0x65,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // num ack blocks ranges.
+      0xff,
+      // first ack block length.
+      0x0f, 0xdd,
+      // 255 = 4 * 63 + 3
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (ack frame)
+      // (has ack blocks, 2 byte largest observed, 2 byte block length)
+      0x65,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // num ack blocks ranges.
+      0xff,
+      // first ack block length.
+      0x0f, 0xdd,
+      // 255 = 4 * 63 + 3
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_ACK frame)
+      0x02,
+      // largest acked
+      kVarInt62TwoBytes + 0x12, 0x34,
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // num ack blocks ranges.
+      kVarInt62TwoBytes + 0x01, 0x2b,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x0f, 0xdc,
+      // 255 added blocks of gap_size == 1, ack_size == 1
+#define V99AddedBLOCK kVarInt62OneByte + 0x00, kVarInt62OneByte + 0x00
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+
+#undef V99AddedBLOCK
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildNewStopWaitingPacket) {
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicStopWaitingFrame stop_waiting_frame;
+  stop_waiting_frame.least_unacked = kLeastUnacked;
+
+  QuicFrames frames = {QuicFrame(stop_waiting_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stop waiting frame)
+    0x06,
+    // least packet number awaiting an ack, delta from packet number.
+    0x00, 0x00, 0x00, 0x08,
+  };
+
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicRstStreamFrame rst_frame;
+  rst_frame.stream_id = kStreamId;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    rst_frame.ietf_error_code = 0x01;
+  } else {
+    rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
+  }
+  rst_frame.byte_offset = 0x0807060504030201;
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (rst stream frame)
+    0x01,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // sent byte offset
+    0x08, 0x07, 0x06, 0x05,
+    0x04, 0x03, 0x02, 0x01,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+  };
+
+  unsigned char packet46[] = {
+    // type (short packet, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (rst stream frame)
+    0x01,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // sent byte offset
+    0x08, 0x07, 0x06, 0x05,
+    0x04, 0x03, 0x02, 0x01,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short packet, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_RST_STREAM frame)
+    0x04,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // error code
+    kVarInt62OneByte + 0x01,
+    // sent byte offset
+    kVarInt62EightBytes + 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01
+  };
+  // clang-format on
+
+  QuicFrames frames = {QuicFrame(&rst_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildCloseFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame close_frame(framer_.transport_version(),
+                                       QUIC_INTERNAL_ERROR, NO_IETF_QUIC_ERROR,
+                                       "because I can", 0x05);
+  QuicFrames frames = {QuicFrame(&close_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x00, 0x00, 0x00, 0x01,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x00, 0x00, 0x00, 0x01,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_CONNECTION_CLOSE frame)
+    0x1c,
+    // error code
+    kVarInt62OneByte + 0x01,
+    // Frame type within the CONNECTION_CLOSE frame
+    kVarInt62OneByte + 0x05,
+    // error details length
+    kVarInt62OneByte + 0x0f,
+    // error details
+    '1',  ':',  'b',  'e',
+    'c',  'a',  'u',  's',
+    'e',  ' ',  'I',  ' ',
+    'c',  'a',  'n',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildCloseFramePacketExtendedInfo) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame close_frame(
+      framer_.transport_version(),
+      static_cast<QuicErrorCode>(
+          VersionHasIetfQuicFrames(framer_.transport_version()) ? 0x01
+                                                                : 0x05060708),
+      NO_IETF_QUIC_ERROR, "because I can", 0x05);
+  // Set this so that it is "there" for both Google QUIC and IETF QUIC
+  // framing. It better not show up for Google QUIC!
+  close_frame.quic_error_code = static_cast<QuicErrorCode>(0x4567);
+
+  QuicFrames frames = {QuicFrame(&close_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_CONNECTION_CLOSE frame)
+    0x1c,
+    // IETF error code INTERNAL_ERROR = 0x01 corresponding to
+    // QuicErrorCode::QUIC_INTERNAL_ERROR = 0x01.
+    kVarInt62OneByte + 0x01,
+    // Frame type within the CONNECTION_CLOSE frame
+    kVarInt62OneByte + 0x05,
+    // error details length
+    kVarInt62OneByte + 0x13,
+    // error details
+    '1',  '7',  '7',  '6',
+    '7',  ':',  'b',  'e',
+    'c',  'a',  'u',  's',
+    'e',  ' ',  'I',  ' ',
+    'c',  'a',  'n'
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame close_frame(framer_.transport_version(),
+                                       QUIC_INTERNAL_ERROR, NO_IETF_QUIC_ERROR,
+                                       std::string(2048, 'A'), 0x05);
+  QuicFrames frames = {QuicFrame(&close_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x00, 0x00, 0x00, 0x01,
+    // error details length
+    0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x00, 0x00, 0x00, 0x01,
+    // error details length
+    0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_CONNECTION_CLOSE frame)
+    0x1c,
+    // error code
+    kVarInt62OneByte + 0x01,
+    // Frame type within the CONNECTION_CLOSE frame
+    kVarInt62OneByte + 0x05,
+    // error details length
+    kVarInt62TwoBytes + 0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    '1',  ':',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildApplicationCloseFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame app_close_frame;
+  app_close_frame.wire_error_code = 0x11;
+  app_close_frame.error_details = "because I can";
+  app_close_frame.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
+
+  QuicFrames frames = {QuicFrame(&app_close_frame)};
+
+  // clang-format off
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_APPLICATION_CLOSE frame)
+    0x1d,
+    // error code
+    kVarInt62OneByte + 0x11,
+    // error details length
+    kVarInt62OneByte + 0x0f,
+    // error details, note that it includes an extended error code.
+    '0',  ':',  'b',  'e',
+    'c',  'a',  'u',  's',
+    'e',  ' ',  'I',  ' ',
+    'c',  'a',  'n',
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildTruncatedApplicationCloseFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame app_close_frame;
+  app_close_frame.wire_error_code = 0x11;
+  app_close_frame.error_details = std::string(2048, 'A');
+  app_close_frame.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
+  // Setting to missing ensures that if it is missing, the extended
+  // code is not added to the text message.
+  app_close_frame.quic_error_code = QUIC_IETF_GQUIC_ERROR_MISSING;
+
+  QuicFrames frames = {QuicFrame(&app_close_frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_APPLICATION_CLOSE frame)
+    0x1d,
+    // error code
+    kVarInt62OneByte + 0x11,
+    // error details length
+    kVarInt62TwoBytes + 0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildGoAwayPacket) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for Google QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicGoAwayFrame goaway_frame;
+  goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
+  goaway_frame.last_good_stream_id = kStreamId;
+  goaway_frame.reason_phrase = "because I can";
+
+  QuicFrames frames = {QuicFrame(&goaway_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (go away frame)
+    0x03,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (go away frame)
+    0x03,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildTruncatedGoAwayPacket) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for Google QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicGoAwayFrame goaway_frame;
+  goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
+  goaway_frame.last_good_stream_id = kStreamId;
+  goaway_frame.reason_phrase = std::string(2048, 'A');
+
+  QuicFrames frames = {QuicFrame(&goaway_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (go away frame)
+    0x03,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // error details length
+    0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (go away frame)
+    0x03,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // error details length
+    0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicWindowUpdateFrame window_update_frame;
+  window_update_frame.stream_id = kStreamId;
+  window_update_frame.max_data = 0x1122334455667788;
+
+  QuicFrames frames = {QuicFrame(window_update_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (window update frame)
+    0x04,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // byte offset
+    0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (window update frame)
+    0x04,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // byte offset
+    0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_STREAM_DATA frame)
+    0x11,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // byte offset
+    kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildMaxStreamDataPacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicWindowUpdateFrame window_update_frame;
+  window_update_frame.stream_id = kStreamId;
+  window_update_frame.max_data = 0x1122334455667788;
+
+  QuicFrames frames = {QuicFrame(window_update_frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_STREAM_DATA frame)
+    0x11,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // byte offset
+    kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildMaxDataPacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicWindowUpdateFrame window_update_frame;
+  window_update_frame.stream_id =
+      QuicUtils::GetInvalidStreamId(framer_.transport_version());
+  window_update_frame.max_data = 0x1122334455667788;
+
+  QuicFrames frames = {QuicFrame(window_update_frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_DATA frame)
+    0x10,
+    // byte offset
+    kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildBlockedPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicBlockedFrame blocked_frame;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // For IETF QUIC, the stream ID must be <invalid> for the frame
+    // to be a BLOCKED frame. if it's valid, it will be a
+    // STREAM_BLOCKED frame.
+    blocked_frame.stream_id =
+        QuicUtils::GetInvalidStreamId(framer_.transport_version());
+  } else {
+    blocked_frame.stream_id = kStreamId;
+  }
+  blocked_frame.offset = kStreamOffset;
+
+  QuicFrames frames = {QuicFrame(blocked_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (blocked frame)
+    0x05,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+  };
+
+  unsigned char packet46[] = {
+    // type (short packet, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (blocked frame)
+    0x05,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short packet, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_DATA_BLOCKED frame)
+    0x14,
+    // Offset
+    kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildPingPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPingFrame())};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ping frame)
+    0x07,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type
+    0x07,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PING frame)
+    0x01,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildHandshakeDonePacket) {
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicHandshakeDoneFrame())};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (Handshake done frame)
+    0x1e,
+  };
+  // clang-format on
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildAckFrequencyPacket) {
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrequencyFrame ack_frequency_frame;
+  ack_frequency_frame.sequence_number = 3;
+  ack_frequency_frame.packet_tolerance = 5;
+  ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMicroseconds(0x3fff);
+  ack_frequency_frame.ignore_order = false;
+  QuicFrames frames = {QuicFrame(&ack_frequency_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (Ack Frequency frame)
+    0x40, 0xaf,
+    // sequence number
+    0x03,
+    // packet tolerance
+    0x05,
+    // max_ack_delay_us
+    0x7f, 0xff,
+    // ignore_oder
+    0x00
+  };
+  // clang-format on
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildMessagePacket) {
+  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicMessageFrame frame(1, MemSliceFromString("message"));
+  QuicMessageFrame frame2(2, MemSliceFromString("message2"));
+  QuicFrames frames = {QuicFrame(&frame), QuicFrame(&frame2)};
+
+  // clang-format off
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (message frame)
+    0x21,
+    // Length
+    0x07,
+    // Message Data
+    'm', 'e', 's', 's', 'a', 'g', 'e',
+    // frame type (message frame no length)
+    0x20,
+    // Message Data
+    'm', 'e', 's', 's', 'a', 'g', 'e', '2'
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MESSAGE frame)
+    0x31,
+    // Length
+    0x07,
+    // Message Data
+    'm', 'e', 's', 's', 'a', 'g', 'e',
+    // frame type (message frame no length)
+    0x30,
+    // Message Data
+    'm', 'e', 's', 's', 'a', 'g', 'e', '2'
+  };
+  // clang-format on
+
+  unsigned char* p = packet46;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      ABSL_ARRAYSIZE(packet46));
+}
+
+// Test that the MTU discovery packet is serialized correctly as a PING packet.
+TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicMtuDiscoveryFrame())};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ping frame)
+    0x07,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type
+    0x07,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PING frame)
+    0x01,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildPublicResetPacket) {
+  QuicPublicResetPacket reset_packet;
+  reset_packet.connection_id = FramerTestConnectionId();
+  reset_packet.nonce_proof = kNonceProof;
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (public reset, 8 byte ConnectionId)
+    0x0E,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // message tag (kPRST)
+    'P', 'R', 'S', 'T',
+    // num_entries (1) + padding
+    0x01, 0x00, 0x00, 0x00,
+    // tag kRNON
+    'R', 'N', 'O', 'N',
+    // end offset 8
+    0x08, 0x00, 0x00, 0x00,
+    // nonce proof
+    0x89, 0x67, 0x45, 0x23,
+    0x01, 0xEF, 0xCD, 0xAB,
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> data(
+      framer_.BuildPublicResetPacket(reset_packet));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
+  QuicPublicResetPacket reset_packet;
+  reset_packet.connection_id = FramerTestConnectionId();
+  reset_packet.nonce_proof = kNonceProof;
+  reset_packet.client_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), 0x1234);
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (public reset, 8 byte ConnectionId)
+      0x0E,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98,
+      0x76, 0x54, 0x32, 0x10,
+      // message tag (kPRST)
+      'P', 'R', 'S', 'T',
+      // num_entries (2) + padding
+      0x02, 0x00, 0x00, 0x00,
+      // tag kRNON
+      'R', 'N', 'O', 'N',
+      // end offset 8
+      0x08, 0x00, 0x00, 0x00,
+      // tag kCADR
+      'C', 'A', 'D', 'R',
+      // end offset 16
+      0x10, 0x00, 0x00, 0x00,
+      // nonce proof
+      0x89, 0x67, 0x45, 0x23,
+      0x01, 0xEF, 0xCD, 0xAB,
+      // client address
+      0x02, 0x00,
+      0x7F, 0x00, 0x00, 0x01,
+      0x34, 0x12,
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> data(
+      framer_.BuildPublicResetPacket(reset_packet));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildPublicResetPacketWithEndpointId) {
+  QuicPublicResetPacket reset_packet;
+  reset_packet.connection_id = FramerTestConnectionId();
+  reset_packet.nonce_proof = kNonceProof;
+  reset_packet.endpoint_id = "FakeServerId";
+
+  // The tag value map in CryptoHandshakeMessage is a std::map, so the two tags
+  // in the packet, kRNON and kEPID, have unspecified ordering w.r.t each other.
+  // clang-format off
+  unsigned char packet_variant1[] = {
+      // public flags (public reset, 8 byte ConnectionId)
+      0x0E,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98,
+      0x76, 0x54, 0x32, 0x10,
+      // message tag (kPRST)
+      'P', 'R', 'S', 'T',
+      // num_entries (2) + padding
+      0x02, 0x00, 0x00, 0x00,
+      // tag kRNON
+      'R', 'N', 'O', 'N',
+      // end offset 8
+      0x08, 0x00, 0x00, 0x00,
+      // tag kEPID
+      'E', 'P', 'I', 'D',
+      // end offset 20
+      0x14, 0x00, 0x00, 0x00,
+      // nonce proof
+      0x89, 0x67, 0x45, 0x23,
+      0x01, 0xEF, 0xCD, 0xAB,
+      // Endpoint ID
+      'F', 'a', 'k', 'e', 'S', 'e', 'r', 'v', 'e', 'r', 'I', 'd',
+  };
+  unsigned char packet_variant2[] = {
+      // public flags (public reset, 8 byte ConnectionId)
+      0x0E,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98,
+      0x76, 0x54, 0x32, 0x10,
+      // message tag (kPRST)
+      'P', 'R', 'S', 'T',
+      // num_entries (2) + padding
+      0x02, 0x00, 0x00, 0x00,
+      // tag kEPID
+      'E', 'P', 'I', 'D',
+      // end offset 12
+      0x0C, 0x00, 0x00, 0x00,
+      // tag kRNON
+      'R', 'N', 'O', 'N',
+      // end offset 20
+      0x14, 0x00, 0x00, 0x00,
+      // Endpoint ID
+      'F', 'a', 'k', 'e', 'S', 'e', 'r', 'v', 'e', 'r', 'I', 'd',
+      // nonce proof
+      0x89, 0x67, 0x45, 0x23,
+      0x01, 0xEF, 0xCD, 0xAB,
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> data(
+      framer_.BuildPublicResetPacket(reset_packet));
+  ASSERT_TRUE(data != nullptr);
+
+  // Variant 1 ends with char 'd'. Variant 1 ends with char 0xAB.
+  if ('d' == data->data()[data->length() - 1]) {
+    quiche::test::CompareCharArraysWithHexError(
+        "constructed packet", data->data(), data->length(),
+        AsChars(packet_variant1), ABSL_ARRAYSIZE(packet_variant1));
+  } else {
+    quiche::test::CompareCharArraysWithHexError(
+        "constructed packet", data->data(), data->length(),
+        AsChars(packet_variant2), ABSL_ARRAYSIZE(packet_variant2));
+  }
+}
+
+TEST_P(QuicFramerTest, BuildIetfStatelessResetPacket) {
+  // clang-format off
+    unsigned char packet[] = {
+      // 1st byte 01XX XXXX
+      0x40,
+      // At least 4 bytes of random bytes.
+      0x00, 0x00, 0x00, 0x00,
+      // stateless reset token
+      0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+      0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f
+    };
+  // clang-format on
+
+  // Build the minimal stateless reset packet.
+  std::unique_ptr<QuicEncryptedPacket> data(
+      framer_.BuildIetfStatelessResetPacket(
+          FramerTestConnectionId(),
+          QuicFramer::GetMinStatelessResetPacketLength() + 1,
+          kTestStatelessResetToken));
+  ASSERT_TRUE(data);
+  EXPECT_EQ(QuicFramer::GetMinStatelessResetPacketLength(), data->length());
+  // Verify the first 2 bits are 01.
+  EXPECT_FALSE(data->data()[0] & FLAGS_LONG_HEADER);
+  EXPECT_TRUE(data->data()[0] & FLAGS_FIXED_BIT);
+  // Verify stateless reset token.
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet",
+      data->data() + data->length() - kStatelessResetTokenLength,
+      kStatelessResetTokenLength,
+      AsChars(packet) + ABSL_ARRAYSIZE(packet) - kStatelessResetTokenLength,
+      kStatelessResetTokenLength);
+
+  // Packets with length <= minimal stateless reset does not trigger stateless
+  // reset.
+  std::unique_ptr<QuicEncryptedPacket> data2(
+      framer_.BuildIetfStatelessResetPacket(
+          FramerTestConnectionId(),
+          QuicFramer::GetMinStatelessResetPacketLength(),
+          kTestStatelessResetToken));
+  ASSERT_FALSE(data2);
+
+  // Do not send stateless reset >= minimal stateless reset + 1 + max
+  // connection ID length.
+  std::unique_ptr<QuicEncryptedPacket> data3(
+      framer_.BuildIetfStatelessResetPacket(FramerTestConnectionId(), 1000,
+                                            kTestStatelessResetToken));
+  ASSERT_TRUE(data3);
+  EXPECT_EQ(QuicFramer::GetMinStatelessResetPacketLength() + 1 +
+                kQuicMaxConnectionIdWithLengthPrefixLength,
+            data3->length());
+}
+
+TEST_P(QuicFramerTest, EncryptPacket) {
+  QuicPacketNumber packet_number = kPacketNumber;
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+  };
+
+  unsigned char packet50[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+    'q',  'r',  's',  't',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasHeaderProtection()) {
+    p = packet50;
+    p_size = ABSL_ARRAYSIZE(packet50);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  std::unique_ptr<QuicPacket> raw(new QuicPacket(
+      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = framer_.EncryptPayload(
+      ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
+
+  ASSERT_NE(0u, encrypted_length);
+  EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
+}
+
+// Regression test for b/158014497.
+TEST_P(QuicFramerTest, EncryptEmptyPacket) {
+  auto packet = std::make_unique<QuicPacket>(
+      new char[100], 0, true, PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID,
+      /*includes_version=*/true,
+      /*includes_diversification_nonce=*/true, PACKET_1BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0,
+      /*retry_token_length=*/0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = 1;
+  EXPECT_QUIC_BUG(encrypted_length = framer_.EncryptPayload(
+                      ENCRYPTION_INITIAL, kPacketNumber, *packet, buffer,
+                      kMaxOutgoingPacketSize),
+                  "packet is shorter than associated data length");
+  EXPECT_EQ(0u, encrypted_length);
+}
+
+TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketNumber packet_number = kPacketNumber;
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (version, 8 byte connection_id)
+    0x29,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // version tag
+    'Q', '.', '1', '0',
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+  };
+
+  unsigned char packet46[] = {
+    // type (long header with packet type ZERO_RTT_PROTECTED)
+    0xD3,
+    // version tag
+    'Q', '.', '1', '0',
+    // connection_id length
+    0x50,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+  };
+
+  unsigned char packet50[] = {
+    // type (long header with packet type ZERO_RTT_PROTECTED)
+    0xD3,
+    // version tag
+    'Q', '.', '1', '0',
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x00,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+    'q',  'r',  's',  't',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  // TODO(ianswett): see todo in previous test.
+  if (framer_.version().HasHeaderProtection()) {
+    p = packet50;
+    p_size = ABSL_ARRAYSIZE(packet50);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> raw(new QuicPacket(
+      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = framer_.EncryptPayload(
+      ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
+
+  ASSERT_NE(0u, encrypted_length);
+  EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
+}
+
+TEST_P(QuicFramerTest, AckTruncationLargePacket) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This test is not applicable to this version; the range count is
+    // effectively unlimited
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame;
+  // Create a packet with just the ack.
+  ack_frame = MakeAckFrameWithAckBlocks(300, 0u);
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // Build an ack packet with truncation due to limit in number of nack ranges.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
+  ASSERT_EQ(256u, processed_ack_frame.packets.NumPacketsSlow());
+  EXPECT_EQ(QuicPacketNumber(90u), processed_ack_frame.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
+}
+
+// Regression test for b/150386368.
+TEST_P(QuicFramerTest, IetfAckFrameTruncation) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame;
+  // Create a packet with just the ack.
+  ack_frame = MakeAckFrameWithGaps(/*gap_size=*/0xffffffff,
+                                   /*max_num_gaps=*/200,
+                                   /*largest_acked=*/kMaxIetfVarInt);
+  ack_frame.ecn_counters_populated = true;
+  ack_frame.ect_0_count = 100;
+  ack_frame.ect_1_count = 10000;
+  ack_frame.ecn_ce_count = 1000000;
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+  // Build an ACK packet.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+            LargestAcked(processed_ack_frame));
+  // Verify ACK frame gets truncated.
+  ASSERT_LT(processed_ack_frame.packets.NumPacketsSlow(),
+            ack_frame.packets.NumIntervals());
+  EXPECT_EQ(157u, processed_ack_frame.packets.NumPacketsSlow());
+  EXPECT_LT(processed_ack_frame.packets.NumIntervals(),
+            ack_frame.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+            processed_ack_frame.packets.Max());
+}
+
+TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This test is not applicable to this version; the range count is
+    // effectively unlimited
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Create a packet with just the ack.
+  QuicAckFrame ack_frame;
+  ack_frame = MakeAckFrameWithAckBlocks(300, 0u);
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // Build an ack packet with truncation due to limit in number of nack ranges.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(
+      BuildDataPacket(header, frames, 500));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
+  ASSERT_EQ(240u, processed_ack_frame.packets.NumPacketsSlow());
+  EXPECT_EQ(QuicPacketNumber(122u), processed_ack_frame.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
+}
+
+TEST_P(QuicFramerTest, CleanTruncation) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This test is not applicable to this version; the range count is
+    // effectively unlimited
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(201);
+
+  // Create a packet with just the ack.
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+  if (framer_.version().HasHeaderProtection()) {
+    frames.push_back(QuicFrame(QuicPaddingFrame(12)));
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+
+  // Test for clean truncation of the ack by comparing the length of the
+  // original packets to the re-serialized packets.
+  frames.clear();
+  frames.push_back(QuicFrame(visitor_.ack_frames_[0].get()));
+  if (framer_.version().HasHeaderProtection()) {
+    frames.push_back(QuicFrame(*visitor_.padding_frames_[0].get()));
+  }
+
+  size_t original_raw_length = raw_ack_packet->length();
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  raw_ack_packet = BuildDataPacket(header, frames);
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  EXPECT_EQ(original_raw_length, raw_ack_packet->length());
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+}
+
+TEST_P(QuicFramerTest, StopPacketProcessing) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+
+    // frame type (ack frame)
+    0x40,
+    // least packet number awaiting an ack
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xA0,
+    // largest observed packet number
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xBF,
+    // num missing packets
+    0x01,
+    // missing packet
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xBE,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+
+    // frame type (ack frame)
+    0x40,
+    // least packet number awaiting an ack
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xA0,
+    // largest observed packet number
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xBF,
+    // num missing packets
+    0x01,
+    // missing packet
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xBE,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAM frame with fin, length, and offset bits set)
+    0x08 | 0x01 | 0x02 | 0x04,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    kVarInt62TwoBytes + 0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+
+    // frame type (ack frame)
+    0x0d,
+    // largest observed packet number
+    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
+    // Delta time
+    kVarInt62OneByte + 0x00,
+    // Ack Block count
+    kVarInt62OneByte + 0x01,
+    // First block size (one packet)
+    kVarInt62OneByte + 0x00,
+
+    // Next gap size & ack. Missing all preceding packets
+    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
+    kVarInt62OneByte + 0x00,
+  };
+  // clang-format on
+
+  MockFramerVisitor visitor;
+  framer_.set_visitor(&visitor);
+  EXPECT_CALL(visitor, OnPacket());
+  EXPECT_CALL(visitor, OnPacketHeader(_));
+  EXPECT_CALL(visitor, OnStreamFrame(_)).WillOnce(Return(false));
+  EXPECT_CALL(visitor, OnPacketComplete());
+  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)).WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnUnauthenticatedHeader(_)).WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnDecryptedPacket(_, _));
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+}
+
+static char kTestString[] = "At least 20 characters.";
+static QuicStreamId kTestQuicStreamId = 1;
+
+MATCHER_P(ExpectedStreamFrame, version, "") {
+  return (arg.stream_id == kTestQuicStreamId ||
+          QuicUtils::IsCryptoStreamId(version.transport_version,
+                                      arg.stream_id)) &&
+         !arg.fin && arg.offset == 0 &&
+         std::string(arg.data_buffer, arg.data_length) == kTestString;
+  // FIN is hard-coded false in ConstructEncryptedPacket.
+  // Offset 0 is hard-coded in ConstructEncryptedPacket.
+}
+
+// Verify that the packet returned by ConstructEncryptedPacket() can be properly
+// parsed by the framer.
+TEST_P(QuicFramerTest, ConstructEncryptedPacket) {
+  // Since we are using ConstructEncryptedPacket, we have to set the framer's
+  // crypto to be Null.
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullDecrypter>(framer_.perspective()));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 framer_.perspective()));
+  }
+  ParsedQuicVersionVector versions;
+  versions.push_back(framer_.version());
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      TestConnectionId(), EmptyQuicConnectionId(), false, false,
+      kTestQuicStreamId, kTestString, CONNECTION_ID_PRESENT,
+      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &versions));
+
+  MockFramerVisitor visitor;
+  framer_.set_visitor(&visitor);
+  EXPECT_CALL(visitor, OnPacket()).Times(1);
+  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_))
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnUnauthenticatedHeader(_))
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1).WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnDecryptedPacket(_, _)).Times(1);
+  EXPECT_CALL(visitor, OnError(_)).Times(0);
+  EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0);
+  if (!QuicVersionUsesCryptoFrames(framer_.version().transport_version)) {
+    EXPECT_CALL(visitor, OnStreamFrame(ExpectedStreamFrame(framer_.version())))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor, OnCryptoFrame(_)).Times(1);
+  }
+  EXPECT_CALL(visitor, OnPacketComplete()).Times(1);
+
+  EXPECT_TRUE(framer_.ProcessPacket(*packet));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+}
+
+// Verify that the packet returned by ConstructMisFramedEncryptedPacket()
+// does cause the framer to return an error.
+TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) {
+  // Since we are using ConstructEncryptedPacket, we have to set the framer's
+  // crypto to be Null.
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullDecrypter>(framer_.perspective()));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 framer_.perspective()));
+  }
+  framer_.SetEncrypter(ENCRYPTION_INITIAL,
+                       std::make_unique<NullEncrypter>(framer_.perspective()));
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
+      TestConnectionId(), EmptyQuicConnectionId(), false, false,
+      kTestQuicStreamId, kTestString, CONNECTION_ID_PRESENT,
+      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, framer_.version(),
+      Perspective::IS_CLIENT));
+
+  MockFramerVisitor visitor;
+  framer_.set_visitor(&visitor);
+  EXPECT_CALL(visitor, OnPacket()).Times(1);
+  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_))
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnUnauthenticatedHeader(_))
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1);
+  EXPECT_CALL(visitor, OnDecryptedPacket(_, _)).Times(1);
+  EXPECT_CALL(visitor, OnError(_)).Times(1);
+  EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0);
+  EXPECT_CALL(visitor, OnPacketComplete()).Times(0);
+
+  EXPECT_FALSE(framer_.ProcessPacket(*packet));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+}
+
+TEST_P(QuicFramerTest, IetfBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_DATA_BLOCKED)
+      {"",
+       {0x14}},
+      // blocked offset
+      {"Can not read blocked offset.",
+       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfBlockedPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicBlockedFrame frame;
+  frame.stream_id = QuicUtils::GetInvalidStreamId(framer_.transport_version());
+  frame.offset = kStreamOffset;
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_DATA_BLOCKED)
+    0x14,
+    // Offset
+    kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, IetfStreamBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAM_DATA_BLOCKED)
+      {"",
+       {0x15}},
+      // blocked offset
+      {"Unable to read IETF_STREAM_DATA_BLOCKED frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      {"Can not read stream blocked offset.",
+       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id);
+  EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_STREAM_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfStreamBlockedPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicBlockedFrame frame;
+  frame.stream_id = kStreamId;
+  frame.offset = kStreamOffset;
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAM_DATA_BLOCKED)
+    0x15,
+    // Stream ID
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // Offset
+    kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BiDiMaxStreamsFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
+      {"",
+       {0x12}},
+      // max. streams
+      {"Unable to read IETF_MAX_STREAMS_BIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+TEST_P(QuicFramerTest, UniDiMaxStreamsFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // Test runs in client mode, no connection id
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
+      {"",
+       {0x13}},
+      // max. streams
+      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+TEST_P(QuicFramerTest, ServerUniDiMaxStreamsFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
+      {"",
+       {0x13}},
+      // max. streams
+      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+TEST_P(QuicFramerTest, ClientUniDiMaxStreamsFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // Test runs in client mode, no connection id
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
+      {"",
+       {0x13}},
+      // max. streams
+      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+// The following four tests ensure that the framer can deserialize a stream
+// count that is large enough to cause the resulting stream ID to exceed the
+// current implementation limit(32 bits). The intent is that when this happens,
+// the stream limit is pegged to the maximum supported value. There are four
+// tests, for the four combinations of uni- and bi-directional, server- and
+// client- initiated.
+TEST_P(QuicFramerTest, BiDiMaxStreamsFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
+    0x12,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
+}
+
+TEST_P(QuicFramerTest, ClientBiDiMaxStreamsFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // Test runs in client mode, no connection id
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
+    0x12,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
+}
+
+TEST_P(QuicFramerTest, ServerUniDiMaxStreamsFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
+    0x13,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+}
+
+TEST_P(QuicFramerTest, ClientUniDiMaxStreamsFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // Test runs in client mode, no connection id
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_UNDIRECTIONAL)
+    0x13,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+}
+
+// Specifically test that count==0 is accepted.
+TEST_P(QuicFramerTest, MaxStreamsFrameZeroCount) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
+    0x12,
+    // max. streams == 0.
+    kVarInt62OneByte + 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+}
+
+TEST_P(QuicFramerTest, ServerBiDiStreamsBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL frame)
+      {"",
+       {0x13}},
+      // stream count
+      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+TEST_P(QuicFramerTest, BiDiStreamsBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL frame)
+      {"",
+       {0x16}},
+      // stream id
+      {"Unable to read IETF_STREAMS_BLOCKED_BIDIRECTIONAL "
+       "frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
+  EXPECT_FALSE(visitor_.streams_blocked_frame_.unidirectional);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, UniDiStreamsBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
+      {"",
+       {0x17}},
+      // stream id
+      {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
+       "frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
+  EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, ClientUniDiStreamsBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // Test runs in client mode, no connection id
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
+      {"",
+       {0x17}},
+      // stream id
+      {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
+       "frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
+  EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
+}
+
+// Check that when we get a STREAMS_BLOCKED frame that specifies too large
+// a stream count, we reject with an appropriate error. There is no need to
+// check for different combinations of Uni/Bi directional and client/server
+// initiated; the logic does not take these into account.
+TEST_P(QuicFramerTest, StreamsBlockedFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // Test runs in client mode, no connection id
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL)
+    0x16,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_STREAMS_BLOCKED_DATA));
+  EXPECT_EQ(framer_.detailed_error(),
+            "STREAMS_BLOCKED stream count exceeds implementation limit.");
+}
+
+// Specifically test that count==0 is accepted.
+TEST_P(QuicFramerTest, StreamsBlockedFrameZeroCount) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
+      {"",
+       {0x17}},
+      // stream id
+      {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
+       "frame stream id/count.",
+       {kVarInt62OneByte + 0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.streams_blocked_frame_.stream_count);
+  EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildBiDiStreamsBlockedPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicStreamsBlockedFrame frame;
+  frame.stream_count = 3;
+  frame.unidirectional = false;
+
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL frame)
+    0x16,
+    // Stream count
+    kVarInt62OneByte + 0x03
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildUniStreamsBlockedPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicStreamsBlockedFrame frame;
+  frame.stream_count = 3;
+  frame.unidirectional = true;
+
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
+    0x17,
+    // Stream count
+    kVarInt62OneByte + 0x03
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildBiDiMaxStreamsPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicMaxStreamsFrame frame;
+  frame.stream_count = 3;
+  frame.unidirectional = false;
+
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL frame)
+    0x12,
+    // Stream count
+    kVarInt62OneByte + 0x03
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildUniDiMaxStreamsPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  // This test runs in client mode.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicMaxStreamsFrame frame;
+  frame.stream_count = 3;
+  frame.unidirectional = true;
+
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL frame)
+    0x13,
+    // Stream count
+    kVarInt62OneByte + 0x03
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, NewConnectionIdFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_CONNECTION_ID frame)
+      {"",
+       {0x18}},
+      // error code
+      {"Unable to read new connection ID frame sequence number.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read new connection ID frame retire_prior_to.",
+       {kVarInt62OneByte + 0x09}},
+      {"Unable to read new connection ID frame connection id.",
+       {0x08}},  // connection ID length
+      {"Unable to read new connection ID frame connection id.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11}},
+      {"Can not read new connection ID frame reset token.",
+       {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+        0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(FramerTestConnectionIdPlusOne(),
+            visitor_.new_connection_id_.connection_id);
+  EXPECT_EQ(0x11u, visitor_.new_connection_id_.sequence_number);
+  EXPECT_EQ(0x09u, visitor_.new_connection_id_.retire_prior_to);
+  EXPECT_EQ(kTestStatelessResetToken,
+            visitor_.new_connection_id_.stateless_reset_token);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_NEW_CONNECTION_ID_DATA);
+}
+
+TEST_P(QuicFramerTest, NewConnectionIdFrameVariableLength) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_CONNECTION_ID frame)
+      {"",
+       {0x18}},
+      // error code
+      {"Unable to read new connection ID frame sequence number.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read new connection ID frame retire_prior_to.",
+       {kVarInt62OneByte + 0x0a}},
+      {"Unable to read new connection ID frame connection id.",
+       {0x09}},  // connection ID length
+      {"Unable to read new connection ID frame connection id.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
+      {"Can not read new connection ID frame reset token.",
+       {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+        0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(FramerTestConnectionIdNineBytes(),
+            visitor_.new_connection_id_.connection_id);
+  EXPECT_EQ(0x11u, visitor_.new_connection_id_.sequence_number);
+  EXPECT_EQ(0x0au, visitor_.new_connection_id_.retire_prior_to);
+  EXPECT_EQ(kTestStatelessResetToken,
+            visitor_.new_connection_id_.stateless_reset_token);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_NEW_CONNECTION_ID_DATA);
+}
+
+// Verifies that parsing a NEW_CONNECTION_ID frame with a length above the
+// specified maximum fails.
+TEST_P(QuicFramerTest, InvalidLongNewConnectionIdFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // The NEW_CONNECTION_ID frame is only for IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_CONNECTION_ID frame)
+      {"",
+       {0x18}},
+      // error code
+      {"Unable to read new connection ID frame sequence number.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read new connection ID frame retire_prior_to.",
+       {kVarInt62OneByte + 0x0b}},
+      {"Unable to read new connection ID frame connection id.",
+       {0x40}},  // connection ID length
+      {"Unable to read new connection ID frame connection id.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
+        0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
+        0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
+        0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E}},
+      {"Can not read new connection ID frame reset token.",
+       {0xb5, 0x69, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_NEW_CONNECTION_ID_DATA));
+  EXPECT_EQ("Invalid new connection ID length for version.",
+            framer_.detailed_error());
+}
+
+// Verifies that parsing a NEW_CONNECTION_ID frame with an invalid
+// retire-prior-to fails.
+TEST_P(QuicFramerTest, InvalidRetirePriorToNewConnectionIdFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_CONNECTION_ID frame)
+      {"",
+       {0x18}},
+      // sequence number
+      {"Unable to read new connection ID frame sequence number.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read new connection ID frame retire_prior_to.",
+       {kVarInt62OneByte + 0x1b}},
+      {"Unable to read new connection ID frame connection id length.",
+       {0x08}},  // connection ID length
+      {"Unable to read new connection ID frame connection id.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11}},
+      {"Can not read new connection ID frame reset token.",
+       {0xb5, 0x69, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_NEW_CONNECTION_ID_DATA));
+  EXPECT_EQ("Retire_prior_to > sequence_number.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, BuildNewConnectionIdFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC only.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 0x11;
+  frame.retire_prior_to = 0x0c;
+  // Use this value to force a 4-byte encoded variable length connection ID
+  // in the frame.
+  frame.connection_id = FramerTestConnectionIdPlusOne();
+  frame.stateless_reset_token = kTestStatelessResetToken;
+
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_NEW_CONNECTION_ID frame)
+    0x18,
+    // sequence number
+    kVarInt62OneByte + 0x11,
+    // retire_prior_to
+    kVarInt62OneByte + 0x0c,
+    // new connection id length
+    0x08,
+    // new connection id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+    // stateless reset token
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, NewTokenFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_TOKEN frame)
+      {"",
+       {0x07}},
+      // Length
+      {"Unable to read new token length.",
+       {kVarInt62OneByte + 0x08}},
+      {"Unable to read new token data.",
+       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}}
+  };
+  // clang-format on
+  uint8_t expected_token_value[] = {0x00, 0x01, 0x02, 0x03,
+                                    0x04, 0x05, 0x06, 0x07};
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(sizeof(expected_token_value), visitor_.new_token_.token.length());
+  EXPECT_EQ(0, memcmp(expected_token_value, visitor_.new_token_.token.data(),
+                      sizeof(expected_token_value)));
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_NEW_TOKEN);
+}
+
+TEST_P(QuicFramerTest, BuildNewTokenFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC only.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  uint8_t expected_token_value[] = {0x00, 0x01, 0x02, 0x03,
+                                    0x04, 0x05, 0x06, 0x07};
+
+  QuicNewTokenFrame frame(0,
+                          absl::string_view((const char*)(expected_token_value),
+                                            sizeof(expected_token_value)));
+
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_NEW_TOKEN frame)
+    0x07,
+    // Length and token
+    kVarInt62OneByte + 0x08,
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, IetfStopSendingFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Stop sending frame is IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STOP_SENDING frame)
+      {"",
+       {0x05}},
+      // stream id
+      {"Unable to read IETF_STOP_SENDING frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      {"Unable to read stop sending application error code.",
+       {kVarInt62FourBytes + 0x00, 0x00, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.stop_sending_frame_.stream_id);
+  EXPECT_EQ(QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE,
+            visitor_.stop_sending_frame_.error_code);
+  EXPECT_EQ(static_cast<uint64_t>(0x7654),
+            visitor_.stop_sending_frame_.ietf_error_code);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_STOP_SENDING_FRAME_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfStopSendingPacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Stop sending frame is IETF QUIC only.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicStopSendingFrame frame;
+  frame.stream_id = kStreamId;
+  frame.error_code = QUIC_STREAM_ENCODER_STREAM_ERROR;
+  frame.ietf_error_code =
+      static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR);
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STOP_SENDING frame)
+    0x05,
+    // Stream ID
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // Application error code
+    kVarInt62TwoBytes + 0x02, 0x01,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, IetfPathChallengeFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Path Challenge frame is IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_PATH_CHALLENGE)
+      {"",
+       {0x1a}},
+      // data
+      {"Can not read path challenge data.",
+       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}}),
+            visitor_.path_challenge_frame_.data_buffer);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_PATH_CHALLENGE_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfPathChallengePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Path Challenge frame is IETF QUIC only.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicPathChallengeFrame frame;
+  frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PATH_CHALLENGE)
+    0x1a,
+    // Data
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, IetfPathResponseFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Path response frame is IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_PATH_RESPONSE)
+      {"",
+       {0x1b}},
+      // data
+      {"Can not read path response data.",
+       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}}),
+            visitor_.path_response_frame_.data_buffer);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_PATH_RESPONSE_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfPathResponsePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Path response frame is IETF QUIC only
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicPathResponseFrame frame;
+  frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PATH_RESPONSE)
+    0x1b,
+    // Data
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, GetRetransmittableControlFrameSize) {
+  QuicRstStreamFrame rst_stream(1, 3, QUIC_STREAM_CANCELLED, 1024);
+  EXPECT_EQ(QuicFramer::GetRstStreamFrameSize(framer_.transport_version(),
+                                              rst_stream),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&rst_stream)));
+
+  std::string error_detail(2048, 'e');
+  QuicConnectionCloseFrame connection_close(framer_.transport_version(),
+                                            QUIC_NETWORK_IDLE_TIMEOUT,
+                                            NO_IETF_QUIC_ERROR, error_detail,
+                                            /*transport_close_frame_type=*/0);
+
+  EXPECT_EQ(QuicFramer::GetConnectionCloseFrameSize(framer_.transport_version(),
+                                                    connection_close),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&connection_close)));
+
+  QuicGoAwayFrame goaway(2, QUIC_PEER_GOING_AWAY, 3, error_detail);
+  EXPECT_EQ(QuicFramer::GetMinGoAwayFrameSize() + 256,
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&goaway)));
+
+  QuicWindowUpdateFrame window_update(3, 3, 1024);
+  EXPECT_EQ(QuicFramer::GetWindowUpdateFrameSize(framer_.transport_version(),
+                                                 window_update),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(window_update)));
+
+  QuicBlockedFrame blocked(4, 3, 1024);
+  EXPECT_EQ(
+      QuicFramer::GetBlockedFrameSize(framer_.transport_version(), blocked),
+      QuicFramer::GetRetransmittableControlFrameSize(
+          framer_.transport_version(), QuicFrame(blocked)));
+
+  // Following frames are IETF QUIC frames only.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicNewConnectionIdFrame new_connection_id(5, TestConnectionId(), 1,
+                                             kTestStatelessResetToken, 1);
+  EXPECT_EQ(QuicFramer::GetNewConnectionIdFrameSize(new_connection_id),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&new_connection_id)));
+
+  QuicMaxStreamsFrame max_streams(6, 3, /*unidirectional=*/false);
+  EXPECT_EQ(QuicFramer::GetMaxStreamsFrameSize(framer_.transport_version(),
+                                               max_streams),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(max_streams)));
+
+  QuicStreamsBlockedFrame streams_blocked(7, 3, /*unidirectional=*/false);
+  EXPECT_EQ(QuicFramer::GetStreamsBlockedFrameSize(framer_.transport_version(),
+                                                   streams_blocked),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(streams_blocked)));
+
+  QuicPathFrameBuffer buffer = {
+      {0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe5, 0xf7}};
+  QuicPathResponseFrame path_response_frame(8, buffer);
+  EXPECT_EQ(QuicFramer::GetPathResponseFrameSize(path_response_frame),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&path_response_frame)));
+
+  QuicPathChallengeFrame path_challenge_frame(9, buffer);
+  EXPECT_EQ(QuicFramer::GetPathChallengeFrameSize(path_challenge_frame),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&path_challenge_frame)));
+
+  QuicStopSendingFrame stop_sending_frame(10, 3, QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(QuicFramer::GetStopSendingFrameSize(stop_sending_frame),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(stop_sending_frame)));
+}
+
+// A set of tests to ensure that bad frame-type encodings
+// are properly detected and handled.
+// First, four tests to see that unknown frame types generate
+// a QUIC_INVALID_FRAME_DATA error with detailed information
+// "Illegal frame type." This regardless of the encoding of the type
+// (1/2/4/8 bytes).
+// This only for version 99.
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown1Byte) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (unknown value, single-byte encoding)
+      {"",
+       {0x38}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown2Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (unknown value, two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x01, 0x38}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown4Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (unknown value, four-byte encoding)
+      {"",
+       {kVarInt62FourBytes + 0x01, 0x00, 0x00, 0x38}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown8Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (unknown value, eight-byte encoding)
+      {"",
+       {kVarInt62EightBytes + 0x01, 0x00, 0x00, 0x01, 0x02, 0x34, 0x56, 0x38}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
+}
+
+// Three tests to check that known frame types that are not minimally
+// encoded generate IETF_QUIC_PROTOCOL_VIOLATION errors with detailed
+// information "Frame type not minimally encoded."
+// Look at the frame-type encoded in 2, 4, and 8 bytes.
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown2Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (Blocked, two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x08}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown4Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (Blocked, four-byte encoding)
+      {"",
+       {kVarInt62FourBytes + 0x00, 0x00, 0x00, 0x08}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown8Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (Blocked, eight-byte encoding)
+      {"",
+       {kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
+}
+
+// Tests to check that all known IETF frame types that are not minimally
+// encoded generate IETF_QUIC_PROTOCOL_VIOLATION errors with detailed
+// information "Frame type not minimally encoded."
+// Just look at 2-byte encoding.
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown2BytesAllTypes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packets[] = {
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x00}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x01}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x02}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x03}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x04}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x05}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x06}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x07}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x08}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x09}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0a}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0b}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0c}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0d}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0e}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0f}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x10}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x11}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x12}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x13}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x14}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x15}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x16}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x17}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x18}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x20}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x21}}
+    },
+  };
+  // clang-format on
+
+  for (PacketFragments& packet : packets) {
+    std::unique_ptr<QuicEncryptedPacket> encrypted(
+        AssemblePacketFromFragments(packet));
+
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+    EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+    EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
+  }
+}
+
+TEST_P(QuicFramerTest, RetireConnectionIdFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for version 99.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_RETIRE_CONNECTION_ID frame)
+      {"",
+       {0x19}},
+      // Sequence number
+      {"Unable to read retire connection ID frame sequence number.",
+       {kVarInt62TwoBytes + 0x11, 0x22}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(0x1122u, visitor_.retire_connection_id_.sequence_number);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildRetireConnectionIdFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for version 99.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicRetireConnectionIdFrame frame;
+  frame.sequence_number = 0x1122;
+
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_RETIRE_CONNECTION_ID frame)
+    0x19,
+    // sequence number
+    kVarInt62TwoBytes + 0x11, 0x22
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, AckFrameWithInvalidLargestObserved) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x45,
+    // largest observed
+    0x00, 0x00,
+    // Zero delta time.
+    0x00, 0x00,
+    // first ack block length.
+    0x00, 0x00,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x45,
+    // largest observed
+    0x00, 0x00,
+    // Zero delta time.
+    0x00, 0x00,
+    // first ack block length.
+    0x00, 0x00,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_ACK frame)
+    0x02,
+    // Largest acked
+    kVarInt62OneByte + 0x00,
+    // Zero delta time.
+    kVarInt62OneByte + 0x00,
+    // Ack block count 0
+    kVarInt62OneByte + 0x00,
+    // First ack block length
+    kVarInt62OneByte + 0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_EQ(framer_.detailed_error(), "Largest acked is 0.");
+}
+
+TEST_P(QuicFramerTest, FirstAckBlockJustUnderFlow) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x45,
+    // largest observed
+    0x00, 0x02,
+    // Zero delta time.
+    0x00, 0x00,
+    // first ack block length.
+    0x00, 0x03,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x45,
+    // largest observed
+    0x00, 0x02,
+    // Zero delta time.
+    0x00, 0x00,
+    // first ack block length.
+    0x00, 0x03,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_ACK frame)
+    0x02,
+    // Largest acked
+    kVarInt62OneByte + 0x02,
+    // Zero delta time.
+    kVarInt62OneByte + 0x00,
+    // Ack block count 0
+    kVarInt62OneByte + 0x00,
+    // First ack block length
+    kVarInt62OneByte + 0x02,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_EQ(framer_.detailed_error(),
+            "Underflow with first ack block length 3 largest acked is 2.");
+}
+
+TEST_P(QuicFramerTest, ThirdAckBlockJustUnderflow) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x60,
+    // largest observed
+    0x0A,
+    // Zero delta time.
+    0x00, 0x00,
+    // Num of ack blocks
+    0x02,
+    // first ack block length.
+    0x02,
+    // gap to next block
+    0x01,
+    // ack block length
+    0x01,
+    // gap to next block
+    0x01,
+    // ack block length
+    0x06,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x60,
+    // largest observed
+    0x0A,
+    // Zero delta time.
+    0x00, 0x00,
+    // Num of ack blocks
+    0x02,
+    // first ack block length.
+    0x02,
+    // gap to next block
+    0x01,
+    // ack block length
+    0x01,
+    // gap to next block
+    0x01,
+    // ack block length
+    0x06,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_ACK frame)
+    0x02,
+    // Largest acked
+    kVarInt62OneByte + 0x0A,
+    // Zero delta time.
+    kVarInt62OneByte + 0x00,
+    // Ack block count 2
+    kVarInt62OneByte + 0x02,
+    // First ack block length
+    kVarInt62OneByte + 0x01,
+    // gap to next block length
+    kVarInt62OneByte + 0x00,
+    // ack block length
+    kVarInt62OneByte + 0x00,
+    // gap to next block length
+    kVarInt62OneByte + 0x00,
+    // ack block length
+    kVarInt62OneByte + 0x05,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(framer_.detailed_error(),
+              "Underflow with ack block length 6 latest ack block end is 5.");
+  } else {
+    EXPECT_EQ(framer_.detailed_error(),
+              "Underflow with ack block length 6, end of block is 6.");
+  }
+}
+
+TEST_P(QuicFramerTest, CoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  // clang-format on
+  const size_t first_packet_ietf_size = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
+  EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(2u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[1]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[1]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[1]->offset);
+  CheckStreamFrameData("HELLO_WORLD?", visitor_.stream_frames_[1].get());
+}
+
+TEST_P(QuicFramerTest, CoalescedPacketWithUdpPadding) {
+  if (!framer_.version().HasLongHeaderLengths()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // padding
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+      // padding
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  EXPECT_EQ(visitor_.coalesced_packets_.size(), 0u);
+}
+
+TEST_P(QuicFramerTest, CoalescedPacketWithDifferentVersion) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // garbage version
+      'G', 'A', 'B', 'G',
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // garbage version
+      'G', 'A', 'B', 'G',
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  // clang-format on
+  const size_t first_packet_ietf_size = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
+  EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  // Verify version mismatch gets reported.
+  EXPECT_EQ(1, visitor_.version_mismatch_);
+}
+
+TEST_P(QuicFramerTest, UndecryptablePacketWithoutDecrypter) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  if (!framer_.version().KnowsWhichDecrypterToUse()) {
+    // We create a bad client decrypter by using initial encryption with a
+    // bogus connection ID; it should fail to decrypt everything.
+    QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
+    CrypterPair bogus_crypters;
+    CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
+                                          framer_.version(),
+                                          bogus_connection_id, &bogus_crypters);
+    // This removes all other decrypters.
+    framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                         std::move(bogus_crypters.decrypter));
+  }
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (version included, 8-byte connection ID,
+    // 4-byte packet number)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet46[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x05,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x00,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x24,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_length = ABSL_ARRAYSIZE(packet46);
+  }
+  // First attempt decryption without the handshake crypter.
+  EXPECT_FALSE(
+      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+  ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
+  quiche::test::CompareCharArraysWithHexError(
+      "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
+      visitor_.undecryptable_packets_[0]->length(), AsChars(p), p_length);
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    EXPECT_EQ(ENCRYPTION_HANDSHAKE,
+              visitor_.undecryptable_decryption_levels_[0]);
+  }
+  EXPECT_FALSE(visitor_.undecryptable_has_decryption_keys_[0]);
+}
+
+TEST_P(QuicFramerTest, UndecryptablePacketWithDecrypter) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  // We create a bad client decrypter by using initial encryption with a
+  // bogus connection ID; it should fail to decrypt everything.
+  QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
+  CrypterPair bad_handshake_crypters;
+  CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
+                                        framer_.version(), bogus_connection_id,
+                                        &bad_handshake_crypters);
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(ENCRYPTION_HANDSHAKE,
+                             std::move(bad_handshake_crypters.decrypter));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_HANDSHAKE,
+                         std::move(bad_handshake_crypters.decrypter));
+  }
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (version included, 8-byte connection ID,
+    // 4-byte packet number)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet46[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x05,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x00,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x24,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_length = ABSL_ARRAYSIZE(packet46);
+  }
+
+  EXPECT_FALSE(
+      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+  ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
+  quiche::test::CompareCharArraysWithHexError(
+      "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
+      visitor_.undecryptable_packets_[0]->length(), AsChars(p), p_length);
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    EXPECT_EQ(ENCRYPTION_HANDSHAKE,
+              visitor_.undecryptable_decryption_levels_[0]);
+  }
+  EXPECT_EQ(framer_.version().KnowsWhichDecrypterToUse(),
+            visitor_.undecryptable_has_decryption_keys_[0]);
+}
+
+TEST_P(QuicFramerTest, UndecryptableCoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // We create a bad client decrypter by using initial encryption with a
+  // bogus connection ID; it should fail to decrypt everything.
+  QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
+  CrypterPair bad_handshake_crypters;
+  CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
+                                        framer_.version(), bogus_connection_id,
+                                        &bad_handshake_crypters);
+  framer_.InstallDecrypter(ENCRYPTION_HANDSHAKE,
+                           std::move(bad_handshake_crypters.decrypter));
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type HANDSHAKE and
+      // 4-byte packet number)
+      0xE3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type HANDSHAKE and
+      // 4-byte packet number)
+      0xE3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  // clang-format on
+  const size_t length_of_first_coalesced_packet = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+
+  ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
+  // Make sure we only receive the first undecryptable packet and not the
+  // full packet including the second coalesced packet.
+  quiche::test::CompareCharArraysWithHexError(
+      "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
+      visitor_.undecryptable_packets_[0]->length(), AsChars(p),
+      length_of_first_coalesced_packet);
+  EXPECT_EQ(ENCRYPTION_HANDSHAKE, visitor_.undecryptable_decryption_levels_[0]);
+  EXPECT_TRUE(visitor_.undecryptable_has_decryption_keys_[0]);
+
+  // Make sure the second coalesced packet is parsed correctly.
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
+  EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
+
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("HELLO_WORLD?", visitor_.stream_frames_[0].get());
+}
+
+TEST_P(QuicFramerTest, MismatchedCoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  // clang-format on
+  const size_t length_of_first_coalesced_packet = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 0u);
+}
+
+TEST_P(QuicFramerTest, InvalidCoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version would be here but we cut off the invalid coalesced header.
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version would be here but we cut off the invalid coalesced header.
+  };
+  // clang-format on
+  const size_t length_of_first_coalesced_packet = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 0u);
+}
+
+// Some IETF implementations send an initial followed by zeroes instead of
+// padding inside the initial. We need to make sure that we still process
+// the initial correctly and ignore the zeroes.
+TEST_P(QuicFramerTest, CoalescedPacketWithZeroesRoundTrip) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version()) ||
+      !framer_.version().UsesInitialObfuscators()) {
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  QuicConnectionId connection_id = FramerTestConnectionId();
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  CrypterPair client_crypters;
+  CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
+                                        framer_.version(), connection_id,
+                                        &client_crypters);
+  framer_.SetEncrypter(ENCRYPTION_INITIAL,
+                       std::move(client_crypters.encrypter));
+
+  QuicPacketHeader header;
+  header.destination_connection_id = connection_id;
+  header.version_flag = true;
+  header.packet_number = kPacketNumber;
+  header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
+  header.long_packet_type = INITIAL;
+  header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+  QuicFrames frames = {QuicFrame(QuicPingFrame()),
+                       QuicFrame(QuicPaddingFrame(3))};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_NE(nullptr, data);
+
+  // Add zeroes after the valid initial packet.
+  unsigned char packet[kMaxOutgoingPacketSize] = {};
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *data,
+                             AsChars(packet), ABSL_ARRAYSIZE(packet));
+  ASSERT_NE(0u, encrypted_length);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  CrypterPair server_crypters;
+  CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER,
+                                        framer_.version(), connection_id,
+                                        &server_crypters);
+  framer_.InstallDecrypter(ENCRYPTION_INITIAL,
+                           std::move(server_crypters.decrypter));
+
+  // Make sure the first long header initial packet parses correctly.
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+
+  // Make sure we discard the subsequent zeroes.
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_TRUE(visitor_.coalesced_packets_.empty());
+}
+
+TEST_P(QuicFramerTest, ClientReceivesWrongVersion) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  // clang-format off
+  unsigned char packet[] = {
+       // public flags (long header with packet type INITIAL)
+       0xC3,
+       // version that is different from the framer's version
+       'Q', '0', '4', '3',
+       // connection ID lengths
+       0x05,
+       // source connection ID
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+       // packet number
+       0x01,
+       // padding frame
+       0x00,
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_PACKET_WRONG_VERSION));
+  EXPECT_EQ("Client received unexpected version.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWithVariableLengthConnectionId) {
+  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  uint8_t connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
+                                    0x54, 0x32, 0x10, 0x42};
+  QuicConnectionId connection_id(reinterpret_cast<char*>(connection_id_bytes),
+                                 sizeof(connection_id_bytes));
+  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
+  QuicFramerPeer::SetExpectedServerConnectionIDLength(&framer_,
+                                                      connection_id.length());
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read first byte.",
+       {0x40}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x78}},
+  };
+
+  PacketFragments packet_with_padding = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read first byte.",
+       {0x40}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
+      // packet number
+      {"",
+       {0x78}},
+      // padding
+      {"", {0x00, 0x00, 0x00}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection() ? packet_with_padding : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsQuicNoError());
+  } else {
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  }
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(connection_id, visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, MultiplePacketNumberSpaces) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  framer_.EnableMultiplePacketNumberSpacesSupport();
+
+  // clang-format off
+  unsigned char long_header_packet[] = {
+       // public flags (long header with packet type ZERO_RTT_PROTECTED and
+       // 4-byte packet number)
+       0xD3,
+       // version
+       QUIC_VERSION_BYTES,
+       // destination connection ID length
+       0x50,
+       // destination connection ID
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+       // packet number
+       0x12, 0x34, 0x56, 0x78,
+       // padding frame
+       0x00,
+   };
+  unsigned char long_header_packet_ietf[] = {
+       // public flags (long header with packet type ZERO_RTT_PROTECTED and
+       // 4-byte packet number)
+       0xD3,
+       // version
+       QUIC_VERSION_BYTES,
+       // destination connection ID length
+       0x08,
+       // destination connection ID
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+       // source connection ID length
+       0x00,
+       // long header packet length
+       0x05,
+       // packet number
+       0x12, 0x34, 0x56, 0x78,
+       // padding frame
+       0x00,
+  };
+  // clang-format on
+
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+                             std::make_unique<TestDecrypter>());
+    framer_.RemoveDecrypter(ENCRYPTION_INITIAL);
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                         std::make_unique<TestDecrypter>());
+  }
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    EXPECT_TRUE(framer_.ProcessPacket(
+        QuicEncryptedPacket(AsChars(long_header_packet),
+                            ABSL_ARRAYSIZE(long_header_packet), false)));
+  } else {
+    ReviseFirstByteByVersion(long_header_packet_ietf);
+    EXPECT_TRUE(framer_.ProcessPacket(
+        QuicEncryptedPacket(AsChars(long_header_packet_ietf),
+                            ABSL_ARRAYSIZE(long_header_packet_ietf), false)));
+  }
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_FALSE(
+      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, INITIAL_DATA)
+          .IsInitialized());
+  EXPECT_FALSE(
+      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, HANDSHAKE_DATA)
+          .IsInitialized());
+  EXPECT_EQ(kPacketNumber, QuicFramerPeer::GetLargestDecryptedPacketNumber(
+                               &framer_, APPLICATION_DATA));
+
+  // clang-format off
+  unsigned char short_header_packet[] = {
+     // type (short header, 1 byte packet number)
+     0x40,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x79,
+     // padding frame
+     0x00, 0x00, 0x00,
+  };
+  // clang-format on
+
+  QuicEncryptedPacket short_header_encrypted(
+      AsChars(short_header_packet), ABSL_ARRAYSIZE(short_header_packet), false);
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                             std::make_unique<TestDecrypter>());
+    framer_.RemoveDecrypter(ENCRYPTION_ZERO_RTT);
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                         std::make_unique<TestDecrypter>());
+  }
+  EXPECT_TRUE(framer_.ProcessPacket(short_header_encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_FALSE(
+      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, INITIAL_DATA)
+          .IsInitialized());
+  EXPECT_FALSE(
+      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, HANDSHAKE_DATA)
+          .IsInitialized());
+  EXPECT_EQ(kPacketNumber + 1, QuicFramerPeer::GetLargestDecryptedPacketNumber(
+                                   &framer_, APPLICATION_DATA));
+}
+
+TEST_P(QuicFramerTest, IetfRetryPacketRejected) {
+  if (!framer_.version().KnowsWhichDecrypterToUse() ||
+      framer_.version().SupportsRetry()) {
+    return;
+  }
+
+  // clang-format off
+  PacketFragments packet46 = {
+    // public flags (IETF Retry packet, 0-length original destination CID)
+    {"Unable to read first byte.",
+     {0xf0}},
+    // version tag
+    {"Unable to read protocol version.",
+     {QUIC_VERSION_BYTES}},
+    // connection_id length
+    {"RETRY not supported in this version.",
+     {0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet46));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  CheckFramingBoundaries(packet46, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, RetryPacketRejectedWithMultiplePacketNumberSpaces) {
+  if (!framer_.version().HasIetfInvariantHeader() ||
+      framer_.version().SupportsRetry()) {
+    return;
+  }
+  framer_.EnableMultiplePacketNumberSpacesSupport();
+
+  // clang-format off
+  PacketFragments packet = {
+    // public flags (IETF Retry packet, 0-length original destination CID)
+    {"Unable to read first byte.",
+     {0xf0}},
+    // version tag
+    {"Unable to read protocol version.",
+     {QUIC_VERSION_BYTES}},
+    // connection_id length
+    {"RETRY not supported in this version.",
+     {0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, ProcessPublicHeaderNoVersionInferredType) {
+  // The framer needs to have Perspective::IS_SERVER and configured to infer the
+  // packet header type from the packet (not the version). The framer's version
+  // needs to be one that uses the IETF packet format.
+  if (!framer_.version().KnowsWhichDecrypterToUse()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+
+  // Prepare a packet that uses the Google QUIC packet header but has no version
+  // field.
+
+  // clang-format off
+  PacketFragments packet = {
+    // public flags (1-byte packet number, 8-byte connection_id, no version)
+    {"Unable to read public flags.",
+     {0x08}},
+    // connection_id
+    {"Unable to read ConnectionId.",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"Unable to read packet number.",
+     {0x01}},
+    // padding
+    {"Invalid public header type for expected version.",
+     {0x00}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments = packet;
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  EXPECT_EQ("Invalid public header type for expected version.",
+            framer_.detailed_error());
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, ProcessMismatchedHeaderVersion) {
+  // The framer needs to have Perspective::IS_SERVER and configured to infer the
+  // packet header type from the packet (not the version). The framer's version
+  // needs to be one that uses the IETF packet format.
+  if (!framer_.version().KnowsWhichDecrypterToUse()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+
+  // clang-format off
+  PacketFragments packet = {
+    // public flags (Google QUIC header with version present)
+    {"Unable to read public flags.",
+     {0x09}},
+    // connection_id
+    {"Unable to read ConnectionId.",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // version tag
+    {"Unable to read protocol version.",
+     {QUIC_VERSION_BYTES}},
+    // packet number
+    {"Unable to read packet number.",
+     {0x01}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  framer_.ProcessPacket(*encrypted);
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  EXPECT_EQ("Invalid public header type for expected version.",
+            framer_.detailed_error());
+  CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, WriteClientVersionNegotiationProbePacket) {
+  // clang-format off
+  static const uint8_t expected_packet[1200] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version, part of the IETF space reserved for negotiation.
+    0xca, 0xba, 0xda, 0xda,
+    // Destination connection ID length 8.
+    0x08,
+    // 8-byte destination connection ID.
+    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
+    // Source connection ID length 0.
+    0x00,
+    // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
+    // not parse with any known version.
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    // zeroes to pad to 16 byte boundary.
+    0x00,
+    // A polite greeting in case a human sees this in tcpdump.
+    0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
+    0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+    0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
+    0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
+    0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
+    0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
+    0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
+    0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
+    0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
+    0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
+    0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
+    0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
+    0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
+    0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
+    0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
+    0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
+    0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
+    0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
+    0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
+  };
+  // clang-format on
+  char packet[1200];
+  char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                            0x6c, 0x7a, 0x20, 0x21};
+  EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), destination_connection_id_bytes,
+      sizeof(destination_connection_id_bytes)));
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", packet, sizeof(packet),
+      reinterpret_cast<const char*>(expected_packet), sizeof(expected_packet));
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet), false);
+  if (!framer_.version().HasLengthPrefixedConnectionIds()) {
+    // We can only parse the connection ID with a parser expecting
+    // length-prefixed connection IDs.
+    EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+    return;
+  }
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  ASSERT_TRUE(visitor_.header_.get());
+  QuicConnectionId probe_payload_connection_id(
+      reinterpret_cast<const char*>(destination_connection_id_bytes),
+      sizeof(destination_connection_id_bytes));
+  EXPECT_EQ(probe_payload_connection_id,
+            visitor_.header_.get()->destination_connection_id);
+}
+
+TEST_P(QuicFramerTest, DispatcherParseOldClientVersionNegotiationProbePacket) {
+  // clang-format off
+  static const uint8_t packet[1200] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version, part of the IETF space reserved for negotiation.
+    0xca, 0xba, 0xda, 0xba,
+    // Destination connection ID length 8, source connection ID length 0.
+    0x50,
+    // 8-byte destination connection ID.
+    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
+    // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
+    // not parse with any known version.
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    // 2 bytes of zeroes to pad to 16 byte boundary.
+    0x00, 0x00,
+    // A polite greeting in case a human sees this in tcpdump.
+    0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
+    0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+    0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
+    0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
+    0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
+    0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
+    0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
+    0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
+    0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
+    0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
+    0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
+    0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
+    0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
+    0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
+    0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
+    0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
+    0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
+    0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
+    0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
+  };
+  // clang-format on
+  char expected_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                                     0x6c, 0x7a, 0x20, 0x21};
+  QuicConnectionId expected_destination_connection_id(
+      reinterpret_cast<const char*>(expected_destination_connection_id_bytes),
+      sizeof(expected_destination_connection_id_bytes));
+
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet));
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_present = false, has_length_prefix = true;
+  QuicVersionLabel version_label = 33;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  QuicConnectionId destination_connection_id = TestConnectionId(1);
+  QuicConnectionId source_connection_id = TestConnectionId(2);
+  absl::optional<absl::string_view> retry_token;
+  std::string detailed_error = "foobar";
+  QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
+      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_THAT(header_parse_result, IsQuicNoError());
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+  EXPECT_TRUE(version_present);
+  EXPECT_FALSE(has_length_prefix);
+  EXPECT_EQ(0xcabadaba, version_label);
+  EXPECT_EQ(expected_destination_connection_id, destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_EQ("", detailed_error);
+}
+
+TEST_P(QuicFramerTest, DispatcherParseClientVersionNegotiationProbePacket) {
+  // clang-format off
+  static const uint8_t packet[1200] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version, part of the IETF space reserved for negotiation.
+    0xca, 0xba, 0xda, 0xba,
+    // Destination connection ID length 8.
+    0x08,
+    // 8-byte destination connection ID.
+    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
+    // Source connection ID length 0.
+    0x00,
+    // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
+    // not parse with any known version.
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    // 1 byte of zeroes to pad to 16 byte boundary.
+    0x00,
+    // A polite greeting in case a human sees this in tcpdump.
+    0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
+    0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+    0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
+    0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
+    0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
+    0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
+    0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
+    0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
+    0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
+    0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
+    0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
+    0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
+    0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
+    0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
+    0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
+    0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
+    0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
+    0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
+    0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
+  };
+  // clang-format on
+  char expected_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                                     0x6c, 0x7a, 0x20, 0x21};
+  QuicConnectionId expected_destination_connection_id(
+      reinterpret_cast<const char*>(expected_destination_connection_id_bytes),
+      sizeof(expected_destination_connection_id_bytes));
+
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet));
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_present = false, has_length_prefix = false;
+  QuicVersionLabel version_label = 33;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  QuicConnectionId destination_connection_id = TestConnectionId(1);
+  QuicConnectionId source_connection_id = TestConnectionId(2);
+  absl::optional<absl::string_view> retry_token;
+  std::string detailed_error = "foobar";
+  QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
+      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_THAT(header_parse_result, IsQuicNoError());
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+  EXPECT_TRUE(version_present);
+  EXPECT_TRUE(has_length_prefix);
+  EXPECT_EQ(0xcabadaba, version_label);
+  EXPECT_EQ(expected_destination_connection_id, destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+  EXPECT_EQ("", detailed_error);
+}
+
+TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponse) {
+  // clang-format off
+  const uint8_t packet[] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version of 0, indicating version negotiation.
+    0x00, 0x00, 0x00, 0x00,
+    // Destination connection ID length 0, source connection ID length 8.
+    0x00, 0x08,
+    // 8-byte source connection ID.
+    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
+    // A few supported versions.
+    0xaa, 0xaa, 0xaa, 0xaa,
+    QUIC_VERSION_BYTES,
+  };
+  // clang-format on
+  char probe_payload_bytes[] = {0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21};
+  char parsed_probe_payload_bytes[255] = {};
+  uint8_t parsed_probe_payload_length = sizeof(parsed_probe_payload_bytes);
+  std::string parse_detailed_error = "";
+  EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
+      reinterpret_cast<const char*>(packet), sizeof(packet),
+      reinterpret_cast<char*>(parsed_probe_payload_bytes),
+      &parsed_probe_payload_length, &parse_detailed_error));
+  EXPECT_EQ("", parse_detailed_error);
+  quiche::test::CompareCharArraysWithHexError(
+      "parsed probe", parsed_probe_payload_bytes, parsed_probe_payload_length,
+      probe_payload_bytes, sizeof(probe_payload_bytes));
+}
+
+TEST_P(QuicFramerTest, ParseClientVersionNegotiationProbePacket) {
+  char packet[1200];
+  char input_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                                  0x6c, 0x7a, 0x20, 0x21};
+  ASSERT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), input_destination_connection_id_bytes,
+      sizeof(input_destination_connection_id_bytes)));
+  char parsed_destination_connection_id_bytes[255] = {0};
+  uint8_t parsed_destination_connection_id_length =
+      sizeof(parsed_destination_connection_id_bytes);
+  ASSERT_TRUE(ParseClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), parsed_destination_connection_id_bytes,
+      &parsed_destination_connection_id_length));
+  quiche::test::CompareCharArraysWithHexError(
+      "parsed destination connection ID",
+      parsed_destination_connection_id_bytes,
+      parsed_destination_connection_id_length,
+      input_destination_connection_id_bytes,
+      sizeof(input_destination_connection_id_bytes));
+}
+
+TEST_P(QuicFramerTest, WriteServerVersionNegotiationProbeResponse) {
+  char packet[1200];
+  size_t packet_length = sizeof(packet);
+  char input_source_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                             0x6c, 0x7a, 0x20, 0x21};
+  ASSERT_TRUE(WriteServerVersionNegotiationProbeResponse(
+      packet, &packet_length, input_source_connection_id_bytes,
+      sizeof(input_source_connection_id_bytes)));
+  char parsed_source_connection_id_bytes[255] = {0};
+  uint8_t parsed_source_connection_id_length =
+      sizeof(parsed_source_connection_id_bytes);
+  std::string detailed_error;
+  ASSERT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
+      packet, packet_length, parsed_source_connection_id_bytes,
+      &parsed_source_connection_id_length, &detailed_error))
+      << detailed_error;
+  quiche::test::CompareCharArraysWithHexError(
+      "parsed destination connection ID", parsed_source_connection_id_bytes,
+      parsed_source_connection_id_length, input_source_connection_id_bytes,
+      sizeof(input_source_connection_id_bytes));
+}
+
+TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToClient) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_HANDSHAKE);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x50,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x00,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  }
+  const bool parse_success =
+      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
+  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
+    EXPECT_FALSE(parse_success);
+    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+    EXPECT_EQ("Invalid ConnectionId length.", framer_.detailed_error());
+    return;
+  }
+  EXPECT_TRUE(parse_success);
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_EQ("", framer_.detailed_error());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_.get()->destination_connection_id);
+}
+
+TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToServer) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_HANDSHAKE);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x05,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x00, 0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  }
+  const bool parse_success =
+      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
+  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
+    EXPECT_FALSE(parse_success);
+    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+    EXPECT_EQ("Invalid ConnectionId length.", framer_.detailed_error());
+    return;
+  }
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    EXPECT_FALSE(parse_success);
+    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+    EXPECT_EQ("Client connection ID not supported in this version.",
+              framer_.detailed_error());
+    return;
+  }
+  EXPECT_TRUE(parse_success);
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_EQ("", framer_.detailed_error());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_.get()->source_connection_id);
+}
+
+TEST_P(QuicFramerTest, ProcessAndValidateIetfConnectionIdLengthClient) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  char connection_id_lengths = 0x05;
+  QuicDataReader reader(&connection_id_lengths, 1);
+
+  bool should_update_expected_server_connection_id_length = false;
+  uint8_t expected_server_connection_id_length = 8;
+  uint8_t destination_connection_id_length = 0;
+  uint8_t source_connection_id_length = 8;
+  std::string detailed_error = "";
+
+  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
+      &reader, framer_.version(), Perspective::IS_CLIENT,
+      should_update_expected_server_connection_id_length,
+      &expected_server_connection_id_length, &destination_connection_id_length,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ(8, expected_server_connection_id_length);
+  EXPECT_EQ(0, destination_connection_id_length);
+  EXPECT_EQ(8, source_connection_id_length);
+  EXPECT_EQ("", detailed_error);
+
+  QuicDataReader reader2(&connection_id_lengths, 1);
+  should_update_expected_server_connection_id_length = true;
+  expected_server_connection_id_length = 33;
+  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
+      &reader2, framer_.version(), Perspective::IS_CLIENT,
+      should_update_expected_server_connection_id_length,
+      &expected_server_connection_id_length, &destination_connection_id_length,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ(8, expected_server_connection_id_length);
+  EXPECT_EQ(0, destination_connection_id_length);
+  EXPECT_EQ(8, source_connection_id_length);
+  EXPECT_EQ("", detailed_error);
+}
+
+TEST_P(QuicFramerTest, ProcessAndValidateIetfConnectionIdLengthServer) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  char connection_id_lengths = 0x50;
+  QuicDataReader reader(&connection_id_lengths, 1);
+
+  bool should_update_expected_server_connection_id_length = false;
+  uint8_t expected_server_connection_id_length = 8;
+  uint8_t destination_connection_id_length = 8;
+  uint8_t source_connection_id_length = 0;
+  std::string detailed_error = "";
+
+  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
+      &reader, framer_.version(), Perspective::IS_SERVER,
+      should_update_expected_server_connection_id_length,
+      &expected_server_connection_id_length, &destination_connection_id_length,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ(8, expected_server_connection_id_length);
+  EXPECT_EQ(8, destination_connection_id_length);
+  EXPECT_EQ(0, source_connection_id_length);
+  EXPECT_EQ("", detailed_error);
+
+  QuicDataReader reader2(&connection_id_lengths, 1);
+  should_update_expected_server_connection_id_length = true;
+  expected_server_connection_id_length = 33;
+  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
+      &reader2, framer_.version(), Perspective::IS_SERVER,
+      should_update_expected_server_connection_id_length,
+      &expected_server_connection_id_length, &destination_connection_id_length,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ(8, expected_server_connection_id_length);
+  EXPECT_EQ(8, destination_connection_id_length);
+  EXPECT_EQ(0, source_connection_id_length);
+  EXPECT_EQ("", detailed_error);
+}
+
+TEST_P(QuicFramerTest, TestExtendedErrorCodeParser) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Extended error codes only in IETF QUIC
+    return;
+  }
+  QuicConnectionCloseFrame frame;
+
+  frame.error_details = "this has no error code info in it";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("this has no error code info in it", frame.error_details);
+
+  frame.error_details = "1234this does not have the colon in it";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("1234this does not have the colon in it", frame.error_details);
+
+  frame.error_details = "1a234:this has a colon, but a malformed error number";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("1a234:this has a colon, but a malformed error number",
+            frame.error_details);
+
+  frame.error_details = "1234:this is good";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_EQ(1234u, frame.quic_error_code);
+  EXPECT_EQ("this is good", frame.error_details);
+
+  frame.error_details =
+      "1234 :this is not good, space between last digit and colon";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("1234 :this is not good, space between last digit and colon",
+            frame.error_details);
+
+  frame.error_details = "123456789";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(
+      frame.quic_error_code,
+      IsError(QUIC_IETF_GQUIC_ERROR_MISSING));  // Not good, all numbers, no :
+  EXPECT_EQ("123456789", frame.error_details);
+
+  frame.error_details = "1234:";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_EQ(1234u,
+            frame.quic_error_code);  // corner case.
+  EXPECT_EQ("", frame.error_details);
+
+  frame.error_details = "1234:5678";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_EQ(1234u,
+            frame.quic_error_code);  // another corner case.
+  EXPECT_EQ("5678", frame.error_details);
+
+  frame.error_details = "12345 6789:";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code,
+              IsError(QUIC_IETF_GQUIC_ERROR_MISSING));  // Not good
+  EXPECT_EQ("12345 6789:", frame.error_details);
+
+  frame.error_details = ":no numbers, is not good";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ(":no numbers, is not good", frame.error_details);
+
+  frame.error_details = "qwer:also no numbers, is not good";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("qwer:also no numbers, is not good", frame.error_details);
+
+  frame.error_details = " 1234:this is not good, space before first digit";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ(" 1234:this is not good, space before first digit",
+            frame.error_details);
+
+  frame.error_details = "1234:";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_EQ(1234u,
+            frame.quic_error_code);  // this is good
+  EXPECT_EQ("", frame.error_details);
+}
+
+// Regression test for crbug/1029636.
+TEST_P(QuicFramerTest, OverlyLargeAckDelay) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_ACK frame)
+    0x02,
+    // largest acked
+    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
+    // ack delay time.
+    kVarInt62EightBytes + 0x31, 0x00, 0x00, 0x00, 0xF3, 0xA0, 0x81, 0xE0,
+    // Nr. of additional ack blocks
+    kVarInt62OneByte + 0x00,
+    // first ack block length.
+    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
+  };
+  // clang-format on
+
+  framer_.ProcessPacket(QuicEncryptedPacket(
+      AsChars(packet_ietf), ABSL_ARRAYSIZE(packet_ietf), false));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  // Verify ack_delay_time is set correctly.
+  EXPECT_EQ(QuicTime::Delta::Infinite(),
+            visitor_.ack_frames_[0]->ack_delay_time);
+}
+
+TEST_P(QuicFramerTest, KeyUpdate) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed valid packet with phase=0, key=1: no key update.
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed valid packet with phase=1, key=2: key update should have
+  // occurred.
+  ASSERT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[0]);
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed another valid packet with phase=1, key=2: no key update.
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process another key update.
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 2, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_EQ(2u, visitor_.key_update_count());
+  EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[1]);
+  EXPECT_EQ(2, visitor_.derive_next_key_count_);
+  EXPECT_EQ(3, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterUpdate) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 0.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+2 with phase 1.
+  header.packet_number = kPacketNumber + 2;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+1 with phase 0. (Receiving packet from previous phase
+  // after packet from new phase was received.)
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterDiscardPreviousOneRttKeys) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 0.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+2 with phase 1.
+  header.packet_number = kPacketNumber + 2;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Discard keys for previous key phase.
+  framer_.DiscardPreviousOneRttKeys();
+
+  // Process packet N+1 with phase 0. (Receiving packet from previous phase
+  // after packet from new phase was received.)
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should not decrypt and key update count should not change.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdatePacketsOutOfOrder) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 0.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+2 with phase 1.
+  header.packet_number = kPacketNumber + 2;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+1 with phase 1. (Receiving packet from new phase out of
+  // order.)
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateWrongKey) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed valid packet with phase=0, key=1: no key update.
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount());
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 2, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet with phase=1 but key=3, should not process and should not cause key
+  // update, but next decrypter key should have been created to attempt to
+  // decode it.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(1u, framer_.PotentialPeerKeyUpdateAttemptCount());
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet with phase=1 but key=1, should not process and should not cause key
+  // update.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount());
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet with phase=0 but key=2, should not process and should not cause key
+  // update.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount());
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet with phase=0 and key=0, should process and reset
+  // potential_peer_key_update_attempt_count_.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount());
+}
+
+TEST_P(QuicFramerTest, KeyUpdateReceivedWhenNotEnabled) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 1, true));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Received a packet with key phase updated even though framer hasn't had key
+  // update enabled (SetNextOneRttCrypters never called). Should fail to
+  // process.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateLocallyInitiated) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests));
+  // Key update count should be updated, but haven't received packet from peer
+  // with new key phase.
+  ASSERT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(KeyUpdateReason::kLocalForTests, visitor_.key_update_reasons_[0]);
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 1.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 1, true));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change and
+  // OnDecryptedFirstPacketInKeyPhase should have been called.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N-1 with phase 0. (Receiving packet from previous phase
+  // after packet from new phase was received.)
+  header.packet_number = kPacketNumber - 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+1 with phase 0 and key 1. This should not decrypt even
+  // though it's using the previous key, since the packet number is higher than
+  // a packet number received using the current key.
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should not decrypt and key update count should not change.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(2, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateLocallyInitiatedReceivedOldPacket) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests));
+  // Key update count should be updated, but haven't received packet
+  // from peer with new key phase.
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 0. (Receiving packet from previous phase
+  // after locally initiated key update, but before any packet from new phase
+  // was received.)
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted =
+      EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change and
+  // OnDecryptedFirstPacketInKeyPhase should not have been called since the
+  // packet was from the previous key phase.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+1 with phase 1.
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change, but
+  // OnDecryptedFirstPacketInKeyPhase should have been called.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+2 with phase 0 and key 1. This should not decrypt even
+  // though it's using the previous key, since the packet number is higher than
+  // a packet number received using the current key.
+  header.packet_number = kPacketNumber + 2;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should not decrypt and key update count should not change.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(2, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateOnFirstReceivedPacket) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = QuicPacketNumber(123);
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, /*tag=*/1, /*phase=*/true));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed valid packet with phase=1, key=1: do key update.
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, ErrorWhenUnexpectedFrameTypeEncountered) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version()) ||
+      !QuicVersionHasLongHeaderLengths(framer_.transport_version()) ||
+      !framer_.version().HasLongHeaderLengths()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type ZERO_RTT_PROTECTED and
+    // 4-byte packet number)
+    0xD3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // unexpected ietf ack frame type in 0-RTT packet
+    0x02,
+  };
+  // clang-format on
+
+  ReviseFirstByteByVersion(packet);
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ(
+      "IETF frame type IETF_ACK is unexpected at encryption level "
+      "ENCRYPTION_ZERO_RTT",
+      framer_.detailed_error());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_idle_network_detector.cc b/quiche/quic/core/quic_idle_network_detector.cc
new file mode 100644
index 0000000..77d6dba
--- /dev/null
+++ b/quiche/quic/core/quic_idle_network_detector.cc
@@ -0,0 +1,145 @@
+// Copyright (c) 2020 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 "quiche/quic/core/quic_idle_network_detector.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+namespace {
+
+class AlarmDelegate : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit AlarmDelegate(QuicIdleNetworkDetector* detector,
+                         QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context), detector_(detector) {}
+  AlarmDelegate(const AlarmDelegate&) = delete;
+  AlarmDelegate& operator=(const AlarmDelegate&) = delete;
+
+  void OnAlarm() override { detector_->OnAlarm(); }
+
+ private:
+  QuicIdleNetworkDetector* detector_;
+};
+
+}  // namespace
+
+QuicIdleNetworkDetector::QuicIdleNetworkDetector(
+    Delegate* delegate, QuicTime now, QuicConnectionArena* arena,
+    QuicAlarmFactory* alarm_factory, QuicConnectionContext* context)
+    : delegate_(delegate),
+      start_time_(now),
+      handshake_timeout_(QuicTime::Delta::Infinite()),
+      time_of_last_received_packet_(now),
+      time_of_first_packet_sent_after_receiving_(QuicTime::Zero()),
+      idle_network_timeout_(QuicTime::Delta::Infinite()),
+      alarm_(alarm_factory->CreateAlarm(
+          arena->New<AlarmDelegate>(this, context), arena)) {}
+
+void QuicIdleNetworkDetector::OnAlarm() {
+  if (handshake_timeout_.IsInfinite()) {
+    delegate_->OnIdleNetworkDetected();
+    return;
+  }
+  if (idle_network_timeout_.IsInfinite()) {
+    delegate_->OnHandshakeTimeout();
+    return;
+  }
+  if (last_network_activity_time() + idle_network_timeout_ >
+      start_time_ + handshake_timeout_) {
+    delegate_->OnHandshakeTimeout();
+    return;
+  }
+  delegate_->OnIdleNetworkDetected();
+}
+
+void QuicIdleNetworkDetector::SetTimeouts(
+    QuicTime::Delta handshake_timeout,
+    QuicTime::Delta idle_network_timeout) {
+  handshake_timeout_ = handshake_timeout;
+  idle_network_timeout_ = idle_network_timeout;
+
+  SetAlarm();
+}
+
+void QuicIdleNetworkDetector::StopDetection() {
+  alarm_->PermanentCancel();
+  handshake_timeout_ = QuicTime::Delta::Infinite();
+  idle_network_timeout_ = QuicTime::Delta::Infinite();
+  stopped_ = true;
+}
+
+void QuicIdleNetworkDetector::OnPacketSent(QuicTime now,
+                                           QuicTime::Delta pto_delay) {
+  if (time_of_first_packet_sent_after_receiving_ >
+      time_of_last_received_packet_) {
+    return;
+  }
+  time_of_first_packet_sent_after_receiving_ =
+      std::max(time_of_first_packet_sent_after_receiving_, now);
+  if (shorter_idle_timeout_on_sent_packet_) {
+    MaybeSetAlarmOnSentPacket(pto_delay);
+    return;
+  }
+
+  SetAlarm();
+}
+
+void QuicIdleNetworkDetector::OnPacketReceived(QuicTime now) {
+  time_of_last_received_packet_ = std::max(time_of_last_received_packet_, now);
+
+  SetAlarm();
+}
+
+void QuicIdleNetworkDetector::SetAlarm() {
+  if (stopped_) {
+    // TODO(wub): If this QUIC_BUG fires, it indicates a problem in the
+    // QuicConnection, which somehow called this function while disconnected.
+    // That problem needs to be fixed.
+    QUIC_BUG(quic_idle_detector_set_alarm_after_stopped)
+        << "SetAlarm called after stopped";
+    return;
+  }
+  // Set alarm to the nearer deadline.
+  QuicTime new_deadline = QuicTime::Zero();
+  if (!handshake_timeout_.IsInfinite()) {
+    new_deadline = start_time_ + handshake_timeout_;
+  }
+  if (!idle_network_timeout_.IsInfinite()) {
+    const QuicTime idle_network_deadline = GetIdleNetworkDeadline();
+    if (new_deadline.IsInitialized()) {
+      new_deadline = std::min(new_deadline, idle_network_deadline);
+    } else {
+      new_deadline = idle_network_deadline;
+    }
+  }
+  alarm_->Update(new_deadline, kAlarmGranularity);
+}
+
+void QuicIdleNetworkDetector::MaybeSetAlarmOnSentPacket(
+    QuicTime::Delta pto_delay) {
+  QUICHE_DCHECK(shorter_idle_timeout_on_sent_packet_);
+  if (!handshake_timeout_.IsInfinite() || !alarm_->IsSet()) {
+    SetAlarm();
+    return;
+  }
+  // Make sure connection will be alive for another PTO.
+  const QuicTime deadline = alarm_->deadline();
+  const QuicTime min_deadline = last_network_activity_time() + pto_delay;
+  if (deadline > min_deadline) {
+    return;
+  }
+  alarm_->Update(min_deadline, kAlarmGranularity);
+}
+
+QuicTime QuicIdleNetworkDetector::GetIdleNetworkDeadline() const {
+  if (idle_network_timeout_.IsInfinite()) {
+    return QuicTime::Zero();
+  }
+  return last_network_activity_time() + idle_network_timeout_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_idle_network_detector.h b/quiche/quic/core/quic_idle_network_detector.h
new file mode 100644
index 0000000..0b5a20e
--- /dev/null
+++ b/quiche/quic/core/quic_idle_network_detector.h
@@ -0,0 +1,118 @@
+// Copyright (c) 2020 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_IDLE_NETWORK_DETECTOR_H_
+#define QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace test {
+class QuicConnectionPeer;
+class QuicIdleNetworkDetectorTestPeer;
+}  // namespace test
+
+// QuicIdleNetworkDetector detects handshake timeout and idle network timeout.
+// Handshake timeout detection is disabled after handshake completes. Idle
+// network deadline is extended by network activity (e.g., sending or receiving
+// packets).
+class QUIC_EXPORT_PRIVATE QuicIdleNetworkDetector {
+ public:
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // Called when handshake times out.
+    virtual void OnHandshakeTimeout() = 0;
+
+    // Called when idle network has been detected.
+    virtual void OnIdleNetworkDetected() = 0;
+  };
+
+  QuicIdleNetworkDetector(Delegate* delegate, QuicTime now,
+                          QuicConnectionArena* arena,
+                          QuicAlarmFactory* alarm_factory,
+                          QuicConnectionContext* context);
+
+  void OnAlarm();
+
+  // Called to set handshake_timeout_ and idle_network_timeout_.
+  void SetTimeouts(QuicTime::Delta handshake_timeout,
+                   QuicTime::Delta idle_network_timeout);
+
+  // Stop the detection once and for all.
+  void StopDetection();
+
+  // Called when a packet gets sent.
+  void OnPacketSent(QuicTime now, QuicTime::Delta pto_delay);
+
+  // Called when a packet gets received.
+  void OnPacketReceived(QuicTime now);
+
+  void enable_shorter_idle_timeout_on_sent_packet() {
+    shorter_idle_timeout_on_sent_packet_ = true;
+  }
+
+  QuicTime::Delta handshake_timeout() const { return handshake_timeout_; }
+
+  QuicTime time_of_last_received_packet() const {
+    return time_of_last_received_packet_;
+  }
+
+  QuicTime last_network_activity_time() const {
+    return std::max(time_of_last_received_packet_,
+                    time_of_first_packet_sent_after_receiving_);
+  }
+
+  QuicTime::Delta idle_network_timeout() const { return idle_network_timeout_; }
+
+  QuicTime GetIdleNetworkDeadline() const;
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::QuicIdleNetworkDetectorTestPeer;
+
+  void SetAlarm();
+
+  void MaybeSetAlarmOnSentPacket(QuicTime::Delta pto_delay);
+
+  Delegate* delegate_;  // Not owned.
+
+  // Start time of the detector, handshake deadline = start_time_ +
+  // handshake_timeout_.
+  const QuicTime start_time_;
+
+  // Handshake timeout. Infinit means handshake has completed.
+  QuicTime::Delta handshake_timeout_;
+
+  // Time that last packet is received for this connection. Initialized to
+  // start_time_.
+  QuicTime time_of_last_received_packet_;
+
+  // Time that the first packet gets sent after the received packet. idle
+  // network deadline = std::max(time_of_last_received_packet_,
+  // time_of_first_packet_sent_after_receiving_) + idle_network_timeout_.
+  // Initialized to 0.
+  QuicTime time_of_first_packet_sent_after_receiving_;
+
+  // Idle network timeout. Infinit means no idle network timeout.
+  QuicTime::Delta idle_network_timeout_;
+
+  QuicArenaScopedPtr<QuicAlarm> alarm_;
+
+  bool shorter_idle_timeout_on_sent_packet_ = false;
+
+  // Whether |StopDetection| has been called.
+  bool stopped_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
diff --git a/quiche/quic/core/quic_idle_network_detector_test.cc b/quiche/quic/core/quic_idle_network_detector_test.cc
new file mode 100644
index 0000000..31aa8b4
--- /dev/null
+++ b/quiche/quic/core/quic_idle_network_detector_test.cc
@@ -0,0 +1,200 @@
+// Copyright (c) 2020 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 "quiche/quic/core/quic_idle_network_detector.h"
+
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class QuicIdleNetworkDetectorTestPeer {
+ public:
+  static QuicAlarm* GetAlarm(QuicIdleNetworkDetector* detector) {
+    return detector->alarm_.get();
+  }
+};
+
+namespace {
+
+class MockDelegate : public QuicIdleNetworkDetector::Delegate {
+ public:
+  MOCK_METHOD(void, OnHandshakeTimeout, (), (override));
+  MOCK_METHOD(void, OnIdleNetworkDetected, (), (override));
+};
+
+class QuicIdleNetworkDetectorTest : public QuicTest {
+ public:
+  QuicIdleNetworkDetectorTest() {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    detector_ = std::make_unique<QuicIdleNetworkDetector>(
+        &delegate_, clock_.Now(), &arena_, &alarm_factory_,
+        /*context=*/nullptr);
+    alarm_ = static_cast<MockAlarmFactory::TestAlarm*>(
+        QuicIdleNetworkDetectorTestPeer::GetAlarm(detector_.get()));
+  }
+
+ protected:
+  testing::StrictMock<MockDelegate> delegate_;
+  QuicConnectionArena arena_;
+  MockAlarmFactory alarm_factory_;
+
+  std::unique_ptr<QuicIdleNetworkDetector> detector_;
+
+  MockAlarmFactory::TestAlarm* alarm_;
+  MockClock clock_;
+};
+
+TEST_F(QuicIdleNetworkDetectorTest,
+       IdleNetworkDetectedBeforeHandshakeCompletes) {
+  EXPECT_FALSE(alarm_->IsSet());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+  EXPECT_TRUE(alarm_->IsSet());
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(20),
+            alarm_->deadline());
+
+  // No network activity for 20s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
+  EXPECT_CALL(delegate_, OnIdleNetworkDetected());
+  alarm_->Fire();
+}
+
+TEST_F(QuicIdleNetworkDetectorTest, HandshakeTimeout) {
+  EXPECT_FALSE(alarm_->IsSet());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+  EXPECT_TRUE(alarm_->IsSet());
+
+  // Has network activity after 15s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  detector_->OnPacketReceived(clock_.Now());
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(15),
+            alarm_->deadline());
+  // Handshake does not complete for another 15s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  EXPECT_CALL(delegate_, OnHandshakeTimeout());
+  alarm_->Fire();
+}
+
+TEST_F(QuicIdleNetworkDetectorTest,
+       IdleNetworkDetectedAfterHandshakeCompletes) {
+  EXPECT_FALSE(alarm_->IsSet());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+  EXPECT_TRUE(alarm_->IsSet());
+
+  // Handshake completes in 200ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  detector_->OnPacketReceived(clock_.Now());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::Infinite(),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
+            alarm_->deadline());
+
+  // No network activity for 600s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600));
+  EXPECT_CALL(delegate_, OnIdleNetworkDetected());
+  alarm_->Fire();
+}
+
+TEST_F(QuicIdleNetworkDetectorTest,
+       DoNotExtendIdleDeadlineOnConsecutiveSentPackets) {
+  EXPECT_FALSE(alarm_->IsSet());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+  EXPECT_TRUE(alarm_->IsSet());
+
+  // Handshake completes in 200ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  detector_->OnPacketReceived(clock_.Now());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::Infinite(),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
+            alarm_->deadline());
+
+  // Sent packets after 200ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
+  const QuicTime packet_sent_time = clock_.Now();
+  EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
+            alarm_->deadline());
+
+  // Sent another packet after 200ms
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
+  // Verify idle network deadline does not extend.
+  EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
+            alarm_->deadline());
+
+  // No network activity for 600s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600) -
+                     QuicTime::Delta::FromMilliseconds(200));
+  EXPECT_CALL(delegate_, OnIdleNetworkDetected());
+  alarm_->Fire();
+}
+
+TEST_F(QuicIdleNetworkDetectorTest, ShorterIdleTimeoutOnSentPacket) {
+  detector_->enable_shorter_idle_timeout_on_sent_packet();
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::Infinite(),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(alarm_->IsSet());
+  const QuicTime deadline = alarm_->deadline();
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30), deadline);
+
+  // Send a packet after 15s and 2s PTO delay.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
+  EXPECT_TRUE(alarm_->IsSet());
+  // Verify alarm does not get extended because deadline is > PTO delay.
+  EXPECT_EQ(deadline, alarm_->deadline());
+
+  // Send another packet near timeout and 2 s PTO delay.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(14));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
+  EXPECT_TRUE(alarm_->IsSet());
+  // Verify alarm does not get extended although it is shorter than PTO.
+  EXPECT_EQ(deadline, alarm_->deadline());
+
+  // Receive a packet after 1s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  detector_->OnPacketReceived(clock_.Now());
+  EXPECT_TRUE(alarm_->IsSet());
+  // Verify idle timeout gets extended by 30s.
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30),
+            alarm_->deadline());
+
+  // Send a packet near timeout..
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(29));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
+  EXPECT_TRUE(alarm_->IsSet());
+  // Verify idle timeout gets extended by 1s.
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(2), alarm_->deadline());
+}
+
+TEST_F(QuicIdleNetworkDetectorTest, NoAlarmAfterStopped) {
+  detector_->StopDetection();
+
+  EXPECT_QUIC_BUG(
+      detector_->SetTimeouts(
+          /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+          /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20)),
+      "SetAlarm called after stopped");
+  EXPECT_FALSE(alarm_->IsSet());
+}
+
+}  // namespace
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_interval.h b/quiche/quic/core/quic_interval.h
new file mode 100644
index 0000000..040355f
--- /dev/null
+++ b/quiche/quic/core/quic_interval.h
@@ -0,0 +1,390 @@
+// Copyright (c) 2019 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_INTERVAL_H_
+#define QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
+
+// An QuicInterval<T> is a data structure used to represent a contiguous,
+// mutable range over an ordered type T. Supported operations include testing a
+// value to see whether it is included in the QuicInterval, comparing two
+// QuicIntervals, and performing their union, intersection, and difference. For
+// the purposes of this library, an "ordered type" is any type that induces a
+// total order on its values via its less-than operator (operator<()). Examples
+// of such types are basic arithmetic types like int and double as well as class
+// types like string.
+//
+// An QuicInterval<T> is represented using the usual C++ STL convention, namely
+// as the half-open QuicInterval [min, max). A point p is considered to be
+// contained in the QuicInterval iff p >= min && p < max. One consequence of
+// this definition is that for any non-empty QuicInterval, min is contained in
+// the QuicInterval but max is not. There is no canonical representation for the
+// empty QuicInterval; rather, any QuicInterval where max <= min is regarded as
+// empty. As a consequence, two empty QuicIntervals will still compare as equal
+// despite possibly having different underlying min() or max() values. Also
+// beware of the terminology used here: the library uses the terms "min" and
+// "max" rather than "begin" and "end" as is conventional for the STL.
+//
+// T is required to be default- and copy-constructable, to have an assignment
+// operator, and the full complement of comparison operators (<, <=, ==, !=, >=,
+// >).  A difference operator (operator-()) is required if
+// QuicInterval<T>::Length is used.
+//
+// QuicInterval supports operator==. Two QuicIntervals are considered equal if
+// either they are both empty or if their corresponding min and max fields
+// compare equal. QuicInterval also provides an operator<. Unfortunately,
+// operator< is currently buggy because its behavior is inconsistent with
+// operator==: two empty ranges with different representations may be regarded
+// as equal by operator== but regarded as different by operator<. Bug 9240050
+// has been created to address this.
+//
+//
+// Examples:
+//   QuicInterval<int> r1(0, 100);  // The QuicInterval [0, 100).
+//   EXPECT_TRUE(r1.Contains(0));
+//   EXPECT_TRUE(r1.Contains(50));
+//   EXPECT_FALSE(r1.Contains(100));  // 100 is just outside the QuicInterval.
+//
+//   QuicInterval<int> r2(50, 150);  // The QuicInterval [50, 150).
+//   EXPECT_TRUE(r1.Intersects(r2));
+//   EXPECT_FALSE(r1.Contains(r2));
+//   EXPECT_TRUE(r1.IntersectWith(r2));  // Mutates r1.
+//   EXPECT_EQ(QuicInterval<int>(50, 100), r1);  // r1 is now [50, 100).
+//
+//   QuicInterval<int> r3(1000, 2000);  // The QuicInterval [1000, 2000).
+//   EXPECT_TRUE(r1.IntersectWith(r3));  // Mutates r1.
+//   EXPECT_TRUE(r1.Empty());  // Now r1 is empty.
+//   EXPECT_FALSE(r1.Contains(r1.min()));  // e.g. doesn't contain its own min.
+
+#include <stddef.h>
+#include <algorithm>
+#include <ostream>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+template <typename T>
+class QUIC_NO_EXPORT QuicInterval {
+ private:
+  // Type trait for deriving the return type for QuicInterval::Length.  If
+  // operator-() is not defined for T, then the return type is void.  This makes
+  // the signature for Length compile so that the class can be used for such T,
+  // but code that calls Length would still generate a compilation error.
+  template <typename U>
+  class QUIC_NO_EXPORT DiffTypeOrVoid {
+   private:
+    template <typename V>
+    static auto f(const V* v) -> decltype(*v - *v);
+    template <typename V>
+    static void f(...);
+
+   public:
+    using type = typename std::decay<decltype(f<U>(nullptr))>::type;
+  };
+
+ public:
+  // Construct an QuicInterval representing an empty QuicInterval.
+  QuicInterval() : min_(), max_() {}
+
+  // Construct an QuicInterval representing the QuicInterval [min, max). If min
+  // < max, the constructed object will represent the non-empty QuicInterval
+  // containing all values from min up to (but not including) max. On the other
+  // hand, if min >= max, the constructed object will represent the empty
+  // QuicInterval.
+  QuicInterval(const T& min, const T& max) : min_(min), max_(max) {}
+
+  template <typename U1,
+            typename U2,
+            typename = typename std::enable_if<
+                std::is_convertible<U1, T>::value &&
+                std::is_convertible<U2, T>::value>::type>
+  QuicInterval(U1&& min, U2&& max)
+      : min_(std::forward<U1>(min)), max_(std::forward<U2>(max)) {}
+
+  const T& min() const { return min_; }
+  const T& max() const { return max_; }
+  void SetMin(const T& t) { min_ = t; }
+  void SetMax(const T& t) { max_ = t; }
+
+  void Set(const T& min, const T& max) {
+    SetMin(min);
+    SetMax(max);
+  }
+
+  void Clear() { *this = {}; }
+
+  bool Empty() const { return min() >= max(); }
+
+  // Returns the length of this QuicInterval. The value returned is zero if
+  // Empty() is true; otherwise the value returned is max() - min().
+  typename DiffTypeOrVoid<T>::type Length() const {
+    return (Empty() ? min() : max()) - min();
+  }
+
+  // Returns true iff t >= min() && t < max().
+  bool Contains(const T& t) const { return min() <= t && max() > t; }
+
+  // Returns true iff *this and i are non-empty, and *this includes i. "*this
+  // includes i" means that for all t, if i.Contains(t) then this->Contains(t).
+  // Note the unintuitive consequence of this definition: this method always
+  // returns false when i is the empty QuicInterval.
+  bool Contains(const QuicInterval& i) const {
+    return !Empty() && !i.Empty() && min() <= i.min() && max() >= i.max();
+  }
+
+  // Returns true iff there exists some point t for which this->Contains(t) &&
+  // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
+  bool Intersects(const QuicInterval& i) const {
+    return !Empty() && !i.Empty() && min() < i.max() && max() > i.min();
+  }
+
+  // Returns true iff there exists some point t for which this->Contains(t) &&
+  // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
+  // Furthermore, if the intersection is non-empty and the out pointer is not
+  // null, this method stores the calculated intersection in *out.
+  bool Intersects(const QuicInterval& i, QuicInterval* out) const;
+
+  // Sets *this to be the intersection of itself with i. Returns true iff
+  // *this was modified.
+  bool IntersectWith(const QuicInterval& i);
+
+  // Returns true iff this and other have disjoint closures.  For nonempty
+  // intervals, that means there is at least one point between this and other.
+  // Roughly speaking that means the intervals don't intersect, and they are not
+  // adjacent.   Empty intervals are always separated from any other interval.
+  bool Separated(const QuicInterval& other) const {
+    if (Empty() || other.Empty())
+      return true;
+    return other.max() < min() || max() < other.min();
+  }
+
+  // Calculates the smallest QuicInterval containing both *this i, and updates
+  // *this to represent that QuicInterval, and returns true iff *this was
+  // modified.
+  bool SpanningUnion(const QuicInterval& i);
+
+  // Determines the difference between two QuicIntervals by finding all points
+  // that are contained in *this but not in i, coalesces those points into the
+  // largest possible contiguous QuicIntervals, and appends those QuicIntervals
+  // to the *difference vector. Intuitively this can be thought of as "erasing"
+  // i from *this. This will either completely erase *this (leaving nothing
+  // behind), partially erase some of *this from the left or right side (leaving
+  // some residual behind), or erase a hole in the middle of *this (leaving
+  // behind an QuicInterval on either side). Therefore, 0, 1, or 2 QuicIntervals
+  // will be appended to *difference. The method returns true iff the
+  // intersection of *this and i is non-empty. The caller owns the vector and
+  // the QuicInterval* pointers inside it. The difference vector is required to
+  // be non-null.
+  bool Difference(const QuicInterval& i,
+                  std::vector<QuicInterval*>* difference) const;
+
+  // Determines the difference between two QuicIntervals as in
+  // Difference(QuicInterval&, vector*), but stores the results directly in out
+  // parameters rather than dynamically allocating an QuicInterval* and
+  // appending it to a vector. If two results are generated, the one with the
+  // smaller value of min() will be stored in *lo and the other in *hi.
+  // Otherwise (if fewer than two results are generated), unused arguments will
+  // be set to the empty QuicInterval (it is possible that *lo will be empty and
+  // *hi non-empty). The method returns true iff the intersection of *this and i
+  // is non-empty.
+  bool Difference(const QuicInterval& i,
+                  QuicInterval* lo,
+                  QuicInterval* hi) const;
+
+  friend bool operator==(const QuicInterval& a, const QuicInterval& b) {
+    bool ae = a.Empty();
+    bool be = b.Empty();
+    if (ae && be)
+      return true;  // All empties are equal.
+    if (ae != be)
+      return false;  // Empty cannot equal nonempty.
+    return a.min() == b.min() && a.max() == b.max();
+  }
+
+  friend bool operator!=(const QuicInterval& a, const QuicInterval& b) {
+    return !(a == b);
+  }
+
+  // Defines a comparator which can be used to induce an order on QuicIntervals,
+  // so that, for example, they can be stored in an ordered container such as
+  // std::set. The ordering is arbitrary, but does provide the guarantee that,
+  // for non-empty QuicIntervals X and Y, if X contains Y, then X <= Y.
+  // TODO(kosak): The current implementation of this comparator has a problem
+  // because the ordering it induces is inconsistent with that of Equals(). In
+  // particular, this comparator does not properly consider all empty
+  // QuicIntervals equivalent. Bug 9240050 has been created to track this.
+  friend bool operator<(const QuicInterval& a, const QuicInterval& b) {
+    return a.min() < b.min() || (!(b.min() < a.min()) && b.max() < a.max());
+  }
+
+ private:
+  T min_;  // Inclusive lower bound.
+  T max_;  // Exclusive upper bound.
+};
+
+// Constructs an QuicInterval by deducing the types from the function arguments.
+template <typename T>
+QuicInterval<T> MakeQuicInterval(T&& lhs, T&& rhs) {
+  return QuicInterval<T>(std::forward<T>(lhs), std::forward<T>(rhs));
+}
+
+// Note: ideally we'd use
+//   decltype(out << "[" << i.min() << ", " << i.max() << ")")
+// as return type of the function, but as of July 2017 this triggers g++
+// "sorry, unimplemented: string literal in function template signature" error.
+template <typename T>
+auto operator<<(std::ostream& out, const QuicInterval<T>& i)
+    -> decltype(out << i.min()) {
+  return out << "[" << i.min() << ", " << i.max() << ")";
+}
+
+//==============================================================================
+// Implementation details: Clients can stop reading here.
+
+template <typename T>
+bool QuicInterval<T>::Intersects(const QuicInterval& i,
+                                 QuicInterval* out) const {
+  if (!Intersects(i))
+    return false;
+  if (out != nullptr) {
+    *out = QuicInterval(std::max(min(), i.min()), std::min(max(), i.max()));
+  }
+  return true;
+}
+
+template <typename T>
+bool QuicInterval<T>::IntersectWith(const QuicInterval& i) {
+  if (Empty())
+    return false;
+  bool modified = false;
+  if (i.min() > min()) {
+    SetMin(i.min());
+    modified = true;
+  }
+  if (i.max() < max()) {
+    SetMax(i.max());
+    modified = true;
+  }
+  return modified;
+}
+
+template <typename T>
+bool QuicInterval<T>::SpanningUnion(const QuicInterval& i) {
+  if (i.Empty())
+    return false;
+  if (Empty()) {
+    *this = i;
+    return true;
+  }
+  bool modified = false;
+  if (i.min() < min()) {
+    SetMin(i.min());
+    modified = true;
+  }
+  if (i.max() > max()) {
+    SetMax(i.max());
+    modified = true;
+  }
+  return modified;
+}
+
+template <typename T>
+bool QuicInterval<T>::Difference(const QuicInterval& i,
+                                 std::vector<QuicInterval*>* difference) const {
+  if (Empty()) {
+    // <empty> - <i> = <empty>
+    return false;
+  }
+  if (i.Empty()) {
+    // <this> - <empty> = <this>
+    difference->push_back(new QuicInterval(*this));
+    return false;
+  }
+  if (min() < i.max() && min() >= i.min() && max() > i.max()) {
+    //            [------ this ------)
+    // [------ i ------)
+    //                 [-- result ---)
+    difference->push_back(new QuicInterval(i.max(), max()));
+    return true;
+  }
+  if (max() > i.min() && max() <= i.max() && min() < i.min()) {
+    // [------ this ------)
+    //            [------ i ------)
+    // [- result -)
+    difference->push_back(new QuicInterval(min(), i.min()));
+    return true;
+  }
+  if (min() < i.min() && max() > i.max()) {
+    // [------- this --------)
+    //      [---- i ----)
+    // [ R1 )           [ R2 )
+    // There are two results: R1 and R2.
+    difference->push_back(new QuicInterval(min(), i.min()));
+    difference->push_back(new QuicInterval(i.max(), max()));
+    return true;
+  }
+  if (min() >= i.min() && max() <= i.max()) {
+    //   [--- this ---)
+    // [------ i --------)
+    // Intersection is <this>, so difference yields the empty QuicInterval.
+    // Nothing is appended to *difference.
+    return true;
+  }
+  // No intersection. Append <this>.
+  difference->push_back(new QuicInterval(*this));
+  return false;
+}
+
+template <typename T>
+bool QuicInterval<T>::Difference(const QuicInterval& i,
+                                 QuicInterval* lo,
+                                 QuicInterval* hi) const {
+  // Initialize *lo and *hi to empty
+  *lo = {};
+  *hi = {};
+  if (Empty())
+    return false;
+  if (i.Empty()) {
+    *lo = *this;
+    return false;
+  }
+  if (min() < i.max() && min() >= i.min() && max() > i.max()) {
+    //            [------ this ------)
+    // [------ i ------)
+    //                 [-- result ---)
+    *hi = QuicInterval(i.max(), max());
+    return true;
+  }
+  if (max() > i.min() && max() <= i.max() && min() < i.min()) {
+    // [------ this ------)
+    //            [------ i ------)
+    // [- result -)
+    *lo = QuicInterval(min(), i.min());
+    return true;
+  }
+  if (min() < i.min() && max() > i.max()) {
+    // [------- this --------)
+    //      [---- i ----)
+    // [ R1 )           [ R2 )
+    // There are two results: R1 and R2.
+    *lo = QuicInterval(min(), i.min());
+    *hi = QuicInterval(i.max(), max());
+    return true;
+  }
+  if (min() >= i.min() && max() <= i.max()) {
+    //   [--- this ---)
+    // [------ i --------)
+    // Intersection is <this>, so difference yields the empty QuicInterval.
+    return true;
+  }
+  *lo = *this;  // No intersection.
+  return false;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
diff --git a/quiche/quic/core/quic_interval_deque.h b/quiche/quic/core/quic_interval_deque.h
new file mode 100644
index 0000000..f4bf092
--- /dev/null
+++ b/quiche/quic/core/quic_interval_deque.h
@@ -0,0 +1,393 @@
+// Copyright (c) 2019 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_INTERVAL_DEQUE_H_
+#define QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
+
+#include <algorithm>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class QuicIntervalDequePeer;
+}  // namespace test
+
+// QuicIntervalDeque<T, C> is a templated wrapper container, wrapping random
+// access data structures. The wrapper allows items to be added to the
+// underlying container with intervals associated with each item. The intervals
+// _should_ be added already sorted and represent searchable indices. The search
+// is optimized for sequential usage.
+//
+// As the intervals are to be searched sequentially the search for the next
+// interval can be achieved in O(1), by simply remembering the last interval
+// consumed. The structure also checks for an "off-by-one" use case wherein the
+// |cached_index_| is off by one index as the caller didn't call operator |++|
+// to increment the index. Other intervals can be found in O(log(n)) as they are
+// binary searchable. A use case for this structure is packet buffering: Packets
+// are sent sequentially but can sometimes needed for retransmission. The
+// packets and their payloads are added with associated intervals representing
+// data ranges they carry. When a user asks for a particular interval it's very
+// likely they are requesting the next sequential interval, receiving it in O(1)
+// time. Updating the sequential index is done automatically through the
+// |DataAt| method and its iterator operator |++|.
+//
+// The intervals are represented using the usual C++ STL convention, namely as
+// the half-open QuicInterval [min, max). A point p is considered to be
+// contained in the QuicInterval iff p >= min && p < max. One consequence of
+// this definition is that for any non-empty QuicInterval, min is contained in
+// the QuicInterval but max is not. There is no canonical representation for the
+// empty QuicInterval; and empty intervals are forbidden from being added to
+// this container as they would be unsearchable.
+//
+// The type T is required to be copy-constructable or move-constructable. The
+// type T is also expected to have an |interval()| method returning a
+// QuicInterval<std::size> for the particular value. The type C is required to
+// be a random access container supporting the methods |pop_front|, |push_back|,
+// |operator[]|, |size|, and iterator support for |std::lower_bound| eg. a
+// |deque| or |vector|.
+//
+// The QuicIntervalDeque<T, C>, like other C++ STL random access containers,
+// doesn't have any explicit support for any equality operators.
+//
+//
+// Examples with internal state:
+//
+//   // An example class to be stored inside the Interval Deque.
+//   struct IntervalVal {
+//     const int32_t val;
+//     const size_t interval_begin, interval_end;
+//     QuicInterval<size_t> interval();
+//   };
+//   typedef IntervalVal IV;
+//   QuicIntervialDeque<IntervalValue> deque;
+//
+//   // State:
+//   //   cached_index -> None
+//   //   container -> {}
+//
+//   // Add interval items
+//   deque.PushBack(IV(val: 0, interval_begin: 0, interval_end: 10));
+//   deque.PushBack(IV(val: 1, interval_begin: 20, interval_end: 25));
+//   deque.PushBack(IV(val: 2, interval_begin: 25, interval_end: 30));
+//
+//   // State:
+//   //   cached_index -> 0
+//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
+//
+//   // Look for 0 and return [0, 10). Time: O(1)
+//   auto it = deque.DataAt(0);
+//   assert(it->val == 0);
+//   it++;  // Increment and move the |cached_index_| over [0, 10) to [20, 25).
+//   assert(it->val == 1);
+//
+//   // State:
+//   //   cached_index -> 1
+//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
+//
+//   // Look for 20 and return [20, 25). Time: O(1)
+//   auto it = deque.DataAt(20); // |cached_index_| remains unchanged.
+//   assert(it->val == 1);
+//
+//   // State:
+//   //   cached_index -> 1
+//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
+//
+//   // Look for 15 and return deque.DataEnd(). Time: O(log(n))
+//   auto it = deque.DataAt(15); // |cached_index_| remains unchanged.
+//   assert(it == deque.DataEnd());
+//
+//   // Look for 25 and return [25, 30). Time: O(1) with off-by-one.
+//   auto it = deque.DataAt(25); // |cached_index_| is updated to 2.
+//   assert(it->val == 2);
+//   it++; // |cached_index_| is set to |None| as all data has been iterated.
+//
+//
+//   // State:
+//   //   cached_index -> None
+//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
+//
+//   // Look again for 0 and return [0, 10). Time: O(log(n))
+//   auto it = deque.DataAt(0);
+//
+//
+//   deque.PopFront();  // Pop -> {0, [0, 10)}
+//
+//   // State:
+//   //   cached_index -> None
+//   //   container -> {{1, [20, 25)}, {2, [25, 30)}}
+//
+//   deque.PopFront();  // Pop -> {1, [20, 25)}
+//
+//   // State:
+//   //   cached_index -> None
+//   //   container -> {{2, [25, 30)}}
+//
+//   deque.PushBack(IV(val: 3, interval_begin: 35, interval_end: 50));
+//
+//   // State:
+//   //   cached_index -> 1
+//   //   container -> {{2, [25, 30)}, {3, [35, 50)}}
+
+template <class T, class C = QUIC_NO_EXPORT quiche::QuicheCircularDeque<T>>
+class QUIC_NO_EXPORT QuicIntervalDeque {
+ public:
+  class QUIC_NO_EXPORT Iterator {
+   public:
+    // Used by |std::lower_bound|
+    using iterator_category = std::forward_iterator_tag;
+    using value_type = T;
+    using difference_type = std::ptrdiff_t;
+    using pointer = T*;
+    using reference = T&;
+
+    // Every increment of the iterator will increment the |cached_index_| if
+    // |index_| is larger than the current |cached_index_|. |index_| is bounded
+    // at |deque_.size()| and any attempt to increment above that will be
+    // ignored. Once an iterator has iterated all elements the |cached_index_|
+    // will be reset.
+    Iterator(std::size_t index, QuicIntervalDeque* deque)
+        : index_(index), deque_(deque) {}
+    // Only the ++ operator attempts to update the cached index. Other operators
+    // are used by |lower_bound| to binary search and are thus private.
+    Iterator& operator++() {
+      // Don't increment when we are at the end.
+      const std::size_t container_size = deque_->container_.size();
+      if (index_ >= container_size) {
+        QUIC_BUG(quic_bug_10862_1) << "Iterator out of bounds.";
+        return *this;
+      }
+      index_++;
+      if (deque_->cached_index_.has_value()) {
+        const std::size_t cached_index = deque_->cached_index_.value();
+        // If all items are iterated then reset the |cached_index_|
+        if (index_ == container_size) {
+          deque_->cached_index_.reset();
+        } else {
+          // Otherwise the new |cached_index_| is the max of itself and |index_|
+          if (cached_index < index_) {
+            deque_->cached_index_ = index_;
+          }
+        }
+      }
+      return *this;
+    }
+    Iterator operator++(int) {
+      Iterator copy = *this;
+      ++(*this);
+      return copy;
+    }
+    reference operator*() { return deque_->container_[index_]; }
+    reference operator*() const { return deque_->container_[index_]; }
+    pointer operator->() { return &deque_->container_[index_]; }
+    bool operator==(const Iterator& rhs) const {
+      return index_ == rhs.index_ && deque_ == rhs.deque_;
+    }
+    bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
+
+   private:
+    // A set of private operators for |std::lower_bound|
+    Iterator operator+(difference_type amount) const {
+      Iterator copy = *this;
+      copy.index_ += amount;
+      QUICHE_DCHECK(copy.index_ < copy.deque_->size());
+      return copy;
+    }
+    Iterator& operator+=(difference_type amount) {
+      index_ += amount;
+      QUICHE_DCHECK(index_ < deque_->size());
+      return *this;
+    }
+    difference_type operator-(const Iterator& rhs) const {
+      return static_cast<difference_type>(index_) -
+             static_cast<difference_type>(rhs.index_);
+    }
+
+    // |index_| is the index of the item in |*deque_|.
+    std::size_t index_;
+    // |deque_| is a pointer to the container the iterator came from.
+    QuicIntervalDeque* deque_;
+
+    friend class QuicIntervalDeque;
+  };
+
+  QuicIntervalDeque();
+
+  // Adds an item to the underlying container. The |item|'s interval _should_ be
+  // strictly greater than the last interval added.
+  void PushBack(T&& item);
+  void PushBack(const T& item);
+  // Removes the front/top of the underlying container and the associated
+  // interval.
+  void PopFront();
+  // Returns an iterator to the beginning of the data. The iterator will move
+  // the |cached_index_| as the iterator moves.
+  Iterator DataBegin();
+  // Returns an iterator to the end of the data.
+  Iterator DataEnd();
+  // Returns an iterator pointing to the item in |interval_begin|. The iterator
+  // will move the |cached_index_| as the iterator moves.
+  Iterator DataAt(const std::size_t interval_begin);
+
+  // Returns the number of items contained inside the structure.
+  std::size_t Size() const;
+  // Returns whether the structure is empty.
+  bool Empty() const;
+
+ private:
+  struct QUIC_NO_EXPORT IntervalCompare {
+    bool operator()(const T& item, std::size_t interval_begin) const {
+      return item.interval().max() <= interval_begin;
+    }
+  };
+
+  template <class U>
+  void PushBackUniversal(U&& item);
+
+  Iterator Search(const std::size_t interval_begin,
+                  const std::size_t begin_index,
+                  const std::size_t end_index);
+
+  // For accessing the |cached_index_|
+  friend class test::QuicIntervalDequePeer;
+
+  C container_;
+  absl::optional<std::size_t> cached_index_;
+};
+
+template <class T, class C>
+QuicIntervalDeque<T, C>::QuicIntervalDeque() {}
+
+template <class T, class C>
+void QuicIntervalDeque<T, C>::PushBack(T&& item) {
+  PushBackUniversal(std::move(item));
+}
+
+template <class T, class C>
+void QuicIntervalDeque<T, C>::PushBack(const T& item) {
+  PushBackUniversal(item);
+}
+
+template <class T, class C>
+void QuicIntervalDeque<T, C>::PopFront() {
+  if (container_.size() == 0) {
+    QUIC_BUG(quic_bug_10862_2) << "Trying to pop from an empty container.";
+    return;
+  }
+  container_.pop_front();
+  if (container_.size() == 0) {
+    cached_index_.reset();
+  }
+  if (cached_index_.value_or(0) > 0) {
+    cached_index_ = cached_index_.value() - 1;
+  }
+}
+
+template <class T, class C>
+typename QuicIntervalDeque<T, C>::Iterator
+QuicIntervalDeque<T, C>::DataBegin() {
+  return Iterator(0, this);
+}
+
+template <class T, class C>
+typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::DataEnd() {
+  return Iterator(container_.size(), this);
+}
+
+template <class T, class C>
+typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::DataAt(
+    const std::size_t interval_begin) {
+  // No |cached_index_| value means all items can be searched.
+  if (!cached_index_.has_value()) {
+    return Search(interval_begin, 0, container_.size());
+  }
+
+  const std::size_t cached_index = cached_index_.value();
+  QUICHE_DCHECK(cached_index < container_.size());
+
+  const QuicInterval<size_t> cached_interval =
+      container_[cached_index].interval();
+  // Does our cached index point directly to what we want?
+  if (cached_interval.Contains(interval_begin)) {
+    return Iterator(cached_index, this);
+  }
+
+  // Are we off-by-one?
+  const std::size_t next_index = cached_index + 1;
+  if (next_index < container_.size()) {
+    if (container_[next_index].interval().Contains(interval_begin)) {
+      cached_index_ = next_index;
+      return Iterator(next_index, this);
+    }
+  }
+
+  // Small optimization:
+  // Determine if we should binary search above or below the cached interval.
+  const std::size_t cached_begin = cached_interval.min();
+  bool looking_below = interval_begin < cached_begin;
+  const std::size_t lower = looking_below ? 0 : cached_index + 1;
+  const std::size_t upper = looking_below ? cached_index : container_.size();
+  Iterator ret = Search(interval_begin, lower, upper);
+  if (ret == DataEnd()) {
+    return ret;
+  }
+  // Update the |cached_index_| to point to the higher index.
+  if (!looking_below) {
+    cached_index_ = ret.index_;
+  }
+  return ret;
+}
+
+template <class T, class C>
+std::size_t QuicIntervalDeque<T, C>::Size() const {
+  return container_.size();
+}
+
+template <class T, class C>
+bool QuicIntervalDeque<T, C>::Empty() const {
+  return container_.size() == 0;
+}
+
+template <class T, class C>
+template <class U>
+void QuicIntervalDeque<T, C>::PushBackUniversal(U&& item) {
+  QuicInterval<std::size_t> interval = item.interval();
+  // Adding an empty interval is a bug.
+  if (interval.Empty()) {
+    QUIC_BUG(quic_bug_10862_3)
+        << "Trying to save empty interval to quiche::QuicheCircularDeque.";
+    return;
+  }
+  container_.push_back(std::forward<U>(item));
+  if (!cached_index_.has_value()) {
+    cached_index_ = container_.size() - 1;
+  }
+}
+
+template <class T, class C>
+typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::Search(
+    const std::size_t interval_begin,
+    const std::size_t begin_index,
+    const std::size_t end_index) {
+  auto begin = container_.begin() + begin_index;
+  auto end = container_.begin() + end_index;
+  auto res = std::lower_bound(begin, end, interval_begin, IntervalCompare());
+  // Just because we run |lower_bound| and it didn't return |container_.end()|
+  // doesn't mean we found our desired interval.
+  if (res != end && res->interval().Contains(interval_begin)) {
+    return Iterator(std::distance(begin, res) + begin_index, this);
+  }
+  return DataEnd();
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
diff --git a/quiche/quic/core/quic_interval_deque_test.cc b/quiche/quic/core/quic_interval_deque_test.cc
new file mode 100644
index 0000000..8a1f028
--- /dev/null
+++ b/quiche/quic/core/quic_interval_deque_test.cc
@@ -0,0 +1,360 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_interval_deque.h"
+#include <cstdint>
+#include <ostream>
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_interval_deque_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+const int32_t kSize = 100;
+const std::size_t kIntervalStep = 10;
+
+}  // namespace
+
+struct TestIntervalItem {
+  int32_t val;
+  std::size_t interval_start, interval_end;
+  QuicInterval<std::size_t> interval() const {
+    return QuicInterval<std::size_t>(interval_start, interval_end);
+  }
+  TestIntervalItem(int32_t val,
+                   std::size_t interval_start,
+                   std::size_t interval_end)
+      : val(val), interval_start(interval_start), interval_end(interval_end) {}
+};
+
+using QID = QuicIntervalDeque<TestIntervalItem>;
+
+class QuicIntervalDequeTest : public QuicTest {
+ public:
+  QuicIntervalDequeTest() {
+    // Add items with intervals of |kIntervalStep| size.
+    for (int32_t i = 0; i < kSize; ++i) {
+      const std::size_t interval_begin = kIntervalStep * i;
+      const std::size_t interval_end = interval_begin + kIntervalStep;
+      qid_.PushBack(TestIntervalItem(i, interval_begin, interval_end));
+    }
+  }
+
+  QID qid_;
+};
+
+// The goal of this test is to show insertion/push_back, iteration, and and
+// deletion/pop_front from the container.
+TEST_F(QuicIntervalDequeTest, InsertRemoveSize) {
+  QID qid;
+
+  EXPECT_EQ(qid.Size(), std::size_t(0));
+  qid.PushBack(TestIntervalItem(0, 0, 10));
+  EXPECT_EQ(qid.Size(), std::size_t(1));
+  qid.PushBack(TestIntervalItem(1, 10, 20));
+  EXPECT_EQ(qid.Size(), std::size_t(2));
+  qid.PushBack(TestIntervalItem(2, 20, 30));
+  EXPECT_EQ(qid.Size(), std::size_t(3));
+  qid.PushBack(TestIntervalItem(3, 30, 40));
+  EXPECT_EQ(qid.Size(), std::size_t(4));
+
+  // Advance the index all the way...
+  int32_t i = 0;
+  for (auto it = qid.DataAt(0); it != qid.DataEnd(); ++it, ++i) {
+    const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid);
+    EXPECT_EQ(index, i);
+    EXPECT_EQ(it->val, i);
+  }
+  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid);
+  EXPECT_EQ(index, -1);
+
+  qid.PopFront();
+  EXPECT_EQ(qid.Size(), std::size_t(3));
+  qid.PopFront();
+  EXPECT_EQ(qid.Size(), std::size_t(2));
+  qid.PopFront();
+  EXPECT_EQ(qid.Size(), std::size_t(1));
+  qid.PopFront();
+  EXPECT_EQ(qid.Size(), std::size_t(0));
+
+  EXPECT_QUIC_BUG(qid.PopFront(), "Trying to pop from an empty container.");
+}
+
+// The goal of this test is to push data into the container at specific
+// intervals and show how the |DataAt| method can move the |cached_index| as the
+// iterator moves through the data.
+TEST_F(QuicIntervalDequeTest, InsertIterateWhole) {
+  // The write index should point to the beginning of the container.
+  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(cached_index, 0);
+
+  auto it = qid_.DataBegin();
+  auto end = qid_.DataEnd();
+  for (int32_t i = 0; i < kSize; ++i, ++it) {
+    EXPECT_EQ(it->val, i);
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(i, lookup->val);
+    // Make sure the index hasn't changed just from using |DataAt|
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_before, i);
+    // This increment should move the index forward.
+    lookup++;
+    // Check that the index has changed.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
+    EXPECT_EQ(index_after, after_i);
+    EXPECT_NE(it, end);
+  }
+}
+
+// The goal of this test is to push data into the container at specific
+// intervals and show how the |DataAt| method can move the |cached_index| using
+// the off-by-one logic.
+TEST_F(QuicIntervalDequeTest, OffByOne) {
+  // The write index should point to the beginning of the container.
+  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(cached_index, 0);
+
+  auto it = qid_.DataBegin();
+  auto end = qid_.DataEnd();
+  for (int32_t i = 0; i < kSize - 1; ++i, ++it) {
+    EXPECT_EQ(it->val, i);
+    const int32_t off_by_one_i = i + 1;
+    const std::size_t current_iteraval_begin = off_by_one_i * kIntervalStep;
+    // Make sure the index has changed just from using |DataAt|
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_before, i);
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(off_by_one_i, lookup->val);
+    // Check that the index has changed.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = off_by_one_i == kSize ? -1 : off_by_one_i;
+    EXPECT_EQ(index_after, after_i);
+    EXPECT_NE(it, end);
+  }
+}
+
+// The goal of this test is to push data into the container at specific
+// intervals and show modify the structure with a live iterator.
+TEST_F(QuicIntervalDequeTest, IteratorInvalidation) {
+  // The write index should point to the beginning of the container.
+  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(cached_index, 0);
+
+  const std::size_t iteraval_begin = (kSize - 1) * kIntervalStep;
+  auto lookup = qid_.DataAt(iteraval_begin);
+  EXPECT_EQ((*lookup).val, (kSize - 1));
+  qid_.PopFront();
+  EXPECT_QUIC_BUG(lookup++, "Iterator out of bounds.");
+  auto lookup_end = qid_.DataAt(iteraval_begin + kIntervalStep);
+  EXPECT_EQ(lookup_end, qid_.DataEnd());
+}
+
+// The goal of this test is the same as |InsertIterateWhole| but to
+// skip certain intervals and show the |cached_index| is updated properly.
+TEST_F(QuicIntervalDequeTest, InsertIterateSkip) {
+  // The write index should point to the beginning of the container.
+  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(cached_index, 0);
+
+  const std::size_t step = 4;
+  for (int32_t i = 0; i < kSize; i += 4) {
+    if (i != 0) {
+      const int32_t before_i = (i - (step - 1));
+      EXPECT_EQ(QuicIntervalDequePeer::GetCachedIndex(&qid_), before_i);
+    }
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(i, lookup->val);
+    // Make sure the index _has_ changed just from using |DataAt| since we're
+    // skipping data.
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_before, i);
+    // This increment should move the index forward.
+    lookup++;
+    // Check that the index has changed.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
+    EXPECT_EQ(index_after, after_i);
+  }
+}
+
+// The goal of this test is the same as |InsertIterateWhole| but it has
+// |PopFront| calls interleaved to show the |cached_index| updates correctly.
+TEST_F(QuicIntervalDequeTest, InsertDeleteIterate) {
+  // The write index should point to the beginning of the container.
+  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(index, 0);
+
+  std::size_t limit = 0;
+  for (int32_t i = 0; limit < qid_.Size(); ++i, ++limit) {
+    // Always point to the beginning of the container.
+    auto it = qid_.DataBegin();
+    EXPECT_EQ(it->val, i);
+
+    // Get an iterator.
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    // The index should always point to 0.
+    EXPECT_EQ(index_before, 0);
+    // This iterator increment should effect the index.
+    lookup++;
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_after, 1);
+    // Decrement the |temp_size| and pop from the front.
+    qid_.PopFront();
+    // Show the index has been updated to point to 0 again (from 1).
+    const int32_t index_after_pop =
+        QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_after_pop, 0);
+  }
+}
+
+// The goal of this test is to move the index to the end and then add more data
+// to show it can be reset to a valid index.
+TEST_F(QuicIntervalDequeTest, InsertIterateInsert) {
+  // The write index should point to the beginning of the container.
+  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(index, 0);
+
+  int32_t iterated_elements = 0;
+  for (int32_t i = 0; i < kSize; ++i, ++iterated_elements) {
+    // Get an iterator.
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    // The index should always point to i.
+    EXPECT_EQ(index_before, i);
+    // This iterator increment should effect the index.
+    lookup++;
+    // Show the index has been updated to point to i + 1 or -1 if at the end.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
+    EXPECT_EQ(index_after, after_i);
+  }
+  const int32_t invalid_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(invalid_index, -1);
+
+  // Add more data to the container, making the index valid.
+  const std::size_t offset = qid_.Size();
+  for (int32_t i = 0; i < kSize; ++i) {
+    const std::size_t interval_begin = offset + (kIntervalStep * i);
+    const std::size_t interval_end = offset + interval_begin + kIntervalStep;
+    qid_.PushBack(TestIntervalItem(i + offset, interval_begin, interval_end));
+    const int32_t index_current = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    // Index should now be valid and equal to the size of the container before
+    // adding more items to it.
+    EXPECT_EQ(index_current, iterated_elements);
+  }
+  // Show the index is still valid and hasn't changed since the first iteration
+  // of the loop.
+  const int32_t index_after_add = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(index_after_add, iterated_elements);
+
+  // Iterate over all the data in the container and eventually reset the index
+  // as we did before.
+  for (int32_t i = 0; i < kSize; ++i, ++iterated_elements) {
+    const std::size_t interval_begin = offset + (kIntervalStep * i);
+    const int32_t index_current = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_current, iterated_elements);
+    auto lookup = qid_.DataAt(interval_begin);
+    const int32_t expected_value = i + offset;
+    EXPECT_EQ(lookup->val, expected_value);
+    lookup++;
+    const int32_t after_inc =
+        (iterated_elements + 1) == (kSize * 2) ? -1 : (iterated_elements + 1);
+    const int32_t after_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(after_index, after_inc);
+  }
+  // Show the index is now invalid.
+  const int32_t invalid_index_again =
+      QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(invalid_index_again, -1);
+}
+
+// The goal of this test is to push data into the container at specific
+// intervals and show how the |DataAt| can iterate over already scanned data.
+TEST_F(QuicIntervalDequeTest, RescanData) {
+  // The write index should point to the beginning of the container.
+  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(index, 0);
+
+  auto it = qid_.DataBegin();
+  auto end = qid_.DataEnd();
+  for (int32_t i = 0; i < kSize - 1; ++i, ++it) {
+    EXPECT_EQ(it->val, i);
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(i, lookup->val);
+    // Make sure the index has changed just from using |DataAt|
+    const int32_t cached_index_before =
+        QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(cached_index_before, i);
+    // Ensure the real index has changed just from using |DataAt| and the
+    // off-by-one logic
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t before_i = i;
+    EXPECT_EQ(index_before, before_i);
+    // This increment should move the cached index forward.
+    lookup++;
+    // Check that the cached index has moved foward.
+    const int32_t cached_index_after =
+        QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = (i + 1);
+    EXPECT_EQ(cached_index_after, after_i);
+    EXPECT_NE(it, end);
+  }
+
+  // Iterate over items which have been consumed before.
+  int32_t expected_index = static_cast<int32_t>(kSize - 1);
+  for (int32_t i = 0; i < kSize - 1; ++i) {
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(i, lookup->val);
+    // This increment shouldn't move the index forward as the index is currently
+    // ahead.
+    lookup++;
+    // Check that the index hasn't moved foward.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_after, expected_index);
+    EXPECT_NE(it, end);
+  }
+}
+
+// The goal of this test is to show that popping from an empty container is a
+// bug.
+TEST_F(QuicIntervalDequeTest, PopEmpty) {
+  QID qid;
+  EXPECT_TRUE(qid.Empty());
+  EXPECT_QUIC_BUG(qid.PopFront(), "Trying to pop from an empty container.");
+}
+
+// The goal of this test is to show that adding a zero-sized interval is a bug.
+TEST_F(QuicIntervalDequeTest, ZeroSizedInterval) {
+  QID qid;
+  EXPECT_QUIC_BUG(qid.PushBack(TestIntervalItem(0, 0, 0)),
+                  "Trying to save empty interval to .");
+}
+
+// The goal of this test is to show that an iterator to an empty container
+// returns |DataEnd|.
+TEST_F(QuicIntervalDequeTest, IteratorEmpty) {
+  QID qid;
+  auto it = qid.DataAt(0);
+  EXPECT_EQ(it, qid.DataEnd());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_interval_set.h b/quiche/quic/core/quic_interval_set.h
new file mode 100644
index 0000000..e97efed
--- /dev/null
+++ b/quiche/quic/core/quic_interval_set.h
@@ -0,0 +1,896 @@
+// Copyright (c) 2019 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_INTERVAL_SET_H_
+#define QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
+
+// QuicIntervalSet<T> is a data structure used to represent a sorted set of
+// non-empty, non-adjacent, and mutually disjoint intervals. Mutations to an
+// interval set preserve these properties, altering the set as needed. For
+// example, adding [2, 3) to a set containing only [1, 2) would result in the
+// set containing the single interval [1, 3).
+//
+// Supported operations include testing whether an Interval is contained in the
+// QuicIntervalSet, comparing two QuicIntervalSets, and performing
+// QuicIntervalSet union, intersection, and difference.
+//
+// QuicIntervalSet maintains the minimum number of entries needed to represent
+// the set of underlying intervals. When the QuicIntervalSet is modified (e.g.
+// due to an Add operation), other interval entries may be coalesced, removed,
+// or otherwise modified in order to maintain this invariant. The intervals are
+// maintained in sorted order, by ascending min() value.
+//
+// The reader is cautioned to beware of the terminology used here: this library
+// uses the terms "min" and "max" rather than "begin" and "end" as is
+// conventional for the STL. The terminology [min, max) refers to the half-open
+// interval which (if the interval is not empty) contains min but does not
+// contain max. An interval is considered empty if min >= max.
+//
+// T is required to be default- and copy-constructible, to have an assignment
+// operator, a difference operator (operator-()), and the full complement of
+// comparison operators (<, <=, ==, !=, >=, >). These requirements are inherited
+// from value_type.
+//
+// QuicIntervalSet has constant-time move operations.
+//
+//
+// Examples:
+//   QuicIntervalSet<int> intervals;
+//   intervals.Add(Interval<int>(10, 20));
+//   intervals.Add(Interval<int>(30, 40));
+//   // intervals contains [10,20) and [30,40).
+//   intervals.Add(Interval<int>(15, 35));
+//   // intervals has been coalesced. It now contains the single range [10,40).
+//   EXPECT_EQ(1, intervals.Size());
+//   EXPECT_TRUE(intervals.Contains(Interval<int>(10, 40)));
+//
+//   intervals.Difference(Interval<int>(10, 20));
+//   // intervals should now contain the single range [20, 40).
+//   EXPECT_EQ(1, intervals.Size());
+//   EXPECT_TRUE(intervals.Contains(Interval<int>(20, 40)));
+
+#include <stddef.h>
+#include <algorithm>
+#include <initializer_list>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include <string>
+
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+template <typename T>
+class QUIC_NO_EXPORT QuicIntervalSet {
+ public:
+  using value_type = QuicInterval<T>;
+
+ private:
+  struct QUIC_NO_EXPORT IntervalLess {
+    using is_transparent = void;
+    bool operator()(const value_type& a, const value_type& b) const;
+    // These transparent overloads are used when we do all of our searches (via
+    // Set::lower_bound() and Set::upper_bound()), which avoids the need to
+    // construct an interval when we are looking for a point and also avoids
+    // needing to worry about comparing overlapping intervals in the overload
+    // that takes two value_types (the one just above this comment).
+    bool operator()(const value_type& a, const T& point) const;
+    bool operator()(const value_type& a, T&& point) const;
+    bool operator()(const T& point, const value_type& a) const;
+    bool operator()(T&& point, const value_type& a) const;
+  };
+
+  using Set = QuicSmallOrderedSet<value_type, IntervalLess>;
+
+ public:
+  using const_iterator = typename Set::const_iterator;
+  using const_reverse_iterator = typename Set::const_reverse_iterator;
+
+  // Instantiates an empty QuicIntervalSet.
+  QuicIntervalSet() = default;
+
+  // Instantiates a QuicIntervalSet containing exactly one initial half-open
+  // interval [min, max), unless the given interval is empty, in which case the
+  // QuicIntervalSet will be empty.
+  explicit QuicIntervalSet(const value_type& interval) { Add(interval); }
+
+  // Instantiates a QuicIntervalSet containing the half-open interval [min,
+  // max).
+  QuicIntervalSet(const T& min, const T& max) { Add(min, max); }
+
+  QuicIntervalSet(std::initializer_list<value_type> il) { assign(il); }
+
+  // Clears this QuicIntervalSet.
+  void Clear() { intervals_.clear(); }
+
+  // Returns the number of disjoint intervals contained in this QuicIntervalSet.
+  size_t Size() const { return intervals_.size(); }
+
+  // Returns the smallest interval that contains all intervals in this
+  // QuicIntervalSet, or the empty interval if the set is empty.
+  value_type SpanningInterval() const;
+
+  // Adds "interval" to this QuicIntervalSet. Adding the empty interval has no
+  // effect.
+  void Add(const value_type& interval);
+
+  // Adds the interval [min, max) to this QuicIntervalSet. Adding the empty
+  // interval has no effect.
+  void Add(const T& min, const T& max) { Add(value_type(min, max)); }
+
+  // Same semantics as Add(const value_type&), but optimized for the case where
+  // rbegin()->min() <= |interval|.min() <= rbegin()->max().
+  void AddOptimizedForAppend(const value_type& interval) {
+    if (Empty()) {
+      Add(interval);
+      return;
+    }
+
+    const_reverse_iterator last_interval = intervals_.rbegin();
+
+    // If interval.min() is outside of [last_interval->min, last_interval->max],
+    // we can not simply extend last_interval->max.
+    if (interval.min() < last_interval->min() ||
+        interval.min() > last_interval->max()) {
+      Add(interval);
+      return;
+    }
+
+    if (interval.max() <= last_interval->max()) {
+      // interval is fully contained by last_interval.
+      return;
+    }
+
+    // Extend last_interval.max to interval.max, in place.
+    //
+    // Set does not allow in-place updates due to the potential of violating its
+    // ordering requirements. But we know setting the max of the last interval
+    // is safe w.r.t set ordering and other invariants of QuicIntervalSet, so we
+    // force an in-place update for performance.
+    const_cast<value_type*>(&(*last_interval))->SetMax(interval.max());
+  }
+
+  // Same semantics as Add(const T&, const T&), but optimized for the case where
+  // rbegin()->max() == |min|.
+  void AddOptimizedForAppend(const T& min, const T& max) {
+    AddOptimizedForAppend(value_type(min, max));
+  }
+
+  // TODO(wub): Similar to AddOptimizedForAppend, we can also have a
+  // AddOptimizedForPrepend if there is a use case.
+
+  // Remove the first interval.
+  // REQUIRES: !Empty()
+  void PopFront() {
+    QUICHE_DCHECK(!Empty());
+    intervals_.erase(intervals_.begin());
+  }
+
+  // Trim all values that are smaller than |value|. Which means
+  // a) If all values in an interval is smaller than |value|, the entire
+  //    interval is removed.
+  // b) If some but not all values in an interval is smaller than |value|, the
+  //    min of that interval is raised to |value|.
+  // Returns true if some intervals are trimmed.
+  bool TrimLessThan(const T& value) {
+    // Number of intervals that are fully or partially trimmed.
+    size_t num_intervals_trimmed = 0;
+
+    while (!intervals_.empty()) {
+      const_iterator first_interval = intervals_.begin();
+      if (first_interval->min() >= value) {
+        break;
+      }
+
+      ++num_intervals_trimmed;
+
+      if (first_interval->max() <= value) {
+        // a) Trim the entire interval.
+        intervals_.erase(first_interval);
+        continue;
+      }
+
+      // b) Trim a prefix of the interval.
+      //
+      // Set does not allow in-place updates due to the potential of violating
+      // its ordering requirements. But increasing the min of the first interval
+      // will not break the ordering, hence the const_cast.
+      const_cast<value_type*>(&(*first_interval))->SetMin(value);
+      break;
+    }
+
+    return num_intervals_trimmed != 0;
+  }
+
+  // Returns true if this QuicIntervalSet is empty.
+  bool Empty() const { return intervals_.empty(); }
+
+  // Returns true if any interval in this QuicIntervalSet contains the indicated
+  // value.
+  bool Contains(const T& value) const;
+
+  // Returns true if there is some interval in this QuicIntervalSet that wholly
+  // contains the given interval. An interval O "wholly contains" a non-empty
+  // interval I if O.Contains(p) is true for every p in I. This is the same
+  // definition used by value_type::Contains(). This method returns false on
+  // the empty interval, due to a (perhaps unintuitive) convention inherited
+  // from value_type.
+  // Example:
+  //   Assume an QuicIntervalSet containing the entries { [10,20), [30,40) }.
+  //   Contains(Interval(15, 16)) returns true, because [10,20) contains
+  //   [15,16). However, Contains(Interval(15, 35)) returns false.
+  bool Contains(const value_type& interval) const;
+
+  // Returns true if for each interval in "other", there is some (possibly
+  // different) interval in this QuicIntervalSet which wholly contains it. See
+  // Contains(const value_type& interval) for the meaning of "wholly contains".
+  // Perhaps unintuitively, this method returns false if "other" is the empty
+  // set. The algorithmic complexity of this method is O(other.Size() *
+  // log(this->Size())). The method could be rewritten to run in O(other.Size()
+  // + this->Size()), and this alternative could be implemented as a free
+  // function using the public API.
+  bool Contains(const QuicIntervalSet<T>& other) const;
+
+  // Returns true if there is some interval in this QuicIntervalSet that wholly
+  // contains the interval [min, max). See Contains(const value_type&).
+  bool Contains(const T& min, const T& max) const {
+    return Contains(value_type(min, max));
+  }
+
+  // Returns true if for some interval in "other", there is some interval in
+  // this QuicIntervalSet that intersects with it. See value_type::Intersects()
+  // for the definition of interval intersection.  Runs in time O(n+m) where n
+  // is the number of intervals in this and m is the number of intervals in
+  // other.
+  bool Intersects(const QuicIntervalSet& other) const;
+
+  // Returns an iterator to the value_type in the QuicIntervalSet that contains
+  // the given value. In other words, returns an iterator to the unique interval
+  // [min, max) in the QuicIntervalSet that has the property min <= value < max.
+  // If there is no such interval, this method returns end().
+  const_iterator Find(const T& value) const;
+
+  // Returns an iterator to the value_type in the QuicIntervalSet that wholly
+  // contains the given interval. In other words, returns an iterator to the
+  // unique interval outer in the QuicIntervalSet that has the property that
+  // outer.Contains(interval). If there is no such interval, or if interval is
+  // empty, returns end().
+  const_iterator Find(const value_type& interval) const;
+
+  // Returns an iterator to the value_type in the QuicIntervalSet that wholly
+  // contains [min, max). In other words, returns an iterator to the unique
+  // interval outer in the QuicIntervalSet that has the property that
+  // outer.Contains(Interval<T>(min, max)). If there is no such interval, or if
+  // interval is empty, returns end().
+  const_iterator Find(const T& min, const T& max) const {
+    return Find(value_type(min, max));
+  }
+
+  // Returns an iterator pointing to the first value_type which contains or
+  // goes after the given value.
+  //
+  // Example:
+  //   [10, 20)  [30, 40)
+  //   ^                    LowerBound(10)
+  //   ^                    LowerBound(15)
+  //             ^          LowerBound(20)
+  //             ^          LowerBound(25)
+  const_iterator LowerBound(const T& value) const;
+
+  // Returns an iterator pointing to the first value_type which goes after
+  // the given value.
+  //
+  // Example:
+  //   [10, 20)  [30, 40)
+  //             ^          UpperBound(10)
+  //             ^          UpperBound(15)
+  //             ^          UpperBound(20)
+  //             ^          UpperBound(25)
+  const_iterator UpperBound(const T& value) const;
+
+  // Returns true if every value within the passed interval is not Contained
+  // within the QuicIntervalSet.
+  // Note that empty intervals are always considered disjoint from the
+  // QuicIntervalSet (even though the QuicIntervalSet doesn't `Contain` them).
+  bool IsDisjoint(const value_type& interval) const;
+
+  // Merges all the values contained in "other" into this QuicIntervalSet.
+  //
+  // Performance: Let n == Size() and m = other.Size().  Union() runs in O(m)
+  // Set operations, so that if Set is a tree, it runs in time O(m log(n+m)) and
+  // if Set is a flat_set it runs in time O(m(n+m)).  In principle, for the
+  // flat_set, we should be able to make this run in time O(n+m).
+  //
+  // TODO(bradleybear): Make Union() run in time O(n+m) for flat_set.  This may
+  // require an additional template parameter to indicate that the Set is a
+  // linear-time data structure instead of a log-time data structure.
+  void Union(const QuicIntervalSet& other);
+
+  // Modifies this QuicIntervalSet so that it contains only those values that
+  // are currently present both in *this and in the QuicIntervalSet "other".
+  void Intersection(const QuicIntervalSet& other);
+
+  // Mutates this QuicIntervalSet so that it contains only those values that are
+  // currently in *this but not in "interval".
+  void Difference(const value_type& interval);
+
+  // Mutates this QuicIntervalSet so that it contains only those values that are
+  // currently in *this but not in the interval [min, max).
+  void Difference(const T& min, const T& max);
+
+  // Mutates this QuicIntervalSet so that it contains only those values that are
+  // currently in *this but not in the QuicIntervalSet "other".  Runs in time
+  // O(n+m) where n is this->Size(), m is other.Size(), regardless of whether
+  // the Set is a flat_set or a std::set.
+  void Difference(const QuicIntervalSet& other);
+
+  // Mutates this QuicIntervalSet so that it contains only those values that are
+  // in [min, max) but not currently in *this.
+  void Complement(const T& min, const T& max);
+
+  // QuicIntervalSet's begin() iterator. The invariants of QuicIntervalSet
+  // guarantee that for each entry e in the set, e.min() < e.max() (because the
+  // entries are non-empty) and for each entry f that appears later in the set,
+  // e.max() < f.min() (because the entries are ordered, pairwise-disjoint, and
+  // non-adjacent). Modifications to this QuicIntervalSet invalidate these
+  // iterators.
+  const_iterator begin() const { return intervals_.begin(); }
+
+  // QuicIntervalSet's end() iterator.
+  const_iterator end() const { return intervals_.end(); }
+
+  // QuicIntervalSet's rbegin() and rend() iterators. Iterator invalidation
+  // semantics are the same as those for begin() / end().
+  const_reverse_iterator rbegin() const { return intervals_.rbegin(); }
+
+  const_reverse_iterator rend() const { return intervals_.rend(); }
+
+  template <typename Iter>
+  void assign(Iter first, Iter last) {
+    Clear();
+    for (; first != last; ++first)
+      Add(*first);
+  }
+
+  void assign(std::initializer_list<value_type> il) {
+    assign(il.begin(), il.end());
+  }
+
+  // Returns a human-readable representation of this set. This will typically be
+  // (though is not guaranteed to be) of the form
+  //   "[a1, b1) [a2, b2) ... [an, bn)"
+  // where the intervals are in the same order as given by traversal from
+  // begin() to end(). This representation is intended for human consumption;
+  // computer programs should not rely on the output being in exactly this form.
+  std::string ToString() const;
+
+  QuicIntervalSet& operator=(std::initializer_list<value_type> il) {
+    assign(il.begin(), il.end());
+    return *this;
+  }
+
+  friend bool operator==(const QuicIntervalSet& a, const QuicIntervalSet& b) {
+    return a.Size() == b.Size() &&
+           std::equal(a.begin(), a.end(), b.begin(), NonemptyIntervalEq());
+  }
+
+  friend bool operator!=(const QuicIntervalSet& a, const QuicIntervalSet& b) {
+    return !(a == b);
+  }
+
+ private:
+  // Simple member-wise equality, since all intervals are non-empty.
+  struct QUIC_NO_EXPORT NonemptyIntervalEq {
+    bool operator()(const value_type& a, const value_type& b) const {
+      return a.min() == b.min() && a.max() == b.max();
+    }
+  };
+
+  // Returns true if this set is valid (i.e. all intervals in it are non-empty,
+  // non-adjacent, and mutually disjoint). Currently this is used as an
+  // integrity check by the Intersection() and Difference() methods, but is only
+  // invoked for debug builds (via QUICHE_DCHECK).
+  bool Valid() const;
+
+  // Finds the first interval that potentially intersects 'other'.
+  const_iterator FindIntersectionCandidate(const QuicIntervalSet& other) const;
+
+  // Finds the first interval that potentially intersects 'interval'.  More
+  // precisely, return an interator it pointing at the last interval J such that
+  // interval <= J.  If all the intervals are > J then return begin().
+  const_iterator FindIntersectionCandidate(const value_type& interval) const;
+
+  // Helper for Intersection() and Difference(): Finds the next pair of
+  // intervals from 'x' and 'y' that intersect. 'mine' is an iterator
+  // over x->intervals_. 'theirs' is an iterator over y.intervals_. 'mine'
+  // and 'theirs' are advanced until an intersecting pair is found.
+  // Non-intersecting intervals (aka "holes") from x->intervals_ can be
+  // optionally erased by "on_hole". "on_hole" must return an iterator to the
+  // first element in 'x' after the hole, or x->intervals_.end() if no elements
+  // exist after the hole.
+  template <typename X, typename Func>
+  static bool FindNextIntersectingPairImpl(X* x,
+                                           const QuicIntervalSet& y,
+                                           const_iterator* mine,
+                                           const_iterator* theirs,
+                                           Func on_hole);
+
+  // The variant of the above method that doesn't mutate this QuicIntervalSet.
+  bool FindNextIntersectingPair(const QuicIntervalSet& other,
+                                const_iterator* mine,
+                                const_iterator* theirs) const {
+    return FindNextIntersectingPairImpl(
+        this, other, mine, theirs,
+        [](const QuicIntervalSet*, const_iterator, const_iterator end) {
+          return end;
+        });
+  }
+
+  // The variant of the above method that mutates this QuicIntervalSet by
+  // erasing holes.
+  bool FindNextIntersectingPairAndEraseHoles(const QuicIntervalSet& other,
+                                             const_iterator* mine,
+                                             const_iterator* theirs) {
+    return FindNextIntersectingPairImpl(
+        this, other, mine, theirs,
+        [](QuicIntervalSet* x, const_iterator from, const_iterator to) {
+          return x->intervals_.erase(from, to);
+        });
+  }
+
+  // The representation for the intervals. The intervals in this set are
+  // non-empty, pairwise-disjoint, non-adjacent and ordered in ascending order
+  // by min().
+  Set intervals_;
+};
+
+template <typename T>
+auto operator<<(std::ostream& out, const QuicIntervalSet<T>& seq)
+    -> decltype(out << *seq.begin()) {
+  out << "{";
+  for (const auto& interval : seq) {
+    out << " " << interval;
+  }
+  out << " }";
+
+  return out;
+}
+
+//==============================================================================
+// Implementation details: Clients can stop reading here.
+
+template <typename T>
+typename QuicIntervalSet<T>::value_type QuicIntervalSet<T>::SpanningInterval()
+    const {
+  value_type result;
+  if (!intervals_.empty()) {
+    result.SetMin(intervals_.begin()->min());
+    result.SetMax(intervals_.rbegin()->max());
+  }
+  return result;
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Add(const value_type& interval) {
+  if (interval.Empty())
+    return;
+  const_iterator it = intervals_.lower_bound(interval.min());
+  value_type the_union = interval;
+  if (it != intervals_.begin()) {
+    --it;
+    if (it->Separated(the_union)) {
+      ++it;
+    }
+  }
+  // Don't erase the elements one at a time, since that will produce quadratic
+  // work on a flat_set, and apparently an extra log-factor of work for a
+  // tree-based set.  Instead identify the first and last intervals that need to
+  // be erased, and call erase only once.
+  const_iterator start = it;
+  while (it != intervals_.end() && !it->Separated(the_union)) {
+    the_union.SpanningUnion(*it);
+    ++it;
+  }
+  intervals_.erase(start, it);
+  intervals_.insert(the_union);
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Contains(const T& value) const {
+  // Find the first interval with min() > value, then move back one step
+  const_iterator it = intervals_.upper_bound(value);
+  if (it == intervals_.begin())
+    return false;
+  --it;
+  return it->Contains(value);
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Contains(const value_type& interval) const {
+  // Find the first interval with min() > value, then move back one step.
+  const_iterator it = intervals_.upper_bound(interval.min());
+  if (it == intervals_.begin())
+    return false;
+  --it;
+  return it->Contains(interval);
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Contains(const QuicIntervalSet<T>& other) const {
+  if (!SpanningInterval().Contains(other.SpanningInterval())) {
+    return false;
+  }
+
+  for (const_iterator i = other.begin(); i != other.end(); ++i) {
+    // If we don't contain the interval, can return false now.
+    if (!Contains(*i)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// This method finds the interval that Contains() "value", if such an interval
+// exists in the QuicIntervalSet. The way this is done is to locate the
+// "candidate interval", the only interval that could *possibly* contain value,
+// and test it using Contains(). The candidate interval is the interval with the
+// largest min() having min() <= value.
+//
+// Another detail involves the choice of which Set method to use to try to find
+// the candidate interval. The most appropriate entry point is
+// Set::upper_bound(), which finds the least interval with a min > the
+// value. The semantics of upper_bound() are slightly different from what we
+// want (namely, to find the greatest interval which is <= the probe interval)
+// but they are close enough; the interval found by upper_bound() will always be
+// one step past the interval we are looking for (if it exists) or at begin()
+// (if it does not). Getting to the proper interval is a simple matter of
+// decrementing the iterator.
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::Find(
+    const T& value) const {
+  const_iterator it = intervals_.upper_bound(value);
+  if (it == intervals_.begin())
+    return intervals_.end();
+  --it;
+  if (it->Contains(value))
+    return it;
+  else
+    return intervals_.end();
+}
+
+// This method finds the interval that Contains() the interval "probe", if such
+// an interval exists in the QuicIntervalSet. The way this is done is to locate
+// the "candidate interval", the only interval that could *possibly* contain
+// "probe", and test it using Contains().  We use the same algorithm as for
+// Find(value), except that instead of checking that the value is contained, we
+// check that the probe is contained.
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::Find(
+    const value_type& probe) const {
+  const_iterator it = intervals_.upper_bound(probe.min());
+  if (it == intervals_.begin())
+    return intervals_.end();
+  --it;
+  if (it->Contains(probe))
+    return it;
+  else
+    return intervals_.end();
+}
+
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::LowerBound(
+    const T& value) const {
+  const_iterator it = intervals_.lower_bound(value);
+  if (it == intervals_.begin()) {
+    return it;
+  }
+
+  // The previous intervals_.lower_bound() checking is essentially based on
+  // interval.min(), so we need to check whether the `value` is contained in
+  // the previous interval.
+  --it;
+  if (it->Contains(value)) {
+    return it;
+  } else {
+    return ++it;
+  }
+}
+
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::UpperBound(
+    const T& value) const {
+  return intervals_.upper_bound(value);
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::IsDisjoint(const value_type& interval) const {
+  if (interval.Empty())
+    return true;
+  // Find the first interval with min() > interval.min()
+  const_iterator it = intervals_.upper_bound(interval.min());
+  if (it != intervals_.end() && interval.max() > it->min())
+    return false;
+  if (it == intervals_.begin())
+    return true;
+  --it;
+  return it->max() <= interval.min();
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Union(const QuicIntervalSet& other) {
+  for (const value_type& interval : other.intervals_) {
+    Add(interval);
+  }
+}
+
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator
+QuicIntervalSet<T>::FindIntersectionCandidate(
+    const QuicIntervalSet& other) const {
+  return FindIntersectionCandidate(*other.intervals_.begin());
+}
+
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator
+QuicIntervalSet<T>::FindIntersectionCandidate(
+    const value_type& interval) const {
+  // Use upper_bound to efficiently find the first interval in intervals_
+  // where min() is greater than interval.min().  If the result
+  // isn't the beginning of intervals_ then move backwards one interval since
+  // the interval before it is the first candidate where max() may be
+  // greater than interval.min().
+  // In other words, no interval before that can possibly intersect with any
+  // of other.intervals_.
+  const_iterator mine = intervals_.upper_bound(interval.min());
+  if (mine != intervals_.begin()) {
+    --mine;
+  }
+  return mine;
+}
+
+template <typename T>
+template <typename X, typename Func>
+bool QuicIntervalSet<T>::FindNextIntersectingPairImpl(X* x,
+                                                      const QuicIntervalSet& y,
+                                                      const_iterator* mine,
+                                                      const_iterator* theirs,
+                                                      Func on_hole) {
+  QUICHE_CHECK(x != nullptr);
+  if ((*mine == x->intervals_.end()) || (*theirs == y.intervals_.end())) {
+    return false;
+  }
+  while (!(**mine).Intersects(**theirs)) {
+    const_iterator erase_first = *mine;
+    // Skip over intervals in 'mine' that don't reach 'theirs'.
+    while (*mine != x->intervals_.end() && (**mine).max() <= (**theirs).min()) {
+      ++(*mine);
+    }
+    *mine = on_hole(x, erase_first, *mine);
+    // We're done if the end of intervals_ is reached.
+    if (*mine == x->intervals_.end()) {
+      return false;
+    }
+    // Skip over intervals 'theirs' that don't reach 'mine'.
+    while (*theirs != y.intervals_.end() &&
+           (**theirs).max() <= (**mine).min()) {
+      ++(*theirs);
+    }
+    // If the end of other.intervals_ is reached, we're done.
+    if (*theirs == y.intervals_.end()) {
+      on_hole(x, *mine, x->intervals_.end());
+      return false;
+    }
+  }
+  return true;
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Intersection(const QuicIntervalSet& other) {
+  if (!SpanningInterval().Intersects(other.SpanningInterval())) {
+    intervals_.clear();
+    return;
+  }
+
+  const_iterator mine = FindIntersectionCandidate(other);
+  // Remove any intervals that cannot possibly intersect with other.intervals_.
+  mine = intervals_.erase(intervals_.begin(), mine);
+  const_iterator theirs = other.FindIntersectionCandidate(*this);
+
+  while (FindNextIntersectingPairAndEraseHoles(other, &mine, &theirs)) {
+    // OK, *mine and *theirs intersect.  Now, we find the largest
+    // span of intervals in other (starting at theirs) - say [a..b]
+    // - that intersect *mine, and we replace *mine with (*mine
+    // intersect x) for all x in [a..b] Note that subsequent
+    // intervals in this can't intersect any intervals in [a..b) --
+    // they may only intersect b or subsequent intervals in other.
+    value_type i(*mine);
+    intervals_.erase(mine);
+    mine = intervals_.end();
+    value_type intersection;
+    while (theirs != other.intervals_.end() &&
+           i.Intersects(*theirs, &intersection)) {
+      std::pair<const_iterator, bool> ins = intervals_.insert(intersection);
+      QUICHE_DCHECK(ins.second);
+      mine = ins.first;
+      ++theirs;
+    }
+    QUICHE_DCHECK(mine != intervals_.end());
+    --theirs;
+    ++mine;
+  }
+  QUICHE_DCHECK(Valid());
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Intersects(const QuicIntervalSet& other) const {
+  // Don't bother to handle nonoverlapping spanning intervals as a special case.
+  // This code runs in time O(n+m), as guaranteed, even for that case .
+  // Handling the nonoverlapping spanning intervals as a special case doesn't
+  // improve the asymptotics but does make the code more complex.
+  auto mine = intervals_.begin();
+  auto theirs = other.intervals_.begin();
+  while (mine != intervals_.end() && theirs != other.intervals_.end()) {
+    if (mine->Intersects(*theirs))
+      return true;
+    else if (*mine < *theirs)
+      ++mine;
+    else
+      ++theirs;
+  }
+  return false;
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Difference(const value_type& interval) {
+  if (!SpanningInterval().Intersects(interval)) {
+    return;
+  }
+  Difference(QuicIntervalSet<T>(interval));
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Difference(const T& min, const T& max) {
+  Difference(value_type(min, max));
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Difference(const QuicIntervalSet& other) {
+  // In order to avoid quadratic-time when using a flat set, we don't try to
+  // update intervals_ in place.  Instead we build up a new result_, always
+  // inserting at the end which is O(1) time per insertion.  Since the number of
+  // elements in the result is O(Size() + other.Size()), the cost for all the
+  // insertions is also O(Size() + other.Size()).
+  //
+  // We look at all the elements of intervals_, so that's O(Size()).
+  //
+  // We also look at all the elements of other.intervals_, for O(other.Size()).
+  if (Empty())
+    return;
+  Set result;
+  const_iterator mine = intervals_.begin();
+  value_type myinterval = *mine;
+  const_iterator theirs = other.intervals_.begin();
+  while (mine != intervals_.end()) {
+    // Loop invariants:
+    //   myinterval is nonempty.
+    //   mine points at a range that is a suffix of myinterval.
+    QUICHE_DCHECK(!myinterval.Empty());
+    QUICHE_DCHECK(myinterval.max() == mine->max());
+
+    // There are 3 cases.
+    //  myinterval is completely before theirs (treat theirs==end() as if it is
+    //  infinity).
+    //    --> consume myinterval into result.
+    //  myinterval is completely after theirs
+    //    --> theirs can no longer affect us, so ++theirs.
+    //  myinterval touches theirs with a prefix of myinterval not touching
+    //  *theirs.
+    //    --> consume the prefix of myinterval into the result.
+    //  myinterval touches theirs, with the first element of myinterval in
+    //  *theirs.
+    //    -> reduce myinterval
+    if (theirs == other.intervals_.end() || myinterval.max() <= theirs->min()) {
+      // Keep all of my_interval.
+      result.insert(result.end(), myinterval);
+      myinterval.Clear();
+    } else if (theirs->max() <= myinterval.min()) {
+      ++theirs;
+    } else if (myinterval.min() < theirs->min()) {
+      // Keep a nonempty prefix of my interval.
+      result.insert(result.end(), value_type(myinterval.min(), theirs->min()));
+      myinterval.SetMin(theirs->max());
+    } else {
+      // myinterval starts at or after *theirs, chop down myinterval.
+      myinterval.SetMin(theirs->max());
+    }
+    // if myinterval became empty, find the next interval
+    if (myinterval.Empty()) {
+      ++mine;
+      if (mine != intervals_.end()) {
+        myinterval = *mine;
+      }
+    }
+  }
+  std::swap(result, intervals_);
+  QUICHE_DCHECK(Valid());
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Complement(const T& min, const T& max) {
+  QuicIntervalSet<T> span(min, max);
+  span.Difference(*this);
+  intervals_.swap(span.intervals_);
+}
+
+template <typename T>
+std::string QuicIntervalSet<T>::ToString() const {
+  std::ostringstream os;
+  os << *this;
+  return os.str();
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Valid() const {
+  const_iterator prev = end();
+  for (const_iterator it = begin(); it != end(); ++it) {
+    // invalid or empty interval.
+    if (it->min() >= it->max())
+      return false;
+    // Not sorted, not disjoint, or adjacent.
+    if (prev != end() && prev->max() >= it->min())
+      return false;
+    prev = it;
+  }
+  return true;
+}
+
+// This comparator orders intervals first by ascending min().  The Set never
+// contains overlapping intervals, so that suffices.
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
+                                                  const value_type& b) const {
+  // This overload is probably used only by Set::insert().
+  return a.min() < b.min();
+}
+
+// It appears that the Set::lower_bound(T) method uses only two overloads of the
+// comparison operator that take a T as the second argument..  In contrast
+// Set::upper_bound(T) uses the two overloads that take T as the first argument.
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
+                                                  const T& point) const {
+  // Compare an interval to a point.
+  return a.min() < point;
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
+                                                  T&& point) const {
+  // Compare an interval to a point
+  return a.min() < point;
+}
+
+// It appears that the Set::upper_bound(T) method uses only the next two
+// overloads of the comparison operator.
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(const T& point,
+                                                  const value_type& a) const {
+  // Compare an interval to a point.
+  return point < a.min();
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(T&& point,
+                                                  const value_type& a) const {
+  // Compare an interval to a point.
+  return point < a.min();
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
diff --git a/quiche/quic/core/quic_interval_set_test.cc b/quiche/quic/core/quic_interval_set_test.cc
new file mode 100644
index 0000000..fca037d
--- /dev/null
+++ b/quiche/quic/core/quic_interval_set_test.cc
@@ -0,0 +1,1071 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_interval_set.h"
+
+#include <stdarg.h>
+
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <limits>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::ElementsAreArray;
+
+class QuicIntervalSetTest : public QuicTest {
+ protected:
+  virtual void SetUp() {
+    // Initialize two QuicIntervalSets for union, intersection, and difference
+    // tests
+    is.Add(100, 200);
+    is.Add(300, 400);
+    is.Add(500, 600);
+    is.Add(700, 800);
+    is.Add(900, 1000);
+    is.Add(1100, 1200);
+    is.Add(1300, 1400);
+    is.Add(1500, 1600);
+    is.Add(1700, 1800);
+    is.Add(1900, 2000);
+    is.Add(2100, 2200);
+
+    // Lots of different cases:
+    other.Add(50, 70);      // disjoint, at the beginning
+    other.Add(2250, 2270);  // disjoint, at the end
+    other.Add(650, 670);    // disjoint, in the middle
+    other.Add(350, 360);    // included
+    other.Add(370, 380);    // also included (two at once)
+    other.Add(470, 530);    // overlaps low end
+    other.Add(770, 830);    // overlaps high end
+    other.Add(870, 900);    // meets at low end
+    other.Add(1200, 1230);  // meets at high end
+    other.Add(1270, 1830);  // overlaps multiple ranges
+  }
+
+  virtual void TearDown() {
+    is.Clear();
+    EXPECT_TRUE(is.Empty());
+    other.Clear();
+    EXPECT_TRUE(other.Empty());
+  }
+  QuicIntervalSet<int> is;
+  QuicIntervalSet<int> other;
+};
+
+TEST_F(QuicIntervalSetTest, IsDisjoint) {
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(0, 99)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(0, 100)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 200)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 299)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(400, 407)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(405, 499)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(2300, 2300)));
+  EXPECT_TRUE(
+      is.IsDisjoint(QuicInterval<int>(2300, std::numeric_limits<int>::max())));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(100, 105)));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(199, 300)));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(250, 450)));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(299, 400)));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(250, 2000)));
+  EXPECT_FALSE(
+      is.IsDisjoint(QuicInterval<int>(2199, std::numeric_limits<int>::max())));
+  // Empty intervals.
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(90, 90)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(100, 100)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(100, 90)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(150, 150)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 200)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(400, 300)));
+}
+
+// Base helper method for verifying the contents of an interval set.
+// Returns true iff <is> contains <count> intervals whose successive
+// endpoints match the sequence of args in <ap>:
+static bool VA_Check(const QuicIntervalSet<int>& is, int count, va_list ap) {
+  std::vector<QuicInterval<int>> intervals(is.begin(), is.end());
+  if (count != static_cast<int>(intervals.size())) {
+    QUIC_LOG(ERROR) << "Expected " << count << " intervals, got "
+                    << intervals.size() << ": " << is;
+    return false;
+  }
+  if (count != static_cast<int>(is.Size())) {
+    QUIC_LOG(ERROR) << "Expected " << count << " intervals, got Size "
+                    << is.Size() << ": " << is;
+    return false;
+  }
+  bool result = true;
+  for (int i = 0; i < count; i++) {
+    int min = va_arg(ap, int);
+    int max = va_arg(ap, int);
+    if (min != intervals[i].min() || max != intervals[i].max()) {
+      QUIC_LOG(ERROR) << "Expected: [" << min << ", " << max << ") got "
+                      << intervals[i] << " in " << is;
+      result = false;
+    }
+  }
+  return result;
+}
+
+static bool Check(const QuicIntervalSet<int>& is, int count, ...) {
+  va_list ap;
+  va_start(ap, count);
+  const bool result = VA_Check(is, count, ap);
+  va_end(ap);
+  return result;
+}
+
+// Some helper functions for testing Contains and Find, which are logically the
+// same.
+static void TestContainsAndFind(const QuicIntervalSet<int>& is, int value) {
+  EXPECT_TRUE(is.Contains(value)) << "Set does not contain " << value;
+  auto it = is.Find(value);
+  EXPECT_NE(it, is.end()) << "No iterator to interval containing " << value;
+  EXPECT_TRUE(it->Contains(value)) << "Iterator does not contain " << value;
+}
+
+static void TestContainsAndFind(const QuicIntervalSet<int>& is,
+                                int min,
+                                int max) {
+  EXPECT_TRUE(is.Contains(min, max))
+      << "Set does not contain interval with min " << min << "and max " << max;
+  auto it = is.Find(min, max);
+  EXPECT_NE(it, is.end()) << "No iterator to interval with min " << min
+                          << "and max " << max;
+  EXPECT_TRUE(it->Contains(QuicInterval<int>(min, max)))
+      << "Iterator does not contain interval with min " << min << "and max "
+      << max;
+}
+
+static void TestNotContainsAndFind(const QuicIntervalSet<int>& is, int value) {
+  EXPECT_FALSE(is.Contains(value)) << "Set contains " << value;
+  auto it = is.Find(value);
+  EXPECT_EQ(it, is.end()) << "There is iterator to interval containing "
+                          << value;
+}
+
+static void TestNotContainsAndFind(const QuicIntervalSet<int>& is,
+                                   int min,
+                                   int max) {
+  EXPECT_FALSE(is.Contains(min, max))
+      << "Set contains interval with min " << min << "and max " << max;
+  auto it = is.Find(min, max);
+  EXPECT_EQ(it, is.end()) << "There is iterator to interval with min " << min
+                          << "and max " << max;
+}
+
+TEST_F(QuicIntervalSetTest, AddInterval) {
+  QuicIntervalSet<int> s;
+  s.Add(QuicInterval<int>(0, 10));
+  EXPECT_TRUE(Check(s, 1, 0, 10));
+}
+
+TEST_F(QuicIntervalSetTest, DecrementIterator) {
+  auto it = is.end();
+  EXPECT_NE(it, is.begin());
+  --it;
+  EXPECT_EQ(*it, QuicInterval<int>(2100, 2200));
+  ++it;
+  EXPECT_EQ(it, is.end());
+}
+
+TEST_F(QuicIntervalSetTest, AddOptimizedForAppend) {
+  QuicIntervalSet<int> empty_one, empty_two;
+  empty_one.AddOptimizedForAppend(QuicInterval<int>(0, 99));
+  EXPECT_TRUE(Check(empty_one, 1, 0, 99));
+
+  empty_two.AddOptimizedForAppend(1, 50);
+  EXPECT_TRUE(Check(empty_two, 1, 1, 50));
+
+  QuicIntervalSet<int> iset;
+  iset.AddOptimizedForAppend(100, 150);
+  iset.AddOptimizedForAppend(200, 250);
+  EXPECT_TRUE(Check(iset, 2, 100, 150, 200, 250));
+
+  iset.AddOptimizedForAppend(199, 200);
+  EXPECT_TRUE(Check(iset, 2, 100, 150, 199, 250));
+
+  iset.AddOptimizedForAppend(251, 260);
+  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 260));
+
+  iset.AddOptimizedForAppend(252, 260);
+  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 260));
+
+  iset.AddOptimizedForAppend(252, 300);
+  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 300));
+
+  iset.AddOptimizedForAppend(300, 350);
+  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 350));
+}
+
+TEST_F(QuicIntervalSetTest, PopFront) {
+  QuicIntervalSet<int> iset{{100, 200}, {400, 500}, {700, 800}};
+  EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
+
+  iset.PopFront();
+  EXPECT_TRUE(Check(iset, 2, 400, 500, 700, 800));
+
+  iset.PopFront();
+  EXPECT_TRUE(Check(iset, 1, 700, 800));
+
+  iset.PopFront();
+  EXPECT_TRUE(iset.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, TrimLessThan) {
+  QuicIntervalSet<int> iset{{100, 200}, {400, 500}, {700, 800}};
+  EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
+
+  EXPECT_FALSE(iset.TrimLessThan(99));
+  EXPECT_FALSE(iset.TrimLessThan(100));
+  EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(101));
+  EXPECT_TRUE(Check(iset, 3, 101, 200, 400, 500, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(199));
+  EXPECT_TRUE(Check(iset, 3, 199, 200, 400, 500, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(450));
+  EXPECT_TRUE(Check(iset, 2, 450, 500, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(500));
+  EXPECT_TRUE(Check(iset, 1, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(801));
+  EXPECT_TRUE(iset.Empty());
+
+  EXPECT_FALSE(iset.TrimLessThan(900));
+  EXPECT_TRUE(iset.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetBasic) {
+  // Test Add, Get, Contains and Find
+  QuicIntervalSet<int> iset;
+  EXPECT_TRUE(iset.Empty());
+  EXPECT_EQ(0u, iset.Size());
+  iset.Add(100, 200);
+  EXPECT_FALSE(iset.Empty());
+  EXPECT_EQ(1u, iset.Size());
+  iset.Add(100, 150);
+  iset.Add(150, 200);
+  iset.Add(130, 170);
+  iset.Add(90, 150);
+  iset.Add(170, 220);
+  iset.Add(300, 400);
+  iset.Add(250, 450);
+  EXPECT_FALSE(iset.Empty());
+  EXPECT_EQ(2u, iset.Size());
+  EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450));
+
+  // Test two intervals with a.max == b.min, that will just join up.
+  iset.Clear();
+  iset.Add(100, 200);
+  iset.Add(200, 300);
+  EXPECT_FALSE(iset.Empty());
+  EXPECT_EQ(1u, iset.Size());
+  EXPECT_TRUE(Check(iset, 1, 100, 300));
+
+  // Test adding two sets together.
+  iset.Clear();
+  QuicIntervalSet<int> iset_add;
+  iset.Add(100, 200);
+  iset.Add(100, 150);
+  iset.Add(150, 200);
+  iset.Add(130, 170);
+  iset_add.Add(90, 150);
+  iset_add.Add(170, 220);
+  iset_add.Add(300, 400);
+  iset_add.Add(250, 450);
+
+  iset.Union(iset_add);
+  EXPECT_FALSE(iset.Empty());
+  EXPECT_EQ(2u, iset.Size());
+  EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450));
+
+  // Test begin()/end(), and rbegin()/rend()
+  // to iterate over intervals.
+  {
+    std::vector<QuicInterval<int>> expected(iset.begin(), iset.end());
+
+    std::vector<QuicInterval<int>> actual1;
+    std::copy(iset.begin(), iset.end(), back_inserter(actual1));
+    ASSERT_EQ(expected.size(), actual1.size());
+
+    std::vector<QuicInterval<int>> actual2;
+    std::copy(iset.begin(), iset.end(), back_inserter(actual2));
+    ASSERT_EQ(expected.size(), actual2.size());
+
+    for (size_t i = 0; i < expected.size(); i++) {
+      EXPECT_EQ(expected[i].min(), actual1[i].min());
+      EXPECT_EQ(expected[i].max(), actual1[i].max());
+
+      EXPECT_EQ(expected[i].min(), actual2[i].min());
+      EXPECT_EQ(expected[i].max(), actual2[i].max());
+    }
+
+    // Ensure that the rbegin()/rend() iterators correctly yield the intervals
+    // in reverse order.
+    EXPECT_THAT(std::vector<QuicInterval<int>>(iset.rbegin(), iset.rend()),
+                ElementsAreArray(expected.rbegin(), expected.rend()));
+  }
+
+  TestNotContainsAndFind(iset, 89);
+  TestContainsAndFind(iset, 90);
+  TestContainsAndFind(iset, 120);
+  TestContainsAndFind(iset, 219);
+  TestNotContainsAndFind(iset, 220);
+  TestNotContainsAndFind(iset, 235);
+  TestNotContainsAndFind(iset, 249);
+  TestContainsAndFind(iset, 250);
+  TestContainsAndFind(iset, 300);
+  TestContainsAndFind(iset, 449);
+  TestNotContainsAndFind(iset, 450);
+  TestNotContainsAndFind(iset, 451);
+
+  TestNotContainsAndFind(iset, 50, 60);
+  TestNotContainsAndFind(iset, 50, 90);
+  TestNotContainsAndFind(iset, 50, 200);
+  TestNotContainsAndFind(iset, 90, 90);
+  TestContainsAndFind(iset, 90, 200);
+  TestContainsAndFind(iset, 100, 200);
+  TestContainsAndFind(iset, 100, 220);
+  TestNotContainsAndFind(iset, 100, 221);
+  TestNotContainsAndFind(iset, 220, 220);
+  TestNotContainsAndFind(iset, 240, 300);
+  TestContainsAndFind(iset, 250, 300);
+  TestContainsAndFind(iset, 260, 300);
+  TestContainsAndFind(iset, 300, 450);
+  TestNotContainsAndFind(iset, 300, 451);
+
+  QuicIntervalSet<int> iset_contains;
+  iset_contains.Add(50, 90);
+  EXPECT_FALSE(iset.Contains(iset_contains));
+  iset_contains.Clear();
+
+  iset_contains.Add(90, 200);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(100, 200);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(100, 220);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(250, 300);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(300, 450);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(300, 451);
+  EXPECT_FALSE(iset.Contains(iset_contains));
+  EXPECT_FALSE(iset.Contains(QuicInterval<int>()));
+  EXPECT_FALSE(iset.Contains(QuicIntervalSet<int>()));
+
+  // Check the case where the query set isn't contained, but the spanning
+  // intervals do overlap.
+  QuicIntervalSet<int> i2({{220, 230}});
+  EXPECT_FALSE(iset.Contains(i2));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetContainsEmpty) {
+  const QuicIntervalSet<int> empty;
+  const QuicIntervalSet<int> other_empty;
+  const QuicIntervalSet<int> non_empty({{10, 20}, {40, 50}});
+  EXPECT_FALSE(empty.Contains(empty));
+  EXPECT_FALSE(empty.Contains(other_empty));
+  EXPECT_FALSE(empty.Contains(non_empty));
+  EXPECT_FALSE(non_empty.Contains(empty));
+}
+
+TEST_F(QuicIntervalSetTest, Equality) {
+  QuicIntervalSet<int> is_copy = is;
+  EXPECT_EQ(is, is);
+  EXPECT_EQ(is, is_copy);
+  EXPECT_NE(is, other);
+  EXPECT_NE(is, QuicIntervalSet<int>());
+  EXPECT_EQ(QuicIntervalSet<int>(), QuicIntervalSet<int>());
+}
+
+TEST_F(QuicIntervalSetTest, LowerAndUpperBound) {
+  QuicIntervalSet<int> intervals;
+  intervals.Add(10, 20);
+  intervals.Add(30, 40);
+
+  //   [10, 20)  [30, 40)  end
+  //   ^                        LowerBound(5)
+  //   ^                        LowerBound(10)
+  //   ^                        LowerBound(15)
+  //             ^              LowerBound(20)
+  //             ^              LowerBound(25)
+  //             ^              LowerBound(30)
+  //             ^              LowerBound(35)
+  //                       ^    LowerBound(40)
+  //                       ^    LowerBound(50)
+  EXPECT_EQ(intervals.LowerBound(5)->min(), 10);
+  EXPECT_EQ(intervals.LowerBound(10)->min(), 10);
+  EXPECT_EQ(intervals.LowerBound(15)->min(), 10);
+  EXPECT_EQ(intervals.LowerBound(20)->min(), 30);
+  EXPECT_EQ(intervals.LowerBound(25)->min(), 30);
+  EXPECT_EQ(intervals.LowerBound(30)->min(), 30);
+  EXPECT_EQ(intervals.LowerBound(35)->min(), 30);
+  EXPECT_EQ(intervals.LowerBound(40), intervals.end());
+  EXPECT_EQ(intervals.LowerBound(50), intervals.end());
+
+  //   [10, 20)  [30, 40)  end
+  //   ^                        UpperBound(5)
+  //             ^              UpperBound(10)
+  //             ^              UpperBound(15)
+  //             ^              UpperBound(20)
+  //             ^              UpperBound(25)
+  //                       ^    UpperBound(30)
+  //                       ^    UpperBound(35)
+  //                       ^    UpperBound(40)
+  //                       ^    UpperBound(50)
+  EXPECT_EQ(intervals.UpperBound(5)->min(), 10);
+  EXPECT_EQ(intervals.UpperBound(10)->min(), 30);
+  EXPECT_EQ(intervals.UpperBound(15)->min(), 30);
+  EXPECT_EQ(intervals.UpperBound(20)->min(), 30);
+  EXPECT_EQ(intervals.UpperBound(25)->min(), 30);
+  EXPECT_EQ(intervals.UpperBound(30), intervals.end());
+  EXPECT_EQ(intervals.UpperBound(35), intervals.end());
+  EXPECT_EQ(intervals.UpperBound(40), intervals.end());
+  EXPECT_EQ(intervals.UpperBound(50), intervals.end());
+}
+
+TEST_F(QuicIntervalSetTest, SpanningInterval) {
+  // Spanning interval of an empty set is empty:
+  {
+    QuicIntervalSet<int> iset;
+    const QuicInterval<int>& ival = iset.SpanningInterval();
+    EXPECT_TRUE(ival.Empty());
+  }
+
+  // Spanning interval of a set with one interval is that interval:
+  {
+    QuicIntervalSet<int> iset;
+    iset.Add(100, 200);
+    const QuicInterval<int>& ival = iset.SpanningInterval();
+    EXPECT_EQ(100, ival.min());
+    EXPECT_EQ(200, ival.max());
+  }
+
+  // Spanning interval of a set with multiple elements is determined
+  // by the endpoints of the first and last element:
+  {
+    const QuicInterval<int>& ival = is.SpanningInterval();
+    EXPECT_EQ(100, ival.min());
+    EXPECT_EQ(2200, ival.max());
+  }
+  {
+    const QuicInterval<int>& ival = other.SpanningInterval();
+    EXPECT_EQ(50, ival.min());
+    EXPECT_EQ(2270, ival.max());
+  }
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetUnion) {
+  is.Union(other);
+  EXPECT_TRUE(Check(is, 12, 50, 70, 100, 200, 300, 400, 470, 600, 650, 670, 700,
+                    830, 870, 1000, 1100, 1230, 1270, 1830, 1900, 2000, 2100,
+                    2200, 2250, 2270));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersection) {
+  EXPECT_TRUE(is.Intersects(other));
+  EXPECT_TRUE(other.Intersects(is));
+  is.Intersection(other);
+  EXPECT_TRUE(Check(is, 7, 350, 360, 370, 380, 500, 530, 770, 800, 1300, 1400,
+                    1500, 1600, 1700, 1800));
+  EXPECT_TRUE(is.Intersects(other));
+  EXPECT_TRUE(other.Intersects(is));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionBothEmpty) {
+  QuicIntervalSet<std::string> mine, theirs;
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionEmptyMine) {
+  QuicIntervalSet<std::string> mine;
+  QuicIntervalSet<std::string> theirs("a", "b");
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionEmptyTheirs) {
+  QuicIntervalSet<std::string> mine("a", "b");
+  QuicIntervalSet<std::string> theirs;
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionTheirsBeforeMine) {
+  QuicIntervalSet<std::string> mine("y", "z");
+  QuicIntervalSet<std::string> theirs;
+  theirs.Add("a", "b");
+  theirs.Add("c", "d");
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionMineBeforeTheirs) {
+  QuicIntervalSet<std::string> mine;
+  mine.Add("a", "b");
+  mine.Add("c", "d");
+  QuicIntervalSet<std::string> theirs("y", "z");
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest,
+       QuicIntervalSetIntersectionTheirsBeforeMineInt64Singletons) {
+  QuicIntervalSet<int64_t> mine({{10, 15}});
+  QuicIntervalSet<int64_t> theirs({{-20, -5}});
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest,
+       QuicIntervalSetIntersectionMineBeforeTheirsIntSingletons) {
+  QuicIntervalSet<int> mine({{10, 15}});
+  QuicIntervalSet<int> theirs({{90, 95}});
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionTheirsBetweenMine) {
+  QuicIntervalSet<int64_t> mine({{0, 5}, {40, 50}});
+  QuicIntervalSet<int64_t> theirs({{10, 15}});
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionMineBetweenTheirs) {
+  QuicIntervalSet<int> mine({{20, 25}});
+  QuicIntervalSet<int> theirs({{10, 15}, {30, 32}});
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionAlternatingIntervals) {
+  QuicIntervalSet<int> mine, theirs;
+  mine.Add(10, 20);
+  mine.Add(40, 50);
+  mine.Add(60, 70);
+  theirs.Add(25, 39);
+  theirs.Add(55, 59);
+  theirs.Add(75, 79);
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest,
+       QuicIntervalSetIntersectionAdjacentAlternatingNonIntersectingIntervals) {
+  // Make sure that intersection with adjacent interval set is empty.
+  const QuicIntervalSet<int> x1({{0, 10}});
+  const QuicIntervalSet<int> y1({{-50, 0}, {10, 95}});
+
+  QuicIntervalSet<int> result1 = x1;
+  result1.Intersection(y1);
+  EXPECT_TRUE(result1.Empty()) << result1;
+
+  const QuicIntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
+  const QuicIntervalSet<int16_t> y2(
+      {{-50, -40}, {-2, 0}, {10, 20}, {32, 40}, {90, 95}});
+
+  QuicIntervalSet<int16_t> result2 = x2;
+  result2.Intersection(y2);
+  EXPECT_TRUE(result2.Empty()) << result2;
+
+  const QuicIntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
+  const QuicIntervalSet<int64_t> y3({{-10, -1}, {10, 95}});
+
+  QuicIntervalSet<int64_t> result3 = x3;
+  result3.Intersection(y3);
+  EXPECT_TRUE(result3.Empty()) << result3;
+}
+
+TEST_F(QuicIntervalSetTest,
+       QuicIntervalSetIntersectionAlternatingIntersectingIntervals) {
+  const QuicIntervalSet<int> x1({{0, 10}});
+  const QuicIntervalSet<int> y1({{-50, 1}, {9, 95}});
+  const QuicIntervalSet<int> expected_result1({{0, 1}, {9, 10}});
+
+  QuicIntervalSet<int> result1 = x1;
+  result1.Intersection(y1);
+  EXPECT_EQ(result1, expected_result1);
+
+  const QuicIntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
+  const QuicIntervalSet<int16_t> y2(
+      {{-50, -40}, {-2, 2}, {9, 21}, {32, 41}, {85, 95}});
+  const QuicIntervalSet<int16_t> expected_result2(
+      {{0, 2}, {9, 10}, {20, 21}, {40, 41}, {85, 90}});
+
+  QuicIntervalSet<int16_t> result2 = x2;
+  result2.Intersection(y2);
+  EXPECT_EQ(result2, expected_result2);
+
+  const QuicIntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
+  const QuicIntervalSet<int64_t> y3({{-10, 3}, {4, 95}});
+  const QuicIntervalSet<int64_t> expected_result3({{-1, 3}, {4, 10}});
+
+  QuicIntervalSet<int64_t> result3 = x3;
+  result3.Intersection(y3);
+  EXPECT_EQ(result3, expected_result3);
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionIdentical) {
+  QuicIntervalSet<int> copy(is);
+  EXPECT_TRUE(copy.Intersects(is));
+  EXPECT_TRUE(is.Intersects(copy));
+  is.Intersection(copy);
+  EXPECT_EQ(copy, is);
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionSuperset) {
+  QuicIntervalSet<int> mine(-1, 10000);
+  EXPECT_TRUE(mine.Intersects(is));
+  EXPECT_TRUE(is.Intersects(mine));
+  mine.Intersection(is);
+  EXPECT_EQ(is, mine);
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionSubset) {
+  QuicIntervalSet<int> copy(is);
+  QuicIntervalSet<int> theirs(-1, 10000);
+  EXPECT_TRUE(copy.Intersects(theirs));
+  EXPECT_TRUE(theirs.Intersects(copy));
+  is.Intersection(theirs);
+  EXPECT_EQ(copy, is);
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionLargeSet) {
+  QuicIntervalSet<int> mine, theirs;
+  // mine: [0, 9), [10, 19), ..., [990, 999)
+  for (int i = 0; i < 1000; i += 10) {
+    mine.Add(i, i + 9);
+  }
+
+  theirs.Add(500, 520);
+  theirs.Add(535, 545);
+  theirs.Add(801, 809);
+  EXPECT_TRUE(mine.Intersects(theirs));
+  EXPECT_TRUE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(Check(mine, 5, 500, 509, 510, 519, 535, 539, 540, 545, 801, 809));
+  EXPECT_TRUE(mine.Intersects(theirs));
+  EXPECT_TRUE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifference) {
+  is.Difference(other);
+  EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
+                    700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
+  QuicIntervalSet<int> copy = is;
+  is.Difference(copy);
+  EXPECT_TRUE(is.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceSingleBounds) {
+  std::vector<QuicInterval<int>> ivals(other.begin(), other.end());
+  for (const QuicInterval<int>& ival : ivals) {
+    is.Difference(ival.min(), ival.max());
+  }
+  EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
+                    700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceSingleInterval) {
+  std::vector<QuicInterval<int>> ivals(other.begin(), other.end());
+  for (const QuicInterval<int>& ival : ivals) {
+    is.Difference(ival);
+  }
+  EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
+                    700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceAlternatingIntervals) {
+  QuicIntervalSet<int> mine, theirs;
+  mine.Add(10, 20);
+  mine.Add(40, 50);
+  mine.Add(60, 70);
+  theirs.Add(25, 39);
+  theirs.Add(55, 59);
+  theirs.Add(75, 79);
+
+  mine.Difference(theirs);
+  EXPECT_TRUE(Check(mine, 3, 10, 20, 40, 50, 60, 70));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceEmptyMine) {
+  QuicIntervalSet<std::string> mine, theirs;
+  theirs.Add("a", "b");
+
+  mine.Difference(theirs);
+  EXPECT_TRUE(mine.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceEmptyTheirs) {
+  QuicIntervalSet<std::string> mine, theirs;
+  mine.Add("a", "b");
+
+  mine.Difference(theirs);
+  EXPECT_EQ(1u, mine.Size());
+  EXPECT_EQ("a", mine.begin()->min());
+  EXPECT_EQ("b", mine.begin()->max());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceTheirsBeforeMine) {
+  QuicIntervalSet<std::string> mine, theirs;
+  mine.Add("y", "z");
+  theirs.Add("a", "b");
+
+  mine.Difference(theirs);
+  EXPECT_EQ(1u, mine.Size());
+  EXPECT_EQ("y", mine.begin()->min());
+  EXPECT_EQ("z", mine.begin()->max());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceMineBeforeTheirs) {
+  QuicIntervalSet<std::string> mine, theirs;
+  mine.Add("a", "b");
+  theirs.Add("y", "z");
+
+  mine.Difference(theirs);
+  EXPECT_EQ(1u, mine.Size());
+  EXPECT_EQ("a", mine.begin()->min());
+  EXPECT_EQ("b", mine.begin()->max());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceIdentical) {
+  QuicIntervalSet<std::string> mine;
+  mine.Add("a", "b");
+  mine.Add("c", "d");
+  QuicIntervalSet<std::string> theirs(mine);
+
+  mine.Difference(theirs);
+  EXPECT_TRUE(mine.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, EmptyComplement) {
+  // The complement of an empty set is the input interval:
+  QuicIntervalSet<int> iset;
+  iset.Complement(100, 200);
+  EXPECT_TRUE(Check(iset, 1, 100, 200));
+}
+
+TEST(QuicIntervalSetMultipleCompactionTest, OuterCovering) {
+  QuicIntervalSet<int> iset;
+  // First add a bunch of disjoint ranges
+  iset.Add(100, 150);
+  iset.Add(200, 250);
+  iset.Add(300, 350);
+  iset.Add(400, 450);
+  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
+  // Now add a big range that covers all of these ranges
+  iset.Add(0, 500);
+  EXPECT_TRUE(Check(iset, 1, 0, 500));
+}
+
+TEST(QuicIntervalSetMultipleCompactionTest, InnerCovering) {
+  QuicIntervalSet<int> iset;
+  // First add a bunch of disjoint ranges
+  iset.Add(100, 150);
+  iset.Add(200, 250);
+  iset.Add(300, 350);
+  iset.Add(400, 450);
+  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
+  // Now add a big range that partially covers the left and right most ranges.
+  iset.Add(125, 425);
+  EXPECT_TRUE(Check(iset, 1, 100, 450));
+}
+
+TEST(QuicIntervalSetMultipleCompactionTest, LeftCovering) {
+  QuicIntervalSet<int> iset;
+  // First add a bunch of disjoint ranges
+  iset.Add(100, 150);
+  iset.Add(200, 250);
+  iset.Add(300, 350);
+  iset.Add(400, 450);
+  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
+  // Now add a big range that partially covers the left most range.
+  iset.Add(125, 500);
+  EXPECT_TRUE(Check(iset, 1, 100, 500));
+}
+
+TEST(QuicIntervalSetMultipleCompactionTest, RightCovering) {
+  QuicIntervalSet<int> iset;
+  // First add a bunch of disjoint ranges
+  iset.Add(100, 150);
+  iset.Add(200, 250);
+  iset.Add(300, 350);
+  iset.Add(400, 450);
+  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
+  // Now add a big range that partially covers the right most range.
+  iset.Add(0, 425);
+  EXPECT_TRUE(Check(iset, 1, 0, 450));
+}
+
+// Helper method for testing and verifying the results of a one-interval
+// completement case.
+static bool CheckOneComplement(int add_min,
+                               int add_max,
+                               int comp_min,
+                               int comp_max,
+                               int count,
+                               ...) {
+  QuicIntervalSet<int> iset;
+  iset.Add(add_min, add_max);
+  iset.Complement(comp_min, comp_max);
+  bool result = true;
+  va_list ap;
+  va_start(ap, count);
+  if (!VA_Check(iset, count, ap)) {
+    result = false;
+  }
+  va_end(ap);
+  return result;
+}
+
+TEST_F(QuicIntervalSetTest, SingleIntervalComplement) {
+  // Verify the complement of a set with one interval (i):
+  //                     |-----   i  -----|
+  // |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(0, 10, 50, 150, 1, 50, 150));
+
+  //          |-----   i  -----|
+  //    |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 150, 0, 100, 1, 0, 50));
+
+  //    |-----   i  -----|
+  //    |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 150, 50, 150, 0));
+
+  //    |----------   i  ----------|
+  //        |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 500, 100, 300, 0));
+
+  //        |----- i -----|
+  //    |---------- args  ----------|
+  EXPECT_TRUE(CheckOneComplement(50, 500, 0, 800, 2, 0, 50, 500, 800));
+
+  //    |-----   i  -----|
+  //          |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 150, 100, 300, 1, 150, 300));
+
+  //    |-----   i  -----|
+  //                        |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 150, 200, 300, 1, 200, 300));
+}
+
+// Helper method that copies <iset> and takes its complement,
+// returning false if Check succeeds.
+static bool CheckComplement(const QuicIntervalSet<int>& iset,
+                            int comp_min,
+                            int comp_max,
+                            int count,
+                            ...) {
+  QuicIntervalSet<int> iset_copy = iset;
+  iset_copy.Complement(comp_min, comp_max);
+  bool result = true;
+  va_list ap;
+  va_start(ap, count);
+  if (!VA_Check(iset_copy, count, ap)) {
+    result = false;
+  }
+  va_end(ap);
+  return result;
+}
+
+TEST_F(QuicIntervalSetTest, MultiIntervalComplement) {
+  // Initialize a small test set:
+  QuicIntervalSet<int> iset;
+  iset.Add(100, 200);
+  iset.Add(300, 400);
+  iset.Add(500, 600);
+
+  //                     |-----   i  -----|
+  // |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 0, 50, 1, 0, 50));
+
+  //          |-----   i  -----|
+  //    |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 0, 200, 1, 0, 100));
+  EXPECT_TRUE(CheckComplement(iset, 0, 220, 2, 0, 100, 200, 220));
+
+  //    |-----   i  -----|
+  //    |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 100, 600, 2, 200, 300, 400, 500));
+
+  //    |----------   i  ----------|
+  //        |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 300, 400, 0));
+  EXPECT_TRUE(CheckComplement(iset, 250, 400, 1, 250, 300));
+  EXPECT_TRUE(CheckComplement(iset, 300, 450, 1, 400, 450));
+  EXPECT_TRUE(CheckComplement(iset, 250, 450, 2, 250, 300, 400, 450));
+
+  //        |----- i -----|
+  //    |---------- comp  ----------|
+  EXPECT_TRUE(
+      CheckComplement(iset, 0, 700, 4, 0, 100, 200, 300, 400, 500, 600, 700));
+
+  //    |-----   i  -----|
+  //          |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 400, 700, 2, 400, 500, 600, 700));
+  EXPECT_TRUE(CheckComplement(iset, 350, 700, 2, 400, 500, 600, 700));
+
+  //    |-----   i  -----|
+  //                        |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 700, 800, 1, 700, 800));
+}
+
+// Verifies ToString, operator<< don't assert.
+TEST_F(QuicIntervalSetTest, ToString) {
+  QuicIntervalSet<int> iset;
+  iset.Add(300, 400);
+  iset.Add(100, 200);
+  iset.Add(500, 600);
+  EXPECT_TRUE(!iset.ToString().empty());
+  QUIC_VLOG(2) << iset;
+  // Order and format of ToString() output is guaranteed.
+  EXPECT_EQ("{ [100, 200) [300, 400) [500, 600) }", iset.ToString());
+  EXPECT_EQ("{ [1, 2) }", QuicIntervalSet<int>(1, 2).ToString());
+  EXPECT_EQ("{ }", QuicIntervalSet<int>().ToString());
+}
+
+TEST_F(QuicIntervalSetTest, ConstructionDiscardsEmptyInterval) {
+  EXPECT_TRUE(QuicIntervalSet<int>(QuicInterval<int>(2, 2)).Empty());
+  EXPECT_TRUE(QuicIntervalSet<int>(2, 2).Empty());
+  EXPECT_FALSE(QuicIntervalSet<int>(QuicInterval<int>(2, 3)).Empty());
+  EXPECT_FALSE(QuicIntervalSet<int>(2, 3).Empty());
+}
+
+TEST_F(QuicIntervalSetTest, Swap) {
+  QuicIntervalSet<int> a, b;
+  a.Add(300, 400);
+  b.Add(100, 200);
+  b.Add(500, 600);
+  std::swap(a, b);
+  EXPECT_TRUE(Check(a, 2, 100, 200, 500, 600));
+  EXPECT_TRUE(Check(b, 1, 300, 400));
+  std::swap(a, b);
+  EXPECT_TRUE(Check(a, 1, 300, 400));
+  EXPECT_TRUE(Check(b, 2, 100, 200, 500, 600));
+}
+
+TEST_F(QuicIntervalSetTest, OutputReturnsOstreamRef) {
+  std::stringstream ss;
+  const QuicIntervalSet<int> v(QuicInterval<int>(1, 2));
+  auto return_type_is_a_ref = [](std::ostream&) {};
+  return_type_is_a_ref(ss << v);
+}
+
+struct NotOstreamable {
+  bool operator<(const NotOstreamable&) const { return false; }
+  bool operator>(const NotOstreamable&) const { return false; }
+  bool operator!=(const NotOstreamable&) const { return false; }
+  bool operator>=(const NotOstreamable&) const { return true; }
+  bool operator<=(const NotOstreamable&) const { return true; }
+  bool operator==(const NotOstreamable&) const { return true; }
+};
+
+TEST_F(QuicIntervalSetTest, IntervalOfTypeWithNoOstreamSupport) {
+  const NotOstreamable v;
+  const QuicIntervalSet<NotOstreamable> d(QuicInterval<NotOstreamable>(v, v));
+  // EXPECT_EQ builds a string representation of d. If d::operator<<()
+  // would be defined then this test would not compile because NotOstreamable
+  // objects lack the operator<<() support.
+  EXPECT_EQ(d, d);
+}
+
+class QuicIntervalSetInitTest : public QuicTest {
+ protected:
+  const std::vector<QuicInterval<int>> intervals_{{0, 1}, {2, 4}};
+};
+
+TEST_F(QuicIntervalSetInitTest, DirectInit) {
+  std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
+  QuicIntervalSet<int> s(il);
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, CopyInit) {
+  std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
+  QuicIntervalSet<int> s = il;
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, AssignIterPair) {
+  QuicIntervalSet<int> s(0, 1000);  // Make sure assign clears.
+  s.assign(intervals_.begin(), intervals_.end());
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, AssignInitList) {
+  QuicIntervalSet<int> s(0, 1000);  // Make sure assign clears.
+  s.assign({{0, 1}, {2, 3}, {3, 4}});
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, AssignmentInitList) {
+  std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
+  QuicIntervalSet<int> s;
+  s = il;
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, BracedInitThenBracedAssign) {
+  QuicIntervalSet<int> s{{0, 1}, {2, 3}, {3, 4}};
+  s = {{0, 1}, {2, 4}};
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_interval_test.cc b/quiche/quic/core/quic_interval_test.cc
new file mode 100644
index 0000000..6848472
--- /dev/null
+++ b/quiche/quic/core/quic_interval_test.cc
@@ -0,0 +1,470 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_interval.h"
+
+#include <sstream>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+template <typename ForwardIterator>
+void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) {
+  while (begin != end) {
+    auto temp = begin;
+    ++begin;
+    delete *temp;
+  }
+}
+
+template <typename T>
+void STLDeleteElements(T* container) {
+  if (!container)
+    return;
+  STLDeleteContainerPointers(container->begin(), container->end());
+  container->clear();
+}
+
+class ConstructorListener {
+ public:
+  ConstructorListener(int* copy_construct_counter, int* move_construct_counter)
+      : copy_construct_counter_(copy_construct_counter),
+        move_construct_counter_(move_construct_counter) {
+    *copy_construct_counter_ = 0;
+    *move_construct_counter_ = 0;
+  }
+  ConstructorListener(const ConstructorListener& other) {
+    copy_construct_counter_ = other.copy_construct_counter_;
+    move_construct_counter_ = other.move_construct_counter_;
+    ++*copy_construct_counter_;
+  }
+  ConstructorListener(ConstructorListener&& other) {
+    copy_construct_counter_ = other.copy_construct_counter_;
+    move_construct_counter_ = other.move_construct_counter_;
+    ++*move_construct_counter_;
+  }
+  bool operator<(const ConstructorListener&) { return false; }
+  bool operator>(const ConstructorListener&) { return false; }
+  bool operator<=(const ConstructorListener&) { return true; }
+  bool operator>=(const ConstructorListener&) { return true; }
+  bool operator==(const ConstructorListener&) { return true; }
+
+ private:
+  int* copy_construct_counter_;
+  int* move_construct_counter_;
+};
+
+TEST(QuicIntervalConstructorTest, Move) {
+  int object1_copy_count, object1_move_count;
+  ConstructorListener object1(&object1_copy_count, &object1_move_count);
+  int object2_copy_count, object2_move_count;
+  ConstructorListener object2(&object2_copy_count, &object2_move_count);
+
+  QuicInterval<ConstructorListener> interval(object1, std::move(object2));
+  EXPECT_EQ(1, object1_copy_count);
+  EXPECT_EQ(0, object1_move_count);
+  EXPECT_EQ(0, object2_copy_count);
+  EXPECT_EQ(1, object2_move_count);
+}
+
+TEST(QuicIntervalConstructorTest, ImplicitConversion) {
+  struct WrappedInt {
+    WrappedInt(int value) : value(value) {}
+    bool operator<(const WrappedInt& other) { return value < other.value; }
+    bool operator>(const WrappedInt& other) { return value > other.value; }
+    bool operator<=(const WrappedInt& other) { return value <= other.value; }
+    bool operator>=(const WrappedInt& other) { return value >= other.value; }
+    bool operator==(const WrappedInt& other) { return value == other.value; }
+    int value;
+  };
+
+  static_assert(std::is_convertible<int, WrappedInt>::value, "");
+  static_assert(
+      std::is_constructible<QuicInterval<WrappedInt>, int, int>::value, "");
+
+  QuicInterval<WrappedInt> i(10, 20);
+  EXPECT_EQ(10, i.min().value);
+  EXPECT_EQ(20, i.max().value);
+}
+
+class QuicIntervalTest : public QuicTest {
+ protected:
+  // Test intersection between the two intervals i1 and i2.  Tries
+  // i1.IntersectWith(i2) and vice versa. The intersection should change i1 iff
+  // changes_i1 is true, and the same for changes_i2.  The resulting
+  // intersection should be result.
+  void TestIntersect(const QuicInterval<int64_t>& i1,
+                     const QuicInterval<int64_t>& i2,
+                     bool changes_i1,
+                     bool changes_i2,
+                     const QuicInterval<int64_t>& result) {
+    QuicInterval<int64_t> i;
+    i = i1;
+    EXPECT_TRUE(i.IntersectWith(i2) == changes_i1 && i == result);
+    i = i2;
+    EXPECT_TRUE(i.IntersectWith(i1) == changes_i2 && i == result);
+  }
+};
+
+TEST_F(QuicIntervalTest, ConstructorsCopyAndClear) {
+  QuicInterval<int32_t> empty;
+  EXPECT_TRUE(empty.Empty());
+
+  QuicInterval<int32_t> d2(0, 100);
+  EXPECT_EQ(0, d2.min());
+  EXPECT_EQ(100, d2.max());
+  EXPECT_EQ(QuicInterval<int32_t>(0, 100), d2);
+  EXPECT_NE(QuicInterval<int32_t>(0, 99), d2);
+
+  empty = d2;
+  EXPECT_EQ(0, d2.min());
+  EXPECT_EQ(100, d2.max());
+  EXPECT_TRUE(empty == d2);
+  EXPECT_EQ(empty, d2);
+  EXPECT_TRUE(d2 == empty);
+  EXPECT_EQ(d2, empty);
+
+  QuicInterval<int32_t> max_less_than_min(40, 20);
+  EXPECT_TRUE(max_less_than_min.Empty());
+  EXPECT_EQ(40, max_less_than_min.min());
+  EXPECT_EQ(20, max_less_than_min.max());
+
+  QuicInterval<int> d3(10, 20);
+  d3.Clear();
+  EXPECT_TRUE(d3.Empty());
+}
+
+TEST_F(QuicIntervalTest, MakeQuicInterval) {
+  static_assert(
+      std::is_same<QuicInterval<int>, decltype(MakeQuicInterval(0, 3))>::value,
+      "Type is deduced incorrectly.");
+  static_assert(std::is_same<QuicInterval<double>,
+                             decltype(MakeQuicInterval(0., 3.))>::value,
+                "Type is deduced incorrectly.");
+
+  EXPECT_EQ(MakeQuicInterval(0., 3.), QuicInterval<double>(0, 3));
+}
+
+TEST_F(QuicIntervalTest, GettersSetters) {
+  QuicInterval<int32_t> d1(100, 200);
+
+  // SetMin:
+  d1.SetMin(30);
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(200, d1.max());
+
+  // SetMax:
+  d1.SetMax(220);
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  // Set:
+  d1.Clear();
+  d1.Set(30, 220);
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  // SpanningUnion:
+  QuicInterval<int32_t> d2;
+  EXPECT_TRUE(!d1.SpanningUnion(d2));
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  EXPECT_TRUE(d2.SpanningUnion(d1));
+  EXPECT_EQ(30, d2.min());
+  EXPECT_EQ(220, d2.max());
+
+  d2.SetMin(40);
+  d2.SetMax(100);
+  EXPECT_TRUE(!d1.SpanningUnion(d2));
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  d2.SetMin(20);
+  d2.SetMax(100);
+  EXPECT_TRUE(d1.SpanningUnion(d2));
+  EXPECT_EQ(20, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  d2.SetMin(50);
+  d2.SetMax(300);
+  EXPECT_TRUE(d1.SpanningUnion(d2));
+  EXPECT_EQ(20, d1.min());
+  EXPECT_EQ(300, d1.max());
+
+  d2.SetMin(0);
+  d2.SetMax(500);
+  EXPECT_TRUE(d1.SpanningUnion(d2));
+  EXPECT_EQ(0, d1.min());
+  EXPECT_EQ(500, d1.max());
+
+  d2.SetMin(100);
+  d2.SetMax(0);
+  EXPECT_TRUE(!d1.SpanningUnion(d2));
+  EXPECT_EQ(0, d1.min());
+  EXPECT_EQ(500, d1.max());
+  EXPECT_TRUE(d2.SpanningUnion(d1));
+  EXPECT_EQ(0, d2.min());
+  EXPECT_EQ(500, d2.max());
+}
+
+TEST_F(QuicIntervalTest, CoveringOps) {
+  const QuicInterval<int64_t> empty;
+  const QuicInterval<int64_t> d(100, 200);
+  const QuicInterval<int64_t> d1(0, 50);
+  const QuicInterval<int64_t> d2(50, 110);
+  const QuicInterval<int64_t> d3(110, 180);
+  const QuicInterval<int64_t> d4(180, 220);
+  const QuicInterval<int64_t> d5(220, 300);
+  const QuicInterval<int64_t> d6(100, 150);
+  const QuicInterval<int64_t> d7(150, 200);
+  const QuicInterval<int64_t> d8(0, 300);
+
+  // Intersection:
+  EXPECT_TRUE(d.Intersects(d));
+  EXPECT_TRUE(!empty.Intersects(d) && !d.Intersects(empty));
+  EXPECT_TRUE(!d.Intersects(d1) && !d1.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d2) && d2.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d3) && d3.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d4) && d4.Intersects(d));
+  EXPECT_TRUE(!d.Intersects(d5) && !d5.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d6) && d6.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d7) && d7.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d8) && d8.Intersects(d));
+
+  QuicInterval<int64_t> i;
+  EXPECT_TRUE(d.Intersects(d, &i) && d == i);
+  EXPECT_TRUE(!empty.Intersects(d, nullptr) && !d.Intersects(empty, nullptr));
+  EXPECT_TRUE(!d.Intersects(d1, nullptr) && !d1.Intersects(d, nullptr));
+  EXPECT_TRUE(d.Intersects(d2, &i) && i == QuicInterval<int64_t>(100, 110));
+  EXPECT_TRUE(d2.Intersects(d, &i) && i == QuicInterval<int64_t>(100, 110));
+  EXPECT_TRUE(d.Intersects(d3, &i) && i == d3);
+  EXPECT_TRUE(d3.Intersects(d, &i) && i == d3);
+  EXPECT_TRUE(d.Intersects(d4, &i) && i == QuicInterval<int64_t>(180, 200));
+  EXPECT_TRUE(d4.Intersects(d, &i) && i == QuicInterval<int64_t>(180, 200));
+  EXPECT_TRUE(!d.Intersects(d5, nullptr) && !d5.Intersects(d, nullptr));
+  EXPECT_TRUE(d.Intersects(d6, &i) && i == d6);
+  EXPECT_TRUE(d6.Intersects(d, &i) && i == d6);
+  EXPECT_TRUE(d.Intersects(d7, &i) && i == d7);
+  EXPECT_TRUE(d7.Intersects(d, &i) && i == d7);
+  EXPECT_TRUE(d.Intersects(d8, &i) && i == d);
+  EXPECT_TRUE(d8.Intersects(d, &i) && i == d);
+
+  // Test IntersectsWith().
+  // Arguments are TestIntersect(i1, i2, changes_i1, changes_i2, result).
+  TestIntersect(empty, d, false, true, empty);
+  TestIntersect(d, d1, true, true, empty);
+  TestIntersect(d1, d2, true, true, empty);
+  TestIntersect(d, d2, true, true, QuicInterval<int64_t>(100, 110));
+  TestIntersect(d8, d, true, false, d);
+  TestIntersect(d8, d1, true, false, d1);
+  TestIntersect(d8, d5, true, false, d5);
+
+  // Contains:
+  EXPECT_TRUE(!empty.Contains(d) && !d.Contains(empty));
+  EXPECT_TRUE(d.Contains(d));
+  EXPECT_TRUE(!d.Contains(d1) && !d1.Contains(d));
+  EXPECT_TRUE(!d.Contains(d2) && !d2.Contains(d));
+  EXPECT_TRUE(d.Contains(d3) && !d3.Contains(d));
+  EXPECT_TRUE(!d.Contains(d4) && !d4.Contains(d));
+  EXPECT_TRUE(!d.Contains(d5) && !d5.Contains(d));
+  EXPECT_TRUE(d.Contains(d6) && !d6.Contains(d));
+  EXPECT_TRUE(d.Contains(d7) && !d7.Contains(d));
+  EXPECT_TRUE(!d.Contains(d8) && d8.Contains(d));
+
+  EXPECT_TRUE(d.Contains(100));
+  EXPECT_TRUE(!d.Contains(200));
+  EXPECT_TRUE(d.Contains(150));
+  EXPECT_TRUE(!d.Contains(99));
+  EXPECT_TRUE(!d.Contains(201));
+
+  // Difference:
+  std::vector<QuicInterval<int64_t>*> diff;
+
+  EXPECT_TRUE(!d.Difference(empty, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+  EXPECT_TRUE(!empty.Difference(d, &diff) && diff.empty());
+
+  EXPECT_TRUE(d.Difference(d, &diff) && diff.empty());
+  EXPECT_TRUE(!d.Difference(d1, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  QuicInterval<int64_t> lo;
+  QuicInterval<int64_t> hi;
+
+  EXPECT_TRUE(d.Difference(d2, &lo, &hi));
+  EXPECT_TRUE(lo.Empty());
+  EXPECT_EQ(110, hi.min());
+  EXPECT_EQ(200, hi.max());
+  EXPECT_TRUE(d.Difference(d2, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(110, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d3, &lo, &hi));
+  EXPECT_EQ(100, lo.min());
+  EXPECT_EQ(110, lo.max());
+  EXPECT_EQ(180, hi.min());
+  EXPECT_EQ(200, hi.max());
+  EXPECT_TRUE(d.Difference(d3, &diff));
+  EXPECT_EQ(2u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(110, diff[0]->max());
+  EXPECT_EQ(180, diff[1]->min());
+  EXPECT_EQ(200, diff[1]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d4, &lo, &hi));
+  EXPECT_EQ(100, lo.min());
+  EXPECT_EQ(180, lo.max());
+  EXPECT_TRUE(hi.Empty());
+  EXPECT_TRUE(d.Difference(d4, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(180, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_FALSE(d.Difference(d5, &lo, &hi));
+  EXPECT_EQ(100, lo.min());
+  EXPECT_EQ(200, lo.max());
+  EXPECT_TRUE(hi.Empty());
+  EXPECT_FALSE(d.Difference(d5, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d6, &lo, &hi));
+  EXPECT_TRUE(lo.Empty());
+  EXPECT_EQ(150, hi.min());
+  EXPECT_EQ(200, hi.max());
+  EXPECT_TRUE(d.Difference(d6, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(150, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d7, &lo, &hi));
+  EXPECT_EQ(100, lo.min());
+  EXPECT_EQ(150, lo.max());
+  EXPECT_TRUE(hi.Empty());
+  EXPECT_TRUE(d.Difference(d7, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(150, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d8, &lo, &hi));
+  EXPECT_TRUE(lo.Empty());
+  EXPECT_TRUE(hi.Empty());
+  EXPECT_TRUE(d.Difference(d8, &diff) && diff.empty());
+}
+
+TEST_F(QuicIntervalTest, Separated) {
+  using QI = QuicInterval<int>;
+  EXPECT_FALSE(QI(100, 200).Separated(QI(100, 200)));
+  EXPECT_FALSE(QI(100, 200).Separated(QI(200, 300)));
+  EXPECT_TRUE(QI(100, 200).Separated(QI(201, 300)));
+  EXPECT_FALSE(QI(100, 200).Separated(QI(0, 100)));
+  EXPECT_TRUE(QI(100, 200).Separated(QI(0, 99)));
+  EXPECT_FALSE(QI(100, 200).Separated(QI(150, 170)));
+  EXPECT_FALSE(QI(150, 170).Separated(QI(100, 200)));
+  EXPECT_FALSE(QI(100, 200).Separated(QI(150, 250)));
+  EXPECT_FALSE(QI(150, 250).Separated(QI(100, 200)));
+}
+
+TEST_F(QuicIntervalTest, Length) {
+  const QuicInterval<int> empty1;
+  const QuicInterval<int> empty2(1, 1);
+  const QuicInterval<int> empty3(1, 0);
+  const QuicInterval<QuicTime> empty4(
+      QuicTime::Zero() + QuicTime::Delta::FromSeconds(1), QuicTime::Zero());
+  const QuicInterval<int> d1(1, 2);
+  const QuicInterval<int> d2(0, 50);
+  const QuicInterval<QuicTime> d3(
+      QuicTime::Zero(), QuicTime::Zero() + QuicTime::Delta::FromSeconds(1));
+  const QuicInterval<QuicTime> d4(
+      QuicTime::Zero() + QuicTime::Delta::FromSeconds(3600),
+      QuicTime::Zero() + QuicTime::Delta::FromSeconds(5400));
+
+  EXPECT_EQ(0, empty1.Length());
+  EXPECT_EQ(0, empty2.Length());
+  EXPECT_EQ(0, empty3.Length());
+  EXPECT_EQ(QuicTime::Delta::Zero(), empty4.Length());
+  EXPECT_EQ(1, d1.Length());
+  EXPECT_EQ(50, d2.Length());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1), d3.Length());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1800), d4.Length());
+}
+
+TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOperatorMinus) {
+  // QuicInterval<T> should work even if T does not support operator-().  We
+  // just can't call QuicInterval<T>::Length() for such types.
+  const QuicInterval<std::string> d1("a", "b");
+  const QuicInterval<std::pair<int, int>> d2({1, 2}, {4, 3});
+  EXPECT_EQ("a", d1.min());
+  EXPECT_EQ("b", d1.max());
+  EXPECT_EQ(std::make_pair(1, 2), d2.min());
+  EXPECT_EQ(std::make_pair(4, 3), d2.max());
+}
+
+struct NoEquals {
+  NoEquals(int v) : value(v) {}  // NOLINT
+  int value;
+  bool operator<(const NoEquals& other) const { return value < other.value; }
+};
+
+TEST_F(QuicIntervalTest, OrderedComparisonForTypeWithoutEquals) {
+  const QuicInterval<NoEquals> d1(0, 4);
+  const QuicInterval<NoEquals> d2(0, 3);
+  const QuicInterval<NoEquals> d3(1, 4);
+  const QuicInterval<NoEquals> d4(1, 5);
+  const QuicInterval<NoEquals> d6(0, 4);
+  EXPECT_TRUE(d1 < d2);
+  EXPECT_TRUE(d1 < d3);
+  EXPECT_TRUE(d1 < d4);
+  EXPECT_FALSE(d1 < d6);
+}
+
+TEST_F(QuicIntervalTest, OutputReturnsOstreamRef) {
+  std::stringstream ss;
+  const QuicInterval<int> v(1, 2);
+  // If (ss << v) were to return a value, it wouldn't match the signature of
+  // return_type_is_a_ref() function.
+  auto return_type_is_a_ref = [](std::ostream&) {};
+  return_type_is_a_ref(ss << v);
+}
+
+struct NotOstreamable {
+  bool operator<(const NotOstreamable&) const { return false; }
+  bool operator>=(const NotOstreamable&) const { return true; }
+  bool operator==(const NotOstreamable&) const { return true; }
+};
+
+TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOstreamSupport) {
+  const NotOstreamable v;
+  const QuicInterval<NotOstreamable> d(v, v);
+  // EXPECT_EQ builds a string representation of d. If d::operator<<() would be
+  // defined then this test would not compile because NotOstreamable objects
+  // lack the operator<<() support.
+  EXPECT_EQ(d, d);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_legacy_version_encapsulator.cc b/quiche/quic/core/quic_legacy_version_encapsulator.cc
new file mode 100644
index 0000000..826a101
--- /dev/null
+++ b/quiche/quic/core/quic_legacy_version_encapsulator.cc
@@ -0,0 +1,153 @@
+// Copyright (c) 2020 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 "quiche/quic/core/quic_legacy_version_encapsulator.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QuicLegacyVersionEncapsulator::QuicLegacyVersionEncapsulator(
+    QuicPacketBuffer packet_buffer)
+    : packet_buffer_(packet_buffer) {}
+
+QuicLegacyVersionEncapsulator::~QuicLegacyVersionEncapsulator() {}
+
+// static
+QuicByteCount QuicLegacyVersionEncapsulator::GetMinimumOverhead(
+    absl::string_view sni) {
+  // The number 52 is the sum of:
+  // - Flags (1 byte)
+  // - Server Connection ID (8 bytes)
+  // - Version (4 bytes)
+  // - Packet Number (1 byte)
+  // - Message Authentication Hash (12 bytes)
+  // - Frame Type (1 byte)
+  // - Stream ID (1 byte)
+  // - ClientHello tag (4 bytes)
+  // - ClientHello num tags (2 bytes)
+  // - Padding (2 bytes)
+  // - SNI tag (4 bytes)
+  // - SNI end offset (4 bytes)
+  // - QLVE tag (4 bytes)
+  // - QLVE end offset (4 bytes)
+  return 52 + sni.length();
+}
+
+QuicPacketBuffer QuicLegacyVersionEncapsulator::GetPacketBuffer() {
+  return packet_buffer_;
+}
+
+void QuicLegacyVersionEncapsulator::OnSerializedPacket(
+    SerializedPacket serialized_packet) {
+  if (encrypted_length_ != 0) {
+    unrecoverable_failure_encountered_ = true;
+    QUIC_BUG(quic_bug_10615_1) << "OnSerializedPacket called twice";
+    return;
+  }
+  if (serialized_packet.encrypted_length == 0) {
+    unrecoverable_failure_encountered_ = true;
+    QUIC_BUG(quic_bug_10615_2) << "OnSerializedPacket called with empty packet";
+    return;
+  }
+  encrypted_length_ = serialized_packet.encrypted_length;
+}
+
+void QuicLegacyVersionEncapsulator::OnUnrecoverableError(
+    QuicErrorCode error,
+    const std::string& error_details) {
+  unrecoverable_failure_encountered_ = true;
+  QUIC_BUG(quic_bug_10615_3) << "QuicLegacyVersionEncapsulator received error "
+                             << error << ": " << error_details;
+}
+
+bool QuicLegacyVersionEncapsulator::ShouldGeneratePacket(
+    HasRetransmittableData /*retransmittable*/,
+    IsHandshake /*handshake*/) {
+  return true;
+}
+
+const QuicFrames
+QuicLegacyVersionEncapsulator::MaybeBundleAckOpportunistically() {
+  // We do not want to ever include any ACKs here, return an empty array.
+  return QuicFrames();
+}
+
+SerializedPacketFate QuicLegacyVersionEncapsulator::GetSerializedPacketFate(
+    bool /*is_mtu_discovery*/,
+    EncryptionLevel /*encryption_level*/) {
+  return SEND_TO_WRITER;
+}
+
+// static
+QuicPacketLength QuicLegacyVersionEncapsulator::Encapsulate(
+    absl::string_view sni,
+    absl::string_view inner_packet,
+    const QuicConnectionId& server_connection_id,
+    QuicTime creation_time,
+    QuicByteCount outer_max_packet_length,
+    char* out) {
+  if (outer_max_packet_length > kMaxOutgoingPacketSize) {
+    outer_max_packet_length = kMaxOutgoingPacketSize;
+  }
+  CryptoHandshakeMessage outer_chlo;
+  outer_chlo.set_tag(kCHLO);
+  outer_chlo.SetStringPiece(kSNI, sni);
+  outer_chlo.SetStringPiece(kQLVE, inner_packet);
+  const QuicData& serialized_outer_chlo = outer_chlo.GetSerialized();
+  QUICHE_DCHECK(!LegacyVersionForEncapsulation().UsesCryptoFrames());
+  QUICHE_DCHECK(LegacyVersionForEncapsulation().UsesQuicCrypto());
+  QuicStreamFrame outer_stream_frame(
+      QuicUtils::GetCryptoStreamId(
+          LegacyVersionForEncapsulation().transport_version),
+      /*fin=*/false,
+      /*offset=*/0, serialized_outer_chlo.AsStringPiece());
+  QuicFramer outer_framer(
+      ParsedQuicVersionVector{LegacyVersionForEncapsulation()}, creation_time,
+      Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+  outer_framer.SetInitialObfuscators(server_connection_id);
+  char outer_encrypted_packet[kMaxOutgoingPacketSize];
+  QuicPacketBuffer outer_packet_buffer(outer_encrypted_packet, nullptr);
+  QuicLegacyVersionEncapsulator creator_delegate(outer_packet_buffer);
+  QuicPacketCreator outer_creator(server_connection_id, &outer_framer,
+                                  &creator_delegate);
+  outer_creator.SetMaxPacketLength(outer_max_packet_length);
+  outer_creator.set_encryption_level(ENCRYPTION_INITIAL);
+  outer_creator.SetTransmissionType(NOT_RETRANSMISSION);
+  if (!outer_creator.AddPaddedSavedFrame(QuicFrame(outer_stream_frame),
+                                         NOT_RETRANSMISSION)) {
+    QUIC_BUG(quic_bug_10615_4)
+        << "Failed to add Legacy Version Encapsulation stream frame "
+           "(max packet length is "
+        << outer_creator.max_packet_length() << ") " << outer_stream_frame;
+    return 0;
+  }
+  outer_creator.FlushCurrentPacket();
+  const QuicPacketLength encrypted_length = creator_delegate.encrypted_length_;
+  if (creator_delegate.unrecoverable_failure_encountered_ ||
+      encrypted_length == 0) {
+    QUIC_BUG(quic_bug_10615_5)
+        << "Failed to perform Legacy Version Encapsulation of "
+        << inner_packet.length() << " bytes";
+    return 0;
+  }
+  if (encrypted_length > kMaxOutgoingPacketSize) {
+    QUIC_BUG(quic_bug_10615_6)
+        << "Legacy Version Encapsulation outer creator generated a "
+           "packet with unexpected length "
+        << encrypted_length;
+    return 0;
+  }
+
+  QUIC_DLOG(INFO) << "Successfully performed Legacy Version Encapsulation from "
+                  << inner_packet.length() << " bytes to " << encrypted_length;
+
+  // Replace our current packet with the encapsulated one.
+  memcpy(out, outer_encrypted_packet, encrypted_length);
+  return encrypted_length;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_legacy_version_encapsulator.h b/quiche/quic/core/quic_legacy_version_encapsulator.h
new file mode 100644
index 0000000..fb2db98
--- /dev/null
+++ b/quiche/quic/core/quic_legacy_version_encapsulator.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2020 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_LEGACY_VERSION_ENCAPSULATOR_H_
+#define QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicLegacyVersionEncapsulator is responsible for encapsulation of packets
+// using Legacy Version Encapsulation.
+
+class QUIC_EXPORT_PRIVATE QuicLegacyVersionEncapsulator
+    : public QuicPacketCreator::DelegateInterface {
+ public:
+  // Encapsulates |inner_packet| into a new encapsulated packet that uses a
+  // CHLO of version LegacyVersionForEncapsulation() with server name |sni|
+  // exposed and using |server_connection_id|. The packet will be padded up to
+  // |outer_max_packet_length| bytes if necessary. On failure, returns 0. On
+  // success, returns the length of the outer encapsulated packet, and copies
+  // the contents of the encapsulated packet to |out|. |out| must point to a
+  // valid memory buffer capable of holding kMaxOutgoingPacketSize bytes.
+  static QuicPacketLength Encapsulate(
+      absl::string_view sni,
+      absl::string_view inner_packet,
+      const QuicConnectionId& server_connection_id,
+      QuicTime creation_time,
+      QuicByteCount outer_max_packet_length,
+      char* out);
+
+  // Returns the number of bytes of minimum overhead caused by Legacy Version
+  // Encapsulation, based on the length of the provided server name |sni|.
+  // The overhead may be higher due to extra padding added.
+  static QuicByteCount GetMinimumOverhead(absl::string_view sni);
+
+  // Overrides for QuicPacketCreator::DelegateInterface.
+  QuicPacketBuffer GetPacketBuffer() override;
+  void OnSerializedPacket(SerializedPacket serialized_packet) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& error_details) override;
+  bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
+                            IsHandshake handshake) override;
+  const QuicFrames MaybeBundleAckOpportunistically() override;
+  SerializedPacketFate GetSerializedPacketFate(
+      bool is_mtu_discovery,
+      EncryptionLevel encryption_level) override;
+
+  ~QuicLegacyVersionEncapsulator() override;
+
+ private:
+  explicit QuicLegacyVersionEncapsulator(QuicPacketBuffer packet_buffer);
+
+  // Disallow copy, move and assignment.
+  QuicLegacyVersionEncapsulator(const QuicLegacyVersionEncapsulator&) = delete;
+  QuicLegacyVersionEncapsulator(QuicLegacyVersionEncapsulator&&) = delete;
+  QuicLegacyVersionEncapsulator& operator=(
+      const QuicLegacyVersionEncapsulator&) = delete;
+  QuicLegacyVersionEncapsulator& operator=(QuicLegacyVersionEncapsulator&&) =
+      delete;
+
+  QuicPacketBuffer packet_buffer_;
+  QuicPacketLength encrypted_length_ = 0;
+  bool unrecoverable_failure_encountered_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
diff --git a/quiche/quic/core/quic_legacy_version_encapsulator_test.cc b/quiche/quic/core/quic_legacy_version_encapsulator_test.cc
new file mode 100644
index 0000000..928386d
--- /dev/null
+++ b/quiche/quic/core/quic_legacy_version_encapsulator_test.cc
@@ -0,0 +1,107 @@
+// Copyright (c) 2020 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 "quiche/quic/core/quic_legacy_version_encapsulator.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicLegacyVersionEncapsulatorTest
+    : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicLegacyVersionEncapsulatorTest()
+      : version_(GetParam()),
+        sni_("test.example.org"),
+        server_connection_id_(TestConnectionId()),
+        outer_max_packet_length_(kMaxOutgoingPacketSize),
+        encapsulated_length_(0) {}
+
+  void Encapsulate(const std::string& inner_packet) {
+    encapsulated_length_ = QuicLegacyVersionEncapsulator::Encapsulate(
+        sni_, inner_packet, server_connection_id_, QuicTime::Zero(),
+        outer_max_packet_length_, outer_buffer_);
+  }
+
+  void CheckEncapsulation() {
+    ASSERT_NE(encapsulated_length_, 0u);
+    ASSERT_EQ(encapsulated_length_, outer_max_packet_length_);
+    // Verify that the encapsulated packet parses as encapsulated.
+    PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
+    QuicLongHeaderType long_packet_type;
+    bool version_present;
+    bool has_length_prefix;
+    QuicVersionLabel version_label;
+    ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+    QuicConnectionId destination_connection_id, source_connection_id;
+    absl::optional<absl::string_view> retry_token;
+    std::string detailed_error;
+    const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+        QuicEncryptedPacket(outer_buffer_, encapsulated_length_),
+        kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+        &version_present, &has_length_prefix, &version_label, &parsed_version,
+        &destination_connection_id, &source_connection_id, &retry_token,
+        &detailed_error);
+    ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+    EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
+    EXPECT_TRUE(version_present);
+    EXPECT_FALSE(has_length_prefix);
+    EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
+    EXPECT_EQ(destination_connection_id, server_connection_id_);
+    EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
+    EXPECT_FALSE(retry_token.has_value());
+    EXPECT_TRUE(detailed_error.empty());
+  }
+
+  QuicByteCount Overhead() {
+    return QuicLegacyVersionEncapsulator::GetMinimumOverhead(sni_);
+  }
+
+  ParsedQuicVersion version_;
+  std::string sni_;
+  QuicConnectionId server_connection_id_;
+  QuicByteCount outer_max_packet_length_;
+  char outer_buffer_[kMaxOutgoingPacketSize];
+  QuicPacketLength encapsulated_length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(QuicLegacyVersionEncapsulatorTests,
+                         QuicLegacyVersionEncapsulatorTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, Simple) {
+  Encapsulate("TEST_INNER_PACKET");
+  CheckEncapsulation();
+}
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, TooBig) {
+  std::string inner_packet(kMaxOutgoingPacketSize, '?');
+  EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
+  ASSERT_EQ(encapsulated_length_, 0u);
+}
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, BarelyFits) {
+  QuicByteCount inner_size = kMaxOutgoingPacketSize - Overhead();
+  std::string inner_packet(inner_size, '?');
+  Encapsulate(inner_packet);
+  CheckEncapsulation();
+}
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, DoesNotQuiteFit) {
+  QuicByteCount inner_size = 1 + kMaxOutgoingPacketSize - Overhead();
+  std::string inner_packet(inner_size, '?');
+  EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
+  ASSERT_EQ(encapsulated_length_, 0u);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_linux_socket_utils.cc b/quiche/quic/core/quic_linux_socket_utils.cc
new file mode 100644
index 0000000..c28cf21
--- /dev/null
+++ b/quiche/quic/core/quic_linux_socket_utils.cc
@@ -0,0 +1,315 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_linux_socket_utils.h"
+
+#include <linux/net_tstamp.h>
+#include <netinet/in.h>
+#include <cstdint>
+
+#include "quiche/quic/core/quic_syscall_wrapper.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+QuicMsgHdr::QuicMsgHdr(const char* buffer,
+                       size_t buf_len,
+                       const QuicSocketAddress& peer_address,
+                       char* cbuf,
+                       size_t cbuf_size)
+    : iov_{const_cast<char*>(buffer), buf_len},
+      cbuf_(cbuf),
+      cbuf_size_(cbuf_size),
+      cmsg_(nullptr) {
+  // Only support unconnected sockets.
+  QUICHE_DCHECK(peer_address.IsInitialized());
+
+  raw_peer_address_ = peer_address.generic_address();
+  hdr_.msg_name = &raw_peer_address_;
+  hdr_.msg_namelen = raw_peer_address_.ss_family == AF_INET
+                         ? sizeof(sockaddr_in)
+                         : sizeof(sockaddr_in6);
+
+  hdr_.msg_iov = &iov_;
+  hdr_.msg_iovlen = 1;
+  hdr_.msg_flags = 0;
+
+  hdr_.msg_control = nullptr;
+  hdr_.msg_controllen = 0;
+}
+
+void QuicMsgHdr::SetIpInNextCmsg(const QuicIpAddress& self_address) {
+  if (!self_address.IsInitialized()) {
+    return;
+  }
+
+  if (self_address.IsIPv4()) {
+    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+        self_address, GetNextCmsgData<in_pktinfo>(IPPROTO_IP, IP_PKTINFO));
+  } else {
+    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+        self_address, GetNextCmsgData<in6_pktinfo>(IPPROTO_IPV6, IPV6_PKTINFO));
+  }
+}
+
+void* QuicMsgHdr::GetNextCmsgDataInternal(int cmsg_level,
+                                          int cmsg_type,
+                                          size_t data_size) {
+  // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
+  // return nullptr.
+  hdr_.msg_controllen += CMSG_SPACE(data_size);
+  QUICHE_DCHECK_LE(hdr_.msg_controllen, cbuf_size_);
+
+  if (cmsg_ == nullptr) {
+    QUICHE_DCHECK_EQ(nullptr, hdr_.msg_control);
+    memset(cbuf_, 0, cbuf_size_);
+    hdr_.msg_control = cbuf_;
+    cmsg_ = CMSG_FIRSTHDR(&hdr_);
+  } else {
+    QUICHE_DCHECK_NE(nullptr, hdr_.msg_control);
+    cmsg_ = CMSG_NXTHDR(&hdr_, cmsg_);
+  }
+
+  QUICHE_DCHECK_NE(nullptr, cmsg_) << "Insufficient control buffer space";
+
+  cmsg_->cmsg_len = CMSG_LEN(data_size);
+  cmsg_->cmsg_level = cmsg_level;
+  cmsg_->cmsg_type = cmsg_type;
+
+  return CMSG_DATA(cmsg_);
+}
+
+void QuicMMsgHdr::InitOneHeader(int i, const BufferedWrite& buffered_write) {
+  mmsghdr* mhdr = GetMMsgHdr(i);
+  msghdr* hdr = &mhdr->msg_hdr;
+  iovec* iov = GetIov(i);
+
+  iov->iov_base = const_cast<char*>(buffered_write.buffer);
+  iov->iov_len = buffered_write.buf_len;
+  hdr->msg_iov = iov;
+  hdr->msg_iovlen = 1;
+  hdr->msg_control = nullptr;
+  hdr->msg_controllen = 0;
+
+  // Only support unconnected sockets.
+  QUICHE_DCHECK(buffered_write.peer_address.IsInitialized());
+
+  sockaddr_storage* peer_address_storage = GetPeerAddressStorage(i);
+  *peer_address_storage = buffered_write.peer_address.generic_address();
+  hdr->msg_name = peer_address_storage;
+  hdr->msg_namelen = peer_address_storage->ss_family == AF_INET
+                         ? sizeof(sockaddr_in)
+                         : sizeof(sockaddr_in6);
+}
+
+void QuicMMsgHdr::SetIpInNextCmsg(int i, const QuicIpAddress& self_address) {
+  if (!self_address.IsInitialized()) {
+    return;
+  }
+
+  if (self_address.IsIPv4()) {
+    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+        self_address, GetNextCmsgData<in_pktinfo>(i, IPPROTO_IP, IP_PKTINFO));
+  } else {
+    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+        self_address,
+        GetNextCmsgData<in6_pktinfo>(i, IPPROTO_IPV6, IPV6_PKTINFO));
+  }
+}
+
+void* QuicMMsgHdr::GetNextCmsgDataInternal(int i,
+                                           int cmsg_level,
+                                           int cmsg_type,
+                                           size_t data_size) {
+  mmsghdr* mhdr = GetMMsgHdr(i);
+  msghdr* hdr = &mhdr->msg_hdr;
+  cmsghdr*& cmsg = *GetCmsgHdr(i);
+
+  // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
+  // return nullptr.
+  hdr->msg_controllen += CMSG_SPACE(data_size);
+  QUICHE_DCHECK_LE(hdr->msg_controllen, cbuf_size_);
+
+  if (cmsg == nullptr) {
+    QUICHE_DCHECK_EQ(nullptr, hdr->msg_control);
+    hdr->msg_control = GetCbuf(i);
+    cmsg = CMSG_FIRSTHDR(hdr);
+  } else {
+    QUICHE_DCHECK_NE(nullptr, hdr->msg_control);
+    cmsg = CMSG_NXTHDR(hdr, cmsg);
+  }
+
+  QUICHE_DCHECK_NE(nullptr, cmsg) << "Insufficient control buffer space";
+
+  cmsg->cmsg_len = CMSG_LEN(data_size);
+  cmsg->cmsg_level = cmsg_level;
+  cmsg->cmsg_type = cmsg_type;
+
+  return CMSG_DATA(cmsg);
+}
+
+int QuicMMsgHdr::num_bytes_sent(int num_packets_sent) {
+  QUICHE_DCHECK_LE(0, num_packets_sent);
+  QUICHE_DCHECK_LE(num_packets_sent, num_msgs_);
+
+  int bytes_sent = 0;
+  iovec* iov = GetIov(0);
+  for (int i = 0; i < num_packets_sent; ++i) {
+    bytes_sent += iov[i].iov_len;
+  }
+  return bytes_sent;
+}
+
+// static
+int QuicLinuxSocketUtils::GetUDPSegmentSize(int fd) {
+  int optval;
+  socklen_t optlen = sizeof(optval);
+  int rc = getsockopt(fd, SOL_UDP, UDP_SEGMENT, &optval, &optlen);
+  if (rc < 0) {
+    QUIC_LOG_EVERY_N_SEC(INFO, 10)
+        << "getsockopt(UDP_SEGMENT) failed: " << strerror(errno);
+    return -1;
+  }
+  QUIC_LOG_EVERY_N_SEC(INFO, 10)
+      << "getsockopt(UDP_SEGMENT) returned segment size: " << optval;
+  return optval;
+}
+
+// static
+bool QuicLinuxSocketUtils::EnableReleaseTime(int fd, clockid_t clockid) {
+  // TODO(wub): Change to sock_txtime once it is available in linux/net_tstamp.h
+  struct LinuxSockTxTime {
+    clockid_t clockid; /* reference clockid */
+    uint32_t flags;    /* flags defined by enum txtime_flags */
+  };
+
+  LinuxSockTxTime so_txtime_val{clockid, 0};
+
+  if (setsockopt(fd, SOL_SOCKET, SO_TXTIME, &so_txtime_val,
+                 sizeof(so_txtime_val)) != 0) {
+    QUIC_LOG_EVERY_N_SEC(INFO, 10)
+        << "setsockopt(SOL_SOCKET,SO_TXTIME) failed: " << strerror(errno);
+    return false;
+  }
+
+  return true;
+}
+
+// static
+bool QuicLinuxSocketUtils::GetTtlFromMsghdr(struct msghdr* hdr, int* ttl) {
+  if (hdr->msg_controllen > 0) {
+    struct cmsghdr* cmsg;
+    for (cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
+         cmsg = CMSG_NXTHDR(hdr, cmsg)) {
+      if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
+          (cmsg->cmsg_level == IPPROTO_IPV6 &&
+           cmsg->cmsg_type == IPV6_HOPLIMIT)) {
+        *ttl = *(reinterpret_cast<int*>(CMSG_DATA(cmsg)));
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+// static
+void QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+    const QuicIpAddress& self_address,
+    void* cmsg_data) {
+  QUICHE_DCHECK(self_address.IsInitialized());
+  const std::string& address_str = self_address.ToPackedString();
+  if (self_address.IsIPv4()) {
+    in_pktinfo* pktinfo = static_cast<in_pktinfo*>(cmsg_data);
+    pktinfo->ipi_ifindex = 0;
+    memcpy(&pktinfo->ipi_spec_dst, address_str.c_str(), address_str.length());
+  } else if (self_address.IsIPv6()) {
+    in6_pktinfo* pktinfo = static_cast<in6_pktinfo*>(cmsg_data);
+    memcpy(&pktinfo->ipi6_addr, address_str.c_str(), address_str.length());
+  } else {
+    QUIC_BUG(quic_bug_10598_1) << "Unrecognized IPAddress";
+  }
+}
+
+// static
+size_t QuicLinuxSocketUtils::SetIpInfoInCmsg(const QuicIpAddress& self_address,
+                                             cmsghdr* cmsg) {
+  std::string address_string;
+  if (self_address.IsIPv4()) {
+    cmsg->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
+    cmsg->cmsg_level = IPPROTO_IP;
+    cmsg->cmsg_type = IP_PKTINFO;
+    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+    memset(pktinfo, 0, sizeof(in_pktinfo));
+    pktinfo->ipi_ifindex = 0;
+    address_string = self_address.ToPackedString();
+    memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
+           address_string.length());
+    return sizeof(in_pktinfo);
+  } else if (self_address.IsIPv6()) {
+    cmsg->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
+    cmsg->cmsg_level = IPPROTO_IPV6;
+    cmsg->cmsg_type = IPV6_PKTINFO;
+    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+    memset(pktinfo, 0, sizeof(in6_pktinfo));
+    address_string = self_address.ToPackedString();
+    memcpy(&pktinfo->ipi6_addr, address_string.c_str(),
+           address_string.length());
+    return sizeof(in6_pktinfo);
+  } else {
+    QUIC_BUG(quic_bug_10598_2) << "Unrecognized IPAddress";
+    return 0;
+  }
+}
+
+// static
+WriteResult QuicLinuxSocketUtils::WritePacket(int fd, const QuicMsgHdr& hdr) {
+  int rc;
+  do {
+    rc = GetGlobalSyscallWrapper()->Sendmsg(fd, hdr.hdr(), 0);
+  } while (rc < 0 && errno == EINTR);
+  if (rc >= 0) {
+    return WriteResult(WRITE_STATUS_OK, rc);
+  }
+  return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
+                         ? WRITE_STATUS_BLOCKED
+                         : WRITE_STATUS_ERROR,
+                     errno);
+}
+
+// static
+WriteResult QuicLinuxSocketUtils::WriteMultiplePackets(int fd,
+                                                       QuicMMsgHdr* mhdr,
+                                                       int* num_packets_sent) {
+  *num_packets_sent = 0;
+
+  if (mhdr->num_msgs() <= 0) {
+    return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+  }
+
+  int rc;
+  do {
+    rc = GetGlobalSyscallWrapper()->Sendmmsg(fd, mhdr->mhdr(), mhdr->num_msgs(),
+                                             0);
+  } while (rc < 0 && errno == EINTR);
+
+  if (rc > 0) {
+    *num_packets_sent = rc;
+
+    return WriteResult(WRITE_STATUS_OK, mhdr->num_bytes_sent(rc));
+  } else if (rc == 0) {
+    QUIC_BUG(quic_bug_10598_3)
+        << "sendmmsg returned 0, returning WRITE_STATUS_ERROR. errno: "
+        << errno;
+    errno = EIO;
+  }
+
+  return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
+                         ? WRITE_STATUS_BLOCKED
+                         : WRITE_STATUS_ERROR,
+                     errno);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_linux_socket_utils.h b/quiche/quic/core/quic_linux_socket_utils.h
new file mode 100644
index 0000000..7203a17
--- /dev/null
+++ b/quiche/quic/core/quic_linux_socket_utils.h
@@ -0,0 +1,297 @@
+// Copyright (c) 2019 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_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <deque>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+#ifndef SOL_UDP
+#define SOL_UDP 17
+#endif
+
+#ifndef UDP_SEGMENT
+#define UDP_SEGMENT 103
+#endif
+
+#ifndef UDP_MAX_SEGMENTS
+#define UDP_MAX_SEGMENTS (1 << 6UL)
+#endif
+
+#ifndef SO_TXTIME
+#define SO_TXTIME 61
+#endif
+
+namespace quic {
+
+const int kCmsgSpaceForIpv4 = CMSG_SPACE(sizeof(in_pktinfo));
+const int kCmsgSpaceForIpv6 = CMSG_SPACE(sizeof(in6_pktinfo));
+// kCmsgSpaceForIp should be big enough to hold both IPv4 and IPv6 packet info.
+const int kCmsgSpaceForIp = (kCmsgSpaceForIpv4 < kCmsgSpaceForIpv6)
+                                ? kCmsgSpaceForIpv6
+                                : kCmsgSpaceForIpv4;
+
+const int kCmsgSpaceForSegmentSize = CMSG_SPACE(sizeof(uint16_t));
+
+const int kCmsgSpaceForTxTime = CMSG_SPACE(sizeof(uint64_t));
+
+const int kCmsgSpaceForTTL = CMSG_SPACE(sizeof(int));
+
+// QuicMsgHdr is used to build msghdr objects that can be used send packets via
+// ::sendmsg.
+//
+// Example:
+//   // cbuf holds control messages(cmsgs). The size is determined from what
+//   // cmsgs will be set for this msghdr.
+//   char cbuf[kCmsgSpaceForIp + kCmsgSpaceForSegmentSize];
+//   QuicMsgHdr hdr(packet_buf, packet_buf_len, peer_addr, cbuf, sizeof(cbuf));
+//
+//   // Set IP in cmsgs.
+//   hdr.SetIpInNextCmsg(self_addr);
+//
+//   // Set GSO size in cmsgs.
+//   *hdr.GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = 1200;
+//
+//   QuicLinuxSocketUtils::WritePacket(fd, hdr);
+class QUIC_EXPORT_PRIVATE QuicMsgHdr {
+ public:
+  QuicMsgHdr(const char* buffer,
+             size_t buf_len,
+             const QuicSocketAddress& peer_address,
+             char* cbuf,
+             size_t cbuf_size);
+
+  // Set IP info in the next cmsg. Both IPv4 and IPv6 are supported.
+  void SetIpInNextCmsg(const QuicIpAddress& self_address);
+
+  template <typename DataType>
+  DataType* GetNextCmsgData(int cmsg_level, int cmsg_type) {
+    return reinterpret_cast<DataType*>(
+        GetNextCmsgDataInternal(cmsg_level, cmsg_type, sizeof(DataType)));
+  }
+
+  const msghdr* hdr() const { return &hdr_; }
+
+ protected:
+  void* GetNextCmsgDataInternal(int cmsg_level,
+                                int cmsg_type,
+                                size_t data_size);
+
+  msghdr hdr_;
+  iovec iov_;
+  sockaddr_storage raw_peer_address_;
+  char* cbuf_;
+  const size_t cbuf_size_;
+  // The last cmsg populated so far. nullptr means nothing has been populated.
+  cmsghdr* cmsg_;
+};
+
+// BufferedWrite holds all information needed to send a packet.
+struct QUIC_EXPORT_PRIVATE BufferedWrite {
+  BufferedWrite(const char* buffer,
+                size_t buf_len,
+                const QuicIpAddress& self_address,
+                const QuicSocketAddress& peer_address)
+      : BufferedWrite(buffer,
+                      buf_len,
+                      self_address,
+                      peer_address,
+                      std::unique_ptr<PerPacketOptions>(),
+                      /*release_time=*/0) {}
+
+  BufferedWrite(const char* buffer,
+                size_t buf_len,
+                const QuicIpAddress& self_address,
+                const QuicSocketAddress& peer_address,
+                std::unique_ptr<PerPacketOptions> options,
+                uint64_t release_time)
+      : buffer(buffer),
+        buf_len(buf_len),
+        self_address(self_address),
+        peer_address(peer_address),
+        options(std::move(options)),
+        release_time(release_time) {}
+
+  const char* buffer;  // Not owned.
+  size_t buf_len;
+  QuicIpAddress self_address;
+  QuicSocketAddress peer_address;
+  std::unique_ptr<PerPacketOptions> options;
+
+  // The release time according to the owning packet writer's clock, which is
+  // often not a QuicClock. Calculated from packet writer's Now() and the
+  // release time delay in |options|.
+  // 0 means it can be sent at the same time as the previous packet in a batch,
+  // or can be sent Now() if this is the first packet of a batch.
+  uint64_t release_time;
+};
+
+// QuicMMsgHdr is used to build mmsghdr objects that can be used to send
+// multiple packets at once via ::sendmmsg.
+//
+// Example:
+//   quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+//   ... (Populate buffered_writes) ...
+//
+//   QuicMMsgHdr mhdr(
+//       buffered_writes.begin(), buffered_writes.end(), kCmsgSpaceForIp,
+//       [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+//         mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+//       });
+//
+//   int num_packets_sent;
+//   QuicSocketUtils::WriteMultiplePackets(fd, &mhdr, &num_packets_sent);
+class QUIC_EXPORT_PRIVATE QuicMMsgHdr {
+ public:
+  using ControlBufferInitializer = std::function<
+      void(QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write)>;
+  template <typename IteratorT>
+  QuicMMsgHdr(const IteratorT& first,
+              const IteratorT& last,
+              size_t cbuf_size,
+              ControlBufferInitializer cbuf_initializer)
+      : num_msgs_(std::distance(first, last)), cbuf_size_(cbuf_size) {
+    static_assert(
+        std::is_same<typename std::iterator_traits<IteratorT>::value_type,
+                     BufferedWrite>::value,
+        "Must iterate over a collection of BufferedWrite.");
+
+    QUICHE_DCHECK_LE(0, num_msgs_);
+    if (num_msgs_ == 0) {
+      return;
+    }
+
+    storage_.reset(new char[StorageSize()]);
+    memset(&storage_[0], 0, StorageSize());
+
+    int i = -1;
+    for (auto it = first; it != last; ++it) {
+      ++i;
+
+      InitOneHeader(i, *it);
+      if (cbuf_initializer) {
+        cbuf_initializer(this, i, *it);
+      }
+    }
+  }
+
+  void SetIpInNextCmsg(int i, const QuicIpAddress& self_address);
+
+  template <typename DataType>
+  DataType* GetNextCmsgData(int i, int cmsg_level, int cmsg_type) {
+    return reinterpret_cast<DataType*>(
+        GetNextCmsgDataInternal(i, cmsg_level, cmsg_type, sizeof(DataType)));
+  }
+
+  mmsghdr* mhdr() { return GetMMsgHdr(0); }
+
+  int num_msgs() const { return num_msgs_; }
+
+  // Get the total number of bytes in the first |num_packets_sent| packets.
+  int num_bytes_sent(int num_packets_sent);
+
+ protected:
+  void InitOneHeader(int i, const BufferedWrite& buffered_write);
+
+  void* GetNextCmsgDataInternal(int i,
+                                int cmsg_level,
+                                int cmsg_type,
+                                size_t data_size);
+
+  size_t StorageSize() const {
+    return num_msgs_ *
+           (sizeof(mmsghdr) + sizeof(iovec) + sizeof(sockaddr_storage) +
+            sizeof(cmsghdr*) + cbuf_size_);
+  }
+
+  mmsghdr* GetMMsgHdr(int i) {
+    auto* first = reinterpret_cast<mmsghdr*>(&storage_[0]);
+    return &first[i];
+  }
+
+  iovec* GetIov(int i) {
+    auto* first = reinterpret_cast<iovec*>(GetMMsgHdr(num_msgs_));
+    return &first[i];
+  }
+
+  sockaddr_storage* GetPeerAddressStorage(int i) {
+    auto* first = reinterpret_cast<sockaddr_storage*>(GetIov(num_msgs_));
+    return &first[i];
+  }
+
+  cmsghdr** GetCmsgHdr(int i) {
+    auto* first = reinterpret_cast<cmsghdr**>(GetPeerAddressStorage(num_msgs_));
+    return &first[i];
+  }
+
+  char* GetCbuf(int i) {
+    auto* first = reinterpret_cast<char*>(GetCmsgHdr(num_msgs_));
+    return &first[i * cbuf_size_];
+  }
+
+  const int num_msgs_;
+  // Size of cmsg buffer for each message.
+  const size_t cbuf_size_;
+  // storage_ holds the memory of
+  // |num_msgs_| mmsghdr
+  // |num_msgs_| iovec
+  // |num_msgs_| sockaddr_storage, for peer addresses
+  // |num_msgs_| cmsghdr*
+  // |num_msgs_| cbuf, each of size cbuf_size
+  std::unique_ptr<char[]> storage_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicLinuxSocketUtils {
+ public:
+  // Return the UDP segment size of |fd|, 0 means segment size has not been set
+  // on this socket. If GSO is not supported, return -1.
+  static int GetUDPSegmentSize(int fd);
+
+  // Enable release time on |fd|.
+  static bool EnableReleaseTime(int fd, clockid_t clockid);
+
+  // If the msghdr contains an IP_TTL entry, this will set ttl to the correct
+  // value and return true. Otherwise it will return false.
+  static bool GetTtlFromMsghdr(struct msghdr* hdr, int* ttl);
+
+  // Set IP(self_address) in |cmsg_data|. Does not touch other fields in the
+  // containing cmsghdr.
+  static void SetIpInfoInCmsgData(const QuicIpAddress& self_address,
+                                  void* cmsg_data);
+
+  // A helper for WritePacket which fills in the cmsg with the supplied self
+  // address.
+  // Returns the length of the packet info structure used.
+  static size_t SetIpInfoInCmsg(const QuicIpAddress& self_address,
+                                cmsghdr* cmsg);
+
+  // Writes the packet in |hdr| to the socket, using ::sendmsg.
+  static WriteResult WritePacket(int fd, const QuicMsgHdr& hdr);
+
+  // Writes the packets in |mhdr| to the socket, using ::sendmmsg if available.
+  static WriteResult WriteMultiplePackets(int fd,
+                                          QuicMMsgHdr* mhdr,
+                                          int* num_packets_sent);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
diff --git a/quiche/quic/core/quic_linux_socket_utils_test.cc b/quiche/quic/core/quic_linux_socket_utils_test.cc
new file mode 100644
index 0000000..5ae2fde
--- /dev/null
+++ b/quiche/quic/core/quic_linux_socket_utils_test.cc
@@ -0,0 +1,329 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_linux_socket_utils.h"
+
+#include <netinet/in.h>
+#include <stdint.h>
+#include <cstddef>
+#include <sstream>
+#include <vector>
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_mock_syscall_wrapper.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicLinuxSocketUtilsTest : public QuicTest {
+ protected:
+  WriteResult TestWriteMultiplePackets(
+      int fd,
+      const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& first,
+      const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& last,
+      int* num_packets_sent) {
+    QuicMMsgHdr mhdr(
+        first, last, kCmsgSpaceForIp,
+        [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+          mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+        });
+
+    WriteResult res =
+        QuicLinuxSocketUtils::WriteMultiplePackets(fd, &mhdr, num_packets_sent);
+    return res;
+  }
+
+  MockQuicSyscallWrapper mock_syscalls_;
+  ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
+};
+
+void CheckIpAndTtlInCbuf(msghdr* hdr,
+                         const void* cbuf,
+                         const QuicIpAddress& self_addr,
+                         int ttl) {
+  const bool is_ipv4 = self_addr.IsIPv4();
+  const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
+
+  EXPECT_EQ(cbuf, hdr->msg_control);
+  EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
+
+  cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
+  EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
+                                    : CMSG_LEN(sizeof(in6_pktinfo)));
+  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
+  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
+
+  const std::string& self_addr_str = self_addr.ToPackedString();
+  if (is_ipv4) {
+    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+    EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
+                        self_addr_str.length()));
+  } else {
+    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+    EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
+                        self_addr_str.length()));
+  }
+
+  cmsg = CMSG_NXTHDR(hdr, cmsg);
+  EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
+  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
+  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_TTL : IPV6_HOPLIMIT);
+  EXPECT_EQ(ttl, *reinterpret_cast<int*>(CMSG_DATA(cmsg)));
+
+  EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
+}
+
+void CheckMsghdrWithoutCbuf(const msghdr* hdr,
+                            const void* buffer,
+                            size_t buf_len,
+                            const QuicSocketAddress& peer_addr) {
+  EXPECT_EQ(
+      peer_addr.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6),
+      hdr->msg_namelen);
+  sockaddr_storage peer_generic_addr = peer_addr.generic_address();
+  EXPECT_EQ(0, memcmp(hdr->msg_name, &peer_generic_addr, hdr->msg_namelen));
+  EXPECT_EQ(1u, hdr->msg_iovlen);
+  EXPECT_EQ(buffer, hdr->msg_iov->iov_base);
+  EXPECT_EQ(buf_len, hdr->msg_iov->iov_len);
+  EXPECT_EQ(0, hdr->msg_flags);
+  EXPECT_EQ(nullptr, hdr->msg_control);
+  EXPECT_EQ(0u, hdr->msg_controllen);
+}
+
+void CheckIpAndGsoSizeInCbuf(msghdr* hdr,
+                             const void* cbuf,
+                             const QuicIpAddress& self_addr,
+                             uint16_t gso_size) {
+  const bool is_ipv4 = self_addr.IsIPv4();
+  const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
+
+  EXPECT_EQ(cbuf, hdr->msg_control);
+  EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
+
+  cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
+  EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
+                                    : CMSG_LEN(sizeof(in6_pktinfo)));
+  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
+  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
+
+  const std::string& self_addr_str = self_addr.ToPackedString();
+  if (is_ipv4) {
+    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+    EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
+                        self_addr_str.length()));
+  } else {
+    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+    EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
+                        self_addr_str.length()));
+  }
+
+  cmsg = CMSG_NXTHDR(hdr, cmsg);
+  EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(uint16_t)));
+  EXPECT_EQ(cmsg->cmsg_level, SOL_UDP);
+  EXPECT_EQ(cmsg->cmsg_type, UDP_SEGMENT);
+  EXPECT_EQ(gso_size, *reinterpret_cast<uint16_t*>(CMSG_DATA(cmsg)));
+
+  EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, QuicMsgHdr) {
+  QuicSocketAddress peer_addr(QuicIpAddress::Loopback4(), 1234);
+  char packet_buf[1024];
+
+  QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, nullptr, 0);
+  CheckMsghdrWithoutCbuf(quic_hdr.hdr(), packet_buf, sizeof(packet_buf),
+                         peer_addr);
+
+  for (bool is_ipv4 : {true, false}) {
+    QuicIpAddress self_addr =
+        is_ipv4 ? QuicIpAddress::Loopback4() : QuicIpAddress::Loopback6();
+    char cbuf[kCmsgSpaceForIp + kCmsgSpaceForTTL];
+    QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, cbuf,
+                        sizeof(cbuf));
+    msghdr* hdr = const_cast<msghdr*>(quic_hdr.hdr());
+
+    EXPECT_EQ(nullptr, hdr->msg_control);
+    EXPECT_EQ(0u, hdr->msg_controllen);
+
+    quic_hdr.SetIpInNextCmsg(self_addr);
+    EXPECT_EQ(cbuf, hdr->msg_control);
+    const size_t ip_cmsg_space =
+        is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
+    EXPECT_EQ(ip_cmsg_space, hdr->msg_controllen);
+
+    if (is_ipv4) {
+      *quic_hdr.GetNextCmsgData<int>(IPPROTO_IP, IP_TTL) = 32;
+    } else {
+      *quic_hdr.GetNextCmsgData<int>(IPPROTO_IPV6, IPV6_HOPLIMIT) = 32;
+    }
+
+    CheckIpAndTtlInCbuf(hdr, cbuf, self_addr, 32);
+  }
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, QuicMMsgHdr) {
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+  char packet_buf1[1024];
+  char packet_buf2[512];
+  buffered_writes.emplace_back(
+      packet_buf1, sizeof(packet_buf1), QuicIpAddress::Loopback4(),
+      QuicSocketAddress(QuicIpAddress::Loopback4(), 4));
+  buffered_writes.emplace_back(
+      packet_buf2, sizeof(packet_buf2), QuicIpAddress::Loopback6(),
+      QuicSocketAddress(QuicIpAddress::Loopback6(), 6));
+
+  QuicMMsgHdr quic_mhdr_without_cbuf(buffered_writes.begin(),
+                                     buffered_writes.end(), 0, nullptr);
+  for (size_t i = 0; i < buffered_writes.size(); ++i) {
+    const BufferedWrite& bw = buffered_writes[i];
+    CheckMsghdrWithoutCbuf(&quic_mhdr_without_cbuf.mhdr()[i].msg_hdr, bw.buffer,
+                           bw.buf_len, bw.peer_address);
+  }
+
+  QuicMMsgHdr quic_mhdr_with_cbuf(
+      buffered_writes.begin(), buffered_writes.end(),
+      kCmsgSpaceForIp + kCmsgSpaceForSegmentSize,
+      [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+        mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+        *mhdr->GetNextCmsgData<uint16_t>(i, SOL_UDP, UDP_SEGMENT) = 1300;
+      });
+  for (size_t i = 0; i < buffered_writes.size(); ++i) {
+    const BufferedWrite& bw = buffered_writes[i];
+    msghdr* hdr = &quic_mhdr_with_cbuf.mhdr()[i].msg_hdr;
+    CheckIpAndGsoSizeInCbuf(hdr, hdr->msg_control, bw.self_address, 1300);
+  }
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_NoPacketsToSend) {
+  int num_packets_sent;
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+
+  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _)).Times(0);
+
+  EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL),
+            TestWriteMultiplePackets(1, buffered_writes.begin(),
+                                     buffered_writes.end(), &num_packets_sent));
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteBlocked) {
+  int num_packets_sent;
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+  buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
+                               QuicSocketAddress(QuicIpAddress::Any4(), 0));
+
+  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
+      .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
+                          unsigned int /*vlen*/, int /*flags*/) {
+        errno = EWOULDBLOCK;
+        return -1;
+      }));
+
+  EXPECT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
+            TestWriteMultiplePackets(1, buffered_writes.begin(),
+                                     buffered_writes.end(), &num_packets_sent));
+  EXPECT_EQ(0, num_packets_sent);
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteError) {
+  int num_packets_sent;
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+  buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
+                               QuicSocketAddress(QuicIpAddress::Any4(), 0));
+
+  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
+      .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
+                          unsigned int /*vlen*/, int /*flags*/) {
+        errno = EPERM;
+        return -1;
+      }));
+
+  EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM),
+            TestWriteMultiplePackets(1, buffered_writes.begin(),
+                                     buffered_writes.end(), &num_packets_sent));
+  EXPECT_EQ(0, num_packets_sent);
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteSuccess) {
+  int num_packets_sent;
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+  const int kNumBufferedWrites = 10;
+  static_assert(kNumBufferedWrites < 256, "Must be less than 256");
+  std::vector<std::string> buffer_holder;
+  for (int i = 0; i < kNumBufferedWrites; ++i) {
+    size_t buf_len = (i + 1) * 2;
+    std::ostringstream buffer_ostream;
+    while (buffer_ostream.str().length() < buf_len) {
+      buffer_ostream << i;
+    }
+    buffer_holder.push_back(buffer_ostream.str().substr(0, buf_len - 1) + '$');
+
+    buffered_writes.emplace_back(buffer_holder.back().data(), buf_len,
+                                 QuicIpAddress(),
+                                 QuicSocketAddress(QuicIpAddress::Any4(), 0));
+
+    // Leave the first self_address uninitialized.
+    if (i != 0) {
+      ASSERT_TRUE(buffered_writes.back().self_address.FromString("127.0.0.1"));
+    }
+
+    std::ostringstream peer_ip_ostream;
+    QuicIpAddress peer_ip_address;
+    peer_ip_ostream << "127.0.1." << i + 1;
+    ASSERT_TRUE(peer_ip_address.FromString(peer_ip_ostream.str()));
+    buffered_writes.back().peer_address =
+        QuicSocketAddress(peer_ip_address, i + 1);
+  }
+
+  InSequence s;
+
+  for (int expected_num_packets_sent : {1, 2, 3, 10}) {
+    SCOPED_TRACE(testing::Message()
+                 << "expected_num_packets_sent=" << expected_num_packets_sent);
+    EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
+        .WillOnce(Invoke(
+            [&](int /*fd*/, mmsghdr* msgvec, unsigned int vlen, int /*flags*/) {
+              EXPECT_LE(static_cast<unsigned int>(expected_num_packets_sent),
+                        vlen);
+              for (unsigned int i = 0; i < vlen; ++i) {
+                const BufferedWrite& buffered_write = buffered_writes[i];
+                const msghdr& hdr = msgvec[i].msg_hdr;
+                EXPECT_EQ(1u, hdr.msg_iovlen);
+                EXPECT_EQ(buffered_write.buffer, hdr.msg_iov->iov_base);
+                EXPECT_EQ(buffered_write.buf_len, hdr.msg_iov->iov_len);
+                sockaddr_storage expected_peer_address =
+                    buffered_write.peer_address.generic_address();
+                EXPECT_EQ(0, memcmp(&expected_peer_address, hdr.msg_name,
+                                    sizeof(sockaddr_storage)));
+                EXPECT_EQ(buffered_write.self_address.IsInitialized(),
+                          hdr.msg_control != nullptr);
+              }
+              return expected_num_packets_sent;
+            }))
+        .RetiresOnSaturation();
+
+    int expected_bytes_written = 0;
+    for (auto it = buffered_writes.cbegin();
+         it != buffered_writes.cbegin() + expected_num_packets_sent; ++it) {
+      expected_bytes_written += it->buf_len;
+    }
+
+    EXPECT_EQ(
+        WriteResult(WRITE_STATUS_OK, expected_bytes_written),
+        TestWriteMultiplePackets(1, buffered_writes.cbegin(),
+                                 buffered_writes.cend(), &num_packets_sent));
+    EXPECT_EQ(expected_num_packets_sent, num_packets_sent);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_lru_cache.h b/quiche/quic/core/quic_lru_cache.h
new file mode 100644
index 0000000..d1c010e
--- /dev/null
+++ b/quiche/quic/core/quic_lru_cache.h
@@ -0,0 +1,98 @@
+// Copyright (c) 2018 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_LRU_CACHE_H_
+#define QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
+
+#include <memory>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+// A LRU cache that maps from type Key to Value* in QUIC.
+// This cache CANNOT be shared by multiple threads (even with locks) because
+// Value* returned by Lookup() can be invalid if the entry is evicted by other
+// threads.
+template <class K, class V, class Hash = std::hash<K>,
+          class Eq = std::equal_to<K>>
+class QUIC_NO_EXPORT QuicLRUCache {
+ private:
+  using HashMapType =
+      typename quiche::QuicheLinkedHashMap<K, std::unique_ptr<V>, Hash, Eq>;
+
+ public:
+  // The iterator, if valid, points to std::pair<K, std::unique_ptr<V>>.
+  using iterator = typename HashMapType::iterator;
+  using const_iterator = typename HashMapType::const_iterator;
+  using reverse_iterator = typename HashMapType::reverse_iterator;
+  using const_reverse_iterator = typename HashMapType::const_reverse_iterator;
+
+  explicit QuicLRUCache(size_t capacity) : capacity_(capacity) {}
+  QuicLRUCache(const QuicLRUCache&) = delete;
+  QuicLRUCache& operator=(const QuicLRUCache&) = delete;
+
+  iterator begin() { return cache_.begin(); }
+  const_iterator begin() const { return cache_.begin(); }
+
+  iterator end() { return cache_.end(); }
+  const_iterator end() const { return cache_.end(); }
+
+  reverse_iterator rbegin() { return cache_.rbegin(); }
+  const_reverse_iterator rbegin() const { return cache_.rbegin(); }
+
+  reverse_iterator rend() { return cache_.rend(); }
+  const_reverse_iterator rend() const { return cache_.rend(); }
+
+  // Inserts one unit of |key|, |value| pair to the cache. Cache takes ownership
+  // of inserted |value|.
+  void Insert(const K& key, std::unique_ptr<V> value) {
+    auto it = cache_.find(key);
+    if (it != cache_.end()) {
+      cache_.erase(it);
+    }
+    cache_.emplace(key, std::move(value));
+
+    if (cache_.size() > capacity_) {
+      cache_.pop_front();
+    }
+    QUICHE_DCHECK_LE(cache_.size(), capacity_);
+  }
+
+  iterator Lookup(const K& key) {
+    auto iter = cache_.find(key);
+    if (iter == cache_.end()) {
+      return iter;
+    }
+
+    std::unique_ptr<V> value = std::move(iter->second);
+    cache_.erase(iter);
+    auto result = cache_.emplace(key, std::move(value));
+    QUICHE_DCHECK(result.second);
+    return result.first;
+  }
+
+  iterator Erase(iterator iter) { return cache_.erase(iter); }
+
+  // Removes all entries from the cache.
+  void Clear() { cache_.clear(); }
+
+  // Returns maximum size of the cache.
+  size_t MaxSize() const { return capacity_; }
+
+  // Returns current size of the cache.
+  size_t Size() const { return cache_.size(); }
+
+ private:
+  quiche::QuicheLinkedHashMap<K, std::unique_ptr<V>, Hash, Eq> cache_;
+  const size_t capacity_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
diff --git a/quiche/quic/core/quic_lru_cache_test.cc b/quiche/quic/core/quic_lru_cache_test.cc
new file mode 100644
index 0000000..91a7913
--- /dev/null
+++ b/quiche/quic/core/quic_lru_cache_test.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_lru_cache.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+struct CachedItem {
+  explicit CachedItem(uint32_t new_value) : value(new_value) {}
+
+  uint32_t value;
+};
+
+TEST(QuicLRUCacheTest, InsertAndLookup) {
+  QuicLRUCache<int, CachedItem> cache(5);
+  EXPECT_EQ(cache.end(), cache.Lookup(1));
+  EXPECT_EQ(0u, cache.Size());
+  EXPECT_EQ(5u, cache.MaxSize());
+
+  // Check that item 1 was properly inserted.
+  std::unique_ptr<CachedItem> item1(new CachedItem(11));
+  cache.Insert(1, std::move(item1));
+  EXPECT_EQ(1u, cache.Size());
+  EXPECT_EQ(11u, cache.Lookup(1)->second->value);
+
+  // Check that item 2 overrides item 1.
+  std::unique_ptr<CachedItem> item2(new CachedItem(12));
+  cache.Insert(1, std::move(item2));
+  EXPECT_EQ(1u, cache.Size());
+  EXPECT_EQ(12u, cache.Lookup(1)->second->value);
+
+  std::unique_ptr<CachedItem> item3(new CachedItem(13));
+  cache.Insert(3, std::move(item3));
+  EXPECT_EQ(2u, cache.Size());
+  auto iter = cache.Lookup(3);
+  ASSERT_NE(cache.end(), iter);
+  EXPECT_EQ(13u, iter->second->value);
+  cache.Erase(iter);
+  ASSERT_EQ(cache.end(), cache.Lookup(3));
+  EXPECT_EQ(1u, cache.Size());
+
+  // No memory leakage.
+  cache.Clear();
+  EXPECT_EQ(0u, cache.Size());
+}
+
+TEST(QuicLRUCacheTest, Eviction) {
+  QuicLRUCache<int, CachedItem> cache(3);
+
+  for (size_t i = 1; i <= 4; ++i) {
+    std::unique_ptr<CachedItem> item(new CachedItem(10 + i));
+    cache.Insert(i, std::move(item));
+  }
+
+  EXPECT_EQ(3u, cache.Size());
+  EXPECT_EQ(3u, cache.MaxSize());
+
+  // Make sure item 1 is evicted.
+  EXPECT_EQ(cache.end(), cache.Lookup(1));
+  EXPECT_EQ(14u, cache.Lookup(4)->second->value);
+
+  EXPECT_EQ(12u, cache.Lookup(2)->second->value);
+  std::unique_ptr<CachedItem> item5(new CachedItem(15));
+  cache.Insert(5, std::move(item5));
+  // Make sure item 3 is evicted.
+  EXPECT_EQ(cache.end(), cache.Lookup(3));
+  EXPECT_EQ(15u, cache.Lookup(5)->second->value);
+
+  // No memory leakage.
+  cache.Clear();
+  EXPECT_EQ(0u, cache.Size());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_mtu_discovery.cc b/quiche/quic/core/quic_mtu_discovery.cc
new file mode 100644
index 0000000..95080f7
--- /dev/null
+++ b/quiche/quic/core/quic_mtu_discovery.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_mtu_discovery.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+
+namespace quic {
+
+QuicConnectionMtuDiscoverer::QuicConnectionMtuDiscoverer(
+    QuicPacketCount packets_between_probes_base,
+    QuicPacketNumber next_probe_at)
+    : packets_between_probes_(packets_between_probes_base),
+      next_probe_at_(next_probe_at) {}
+
+void QuicConnectionMtuDiscoverer::Enable(
+    QuicByteCount max_packet_length,
+    QuicByteCount target_max_packet_length) {
+  QUICHE_DCHECK(!IsEnabled());
+
+  if (target_max_packet_length <= max_packet_length) {
+    QUIC_DVLOG(1) << "MtuDiscoverer not enabled. target_max_packet_length:"
+                  << target_max_packet_length
+                  << " <= max_packet_length:" << max_packet_length;
+    return;
+  }
+
+  min_probe_length_ = max_packet_length;
+  max_probe_length_ = target_max_packet_length;
+  QUICHE_DCHECK(IsEnabled());
+
+  QUIC_DVLOG(1) << "MtuDiscoverer enabled. min:" << min_probe_length_
+                << ", max:" << max_probe_length_
+                << ", next:" << next_probe_packet_length();
+}
+
+void QuicConnectionMtuDiscoverer::Disable() {
+  *this = QuicConnectionMtuDiscoverer(packets_between_probes_, next_probe_at_);
+}
+
+bool QuicConnectionMtuDiscoverer::IsEnabled() const {
+  return min_probe_length_ < max_probe_length_;
+}
+
+bool QuicConnectionMtuDiscoverer::ShouldProbeMtu(
+    QuicPacketNumber largest_sent_packet) const {
+  if (!IsEnabled()) {
+    return false;
+  }
+
+  if (remaining_probe_count_ == 0) {
+    QUIC_DVLOG(1)
+        << "ShouldProbeMtu returns false because max probe count reached";
+    return false;
+  }
+
+  if (largest_sent_packet < next_probe_at_) {
+    QUIC_DVLOG(1) << "ShouldProbeMtu returns false because not enough packets "
+                     "sent since last probe. largest_sent_packet:"
+                  << largest_sent_packet
+                  << ", next_probe_at_:" << next_probe_at_;
+    return false;
+  }
+
+  QUIC_DVLOG(1) << "ShouldProbeMtu returns true. largest_sent_packet:"
+                << largest_sent_packet;
+  return true;
+}
+
+QuicPacketLength QuicConnectionMtuDiscoverer::GetUpdatedMtuProbeSize(
+    QuicPacketNumber largest_sent_packet) {
+  QUICHE_DCHECK(ShouldProbeMtu(largest_sent_packet));
+
+  QuicPacketLength probe_packet_length = next_probe_packet_length();
+  if (probe_packet_length == last_probe_length_) {
+    // The next probe packet is as big as the previous one. Assuming the
+    // previous one exceeded MTU, we need to decrease the probe packet length.
+    max_probe_length_ = probe_packet_length;
+  } else {
+    QUICHE_DCHECK_GT(probe_packet_length, last_probe_length_);
+  }
+  last_probe_length_ = next_probe_packet_length();
+
+  packets_between_probes_ *= 2;
+  next_probe_at_ = largest_sent_packet + packets_between_probes_ + 1;
+  if (remaining_probe_count_ > 0) {
+    --remaining_probe_count_;
+  }
+
+  QUIC_DVLOG(1) << "GetUpdatedMtuProbeSize: probe_packet_length:"
+                << last_probe_length_
+                << ", New packets_between_probes_:" << packets_between_probes_
+                << ", next_probe_at_:" << next_probe_at_
+                << ", remaining_probe_count_:" << remaining_probe_count_;
+  QUICHE_DCHECK(!ShouldProbeMtu(largest_sent_packet));
+  return last_probe_length_;
+}
+
+QuicPacketLength QuicConnectionMtuDiscoverer::next_probe_packet_length() const {
+  QUICHE_DCHECK_NE(min_probe_length_, 0);
+  QUICHE_DCHECK_NE(max_probe_length_, 0);
+  QUICHE_DCHECK_GE(max_probe_length_, min_probe_length_);
+
+  const QuicPacketLength normal_next_probe_length =
+      (min_probe_length_ + max_probe_length_ + 1) / 2;
+
+  if (remaining_probe_count_ == 1 &&
+      normal_next_probe_length > last_probe_length_) {
+    // If the previous probe succeeded, and there is only one last probe to
+    // send, use |max_probe_length_| for the last probe.
+    return max_probe_length_;
+  }
+  return normal_next_probe_length;
+}
+
+void QuicConnectionMtuDiscoverer::OnMaxPacketLengthUpdated(
+    QuicByteCount old_value,
+    QuicByteCount new_value) {
+  if (!IsEnabled() || new_value <= old_value) {
+    return;
+  }
+
+  QUICHE_DCHECK_EQ(old_value, min_probe_length_);
+  min_probe_length_ = new_value;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicConnectionMtuDiscoverer& d) {
+  os << "{ min_probe_length_:" << d.min_probe_length_
+     << " max_probe_length_:" << d.max_probe_length_
+     << " last_probe_length_:" << d.last_probe_length_
+     << " remaining_probe_count_:" << d.remaining_probe_count_
+     << " packets_between_probes_:" << d.packets_between_probes_
+     << " next_probe_at_:" << d.next_probe_at_ << " }";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_mtu_discovery.h b/quiche/quic/core/quic_mtu_discovery.h
new file mode 100644
index 0000000..6175d6d
--- /dev/null
+++ b/quiche/quic/core/quic_mtu_discovery.h
@@ -0,0 +1,117 @@
+// Copyright (c) 2019 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_MTU_DISCOVERY_H_
+#define QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
+
+#include <iostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+// The initial number of packets between MTU probes.  After each attempt the
+// number is doubled.
+const QuicPacketCount kPacketsBetweenMtuProbesBase = 100;
+
+// The number of MTU probes that get sent before giving up.
+const size_t kMtuDiscoveryAttempts = 3;
+
+// Ensure that exponential back-off does not result in an integer overflow.
+// The number of packets can be potentially capped, but that is not useful at
+// current kMtuDiscoveryAttempts value, and hence is not implemented at present.
+static_assert(kMtuDiscoveryAttempts + 8 < 8 * sizeof(QuicPacketNumber),
+              "The number of MTU discovery attempts is too high");
+static_assert(kPacketsBetweenMtuProbesBase < (1 << 8),
+              "The initial number of packets between MTU probes is too high");
+
+// The increased packet size targeted when doing path MTU discovery.
+const QuicByteCount kMtuDiscoveryTargetPacketSizeHigh = 1400;
+const QuicByteCount kMtuDiscoveryTargetPacketSizeLow = 1380;
+
+static_assert(kMtuDiscoveryTargetPacketSizeLow <= kMaxOutgoingPacketSize,
+              "MTU discovery target is too large");
+static_assert(kMtuDiscoveryTargetPacketSizeHigh <= kMaxOutgoingPacketSize,
+              "MTU discovery target is too large");
+
+static_assert(kMtuDiscoveryTargetPacketSizeLow > kDefaultMaxPacketSize,
+              "MTU discovery target does not exceed the default packet size");
+static_assert(kMtuDiscoveryTargetPacketSizeHigh > kDefaultMaxPacketSize,
+              "MTU discovery target does not exceed the default packet size");
+
+// QuicConnectionMtuDiscoverer is a MTU discovery controller, it answers two
+// questions:
+// 1) Probe scheduling: Whether a connection should send a MTU probe packet
+//    right now.
+// 2) MTU search stradegy: When it is time to send, what should be the size of
+//    the probing packet.
+// Note the discoverer does not actually send or process probing packets.
+//
+// Unit tests are in QuicConnectionTest.MtuDiscovery*.
+class QUIC_EXPORT_PRIVATE QuicConnectionMtuDiscoverer {
+ public:
+  // Construct a discoverer in the disabled state.
+  QuicConnectionMtuDiscoverer() = default;
+
+  // Construct a discoverer in the disabled state, with the given parameters.
+  QuicConnectionMtuDiscoverer(QuicPacketCount packets_between_probes_base,
+                              QuicPacketNumber next_probe_at);
+
+  // Enable the discoverer by setting the probe target.
+  // max_packet_length: The max packet length currently used.
+  // target_max_packet_length: The target max packet length to probe.
+  void Enable(QuicByteCount max_packet_length,
+              QuicByteCount target_max_packet_length);
+
+  // Disable the discoverer by unsetting the probe target.
+  void Disable();
+
+  // Whether a MTU probe packet should be sent right now.
+  // Always return false if disabled.
+  bool ShouldProbeMtu(QuicPacketNumber largest_sent_packet) const;
+
+  // Called immediately before a probing packet is sent, to get the size of the
+  // packet.
+  // REQUIRES: ShouldProbeMtu(largest_sent_packet) == true.
+  QuicPacketLength GetUpdatedMtuProbeSize(QuicPacketNumber largest_sent_packet);
+
+  // Called after the max packet length is updated, which is triggered by a ack
+  // of a probing packet.
+  void OnMaxPacketLengthUpdated(QuicByteCount old_value,
+                                QuicByteCount new_value);
+
+  QuicPacketCount packets_between_probes() const {
+    return packets_between_probes_;
+  }
+
+  QuicPacketNumber next_probe_at() const { return next_probe_at_; }
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicConnectionMtuDiscoverer& d);
+
+ private:
+  bool IsEnabled() const;
+  QuicPacketLength next_probe_packet_length() const;
+
+  QuicPacketLength min_probe_length_ = 0;
+  QuicPacketLength max_probe_length_ = 0;
+
+  QuicPacketLength last_probe_length_ = 0;
+
+  uint16_t remaining_probe_count_ = kMtuDiscoveryAttempts;
+
+  // The number of packets between MTU probes.
+  QuicPacketCount packets_between_probes_ = kPacketsBetweenMtuProbesBase;
+
+  // The packet number of the packet after which the next MTU probe will be
+  // sent.
+  QuicPacketNumber next_probe_at_ =
+      QuicPacketNumber(kPacketsBetweenMtuProbesBase);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
diff --git a/quiche/quic/core/quic_network_blackhole_detector.cc b/quiche/quic/core/quic_network_blackhole_detector.cc
new file mode 100644
index 0000000..da9262a
--- /dev/null
+++ b/quiche/quic/core/quic_network_blackhole_detector.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2020 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 "quiche/quic/core/quic_network_blackhole_detector.h"
+
+#include "quiche/quic/core/quic_constants.h"
+
+namespace quic {
+
+namespace {
+
+class AlarmDelegate : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit AlarmDelegate(QuicNetworkBlackholeDetector* detector,
+                         QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context), detector_(detector) {}
+  AlarmDelegate(const AlarmDelegate&) = delete;
+  AlarmDelegate& operator=(const AlarmDelegate&) = delete;
+
+  void OnAlarm() override { detector_->OnAlarm(); }
+
+ private:
+  QuicNetworkBlackholeDetector* detector_;
+};
+
+}  // namespace
+
+QuicNetworkBlackholeDetector::QuicNetworkBlackholeDetector(
+    Delegate* delegate, QuicConnectionArena* arena,
+    QuicAlarmFactory* alarm_factory, QuicConnectionContext* context)
+    : delegate_(delegate),
+      alarm_(alarm_factory->CreateAlarm(
+          arena->New<AlarmDelegate>(this, context), arena)) {}
+
+void QuicNetworkBlackholeDetector::OnAlarm() {
+  QuicTime next_deadline = GetEarliestDeadline();
+  if (!next_deadline.IsInitialized()) {
+    QUIC_BUG(quic_bug_10328_1) << "BlackholeDetector alarm fired unexpectedly";
+    return;
+  }
+
+  QUIC_DVLOG(1) << "BlackholeDetector alarm firing. next_deadline:"
+                << next_deadline
+                << ", path_degrading_deadline_:" << path_degrading_deadline_
+                << ", path_mtu_reduction_deadline_:"
+                << path_mtu_reduction_deadline_
+                << ", blackhole_deadline_:" << blackhole_deadline_;
+  if (path_degrading_deadline_ == next_deadline) {
+    path_degrading_deadline_ = QuicTime::Zero();
+    delegate_->OnPathDegradingDetected();
+  }
+
+  if (path_mtu_reduction_deadline_ == next_deadline) {
+    path_mtu_reduction_deadline_ = QuicTime::Zero();
+    delegate_->OnPathMtuReductionDetected();
+  }
+
+  if (blackhole_deadline_ == next_deadline) {
+    blackhole_deadline_ = QuicTime::Zero();
+    delegate_->OnBlackholeDetected();
+  }
+
+  UpdateAlarm();
+}
+
+void QuicNetworkBlackholeDetector::StopDetection(bool permanent) {
+  if (permanent) {
+    alarm_->PermanentCancel();
+  } else {
+    alarm_->Cancel();
+  }
+  path_degrading_deadline_ = QuicTime::Zero();
+  blackhole_deadline_ = QuicTime::Zero();
+  path_mtu_reduction_deadline_ = QuicTime::Zero();
+}
+
+void QuicNetworkBlackholeDetector::RestartDetection(
+    QuicTime path_degrading_deadline,
+    QuicTime blackhole_deadline,
+    QuicTime path_mtu_reduction_deadline) {
+  path_degrading_deadline_ = path_degrading_deadline;
+  blackhole_deadline_ = blackhole_deadline;
+  path_mtu_reduction_deadline_ = path_mtu_reduction_deadline;
+
+  QUIC_BUG_IF(quic_bug_12708_1, blackhole_deadline_.IsInitialized() &&
+                                    blackhole_deadline_ != GetLastDeadline())
+      << "Blackhole detection deadline should be the last deadline.";
+
+  UpdateAlarm();
+}
+
+QuicTime QuicNetworkBlackholeDetector::GetEarliestDeadline() const {
+  QuicTime result = QuicTime::Zero();
+  for (QuicTime t : {path_degrading_deadline_, blackhole_deadline_,
+                     path_mtu_reduction_deadline_}) {
+    if (!t.IsInitialized()) {
+      continue;
+    }
+
+    if (!result.IsInitialized() || t < result) {
+      result = t;
+    }
+  }
+
+  return result;
+}
+
+QuicTime QuicNetworkBlackholeDetector::GetLastDeadline() const {
+  return std::max({path_degrading_deadline_, blackhole_deadline_,
+                   path_mtu_reduction_deadline_});
+}
+
+void QuicNetworkBlackholeDetector::UpdateAlarm() const {
+  // If called after OnBlackholeDetected(), the alarm may have been permanently
+  // cancelled and is not safe to be armed again.
+  if (alarm_->IsPermanentlyCancelled()) {
+    return;
+  }
+
+  QuicTime next_deadline = GetEarliestDeadline();
+
+  QUIC_DVLOG(1) << "Updating alarm. next_deadline:" << next_deadline
+                << ", path_degrading_deadline_:" << path_degrading_deadline_
+                << ", path_mtu_reduction_deadline_:"
+                << path_mtu_reduction_deadline_
+                << ", blackhole_deadline_:" << blackhole_deadline_;
+
+  alarm_->Update(next_deadline, kAlarmGranularity);
+}
+
+bool QuicNetworkBlackholeDetector::IsDetectionInProgress() const {
+  return alarm_->IsSet();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_network_blackhole_detector.h b/quiche/quic/core/quic_network_blackhole_detector.h
new file mode 100644
index 0000000..7defc47
--- /dev/null
+++ b/quiche/quic/core/quic_network_blackhole_detector.h
@@ -0,0 +1,91 @@
+// Copyright (c) 2020 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_NETWORK_BLACKHOLE_DETECTOR_H_
+#define QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace test {
+class QuicConnectionPeer;
+class QuicNetworkBlackholeDetectorPeer;
+}  // namespace test
+
+// QuicNetworkBlackholeDetector can detect path degrading and/or network
+// blackhole. If both detections are in progress, detector will be in path
+// degrading detection mode. After reporting path degrading detected, detector
+// switches to blackhole detection mode. So blackhole detection deadline must
+// be later than path degrading deadline.
+class QUIC_EXPORT_PRIVATE QuicNetworkBlackholeDetector {
+ public:
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // Called when the path degrading alarm fires.
+    virtual void OnPathDegradingDetected() = 0;
+
+    // Called when the path blackhole alarm fires.
+    virtual void OnBlackholeDetected() = 0;
+
+    // Called when the path mtu reduction alarm fires.
+    virtual void OnPathMtuReductionDetected() = 0;
+  };
+
+  QuicNetworkBlackholeDetector(Delegate* delegate, QuicConnectionArena* arena,
+                               QuicAlarmFactory* alarm_factory,
+                               QuicConnectionContext* context);
+
+  // Called to stop all detections. If |permanent|, the alarm will be cancelled
+  // permanently and future calls to RestartDetection will be no-op.
+  void StopDetection(bool permanent);
+
+  // Called to restart path degrading, path mtu reduction and blackhole
+  // detections. Please note, if |blackhole_deadline| is set, it must be the
+  // furthest in the future of all deadlines.
+  void RestartDetection(QuicTime path_degrading_deadline,
+                        QuicTime blackhole_deadline,
+                        QuicTime path_mtu_reduction_deadline);
+
+  // Called when |alarm_| fires.
+  void OnAlarm();
+
+  // Returns true if |alarm_| is set.
+  bool IsDetectionInProgress() const;
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::QuicNetworkBlackholeDetectorPeer;
+
+  QuicTime GetEarliestDeadline() const;
+  QuicTime GetLastDeadline() const;
+
+  // Update alarm to the next deadline.
+  void UpdateAlarm() const;
+
+  Delegate* delegate_;  // Not owned.
+
+  // Time that Delegate::OnPathDegrading will be called. 0 means no path
+  // degrading detection is in progress.
+  QuicTime path_degrading_deadline_ = QuicTime::Zero();
+  // Time that Delegate::OnBlackholeDetected will be called. 0 means no
+  // blackhole detection is in progress.
+  QuicTime blackhole_deadline_ = QuicTime::Zero();
+  // Time that Delegate::OnPathMtuReductionDetected will be called. 0 means no
+  // path mtu reduction detection is in progress.
+  QuicTime path_mtu_reduction_deadline_ = QuicTime::Zero();
+
+  QuicArenaScopedPtr<QuicAlarm> alarm_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
diff --git a/quiche/quic/core/quic_network_blackhole_detector_test.cc b/quiche/quic/core/quic_network_blackhole_detector_test.cc
new file mode 100644
index 0000000..ca2c87d
--- /dev/null
+++ b/quiche/quic/core/quic_network_blackhole_detector_test.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2020 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 "quiche/quic/core/quic_network_blackhole_detector.h"
+
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class QuicNetworkBlackholeDetectorPeer {
+ public:
+  static QuicAlarm* GetAlarm(QuicNetworkBlackholeDetector* detector) {
+    return detector->alarm_.get();
+  }
+};
+
+namespace {
+class MockDelegate : public QuicNetworkBlackholeDetector::Delegate {
+ public:
+  MOCK_METHOD(void, OnPathDegradingDetected, (), (override));
+  MOCK_METHOD(void, OnBlackholeDetected, (), (override));
+  MOCK_METHOD(void, OnPathMtuReductionDetected, (), (override));
+};
+
+const size_t kPathDegradingDelayInSeconds = 5;
+const size_t kPathMtuReductionDelayInSeconds = 7;
+const size_t kBlackholeDelayInSeconds = 10;
+
+class QuicNetworkBlackholeDetectorTest : public QuicTest {
+ public:
+  QuicNetworkBlackholeDetectorTest()
+      : detector_(&delegate_, &arena_, &alarm_factory_, /*context=*/nullptr),
+        alarm_(static_cast<MockAlarmFactory::TestAlarm*>(
+            QuicNetworkBlackholeDetectorPeer::GetAlarm(&detector_))),
+        path_degrading_delay_(
+            QuicTime::Delta::FromSeconds(kPathDegradingDelayInSeconds)),
+        path_mtu_reduction_delay_(
+            QuicTime::Delta::FromSeconds(kPathMtuReductionDelayInSeconds)),
+        blackhole_delay_(
+            QuicTime::Delta::FromSeconds(kBlackholeDelayInSeconds)) {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+ protected:
+  void RestartDetection() {
+    detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
+                               clock_.Now() + blackhole_delay_,
+                               clock_.Now() + path_mtu_reduction_delay_);
+  }
+
+  testing::StrictMock<MockDelegate> delegate_;
+  QuicConnectionArena arena_;
+  MockAlarmFactory alarm_factory_;
+
+  QuicNetworkBlackholeDetector detector_;
+
+  MockAlarmFactory::TestAlarm* alarm_;
+  MockClock clock_;
+  const QuicTime::Delta path_degrading_delay_;
+  const QuicTime::Delta path_mtu_reduction_delay_;
+  const QuicTime::Delta blackhole_delay_;
+};
+
+TEST_F(QuicNetworkBlackholeDetectorTest, StartAndFire) {
+  EXPECT_FALSE(detector_.IsDetectionInProgress());
+
+  RestartDetection();
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
+
+  // Fire path degrading alarm.
+  clock_.AdvanceTime(path_degrading_delay_);
+  EXPECT_CALL(delegate_, OnPathDegradingDetected());
+  alarm_->Fire();
+
+  // Verify path mtu reduction detection is still in progress.
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
+            alarm_->deadline());
+
+  // Fire path mtu reduction detection alarm.
+  clock_.AdvanceTime(path_mtu_reduction_delay_ - path_degrading_delay_);
+  EXPECT_CALL(delegate_, OnPathMtuReductionDetected());
+  alarm_->Fire();
+
+  // Verify blackhole detection is still in progress.
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + blackhole_delay_ - path_mtu_reduction_delay_,
+            alarm_->deadline());
+
+  // Fire blackhole detection alarm.
+  clock_.AdvanceTime(blackhole_delay_ - path_mtu_reduction_delay_);
+  EXPECT_CALL(delegate_, OnBlackholeDetected());
+  alarm_->Fire();
+  EXPECT_FALSE(detector_.IsDetectionInProgress());
+}
+
+TEST_F(QuicNetworkBlackholeDetectorTest, RestartAndStop) {
+  RestartDetection();
+
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  RestartDetection();
+  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
+
+  detector_.StopDetection(/*permanent=*/false);
+  EXPECT_FALSE(detector_.IsDetectionInProgress());
+}
+
+TEST_F(QuicNetworkBlackholeDetectorTest, PathDegradingFiresAndRestart) {
+  EXPECT_FALSE(detector_.IsDetectionInProgress());
+  RestartDetection();
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
+
+  // Fire path degrading alarm.
+  clock_.AdvanceTime(path_degrading_delay_);
+  EXPECT_CALL(delegate_, OnPathDegradingDetected());
+  alarm_->Fire();
+
+  // Verify path mtu reduction detection is still in progress.
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
+            alarm_->deadline());
+
+  // After 100ms, restart detections on forward progress.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  RestartDetection();
+  // Verify alarm is armed based on path degrading deadline.
+  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
+}
+
+}  // namespace
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_one_block_arena.h b/quiche/quic/core/quic_one_block_arena.h
new file mode 100644
index 0000000..4bebebe
--- /dev/null
+++ b/quiche/quic/core/quic_one_block_arena.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2016 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.
+
+// An arena that consists of a single inlined block of |ArenaSize|. Useful to
+// avoid repeated calls to malloc/new and to improve memory locality.
+// QUICHE_DCHECK's if an allocation out of the arena ever fails in debug builds;
+// falls back to heap allocation in release builds.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
+#define QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_arena_scoped_ptr.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+template <uint32_t ArenaSize>
+class QUIC_EXPORT_PRIVATE QuicOneBlockArena {
+  static const uint32_t kMaxAlign = 8;
+
+ public:
+  QuicOneBlockArena() : offset_(0) {}
+  QuicOneBlockArena(const QuicOneBlockArena&) = delete;
+  QuicOneBlockArena& operator=(const QuicOneBlockArena&) = delete;
+
+  // Instantiates an object of type |T| with |args|. |args| are perfectly
+  // forwarded to |T|'s constructor. The returned pointer's lifetime is
+  // controlled by QuicArenaScopedPtr.
+  template <typename T, typename... Args>
+  QuicArenaScopedPtr<T> New(Args&&... args) {
+    QUICHE_DCHECK_LT(AlignedSize<T>(), ArenaSize)
+        << "Object is too large for the arena.";
+    static_assert(alignof(T) > 1,
+                  "Objects added to the arena must be at least 2B aligned.");
+    if (QUIC_PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) {
+      QUIC_BUG(quic_bug_10593_1)
+          << "Ran out of space in QuicOneBlockArena at " << this
+          << ", max size was " << ArenaSize << ", failing request was "
+          << AlignedSize<T>() << ", end of arena was " << offset_;
+      return QuicArenaScopedPtr<T>(new T(std::forward<Args>(args)...));
+    }
+
+    void* buf = &storage_[offset_];
+    new (buf) T(std::forward<Args>(args)...);
+    offset_ += AlignedSize<T>();
+    return QuicArenaScopedPtr<T>(buf,
+                                 QuicArenaScopedPtr<T>::ConstructFrom::kArena);
+  }
+
+ private:
+  // Returns the size of |T| aligned up to |kMaxAlign|.
+  template <typename T>
+  static inline uint32_t AlignedSize() {
+    return ((sizeof(T) + (kMaxAlign - 1)) / kMaxAlign) * kMaxAlign;
+  }
+
+  // Actual storage.
+  // Subtle/annoying: the value '8' must be coded explicitly into the alignment
+  // declaration for MSVC.
+  alignas(8) char storage_[ArenaSize];
+  // Current offset into the storage.
+  uint32_t offset_;
+};
+
+// QuicConnections currently use around 1KB of polymorphic types which would
+// ordinarily be on the heap. Instead, store them inline in an arena.
+using QuicConnectionArena = QuicOneBlockArena<1152>;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
diff --git a/quiche/quic/core/quic_one_block_arena_test.cc b/quiche/quic/core/quic_one_block_arena_test.cc
new file mode 100644
index 0000000..89c774d
--- /dev/null
+++ b/quiche/quic/core/quic_one_block_arena_test.cc
@@ -0,0 +1,60 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_one_block_arena.h"
+
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace {
+
+static const uint32_t kMaxAlign = 8;
+
+struct TestObject {
+  uint32_t value;
+};
+
+class QuicOneBlockArenaTest : public QuicTest {};
+
+TEST_F(QuicOneBlockArenaTest, AllocateSuccess) {
+  QuicOneBlockArena<1024> arena;
+  QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
+  EXPECT_TRUE(ptr.is_from_arena());
+}
+
+TEST_F(QuicOneBlockArenaTest, Exhaust) {
+  QuicOneBlockArena<1024> arena;
+  for (size_t i = 0; i < 1024 / kMaxAlign; ++i) {
+    QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
+    EXPECT_TRUE(ptr.is_from_arena());
+  }
+  QuicArenaScopedPtr<TestObject> ptr;
+  EXPECT_QUIC_BUG(ptr = arena.New<TestObject>(),
+                  "Ran out of space in QuicOneBlockArena");
+  EXPECT_FALSE(ptr.is_from_arena());
+}
+
+TEST_F(QuicOneBlockArenaTest, NoOverlaps) {
+  QuicOneBlockArena<1024> arena;
+  std::vector<QuicArenaScopedPtr<TestObject>> objects;
+  QuicIntervalSet<uintptr_t> used;
+  for (size_t i = 0; i < 1024 / kMaxAlign; ++i) {
+    QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
+    EXPECT_TRUE(ptr.is_from_arena());
+
+    uintptr_t begin = reinterpret_cast<uintptr_t>(ptr.get());
+    uintptr_t end = begin + sizeof(TestObject);
+    EXPECT_FALSE(used.Contains(begin));
+    EXPECT_FALSE(used.Contains(end - 1));
+    used.Add(begin, end);
+  }
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_creator.cc b/quiche/quic/core/quic_packet_creator.cc
new file mode 100644
index 0000000..4390747
--- /dev/null
+++ b/quiche/quic/core/quic_packet_creator.cc
@@ -0,0 +1,2306 @@
+// 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 "quiche/quic/core/quic_packet_creator.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/base/optimization.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/frames/quic_path_challenge_frame.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_chaos_protector.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+#include "quiche/common/print_elements.h"
+
+namespace quic {
+namespace {
+
+QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      return INITIAL;
+    case ENCRYPTION_HANDSHAKE:
+      return HANDSHAKE;
+    case ENCRYPTION_ZERO_RTT:
+      return ZERO_RTT_PROTECTED;
+    case ENCRYPTION_FORWARD_SECURE:
+      QUIC_BUG(quic_bug_12398_1)
+          << "Try to derive long header type for packet with encryption level: "
+          << level;
+      return INVALID_PACKET_TYPE;
+    default:
+      QUIC_BUG(quic_bug_10752_1) << level;
+      return INVALID_PACKET_TYPE;
+  }
+}
+
+void LogCoalesceStreamFrameStatus(bool success) {
+  QUIC_HISTOGRAM_BOOL("QuicSession.CoalesceStreamFrameStatus", success,
+                      "Success rate of coalesing stream frames attempt.");
+}
+
+// ScopedPacketContextSwitcher saves |packet|'s states and change states
+// during its construction. When the switcher goes out of scope, it restores
+// saved states.
+class ScopedPacketContextSwitcher {
+ public:
+  ScopedPacketContextSwitcher(QuicPacketNumber packet_number,
+                              QuicPacketNumberLength packet_number_length,
+                              EncryptionLevel encryption_level,
+                              SerializedPacket* packet)
+
+      : saved_packet_number_(packet->packet_number),
+        saved_packet_number_length_(packet->packet_number_length),
+        saved_encryption_level_(packet->encryption_level),
+        packet_(packet) {
+    packet_->packet_number = packet_number,
+    packet_->packet_number_length = packet_number_length;
+    packet_->encryption_level = encryption_level;
+  }
+
+  ~ScopedPacketContextSwitcher() {
+    packet_->packet_number = saved_packet_number_;
+    packet_->packet_number_length = saved_packet_number_length_;
+    packet_->encryption_level = saved_encryption_level_;
+  }
+
+ private:
+  const QuicPacketNumber saved_packet_number_;
+  const QuicPacketNumberLength saved_packet_number_length_;
+  const EncryptionLevel saved_encryption_level_;
+  SerializedPacket* packet_;
+};
+
+}  // namespace
+
+#define ENDPOINT \
+  (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
+                                     QuicFramer* framer,
+                                     DelegateInterface* delegate)
+    : QuicPacketCreator(server_connection_id,
+                        framer,
+                        QuicRandom::GetInstance(),
+                        delegate) {}
+
+QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
+                                     QuicFramer* framer, QuicRandom* random,
+                                     DelegateInterface* delegate)
+    : delegate_(delegate),
+      debug_delegate_(nullptr),
+      framer_(framer),
+      random_(random),
+      send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
+      have_diversification_nonce_(false),
+      max_packet_length_(0),
+      server_connection_id_included_(CONNECTION_ID_PRESENT),
+      packet_size_(0),
+      server_connection_id_(server_connection_id),
+      client_connection_id_(EmptyQuicConnectionId()),
+      packet_(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER, nullptr, 0, false,
+              false),
+      pending_padding_bytes_(0),
+      needs_full_padding_(false),
+      next_transmission_type_(NOT_RETRANSMISSION),
+      flusher_attached_(false),
+      fully_pad_crypto_handshake_packets_(true),
+      latched_hard_max_packet_length_(0),
+      max_datagram_frame_size_(0),
+      chaos_protection_enabled_(
+          GetQuicFlag(FLAGS_quic_enable_chaos_protection) &&
+          framer->perspective() == Perspective::IS_CLIENT) {
+  SetMaxPacketLength(kDefaultMaxPacketSize);
+  if (!framer_->version().UsesTls()) {
+    // QUIC+TLS negotiates the maximum datagram frame size via the
+    // IETF QUIC max_datagram_frame_size transport parameter.
+    // QUIC_CRYPTO however does not negotiate this so we set its value here.
+    SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+}
+
+QuicPacketCreator::~QuicPacketCreator() {
+  DeleteFrames(&packet_.retransmittable_frames);
+}
+
+void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
+                                     std::unique_ptr<QuicEncrypter> encrypter) {
+  framer_->SetEncrypter(level, std::move(encrypter));
+  max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
+}
+
+bool QuicPacketCreator::CanSetMaxPacketLength() const {
+  // |max_packet_length_| should not be changed mid-packet.
+  return queued_frames_.empty();
+}
+
+void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
+  QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
+
+  // Avoid recomputing |max_plaintext_size_| if the length does not actually
+  // change.
+  if (length == max_packet_length_) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Updating packet creator max packet length from "
+                << max_packet_length_ << " to " << length;
+
+  max_packet_length_ = length;
+  max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
+  QUIC_BUG_IF(quic_bug_12398_2, max_plaintext_size_ - PacketHeaderSize() <
+                                    MinPlaintextPacketSize(framer_->version()))
+      << ENDPOINT << "Attempted to set max packet length too small";
+}
+
+void QuicPacketCreator::SetMaxDatagramFrameSize(
+    QuicByteCount max_datagram_frame_size) {
+  constexpr QuicByteCount upper_bound =
+      std::min<QuicByteCount>(std::numeric_limits<QuicPacketLength>::max(),
+                              std::numeric_limits<size_t>::max());
+  if (max_datagram_frame_size > upper_bound) {
+    // A value of |max_datagram_frame_size| that is equal or greater than
+    // 2^16-1 is effectively infinite because QUIC packets cannot be that large.
+    // We therefore clamp the value here to allow us to safely cast
+    // |max_datagram_frame_size_| to QuicPacketLength or size_t.
+    max_datagram_frame_size = upper_bound;
+  }
+  max_datagram_frame_size_ = max_datagram_frame_size;
+}
+
+void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
+  QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
+  if (length > max_packet_length_) {
+    QUIC_BUG(quic_bug_10752_2)
+        << ENDPOINT
+        << "Try to increase max_packet_length_ in "
+           "SetSoftMaxPacketLength, use SetMaxPacketLength instead.";
+    return;
+  }
+  if (framer_->GetMaxPlaintextSize(length) <
+      PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
+    // Please note: this would not guarantee to fit next packet if the size of
+    // packet header increases (e.g., encryption level changes).
+    QUIC_DLOG(INFO) << ENDPOINT << length
+                    << " is too small to fit packet header";
+    RemoveSoftMaxPacketLength();
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Setting soft max packet length to: " << length;
+  latched_hard_max_packet_length_ = max_packet_length_;
+  max_packet_length_ = length;
+  max_plaintext_size_ = framer_->GetMaxPlaintextSize(length);
+}
+
+// Stops serializing version of the protocol in packets sent after this call.
+// A packet that is already open might send kQuicVersionSize bytes less than the
+// maximum packet size if we stop sending version before it is serialized.
+void QuicPacketCreator::StopSendingVersion() {
+  QUICHE_DCHECK(send_version_in_packet_) << ENDPOINT;
+  QUICHE_DCHECK(!version().HasIetfInvariantHeader()) << ENDPOINT;
+  send_version_in_packet_ = false;
+  if (packet_size_ > 0) {
+    QUICHE_DCHECK_LT(kQuicVersionSize, packet_size_) << ENDPOINT;
+    packet_size_ -= kQuicVersionSize;
+  }
+}
+
+void QuicPacketCreator::SetDiversificationNonce(
+    const DiversificationNonce& nonce) {
+  QUICHE_DCHECK(!have_diversification_nonce_) << ENDPOINT;
+  have_diversification_nonce_ = true;
+  diversification_nonce_ = nonce;
+}
+
+void QuicPacketCreator::UpdatePacketNumberLength(
+    QuicPacketNumber least_packet_awaited_by_peer,
+    QuicPacketCount max_packets_in_flight) {
+  if (!queued_frames_.empty()) {
+    // Don't change creator state if there are frames queued.
+    QUIC_BUG(quic_bug_10752_3)
+        << ENDPOINT << "Called UpdatePacketNumberLength with "
+        << queued_frames_.size()
+        << " queued_frames.  First frame type:" << queued_frames_.front().type
+        << " last frame type:" << queued_frames_.back().type;
+    return;
+  }
+
+  const QuicPacketNumber next_packet_number = NextSendingPacketNumber();
+  QUICHE_DCHECK_LE(least_packet_awaited_by_peer, next_packet_number)
+      << ENDPOINT;
+  const uint64_t current_delta =
+      next_packet_number - least_packet_awaited_by_peer;
+  const uint64_t delta = std::max(current_delta, max_packets_in_flight);
+  const QuicPacketNumberLength packet_number_length =
+      QuicFramer::GetMinPacketNumberLength(QuicPacketNumber(delta * 4));
+  if (packet_.packet_number_length == packet_number_length) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Updating packet number length from "
+                << static_cast<int>(packet_.packet_number_length) << " to "
+                << static_cast<int>(packet_number_length)
+                << ", least_packet_awaited_by_peer: "
+                << least_packet_awaited_by_peer
+                << " max_packets_in_flight: " << max_packets_in_flight
+                << " next_packet_number: " << next_packet_number;
+  packet_.packet_number_length = packet_number_length;
+}
+
+void QuicPacketCreator::SkipNPacketNumbers(
+    QuicPacketCount count,
+    QuicPacketNumber least_packet_awaited_by_peer,
+    QuicPacketCount max_packets_in_flight) {
+  if (!queued_frames_.empty()) {
+    // Don't change creator state if there are frames queued.
+    QUIC_BUG(quic_bug_10752_4)
+        << ENDPOINT << "Called SkipNPacketNumbers with "
+        << queued_frames_.size()
+        << " queued_frames.  First frame type:" << queued_frames_.front().type
+        << " last frame type:" << queued_frames_.back().type;
+    return;
+  }
+  if (packet_.packet_number > packet_.packet_number + count) {
+    // Skipping count packet numbers causes packet number wrapping around,
+    // reject it.
+    QUIC_LOG(WARNING) << ENDPOINT << "Skipping " << count
+                      << " packet numbers causes packet number wrapping "
+                         "around, least_packet_awaited_by_peer: "
+                      << least_packet_awaited_by_peer
+                      << " packet_number:" << packet_.packet_number;
+    return;
+  }
+  packet_.packet_number += count;
+  // Packet number changes, update packet number length if necessary.
+  UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
+}
+
+bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
+    EncryptionLevel level,
+    size_t write_length,
+    QuicStreamOffset offset,
+    bool needs_full_padding,
+    TransmissionType transmission_type,
+    QuicFrame* frame) {
+  QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoDataToFillCurrentPacket " << level
+                << " write_length " << write_length << " offset " << offset
+                << (needs_full_padding ? " needs_full_padding" : "") << " "
+                << transmission_type;
+  if (!CreateCryptoFrame(level, write_length, offset, frame)) {
+    return false;
+  }
+  // When crypto data was sent in stream frames, ConsumeData is called with
+  // |needs_full_padding = true|. Keep the same behavior here when sending
+  // crypto frames.
+  //
+  // TODO(nharper): Check what the IETF drafts say about padding out initial
+  // messages and change this as appropriate.
+  if (needs_full_padding) {
+    needs_full_padding_ = true;
+  }
+  return AddFrame(*frame, transmission_type);
+}
+
+bool QuicPacketCreator::ConsumeDataToFillCurrentPacket(
+    QuicStreamId id,
+    size_t data_size,
+    QuicStreamOffset offset,
+    bool fin,
+    bool needs_full_padding,
+    TransmissionType transmission_type,
+    QuicFrame* frame) {
+  if (!HasRoomForStreamFrame(id, offset, data_size)) {
+    return false;
+  }
+  CreateStreamFrame(id, data_size, offset, fin, frame);
+  // Explicitly disallow multi-packet CHLOs.
+  if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
+      StreamFrameIsClientHello(frame->stream_frame) &&
+      frame->stream_frame.data_length < data_size) {
+    const std::string error_details =
+        "Client hello won't fit in a single packet.";
+    QUIC_BUG(quic_bug_10752_5)
+        << ENDPOINT << error_details << " Constructed stream frame length: "
+        << frame->stream_frame.data_length << " CHLO length: " << data_size;
+    delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
+    return false;
+  }
+  if (!AddFrame(*frame, transmission_type)) {
+    // Fails if we try to write unencrypted stream data.
+    return false;
+  }
+  if (needs_full_padding) {
+    needs_full_padding_ = true;
+  }
+
+  return true;
+}
+
+bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
+                                              QuicStreamOffset offset,
+                                              size_t data_size) {
+  const size_t min_stream_frame_size = QuicFramer::GetMinStreamFrameSize(
+      framer_->transport_version(), id, offset, /*last_frame_in_packet=*/true,
+      data_size);
+  if (BytesFree() > min_stream_frame_size) {
+    return true;
+  }
+  if (!RemoveSoftMaxPacketLength()) {
+    return false;
+  }
+  return BytesFree() > min_stream_frame_size;
+}
+
+bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
+  const size_t message_frame_size = QuicFramer::GetMessageFrameSize(
+      framer_->transport_version(), /*last_frame_in_packet=*/true, length);
+  if (static_cast<QuicByteCount>(message_frame_size) >
+      max_datagram_frame_size_) {
+    return false;
+  }
+  if (BytesFree() >= message_frame_size) {
+    return true;
+  }
+  if (!RemoveSoftMaxPacketLength()) {
+    return false;
+  }
+  return BytesFree() >= message_frame_size;
+}
+
+// static
+size_t QuicPacketCreator::StreamFramePacketOverhead(
+    QuicTransportVersion version,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool include_version,
+    bool include_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicVariableLengthIntegerLength length_length,
+    QuicStreamOffset offset) {
+  return GetPacketHeaderSize(version, destination_connection_id_length,
+                             source_connection_id_length, include_version,
+                             include_diversification_nonce,
+                             packet_number_length, retry_token_length_length, 0,
+                             length_length) +
+
+         // Assumes a packet with a single stream frame, which omits the length,
+         // causing the data length argument to be ignored.
+         QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
+                                           kMaxOutgoingPacketSize /* unused */);
+}
+
+void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
+                                          size_t data_size,
+                                          QuicStreamOffset offset,
+                                          bool fin,
+                                          QuicFrame* frame) {
+  // Make sure max_packet_length_ is greater than the largest possible overhead
+  // or max_packet_length_ is set to the soft limit.
+  QUICHE_DCHECK(
+      max_packet_length_ >
+          StreamFramePacketOverhead(
+              framer_->transport_version(), GetDestinationConnectionIdLength(),
+              GetSourceConnectionIdLength(), kIncludeVersion,
+              IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
+              GetRetryTokenLengthLength(), GetLengthLength(), offset) ||
+      latched_hard_max_packet_length_ > 0)
+      << ENDPOINT;
+
+  QUIC_BUG_IF(quic_bug_12398_3, !HasRoomForStreamFrame(id, offset, data_size))
+      << ENDPOINT << "No room for Stream frame, BytesFree: " << BytesFree()
+      << " MinStreamFrameSize: "
+      << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
+                                           offset, true, data_size);
+
+  QUIC_BUG_IF(quic_bug_12398_4, data_size == 0 && !fin)
+      << ENDPOINT << "Creating a stream frame for stream ID:" << id
+      << " with no data or fin.";
+  size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
+      framer_->transport_version(), id, offset,
+      /* last_frame_in_packet= */ true, data_size);
+  size_t bytes_consumed =
+      std::min<size_t>(BytesFree() - min_frame_size, data_size);
+
+  bool set_fin = fin && bytes_consumed == data_size;  // Last frame.
+  *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
+}
+
+bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
+                                          size_t write_length,
+                                          QuicStreamOffset offset,
+                                          QuicFrame* frame) {
+  const size_t min_frame_size =
+      QuicFramer::GetMinCryptoFrameSize(write_length, offset);
+  if (BytesFree() <= min_frame_size &&
+      (!RemoveSoftMaxPacketLength() || BytesFree() <= min_frame_size)) {
+    return false;
+  }
+  size_t max_write_length = BytesFree() - min_frame_size;
+  size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
+  *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
+  return true;
+}
+
+void QuicPacketCreator::FlushCurrentPacket() {
+  if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
+    return;
+  }
+
+  ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
+  QuicOwnedPacketBuffer external_buffer(delegate_->GetPacketBuffer());
+
+  if (external_buffer.buffer == nullptr) {
+    external_buffer.buffer = stack_buffer;
+    external_buffer.release_buffer = nullptr;
+  }
+
+  QUICHE_DCHECK_EQ(nullptr, packet_.encrypted_buffer) << ENDPOINT;
+  if (!SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize,
+                       /*allow_padding=*/true)) {
+    return;
+  }
+  OnSerializedPacket();
+}
+
+void QuicPacketCreator::OnSerializedPacket() {
+  QUIC_BUG_IF(quic_bug_12398_5, packet_.encrypted_buffer == nullptr)
+      << ENDPOINT;
+
+  SerializedPacket packet(std::move(packet_));
+  ClearPacket();
+  RemoveSoftMaxPacketLength();
+  delegate_->OnSerializedPacket(std::move(packet));
+}
+
+void QuicPacketCreator::ClearPacket() {
+  packet_.has_ack = false;
+  packet_.has_stop_waiting = false;
+  packet_.has_crypto_handshake = NOT_HANDSHAKE;
+  packet_.transmission_type = NOT_RETRANSMISSION;
+  packet_.encrypted_buffer = nullptr;
+  packet_.encrypted_length = 0;
+  packet_.has_ack_frequency = false;
+  packet_.has_message = false;
+  packet_.fate = SEND_TO_WRITER;
+  QUIC_BUG_IF(quic_bug_12398_6, packet_.release_encrypted_buffer != nullptr)
+      << ENDPOINT << "packet_.release_encrypted_buffer should be empty";
+  packet_.release_encrypted_buffer = nullptr;
+  QUICHE_DCHECK(packet_.retransmittable_frames.empty()) << ENDPOINT;
+  QUICHE_DCHECK(packet_.nonretransmittable_frames.empty()) << ENDPOINT;
+  packet_.largest_acked.Clear();
+  needs_full_padding_ = false;
+}
+
+size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
+    const SerializedPacket& packet,
+    size_t padding_size,
+    char* buffer,
+    size_t buffer_len) {
+  QUIC_BUG_IF(quic_bug_12398_7, packet.encryption_level != ENCRYPTION_INITIAL);
+  QUIC_BUG_IF(quic_bug_12398_8, packet.nonretransmittable_frames.empty() &&
+                                    packet.retransmittable_frames.empty())
+      << ENDPOINT
+      << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
+         "packet";
+
+  if (close_connection_if_fail_to_serialzie_coalesced_packet_ &&
+      HasPendingFrames()) {
+    QUIC_BUG(quic_packet_creator_unexpected_queued_frames)
+        << "Unexpected queued frames: " << GetPendingFramesInfo();
+    return 0;
+  }
+
+  ScopedPacketContextSwitcher switcher(
+      packet.packet_number -
+          1,  // -1 because serialize packet increase packet number.
+      packet.packet_number_length, packet.encryption_level, &packet_);
+  for (const QuicFrame& frame : packet.nonretransmittable_frames) {
+    if (!AddFrame(frame, packet.transmission_type)) {
+      QUIC_BUG(quic_bug_10752_6)
+          << ENDPOINT << "Failed to serialize frame: " << frame;
+      return 0;
+    }
+  }
+  for (const QuicFrame& frame : packet.retransmittable_frames) {
+    if (!AddFrame(frame, packet.transmission_type)) {
+      QUIC_BUG(quic_bug_10752_7)
+          << ENDPOINT << "Failed to serialize frame: " << frame;
+      return 0;
+    }
+  }
+  // Add necessary padding.
+  if (padding_size > 0) {
+    QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
+    if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
+                  packet.transmission_type)) {
+      QUIC_BUG(quic_bug_10752_8)
+          << ENDPOINT << "Failed to add padding of size " << padding_size
+          << " when serializing ENCRYPTION_INITIAL "
+             "packet in coalesced packet";
+      return 0;
+    }
+  }
+
+  if (close_connection_if_fail_to_serialzie_coalesced_packet_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(
+        quic_close_connection_if_fail_to_serialzie_coalesced_packet2, 1, 2);
+  }
+
+  if (!SerializePacket(
+          QuicOwnedPacketBuffer(buffer, nullptr), buffer_len,
+          /*allow_padding=*/
+          !close_connection_if_fail_to_serialzie_coalesced_packet_)) {
+    return 0;
+  }
+  const size_t encrypted_length = packet_.encrypted_length;
+  // Clear frames in packet_. No need to DeleteFrames since frames are owned by
+  // initial_packet.
+  packet_.retransmittable_frames.clear();
+  packet_.nonretransmittable_frames.clear();
+  ClearPacket();
+  return encrypted_length;
+}
+
+void QuicPacketCreator::CreateAndSerializeStreamFrame(
+    QuicStreamId id,
+    size_t write_length,
+    QuicStreamOffset iov_offset,
+    QuicStreamOffset stream_offset,
+    bool fin,
+    TransmissionType transmission_type,
+    size_t* num_bytes_consumed) {
+  // TODO(b/167222597): consider using ScopedSerializationFailureHandler.
+  QUICHE_DCHECK(queued_frames_.empty()) << ENDPOINT;
+  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
+      << ENDPOINT;
+  // Write out the packet header
+  QuicPacketHeader header;
+  FillPacketHeader(&header);
+  packet_.fate = delegate_->GetSerializedPacketFate(
+      /*is_mtu_discovery=*/false, packet_.encryption_level);
+  QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
+                << ": " << SerializedPacketFateToString(packet_.fate) << " of "
+                << EncryptionLevelToString(packet_.encryption_level);
+
+  ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
+  QuicOwnedPacketBuffer packet_buffer(delegate_->GetPacketBuffer());
+
+  if (packet_buffer.buffer == nullptr) {
+    packet_buffer.buffer = stack_buffer;
+    packet_buffer.release_buffer = nullptr;
+  }
+
+  char* encrypted_buffer = packet_buffer.buffer;
+
+  QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
+  size_t length_field_offset = 0;
+  if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
+    QUIC_BUG(quic_bug_10752_9) << ENDPOINT << "AppendPacketHeader failed";
+    return;
+  }
+
+  // Create a Stream frame with the remaining space.
+  QUIC_BUG_IF(quic_bug_12398_9, iov_offset == write_length && !fin)
+      << ENDPOINT << "Creating a stream frame with no data or fin.";
+  const size_t remaining_data_size = write_length - iov_offset;
+  size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
+      framer_->transport_version(), id, stream_offset,
+      /* last_frame_in_packet= */ true, remaining_data_size);
+  size_t available_size =
+      max_plaintext_size_ - writer.length() - min_frame_size;
+  size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
+  size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
+  bool needs_padding = false;
+  if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
+    needs_padding = true;
+    // Recalculate sizes with the stream frame not being marked as the last
+    // frame in the packet.
+    min_frame_size = QuicFramer::GetMinStreamFrameSize(
+        framer_->transport_version(), id, stream_offset,
+        /* last_frame_in_packet= */ false, remaining_data_size);
+    available_size = max_plaintext_size_ - writer.length() - min_frame_size;
+    bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
+    plaintext_bytes_written = min_frame_size + bytes_consumed;
+  }
+
+  const bool set_fin = fin && (bytes_consumed == remaining_data_size);
+  QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
+
+  // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
+  // into one method that takes a QuicStreamFrame, if warranted.
+  bool omit_frame_length = !needs_padding;
+  if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
+    QUIC_BUG(quic_bug_10752_10) << ENDPOINT << "AppendTypeByte failed";
+    return;
+  }
+  if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
+    QUIC_BUG(quic_bug_10752_11) << ENDPOINT << "AppendStreamFrame failed";
+    return;
+  }
+  if (needs_padding &&
+      plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
+      !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
+                                plaintext_bytes_written)) {
+    QUIC_BUG(quic_bug_10752_12) << ENDPOINT << "Unable to add padding bytes";
+    return;
+  }
+
+  if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
+                                          packet_.encryption_level)) {
+    return;
+  }
+
+  packet_.transmission_type = transmission_type;
+
+  QUICHE_DCHECK(packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
+                packet_.encryption_level == ENCRYPTION_ZERO_RTT)
+      << ENDPOINT << packet_.encryption_level;
+  size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header),
+      writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
+  if (encrypted_length == 0) {
+    QUIC_BUG(quic_bug_10752_13)
+        << ENDPOINT << "Failed to encrypt packet number "
+        << header.packet_number;
+    return;
+  }
+  // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
+  // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
+  *num_bytes_consumed = bytes_consumed;
+  packet_size_ = 0;
+  packet_.encrypted_buffer = encrypted_buffer;
+  packet_.encrypted_length = encrypted_length;
+
+  packet_buffer.buffer = nullptr;
+  packet_.release_encrypted_buffer = std::move(packet_buffer).release_buffer;
+
+  packet_.retransmittable_frames.push_back(QuicFrame(frame));
+  OnSerializedPacket();
+}
+
+bool QuicPacketCreator::HasPendingFrames() const {
+  return !queued_frames_.empty();
+}
+
+std::string QuicPacketCreator::GetPendingFramesInfo() const {
+  return QuicFramesToString(queued_frames_);
+}
+
+bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
+  return !packet_.retransmittable_frames.empty();
+}
+
+bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
+  for (const auto& frame : packet_.retransmittable_frames) {
+    if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
+      return true;
+    }
+  }
+  return false;
+}
+
+size_t QuicPacketCreator::ExpansionOnNewFrame() const {
+  // If the last frame in the packet is a message frame, then it will expand to
+  // include the varint message length when a new frame is added.
+  if (queued_frames_.empty()) {
+    return 0;
+  }
+  return ExpansionOnNewFrameWithLastFrame(queued_frames_.back(),
+                                          framer_->transport_version());
+}
+
+// static
+size_t QuicPacketCreator::ExpansionOnNewFrameWithLastFrame(
+    const QuicFrame& last_frame,
+    QuicTransportVersion version) {
+  if (last_frame.type == MESSAGE_FRAME) {
+    return QuicDataWriter::GetVarInt62Len(
+        last_frame.message_frame->message_length);
+  }
+  if (last_frame.type != STREAM_FRAME) {
+    return 0;
+  }
+  if (VersionHasIetfQuicFrames(version)) {
+    return QuicDataWriter::GetVarInt62Len(last_frame.stream_frame.data_length);
+  }
+  return kQuicStreamPayloadLengthSize;
+}
+
+size_t QuicPacketCreator::BytesFree() const {
+  return max_plaintext_size_ -
+         std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
+}
+
+size_t QuicPacketCreator::PacketSize() const {
+  return queued_frames_.empty() ? PacketHeaderSize() : packet_size_;
+}
+
+bool QuicPacketCreator::AddPaddedSavedFrame(
+    const QuicFrame& frame,
+    TransmissionType transmission_type) {
+  if (AddFrame(frame, transmission_type)) {
+    needs_full_padding_ = true;
+    return true;
+  }
+  return false;
+}
+
+absl::optional<size_t>
+QuicPacketCreator::MaybeBuildDataPacketWithChaosProtection(
+    const QuicPacketHeader& header,
+    char* buffer) {
+  if (!chaos_protection_enabled_ ||
+      packet_.encryption_level != ENCRYPTION_INITIAL ||
+      !framer_->version().UsesCryptoFrames() || queued_frames_.size() != 2u ||
+      queued_frames_[0].type != CRYPTO_FRAME ||
+      queued_frames_[1].type != PADDING_FRAME ||
+      // Do not perform chaos protection if we do not have a known number of
+      // padding bytes to work with.
+      queued_frames_[1].padding_frame.num_padding_bytes <= 0 ||
+      // Chaos protection relies on the framer using a crypto data producer,
+      // which is always the case in practice.
+      framer_->data_producer() == nullptr) {
+    return absl::nullopt;
+  }
+  const QuicCryptoFrame& crypto_frame = *queued_frames_[0].crypto_frame;
+  if (packet_.encryption_level != crypto_frame.level) {
+    QUIC_BUG(chaos frame level)
+        << ENDPOINT << packet_.encryption_level << " != " << crypto_frame.level;
+    return absl::nullopt;
+  }
+  QuicChaosProtector chaos_protector(
+      crypto_frame, queued_frames_[1].padding_frame.num_padding_bytes,
+      packet_size_, framer_, random_);
+  return chaos_protector.BuildDataPacket(header, buffer);
+}
+
+bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
+                                        size_t encrypted_buffer_len,
+                                        bool allow_padding) {
+  if (packet_.encrypted_buffer != nullptr) {
+    const std::string error_details =
+        "Packet's encrypted buffer is not empty before serialization";
+    QUIC_BUG(quic_bug_10752_14) << ENDPOINT << error_details;
+    delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
+                                    error_details);
+    return false;
+  }
+  ScopedSerializationFailureHandler handler(this);
+
+  QUICHE_DCHECK_LT(0u, encrypted_buffer_len) << ENDPOINT;
+  QUIC_BUG_IF(quic_bug_12398_10,
+              queued_frames_.empty() && pending_padding_bytes_ == 0)
+      << ENDPOINT << "Attempt to serialize empty packet";
+  QuicPacketHeader header;
+  // FillPacketHeader increments packet_number_.
+  FillPacketHeader(&header);
+  if (delegate_ != nullptr) {
+    packet_.fate = delegate_->GetSerializedPacketFate(
+        /*is_mtu_discovery=*/QuicUtils::ContainsFrameType(queued_frames_,
+                                                          MTU_DISCOVERY_FRAME),
+        packet_.encryption_level);
+    QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
+                  << ": " << SerializedPacketFateToString(packet_.fate)
+                  << " of "
+                  << EncryptionLevelToString(packet_.encryption_level);
+  }
+
+  if (allow_padding) {
+    MaybeAddPadding();
+  }
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
+                << QuicFramesToString(queued_frames_) << " at encryption_level "
+                << packet_.encryption_level
+                << ", allow_padding:" << allow_padding;
+
+  if (!framer_->HasEncrypterOfEncryptionLevel(packet_.encryption_level)) {
+    // TODO(fayang): Use QUIC_MISSING_WRITE_KEYS for serialization failures due
+    // to missing keys.
+    QUIC_BUG(quic_bug_10752_15)
+        << ENDPOINT << "Attempting to serialize " << header
+        << QuicFramesToString(queued_frames_) << " at missing encryption_level "
+        << packet_.encryption_level << " using " << framer_->version();
+    return false;
+  }
+
+  QUICHE_DCHECK_GE(max_plaintext_size_, packet_size_) << ENDPOINT;
+  // Use the packet_size_ instead of the buffer size to ensure smaller
+  // packet sizes are properly used.
+
+  size_t length;
+  absl::optional<size_t> length_with_chaos_protection =
+      MaybeBuildDataPacketWithChaosProtection(header, encrypted_buffer.buffer);
+  if (length_with_chaos_protection.has_value()) {
+    length = length_with_chaos_protection.value();
+  } else {
+    length = framer_->BuildDataPacket(header, queued_frames_,
+                                      encrypted_buffer.buffer, packet_size_,
+                                      packet_.encryption_level);
+  }
+
+  if (length == 0) {
+    QUIC_BUG(quic_bug_10752_16)
+        << ENDPOINT << "Failed to serialize "
+        << QuicFramesToString(queued_frames_)
+        << " at encryption_level: " << packet_.encryption_level
+        << ", needs_full_padding_: " << needs_full_padding_
+        << ", pending_padding_bytes_: " << pending_padding_bytes_
+        << ", latched_hard_max_packet_length_: "
+        << latched_hard_max_packet_length_
+        << ", max_packet_length_: " << max_packet_length_
+        << ", header: " << header;
+    return false;
+  }
+
+  // ACK Frames will be truncated due to length only if they're the only frame
+  // in the packet, and if packet_size_ was set to max_plaintext_size_. If
+  // truncation due to length occurred, then GetSerializedFrameLength will have
+  // returned all bytes free.
+  bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
+                                      queued_frames_.size() == 1 &&
+                                      queued_frames_.back().type == ACK_FRAME;
+  // Because of possible truncation, we can't be confident that our
+  // packet size calculation worked correctly.
+  if (!possibly_truncated_by_length) {
+    QUICHE_DCHECK_EQ(packet_size_, length) << ENDPOINT;
+  }
+  const size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header), length,
+      encrypted_buffer_len, encrypted_buffer.buffer);
+  if (encrypted_length == 0) {
+    QUIC_BUG(quic_bug_10752_17)
+        << ENDPOINT << "Failed to encrypt packet number "
+        << packet_.packet_number;
+    return false;
+  }
+
+  packet_size_ = 0;
+  packet_.encrypted_buffer = encrypted_buffer.buffer;
+  packet_.encrypted_length = encrypted_length;
+
+  encrypted_buffer.buffer = nullptr;
+  packet_.release_encrypted_buffer = std::move(encrypted_buffer).release_buffer;
+  return true;
+}
+
+std::unique_ptr<SerializedPacket>
+QuicPacketCreator::SerializeConnectivityProbingPacket() {
+  QUIC_BUG_IF(quic_bug_12398_11,
+              VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT
+      << "Must not be version 99 to serialize padded ping connectivity probe";
+  RemoveSoftMaxPacketLength();
+  QuicPacketHeader header;
+  // FillPacketHeader increments packet_number_.
+  FillPacketHeader(&header);
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
+                << header;
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  size_t length = BuildConnectivityProbingPacket(
+      header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
+  QUICHE_DCHECK(length) << ENDPOINT;
+
+  QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
+      << ENDPOINT;
+  const size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header), length,
+      kMaxOutgoingPacketSize, buffer.get());
+  QUICHE_DCHECK(encrypted_length) << ENDPOINT;
+
+  std::unique_ptr<SerializedPacket> serialize_packet(new SerializedPacket(
+      header.packet_number, header.packet_number_length, buffer.release(),
+      encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
+
+  serialize_packet->release_encrypted_buffer = [](const char* p) {
+    delete[] p;
+  };
+  serialize_packet->encryption_level = packet_.encryption_level;
+  serialize_packet->transmission_type = NOT_RETRANSMISSION;
+
+  return serialize_packet;
+}
+
+std::unique_ptr<SerializedPacket>
+QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
+    const QuicPathFrameBuffer& payload) {
+  QUIC_BUG_IF(quic_bug_12398_12,
+              !VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT
+      << "Must be version 99 to serialize path challenge connectivity probe, "
+         "is version "
+      << framer_->transport_version();
+  RemoveSoftMaxPacketLength();
+  QuicPacketHeader header;
+  // FillPacketHeader increments packet_number_.
+  FillPacketHeader(&header);
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  size_t length =
+      BuildPaddedPathChallengePacket(header, buffer.get(), max_plaintext_size_,
+                                     payload, packet_.encryption_level);
+  QUICHE_DCHECK(length) << ENDPOINT;
+
+  QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
+      << ENDPOINT;
+  const size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header), length,
+      kMaxOutgoingPacketSize, buffer.get());
+  QUICHE_DCHECK(encrypted_length) << ENDPOINT;
+
+  std::unique_ptr<SerializedPacket> serialize_packet(
+      new SerializedPacket(header.packet_number, header.packet_number_length,
+                           buffer.release(), encrypted_length,
+                           /*has_ack=*/false, /*has_stop_waiting=*/false));
+
+  serialize_packet->release_encrypted_buffer = [](const char* p) {
+    delete[] p;
+  };
+  serialize_packet->encryption_level = packet_.encryption_level;
+  serialize_packet->transmission_type = NOT_RETRANSMISSION;
+
+  return serialize_packet;
+}
+
+std::unique_ptr<SerializedPacket>
+QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
+    const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
+    const bool is_padded) {
+  QUIC_BUG_IF(quic_bug_12398_13,
+              !VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT
+      << "Must be version 99 to serialize path response connectivity probe, is "
+         "version "
+      << framer_->transport_version();
+  RemoveSoftMaxPacketLength();
+  QuicPacketHeader header;
+  // FillPacketHeader increments packet_number_.
+  FillPacketHeader(&header);
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  size_t length =
+      BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
+                              payloads, is_padded, packet_.encryption_level);
+  QUICHE_DCHECK(length) << ENDPOINT;
+
+  QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
+      << ENDPOINT;
+  const size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header), length,
+      kMaxOutgoingPacketSize, buffer.get());
+  QUICHE_DCHECK(encrypted_length) << ENDPOINT;
+
+  std::unique_ptr<SerializedPacket> serialize_packet(
+      new SerializedPacket(header.packet_number, header.packet_number_length,
+                           buffer.release(), encrypted_length,
+                           /*has_ack=*/false, /*has_stop_waiting=*/false));
+
+  serialize_packet->release_encrypted_buffer = [](const char* p) {
+    delete[] p;
+  };
+  serialize_packet->encryption_level = packet_.encryption_level;
+  serialize_packet->transmission_type = NOT_RETRANSMISSION;
+
+  return serialize_packet;
+}
+
+size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
+    const QuicPacketHeader& header,
+    char* buffer,
+    size_t packet_length,
+    const QuicPathFrameBuffer& payload,
+    EncryptionLevel level) {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT;
+  QuicFrames frames;
+
+  // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
+  QuicPathChallengeFrame path_challenge_frame(0, payload);
+  frames.push_back(QuicFrame(&path_challenge_frame));
+
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
+  }
+
+  // Add padding to the rest of the packet in order to assess Path MTU
+  // characteristics.
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(padding_frame));
+
+  return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
+}
+
+size_t QuicPacketCreator::BuildPathResponsePacket(
+    const QuicPacketHeader& header,
+    char* buffer,
+    size_t packet_length,
+    const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
+    const bool is_padded,
+    EncryptionLevel level) {
+  if (payloads.empty()) {
+    QUIC_BUG(quic_bug_12398_14)
+        << ENDPOINT
+        << "Attempt to generate connectivity response with no request payloads";
+    return 0;
+  }
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT;
+
+  std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
+  for (const QuicPathFrameBuffer& payload : payloads) {
+    // Note that the control frame ID can be 0 since this is not retransmitted.
+    path_response_frames.push_back(
+        std::make_unique<QuicPathResponseFrame>(0, payload));
+  }
+
+  QuicFrames frames;
+  for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
+       path_response_frames) {
+    frames.push_back(QuicFrame(path_response_frame.get()));
+    if (debug_delegate_ != nullptr) {
+      debug_delegate_->OnFrameAddedToPacket(
+          QuicFrame(path_response_frame.get()));
+    }
+  }
+
+  if (is_padded) {
+    // Add padding to the rest of the packet in order to assess Path MTU
+    // characteristics.
+    QuicPaddingFrame padding_frame;
+    frames.push_back(QuicFrame(padding_frame));
+  }
+
+  return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
+}
+
+size_t QuicPacketCreator::BuildConnectivityProbingPacket(
+    const QuicPacketHeader& header,
+    char* buffer,
+    size_t packet_length,
+    EncryptionLevel level) {
+  QuicFrames frames;
+
+  // Write a PING frame, which has no data payload.
+  QuicPingFrame ping_frame;
+  frames.push_back(QuicFrame(ping_frame));
+
+  // Add padding to the rest of the packet.
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(padding_frame));
+
+  return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
+}
+
+size_t QuicPacketCreator::SerializeCoalescedPacket(
+    const QuicCoalescedPacket& coalesced,
+    char* buffer,
+    size_t buffer_len) {
+  if (HasPendingFrames()) {
+    QUIC_BUG(quic_bug_10752_18)
+        << ENDPOINT << "Try to serialize coalesced packet with pending frames";
+    return 0;
+  }
+  RemoveSoftMaxPacketLength();
+  QUIC_BUG_IF(quic_bug_12398_15, coalesced.length() == 0)
+      << ENDPOINT << "Attempt to serialize empty coalesced packet";
+  size_t packet_length = 0;
+  size_t initial_length = 0;
+  size_t padding_size = 0;
+  if (coalesced.initial_packet() != nullptr) {
+    // Padding coalesced packet containing initial packet to full.
+    padding_size = coalesced.max_packet_length() - coalesced.length();
+    if (framer_->perspective() == Perspective::IS_SERVER &&
+        QuicUtils::ContainsFrameType(
+            coalesced.initial_packet()->retransmittable_frames,
+            CONNECTION_CLOSE_FRAME)) {
+      // Do not pad server initial connection close packet.
+      padding_size = 0;
+    }
+    initial_length = ReserializeInitialPacketInCoalescedPacket(
+        *coalesced.initial_packet(), padding_size, buffer, buffer_len);
+    if (initial_length == 0) {
+      QUIC_BUG(quic_bug_10752_19)
+          << ENDPOINT
+          << "Failed to reserialize ENCRYPTION_INITIAL packet in "
+             "coalesced packet";
+      return 0;
+    }
+    QUIC_BUG_IF(quic_reserialize_initial_packet_unexpected_size,
+                coalesced.initial_packet()->encrypted_length + padding_size !=
+                    initial_length)
+        << "Reserialize initial packet in coalescer has unexpected size, "
+           "original_length: "
+        << coalesced.initial_packet()->encrypted_length
+        << ", coalesced.max_packet_length: " << coalesced.max_packet_length()
+        << ", coalesced.length: " << coalesced.length()
+        << ", padding_size: " << padding_size
+        << ", serialized_length: " << initial_length
+        << ", retransmittable frames: "
+        << QuicFramesToString(
+               coalesced.initial_packet()->retransmittable_frames)
+        << ", nonretransmittable frames: "
+        << QuicFramesToString(
+               coalesced.initial_packet()->nonretransmittable_frames);
+    buffer += initial_length;
+    buffer_len -= initial_length;
+    packet_length += initial_length;
+  }
+  size_t length_copied = 0;
+  if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
+    QUIC_BUG(quic_serialize_coalesced_packet_copy_failure)
+        << "SerializeCoalescedPacket failed. buffer_len:" << buffer_len
+        << ", initial_length:" << initial_length
+        << ", padding_size: " << padding_size
+        << ", length_copied:" << length_copied
+        << ", coalesced.length:" << coalesced.length()
+        << ", coalesced.max_packet_length:" << coalesced.max_packet_length()
+        << ", coalesced.packet_lengths:"
+        << absl::StrJoin(coalesced.packet_lengths(), ":");
+    return 0;
+  }
+  packet_length += length_copied;
+  QUIC_DVLOG(1) << ENDPOINT
+                << "Successfully serialized coalesced packet of length: "
+                << packet_length;
+  return packet_length;
+}
+
+// TODO(b/74062209): Make this a public method of framer?
+SerializedPacket QuicPacketCreator::NoPacket() {
+  return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
+                          nullptr, 0, false, false);
+}
+
+QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
+  if (framer_->perspective() == Perspective::IS_SERVER) {
+    return client_connection_id_;
+  }
+  return server_connection_id_;
+}
+
+QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
+  if (framer_->perspective() == Perspective::IS_CLIENT) {
+    return client_connection_id_;
+  }
+  return server_connection_id_;
+}
+
+QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
+    const {
+  // In versions that do not support client connection IDs, the destination
+  // connection ID is only sent from client to server.
+  return (framer_->perspective() == Perspective::IS_CLIENT ||
+          framer_->version().SupportsClientConnectionIds())
+             ? CONNECTION_ID_PRESENT
+             : CONNECTION_ID_ABSENT;
+}
+
+QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
+    const {
+  // Long header packets sent by server include source connection ID.
+  // Ones sent by the client only include source connection ID if the version
+  // supports client connection IDs.
+  if (HasIetfLongHeader() &&
+      (framer_->perspective() == Perspective::IS_SERVER ||
+       framer_->version().SupportsClientConnectionIds())) {
+    return CONNECTION_ID_PRESENT;
+  }
+  if (framer_->perspective() == Perspective::IS_SERVER) {
+    return server_connection_id_included_;
+  }
+  return CONNECTION_ID_ABSENT;
+}
+
+QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
+    const {
+  QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
+                                                         transport_version()))
+      << ENDPOINT;
+  return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
+             ? static_cast<QuicConnectionIdLength>(
+                   GetDestinationConnectionId().length())
+             : PACKET_0BYTE_CONNECTION_ID;
+}
+
+QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
+  QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
+                                                         transport_version()))
+      << ENDPOINT;
+  return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
+             ? static_cast<QuicConnectionIdLength>(
+                   GetSourceConnectionId().length())
+             : PACKET_0BYTE_CONNECTION_ID;
+}
+
+QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
+  if (HasIetfLongHeader() &&
+      !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
+    return PACKET_4BYTE_PACKET_NUMBER;
+  }
+  return packet_.packet_number_length;
+}
+
+size_t QuicPacketCreator::PacketHeaderSize() const {
+  return GetPacketHeaderSize(
+      framer_->transport_version(), GetDestinationConnectionIdLength(),
+      GetSourceConnectionIdLength(), IncludeVersionInHeader(),
+      IncludeNonceInPublicHeader(), GetPacketNumberLength(),
+      GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
+}
+
+QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
+    const {
+  if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
+      HasIetfLongHeader() &&
+      EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
+    return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
+  }
+  return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+}
+
+absl::string_view QuicPacketCreator::GetRetryToken() const {
+  if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
+      HasIetfLongHeader() &&
+      EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
+    return retry_token_;
+  }
+  return absl::string_view();
+}
+
+void QuicPacketCreator::SetRetryToken(absl::string_view retry_token) {
+  retry_token_ = std::string(retry_token);
+}
+
+bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
+    const QuicFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12398_16, IsControlFrame(frame.type) &&
+                                     !GetControlFrameId(frame) &&
+                                     frame.type != PING_FRAME)
+      << ENDPOINT
+      << "Adding a control frame with no control frame id: " << frame;
+  QUICHE_DCHECK(QuicUtils::IsRetransmittableFrame(frame.type))
+      << ENDPOINT << frame;
+  MaybeBundleAckOpportunistically();
+  if (HasPendingFrames()) {
+    if (AddFrame(frame, next_transmission_type_)) {
+      // There is pending frames and current frame fits.
+      return true;
+    }
+  }
+  QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
+  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 = AddFrame(frame, next_transmission_type_);
+  QUIC_BUG_IF(quic_bug_10752_20, !success)
+      << ENDPOINT << "Failed to add frame:" << frame
+      << " transmission_type:" << next_transmission_type_;
+  return success;
+}
+
+QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
+                                                size_t write_length,
+                                                QuicStreamOffset offset,
+                                                StreamSendingState state) {
+  QUIC_BUG_IF(quic_bug_10752_21, !flusher_attached_)
+      << ENDPOINT
+      << "Packet flusher is not attached when "
+         "generator tries to write stream data.";
+  bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
+  MaybeBundleAckOpportunistically();
+  bool fin = state != NO_FIN;
+  QUIC_BUG_IF(quic_bug_12398_17, has_handshake && fin)
+      << ENDPOINT << "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 && HasPendingRetransmittableFrames()) {
+    FlushCurrentPacket();
+  }
+
+  size_t total_bytes_consumed = 0;
+  bool fin_consumed = false;
+
+  if (!HasRoomForStreamFrame(id, offset, write_length)) {
+    FlushCurrentPacket();
+  }
+
+  if (!fin && (write_length == 0)) {
+    QUIC_BUG(quic_bug_10752_22)
+        << ENDPOINT << "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 &&
+      latched_hard_max_packet_length_ == 0;
+
+  while (!run_fast_path &&
+         (has_handshake || delegate_->ShouldGeneratePacket(
+                               HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE))) {
+    QuicFrame frame;
+    bool needs_full_padding =
+        has_handshake && fully_pad_crypto_handshake_packets_;
+
+    if (!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(quic_bug_10752_23)
+          << ENDPOINT << "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();
+    }
+    QUICHE_DCHECK(total_bytes_consumed == write_length ||
+                  (bytes_consumed > 0 && HasPendingFrames()))
+        << ENDPOINT;
+
+    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;
+    }
+    FlushCurrentPacket();
+
+    run_fast_path =
+        !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
+        write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
+        latched_hard_max_packet_length_ == 0;
+  }
+
+  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) {
+    FlushCurrentPacket();
+  }
+
+  return QuicConsumedData(total_bytes_consumed, fin_consumed);
+}
+
+QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
+    QuicStreamId id,
+    size_t write_length,
+    QuicStreamOffset offset,
+    bool fin,
+    size_t total_bytes_consumed) {
+  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
+      << ENDPOINT;
+  if (AttemptingToSendUnencryptedStreamData()) {
+    return QuicConsumedData(total_bytes_consumed,
+                            fin && (total_bytes_consumed == write_length));
+  }
+
+  while (total_bytes_consumed < write_length &&
+         delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
+                                         NOT_HANDSHAKE)) {
+    // Serialize and encrypt the packet.
+    size_t bytes_consumed = 0;
+    CreateAndSerializeStreamFrame(id, write_length, total_bytes_consumed,
+                                  offset + total_bytes_consumed, fin,
+                                  next_transmission_type_, &bytes_consumed);
+    if (bytes_consumed == 0) {
+      const std::string error_details =
+          "Failed in CreateAndSerializeStreamFrame.";
+      QUIC_BUG(quic_bug_10752_24) << ENDPOINT << error_details;
+      delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
+                                      error_details);
+      break;
+    }
+    total_bytes_consumed += bytes_consumed;
+  }
+
+  return QuicConsumedData(total_bytes_consumed,
+                          fin && (total_bytes_consumed == write_length));
+}
+
+size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
+                                            size_t write_length,
+                                            QuicStreamOffset offset) {
+  QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoData " << level << " write_length "
+                << write_length << " offset " << offset;
+  QUIC_BUG_IF(quic_bug_10752_25, !flusher_attached_)
+      << ENDPOINT
+      << "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 (HasPendingRetransmittableFrames()) {
+    FlushCurrentPacket();
+  }
+
+  size_t total_bytes_consumed = 0;
+
+  while (
+      total_bytes_consumed < write_length &&
+      delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, IS_HANDSHAKE)) {
+    QuicFrame frame;
+    if (!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_IF(quic_bug_10752_26, !HasSoftMaxPacketLength()) << absl::StrCat(
+          ENDPOINT, "Failed to ConsumeCryptoData at level ", level,
+          ", pending_frames: ", GetPendingFramesInfo(),
+          ", has_soft_max_packet_length: ", HasSoftMaxPacketLength(),
+          ", max_packet_length: ", max_packet_length_, ", transmission_type: ",
+          TransmissionTypeToString(next_transmission_type_),
+          ", packet_number: ", packet_number().ToString());
+      return 0;
+    }
+    total_bytes_consumed += frame.crypto_frame->data_length;
+    FlushCurrentPacket();
+  }
+
+  // Don't allow the handshake to be bundled with other retransmittable frames.
+  FlushCurrentPacket();
+
+  return total_bytes_consumed;
+}
+
+void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
+  // MTU discovery frames must be sent by themselves.
+  if (!CanSetMaxPacketLength()) {
+    QUIC_BUG(quic_bug_10752_27)
+        << ENDPOINT
+        << "MTU discovery packets should only be sent when no other "
+        << "frames needs to be sent.";
+    return;
+  }
+  const QuicByteCount current_mtu = max_packet_length();
+
+  // 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 = AddPaddedSavedFrame(frame, next_transmission_type_);
+  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.
+  QUIC_BUG_IF(quic_bug_10752_28, !success)
+      << ENDPOINT << "Failed to send path MTU target_mtu:" << target_mtu
+      << " transmission_type:" << next_transmission_type_;
+
+  // Reset the packet length back.
+  SetMaxPacketLength(current_mtu);
+}
+
+void QuicPacketCreator::MaybeBundleAckOpportunistically() {
+  if (has_ack()) {
+    // Ack already queued, nothing to do.
+    return;
+  }
+  if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                       NOT_HANDSHAKE)) {
+    return;
+  }
+  const bool flushed =
+      FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
+  QUIC_BUG_IF(quic_bug_10752_29, !flushed)
+      << ENDPOINT << "Failed to flush ACK frame. encryption_level:"
+      << packet_.encryption_level;
+}
+
+bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
+  QUIC_BUG_IF(quic_bug_10752_30, !flusher_attached_)
+      << ENDPOINT
+      << "Packet flusher is not attached when "
+         "generator tries to send ACK frame.";
+  // MaybeBundleAckOpportunistically could be called nestedly when sending a
+  // control frame causing another control frame to be sent.
+  QUIC_BUG_IF(quic_bug_12398_18, !frames.empty() && has_ack())
+      << ENDPOINT << "Trying to flush " << quiche::PrintElements(frames)
+      << " when there is ACK queued";
+  for (const auto& frame : frames) {
+    QUICHE_DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME)
+        << ENDPOINT;
+    if (HasPendingFrames()) {
+      if (AddFrame(frame, next_transmission_type_)) {
+        // There is pending frames and current frame fits.
+        continue;
+      }
+    }
+    QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
+    // 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 = AddFrame(frame, next_transmission_type_);
+    QUIC_BUG_IF(quic_bug_10752_31, !success)
+        << ENDPOINT << "Failed to flush " << frame;
+  }
+  return true;
+}
+
+void QuicPacketCreator::AddRandomPadding() {
+  AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
+}
+
+void QuicPacketCreator::AttachPacketFlusher() {
+  flusher_attached_ = true;
+  if (!write_start_packet_number_.IsInitialized()) {
+    write_start_packet_number_ = NextSendingPacketNumber();
+  }
+}
+
+void QuicPacketCreator::Flush() {
+  FlushCurrentPacket();
+  SendRemainingPendingPadding();
+  flusher_attached_ = false;
+  if (GetQuicFlag(FLAGS_quic_export_write_path_stats_at_server)) {
+    if (!write_start_packet_number_.IsInitialized()) {
+      QUIC_BUG(quic_bug_10752_32)
+          << ENDPOINT << "write_start_packet_number is not initialized";
+      return;
+    }
+    QUIC_SERVER_HISTOGRAM_COUNTS(
+        "quic_server_num_written_packets_per_write",
+        NextSendingPacketNumber() - write_start_packet_number_, 1, 200, 50,
+        "Number of QUIC packets written per write operation");
+  }
+  write_start_packet_number_.Clear();
+}
+
+void QuicPacketCreator::SendRemainingPendingPadding() {
+  while (
+      pending_padding_bytes() > 0 && !HasPendingFrames() &&
+      delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
+    FlushCurrentPacket();
+  }
+}
+
+void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
+  if (length == 0) {
+    SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
+  } else {
+    SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
+  }
+}
+
+void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
+  next_transmission_type_ = type;
+}
+
+MessageStatus QuicPacketCreator::AddMessageFrame(
+    QuicMessageId message_id, absl::Span<quiche::QuicheMemSlice> message) {
+  QUIC_BUG_IF(quic_bug_10752_33, !flusher_attached_)
+      << ENDPOINT
+      << "Packet flusher is not attached when "
+         "generator tries to add message frame.";
+  MaybeBundleAckOpportunistically();
+  const QuicByteCount message_length = MemSliceSpanTotalSize(message);
+  if (message_length > GetCurrentLargestMessagePayload()) {
+    return MESSAGE_STATUS_TOO_LARGE;
+  }
+  if (!HasRoomForMessageFrame(message_length)) {
+    FlushCurrentPacket();
+  }
+  QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
+  const bool success = AddFrame(QuicFrame(frame), next_transmission_type_);
+  if (!success) {
+    QUIC_BUG(quic_bug_10752_34)
+        << ENDPOINT << "Failed to send message " << message_id;
+    delete frame;
+    return MESSAGE_STATUS_INTERNAL_ERROR;
+  }
+  QUICHE_DCHECK_EQ(MemSliceSpanTotalSize(message),
+                   0u);  // Ensure the old slices are empty.
+  return MESSAGE_STATUS_SUCCESS;
+}
+
+QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
+  if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
+      HasIetfLongHeader()) {
+    QuicLongHeaderType long_header_type =
+        EncryptionlevelToLongHeaderType(packet_.encryption_level);
+    if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
+        long_header_type == HANDSHAKE) {
+      return VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    }
+  }
+  return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+}
+
+void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
+  header->destination_connection_id = GetDestinationConnectionId();
+  header->destination_connection_id_included =
+      GetDestinationConnectionIdIncluded();
+  header->source_connection_id = GetSourceConnectionId();
+  header->source_connection_id_included = GetSourceConnectionIdIncluded();
+  header->reset_flag = false;
+  header->version_flag = IncludeVersionInHeader();
+  if (IncludeNonceInPublicHeader()) {
+    QUICHE_DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective())
+        << ENDPOINT;
+    header->nonce = &diversification_nonce_;
+  } else {
+    header->nonce = nullptr;
+  }
+  packet_.packet_number = NextSendingPacketNumber();
+  header->packet_number = packet_.packet_number;
+  header->packet_number_length = GetPacketNumberLength();
+  header->retry_token_length_length = GetRetryTokenLengthLength();
+  header->retry_token = GetRetryToken();
+  header->length_length = GetLengthLength();
+  header->remaining_packet_length = 0;
+  if (!HasIetfLongHeader()) {
+    return;
+  }
+  header->long_packet_type =
+      EncryptionlevelToLongHeaderType(packet_.encryption_level);
+}
+
+size_t QuicPacketCreator::GetSerializedFrameLength(const QuicFrame& frame) {
+  size_t serialized_frame_length = framer_->GetSerializedFrameLength(
+      frame, BytesFree(), queued_frames_.empty(),
+      /* last_frame_in_packet= */ true, GetPacketNumberLength());
+  if (!framer_->version().HasHeaderProtection() ||
+      serialized_frame_length == 0) {
+    return serialized_frame_length;
+  }
+  // Calculate frame bytes and bytes free with this frame added.
+  const size_t frame_bytes = PacketSize() - PacketHeaderSize() +
+                             ExpansionOnNewFrame() + serialized_frame_length;
+  if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
+    // No extra bytes is needed.
+    return serialized_frame_length;
+  }
+  if (BytesFree() < serialized_frame_length) {
+    QUIC_BUG(quic_bug_10752_35) << ENDPOINT << "Frame does not fit: " << frame;
+    return 0;
+  }
+  // Please note bytes_free does not take |frame|'s expansion into account.
+  size_t bytes_free = BytesFree() - serialized_frame_length;
+  // Extra bytes needed (this is NOT padding needed) should be at least 1
+  // padding + expansion.
+  const size_t extra_bytes_needed = std::max(
+      1 + ExpansionOnNewFrameWithLastFrame(frame, framer_->transport_version()),
+      MinPlaintextPacketSize(framer_->version()) - frame_bytes);
+  if (bytes_free < extra_bytes_needed) {
+    // This frame does not fit.
+    return 0;
+  }
+  return serialized_frame_length;
+}
+
+bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
+                                 TransmissionType transmission_type) {
+  QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
+                << transmission_type << ": " << frame;
+  if (frame.type == STREAM_FRAME &&
+      !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
+                                   frame.stream_frame.stream_id) &&
+      AttemptingToSendUnencryptedStreamData()) {
+    return false;
+  }
+
+  // Sanity check to ensure we don't send frames at the wrong encryption level.
+  QUICHE_DCHECK(
+      packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
+      packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
+      (frame.type != GOAWAY_FRAME && frame.type != WINDOW_UPDATE_FRAME &&
+       frame.type != HANDSHAKE_DONE_FRAME &&
+       frame.type != NEW_CONNECTION_ID_FRAME &&
+       frame.type != MAX_STREAMS_FRAME && frame.type != STREAMS_BLOCKED_FRAME &&
+       frame.type != PATH_RESPONSE_FRAME &&
+       frame.type != PATH_CHALLENGE_FRAME && frame.type != STOP_SENDING_FRAME &&
+       frame.type != MESSAGE_FRAME && frame.type != NEW_TOKEN_FRAME &&
+       frame.type != RETIRE_CONNECTION_ID_FRAME &&
+       frame.type != ACK_FREQUENCY_FRAME))
+      << ENDPOINT << frame.type << " not allowed at "
+      << packet_.encryption_level;
+
+  if (frame.type == STREAM_FRAME) {
+    if (MaybeCoalesceStreamFrame(frame.stream_frame)) {
+      LogCoalesceStreamFrameStatus(true);
+      return true;
+    } else {
+      LogCoalesceStreamFrameStatus(false);
+    }
+  }
+
+  // If this is an ACK frame, validate that it is non-empty and that
+  // largest_acked matches the max packet number.
+  QUICHE_DCHECK(frame.type != ACK_FRAME || (!frame.ack_frame->packets.Empty() &&
+                                            frame.ack_frame->packets.Max() ==
+                                                frame.ack_frame->largest_acked))
+      << ENDPOINT << "Invalid ACK frame: " << frame;
+
+  size_t frame_len = GetSerializedFrameLength(frame);
+  if (frame_len == 0 && RemoveSoftMaxPacketLength()) {
+    // Remove soft max_packet_length and retry.
+    frame_len = GetSerializedFrameLength(frame);
+  }
+  if (frame_len == 0) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Flushing because current open packet is full when adding "
+                  << frame;
+    FlushCurrentPacket();
+    return false;
+  }
+  if (queued_frames_.empty()) {
+    packet_size_ = PacketHeaderSize();
+  }
+  QUICHE_DCHECK_LT(0u, packet_size_) << ENDPOINT;
+
+  packet_size_ += ExpansionOnNewFrame() + frame_len;
+
+  if (QuicUtils::IsRetransmittableFrame(frame.type)) {
+    packet_.retransmittable_frames.push_back(frame);
+    queued_frames_.push_back(frame);
+    if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
+      packet_.has_crypto_handshake = IS_HANDSHAKE;
+    }
+  } else {
+    if (frame.type == PADDING_FRAME &&
+        frame.padding_frame.num_padding_bytes == -1) {
+      // Populate the actual length of full padding frame, such that one can
+      // know how much padding is actually added.
+      packet_.nonretransmittable_frames.push_back(
+          QuicFrame(QuicPaddingFrame(frame_len)));
+    } else {
+      packet_.nonretransmittable_frames.push_back(frame);
+    }
+    queued_frames_.push_back(frame);
+  }
+
+  if (frame.type == ACK_FRAME) {
+    packet_.has_ack = true;
+    packet_.largest_acked = LargestAcked(*frame.ack_frame);
+  } else if (frame.type == STOP_WAITING_FRAME) {
+    packet_.has_stop_waiting = true;
+  } else if (frame.type == ACK_FREQUENCY_FRAME) {
+    packet_.has_ack_frequency = true;
+  } else if (frame.type == MESSAGE_FRAME) {
+    packet_.has_message = true;
+  }
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnFrameAddedToPacket(frame);
+  }
+
+  // Packet transmission type is determined by the last added retransmittable
+  // frame.
+  if (QuicUtils::IsRetransmittableFrame(frame.type)) {
+    packet_.transmission_type = transmission_type;
+  }
+  return true;
+}
+
+void QuicPacketCreator::MaybeAddExtraPaddingForHeaderProtection() {
+  if (!framer_->version().HasHeaderProtection() || needs_full_padding_) {
+    return;
+  }
+  const size_t frame_bytes = PacketSize() - PacketHeaderSize();
+  if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
+    return;
+  }
+  const QuicByteCount min_header_protection_padding =
+      std::max(1 + ExpansionOnNewFrame(),
+               MinPlaintextPacketSize(framer_->version()) - frame_bytes) -
+      ExpansionOnNewFrame();
+  // Update pending_padding_bytes_.
+  pending_padding_bytes_ =
+      std::max(pending_padding_bytes_, min_header_protection_padding);
+}
+
+bool QuicPacketCreator::MaybeCoalesceStreamFrame(const QuicStreamFrame& frame) {
+  if (queued_frames_.empty() || queued_frames_.back().type != STREAM_FRAME) {
+    return false;
+  }
+  QuicStreamFrame* candidate = &queued_frames_.back().stream_frame;
+  if (candidate->stream_id != frame.stream_id ||
+      candidate->offset + candidate->data_length != frame.offset ||
+      frame.data_length > BytesFree()) {
+    return false;
+  }
+  candidate->data_length += frame.data_length;
+  candidate->fin = frame.fin;
+
+  // The back of retransmittable frames must be the same as the original
+  // queued frames' back.
+  QUICHE_DCHECK_EQ(packet_.retransmittable_frames.back().type, STREAM_FRAME)
+      << ENDPOINT;
+  QuicStreamFrame* retransmittable =
+      &packet_.retransmittable_frames.back().stream_frame;
+  QUICHE_DCHECK_EQ(retransmittable->stream_id, frame.stream_id) << ENDPOINT;
+  QUICHE_DCHECK_EQ(retransmittable->offset + retransmittable->data_length,
+                   frame.offset)
+      << ENDPOINT;
+  retransmittable->data_length = candidate->data_length;
+  retransmittable->fin = candidate->fin;
+  packet_size_ += frame.data_length;
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnStreamFrameCoalesced(*candidate);
+  }
+  return true;
+}
+
+bool QuicPacketCreator::RemoveSoftMaxPacketLength() {
+  if (latched_hard_max_packet_length_ == 0) {
+    return false;
+  }
+  if (!CanSetMaxPacketLength()) {
+    return false;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Restoring max packet length to: "
+                << latched_hard_max_packet_length_;
+  SetMaxPacketLength(latched_hard_max_packet_length_);
+  // Reset latched_max_packet_length_.
+  latched_hard_max_packet_length_ = 0;
+  return true;
+}
+
+void QuicPacketCreator::MaybeAddPadding() {
+  // The current packet should have no padding bytes because padding is only
+  // added when this method is called just before the packet is serialized.
+  if (BytesFree() == 0) {
+    // Don't pad full packets.
+    return;
+  }
+
+  if (packet_.transmission_type == PROBING_RETRANSMISSION) {
+    needs_full_padding_ = true;
+  }
+
+  if (packet_.fate == COALESCE || packet_.fate == LEGACY_VERSION_ENCAPSULATE) {
+    // Do not add full padding if the packet is going to be coalesced or
+    // encapsulated.
+    needs_full_padding_ = false;
+  }
+
+  // Header protection requires a minimum plaintext packet size.
+  MaybeAddExtraPaddingForHeaderProtection();
+
+  QUIC_DVLOG(3) << "MaybeAddPadding for " << packet_.packet_number
+                << ": transmission_type:" << packet_.transmission_type
+                << ", fate:" << packet_.fate
+                << ", needs_full_padding_:" << needs_full_padding_
+                << ", pending_padding_bytes_:" << pending_padding_bytes_
+                << ", BytesFree:" << BytesFree();
+
+  if (!needs_full_padding_ && pending_padding_bytes_ == 0) {
+    // Do not need padding.
+    return;
+  }
+
+  int padding_bytes = -1;
+  if (!needs_full_padding_) {
+    padding_bytes = std::min<int16_t>(pending_padding_bytes_, BytesFree());
+    pending_padding_bytes_ -= padding_bytes;
+  }
+
+  bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
+                          packet_.transmission_type);
+  QUIC_BUG_IF(quic_bug_10752_36, !success)
+      << ENDPOINT << "Failed to add padding_bytes: " << padding_bytes
+      << " transmission_type: " << packet_.transmission_type;
+}
+
+bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
+  return have_diversification_nonce_ &&
+         packet_.encryption_level == ENCRYPTION_ZERO_RTT;
+}
+
+bool QuicPacketCreator::IncludeVersionInHeader() const {
+  if (version().HasIetfInvariantHeader()) {
+    return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
+  }
+  return send_version_in_packet_;
+}
+
+void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
+  pending_padding_bytes_ += size;
+  QUIC_DVLOG(3) << "After AddPendingPadding(" << size
+                << "), pending_padding_bytes_:" << pending_padding_bytes_;
+}
+
+bool QuicPacketCreator::StreamFrameIsClientHello(
+    const QuicStreamFrame& frame) const {
+  if (framer_->perspective() == Perspective::IS_SERVER ||
+      !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
+                                   frame.stream_id)) {
+    return false;
+  }
+  // The ClientHello is always sent with INITIAL encryption.
+  return packet_.encryption_level == ENCRYPTION_INITIAL;
+}
+
+void QuicPacketCreator::SetServerConnectionIdIncluded(
+    QuicConnectionIdIncluded server_connection_id_included) {
+  QUICHE_DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
+                server_connection_id_included == CONNECTION_ID_ABSENT)
+      << ENDPOINT;
+  QUICHE_DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
+                server_connection_id_included != CONNECTION_ID_ABSENT)
+      << ENDPOINT;
+  server_connection_id_included_ = server_connection_id_included;
+}
+
+void QuicPacketCreator::SetServerConnectionId(
+    QuicConnectionId server_connection_id) {
+  server_connection_id_ = server_connection_id;
+}
+
+void QuicPacketCreator::SetClientConnectionId(
+    QuicConnectionId client_connection_id) {
+  QUICHE_DCHECK(client_connection_id.IsEmpty() ||
+                framer_->version().SupportsClientConnectionIds())
+      << ENDPOINT;
+  client_connection_id_ = client_connection_id;
+}
+
+QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
+  if (!VersionSupportsMessageFrames(framer_->transport_version())) {
+    return 0;
+  }
+  const size_t packet_header_size = GetPacketHeaderSize(
+      framer_->transport_version(), GetDestinationConnectionIdLength(),
+      GetSourceConnectionIdLength(), IncludeVersionInHeader(),
+      IncludeNonceInPublicHeader(), GetPacketNumberLength(),
+      // No Retry token on packets containing application data.
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
+  // This is the largest possible message payload when the length field is
+  // omitted.
+  size_t max_plaintext_size =
+      latched_hard_max_packet_length_ == 0
+          ? max_plaintext_size_
+          : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
+  size_t largest_frame =
+      max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
+  if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
+    largest_frame = static_cast<size_t>(max_datagram_frame_size_);
+  }
+  return largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
+}
+
+QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
+  if (!VersionSupportsMessageFrames(framer_->transport_version())) {
+    return 0;
+  }
+  // QUIC Crypto server packets may include a diversification nonce.
+  const bool may_include_nonce =
+      framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
+      framer_->perspective() == Perspective::IS_SERVER;
+  // IETF QUIC long headers include a length on client 0RTT packets.
+  QuicVariableLengthIntegerLength length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  if (framer_->perspective() == Perspective::IS_CLIENT) {
+    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+  if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
+    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  const size_t packet_header_size = GetPacketHeaderSize(
+      framer_->transport_version(), GetDestinationConnectionIdLength(),
+      // Assume CID lengths don't change, but version may be present.
+      GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
+      PACKET_4BYTE_PACKET_NUMBER,
+      // No Retry token on packets containing application data.
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
+  // This is the largest possible message payload when the length field is
+  // omitted.
+  size_t max_plaintext_size =
+      latched_hard_max_packet_length_ == 0
+          ? max_plaintext_size_
+          : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
+  size_t largest_frame =
+      max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
+  if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
+    largest_frame = static_cast<size_t>(max_datagram_frame_size_);
+  }
+  const QuicPacketLength largest_payload =
+      largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
+  // This must always be less than or equal to GetCurrentLargestMessagePayload.
+  QUICHE_DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload())
+      << ENDPOINT;
+  return largest_payload;
+}
+
+bool QuicPacketCreator::AttemptingToSendUnencryptedStreamData() {
+  if (packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
+      packet_.encryption_level == ENCRYPTION_FORWARD_SECURE) {
+    return false;
+  }
+  const std::string error_details =
+      absl::StrCat("Cannot send stream data with level: ",
+                   EncryptionLevelToString(packet_.encryption_level));
+  QUIC_BUG(quic_bug_10752_37) << ENDPOINT << error_details;
+  delegate_->OnUnrecoverableError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA,
+                                  error_details);
+  return true;
+}
+
+bool QuicPacketCreator::HasIetfLongHeader() const {
+  return version().HasIetfInvariantHeader() &&
+         packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
+}
+
+// static
+size_t QuicPacketCreator::MinPlaintextPacketSize(
+    const ParsedQuicVersion& version) {
+  if (!version.HasHeaderProtection()) {
+    return 0;
+  }
+  // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
+  // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
+  // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
+  // numbers could be as small as 1 byte, but the sample starts 4 bytes after
+  // the packet number, at least 3 bytes of plaintext are needed to make sure
+  // that there is enough ciphertext to sample.
+  //
+  // Google QUIC crypto uses different AEAD algorithms - in particular the auth
+  // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
+  // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
+  // ciphertext to sample.
+  //
+  // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
+  // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
+  // determined based on the handshake protocol used). However, even when TLS
+  // 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
+  // test crypters) which also only use 12 byte tags.
+  //
+  // TODO(nharper): Set this based on the handshake protocol in use.
+  return 7;
+}
+
+QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
+  if (!packet_number().IsInitialized()) {
+    return framer_->first_sending_packet_number();
+  }
+  return packet_number() + 1;
+}
+
+bool QuicPacketCreator::PacketFlusherAttached() const {
+  return flusher_attached_;
+}
+
+bool QuicPacketCreator::HasSoftMaxPacketLength() const {
+  return latched_hard_max_packet_length_ != 0;
+}
+
+void QuicPacketCreator::SetDefaultPeerAddress(QuicSocketAddress address) {
+  if (!packet_.peer_address.IsInitialized()) {
+    packet_.peer_address = address;
+    return;
+  }
+  if (packet_.peer_address != address) {
+    FlushCurrentPacket();
+    packet_.peer_address = address;
+  }
+}
+
+#define ENDPOINT2                                                          \
+  (creator_->framer_->perspective() == Perspective::IS_SERVER ? "Server: " \
+                                                              : "Client: ")
+
+QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
+    QuicPacketCreator* creator,
+    QuicSocketAddress address,
+    bool update_connection_id)
+    : ScopedPeerAddressContext(creator,
+                               address,
+                               EmptyQuicConnectionId(),
+                               EmptyQuicConnectionId(),
+                               update_connection_id) {}
+
+QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
+    QuicPacketCreator* creator,
+    QuicSocketAddress address,
+    const QuicConnectionId& client_connection_id,
+    const QuicConnectionId& server_connection_id,
+    bool update_connection_id)
+    : creator_(creator),
+      old_peer_address_(creator_->packet_.peer_address),
+      old_client_connection_id_(creator_->GetClientConnectionId()),
+      old_server_connection_id_(creator_->GetServerConnectionId()),
+      update_connection_id_(update_connection_id) {
+  QUIC_BUG_IF(quic_bug_12398_19, !old_peer_address_.IsInitialized())
+      << ENDPOINT2
+      << "Context is used before serialized packet's peer address is "
+         "initialized.";
+  creator_->SetDefaultPeerAddress(address);
+  if (update_connection_id_) {
+    // Flush current packet if connection ID length changes.
+    if (address == old_peer_address_ &&
+        ((client_connection_id.length() !=
+          old_client_connection_id_.length()) ||
+         (server_connection_id.length() !=
+          old_server_connection_id_.length()))) {
+      creator_->FlushCurrentPacket();
+    }
+    creator_->SetClientConnectionId(client_connection_id);
+    creator_->SetServerConnectionId(server_connection_id);
+  }
+}
+
+QuicPacketCreator::ScopedPeerAddressContext::~ScopedPeerAddressContext() {
+  creator_->SetDefaultPeerAddress(old_peer_address_);
+  if (update_connection_id_) {
+    creator_->SetClientConnectionId(old_client_connection_id_);
+    creator_->SetServerConnectionId(old_server_connection_id_);
+  }
+}
+
+QuicPacketCreator::ScopedSerializationFailureHandler::
+    ScopedSerializationFailureHandler(QuicPacketCreator* creator)
+    : creator_(creator) {}
+
+QuicPacketCreator::ScopedSerializationFailureHandler::
+    ~ScopedSerializationFailureHandler() {
+  if (creator_ == nullptr) {
+    return;
+  }
+  // Always clear queued_frames_.
+  creator_->queued_frames_.clear();
+
+  if (creator_->packet_.encrypted_buffer == nullptr) {
+    const std::string error_details = "Failed to SerializePacket.";
+    QUIC_BUG(quic_bug_10752_38) << ENDPOINT2 << error_details;
+    creator_->delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
+                                              error_details);
+  }
+}
+
+#undef ENDPOINT2
+
+void QuicPacketCreator::set_encryption_level(EncryptionLevel level) {
+  QUICHE_DCHECK(level == packet_.encryption_level || !HasPendingFrames())
+      << ENDPOINT << "Cannot update encryption level from "
+      << packet_.encryption_level << " to " << level
+      << " when we already have pending frames: "
+      << QuicFramesToString(queued_frames_);
+  packet_.encryption_level = level;
+}
+
+void QuicPacketCreator::AddPathChallengeFrame(
+    const QuicPathFrameBuffer& payload) {
+  // TODO(danzh) Unify similar checks at several entry points into one in
+  // AddFrame(). Sort out test helper functions and peer class that don't
+  // enforce this check.
+  QUIC_BUG_IF(quic_bug_10752_39, !flusher_attached_)
+      << ENDPOINT
+      << "Packet flusher is not attached when "
+         "generator tries to write stream data.";
+  // Write a PATH_CHALLENGE frame, which has a random 8-byte payload.
+  auto path_challenge_frame = new QuicPathChallengeFrame(0, payload);
+  QuicFrame frame(path_challenge_frame);
+  if (AddPaddedFrameWithRetry(frame)) {
+    return;
+  }
+  // Fail silently if the probing packet cannot be written, path validation
+  // initiator will retry sending automatically.
+  // TODO(danzh) This will consume retry budget, if it causes performance
+  // regression, consider to notify the caller about the sending failure and let
+  // the caller to decide if it worth retrying.
+  QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_CHALLENGE now";
+  delete path_challenge_frame;
+}
+
+bool QuicPacketCreator::AddPathResponseFrame(
+    const QuicPathFrameBuffer& data_buffer) {
+  auto path_response =
+      new QuicPathResponseFrame(kInvalidControlFrameId, data_buffer);
+  QuicFrame frame(path_response);
+  if (AddPaddedFrameWithRetry(frame)) {
+    return true;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_RESPONSE now";
+  delete path_response;
+  return false;
+}
+
+bool QuicPacketCreator::AddPaddedFrameWithRetry(const QuicFrame& frame) {
+  if (HasPendingFrames()) {
+    if (AddPaddedSavedFrame(frame, NOT_RETRANSMISSION)) {
+      // Frame is queued.
+      return true;
+    }
+  }
+  // Frame was not queued but queued frames were flushed.
+  QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
+  if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                       NOT_HANDSHAKE)) {
+    return false;
+  }
+  bool success = AddPaddedSavedFrame(frame, NOT_RETRANSMISSION);
+  QUIC_BUG_IF(quic_bug_12398_20, !success) << ENDPOINT;
+  return true;
+}
+
+bool QuicPacketCreator::HasRetryToken() const {
+  return !retry_token_.empty();
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_creator.h b/quiche/quic/core/quic_packet_creator.h
new file mode 100644
index 0000000..55b7a2d
--- /dev/null
+++ b/quiche/quic/core/quic_packet_creator.h
@@ -0,0 +1,732 @@
+// 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 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_
+
+#include <cstddef>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_coalesced_packet.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+namespace test {
+class QuicPacketCreatorPeer;
+}
+
+class QUIC_EXPORT_PRIVATE QuicPacketCreator {
+ public:
+  // A delegate interface for further processing serialized packet.
+  class QUIC_EXPORT_PRIVATE DelegateInterface {
+   public:
+    virtual ~DelegateInterface() {}
+    // Get a buffer of kMaxOutgoingPacketSize bytes to serialize the next
+    // packet. If the return value's buffer is nullptr, QuicPacketCreator will
+    // serialize on a stack buffer.
+    virtual QuicPacketBuffer GetPacketBuffer() = 0;
+    // Called when a packet is serialized. Delegate take the ownership of
+    // |serialized_packet|.
+    virtual void OnSerializedPacket(SerializedPacket serialized_packet) = 0;
+
+    // Called when an unrecoverable error is encountered.
+    virtual void OnUnrecoverableError(QuicErrorCode error,
+                                      const std::string& error_details) = 0;
+
+    // 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;
+
+    // Returns the packet fate for serialized packets which will be handed over
+    // to delegate via OnSerializedPacket(). Called when a packet is about to be
+    // serialized.
+    virtual SerializedPacketFate GetSerializedPacketFate(
+        bool is_mtu_discovery,
+        EncryptionLevel encryption_level) = 0;
+  };
+
+  // Interface which gets callbacks from the QuicPacketCreator at interesting
+  // points.  Implementations must not mutate the state of the creator
+  // as a result of these callbacks.
+  class QUIC_EXPORT_PRIVATE DebugDelegate {
+   public:
+    virtual ~DebugDelegate() {}
+
+    // Called when a frame has been added to the current packet.
+    virtual void OnFrameAddedToPacket(const QuicFrame& /*frame*/) {}
+
+    // Called when a stream frame is coalesced with an existing stream frame.
+    // |frame| is the new stream frame.
+    virtual void OnStreamFrameCoalesced(const QuicStreamFrame& /*frame*/) {}
+  };
+
+  // Set the peer address and connection IDs with which the serialized packet
+  // will be sent to during the scope of this object. Upon exiting the scope,
+  // the original peer address and connection IDs are restored.
+  class QUIC_EXPORT_PRIVATE ScopedPeerAddressContext {
+   public:
+    ScopedPeerAddressContext(QuicPacketCreator* creator,
+                             QuicSocketAddress address,
+                             bool update_connection_id);
+
+    ScopedPeerAddressContext(QuicPacketCreator* creator,
+                             QuicSocketAddress address,
+                             const QuicConnectionId& client_connection_id,
+                             const QuicConnectionId& server_connection_id,
+                             bool update_connection_id);
+    ~ScopedPeerAddressContext();
+
+   private:
+    QuicPacketCreator* creator_;
+    QuicSocketAddress old_peer_address_;
+    QuicConnectionId old_client_connection_id_;
+    QuicConnectionId old_server_connection_id_;
+    bool update_connection_id_;
+  };
+
+  QuicPacketCreator(QuicConnectionId server_connection_id,
+                    QuicFramer* framer,
+                    DelegateInterface* delegate);
+  QuicPacketCreator(QuicConnectionId server_connection_id,
+                    QuicFramer* framer,
+                    QuicRandom* random,
+                    DelegateInterface* delegate);
+  QuicPacketCreator(const QuicPacketCreator&) = delete;
+  QuicPacketCreator& operator=(const QuicPacketCreator&) = delete;
+
+  ~QuicPacketCreator();
+
+  // 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);
+
+  // Update the packet number length to use in future packets as soon as it
+  // can be safely changed.
+  // TODO(fayang): Directly set packet number length instead of compute it in
+  // creator.
+  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);
+
+  // The overhead the framing will add for a packet with one frame.
+  static size_t StreamFramePacketOverhead(
+      QuicTransportVersion version,
+      QuicConnectionIdLength destination_connection_id_length,
+      QuicConnectionIdLength source_connection_id_length,
+      bool include_version,
+      bool include_diversification_nonce,
+      QuicPacketNumberLength packet_number_length,
+      QuicVariableLengthIntegerLength retry_token_length_length,
+      QuicVariableLengthIntegerLength length_length,
+      QuicStreamOffset offset);
+
+  // Returns false and flushes all pending frames if current open packet is
+  // full.
+  // If current packet is not full, creates a stream frame that fits into the
+  // open packet and adds it to the packet.
+  bool ConsumeDataToFillCurrentPacket(QuicStreamId id,
+                                      size_t data_size,
+                                      QuicStreamOffset offset,
+                                      bool fin,
+                                      bool needs_full_padding,
+                                      TransmissionType transmission_type,
+                                      QuicFrame* frame);
+
+  // Creates a CRYPTO frame that fits into the current packet (which must be
+  // empty) and adds it to the packet.
+  bool ConsumeCryptoDataToFillCurrentPacket(EncryptionLevel level,
+                                            size_t write_length,
+                                            QuicStreamOffset offset,
+                                            bool needs_full_padding,
+                                            TransmissionType transmission_type,
+                                            QuicFrame* frame);
+
+  // Returns true if current open packet can accommodate more stream frames of
+  // stream |id| at |offset| and data length |data_size|, false otherwise.
+  // TODO(fayang): mark this const by moving RemoveSoftMaxPacketLength out.
+  bool HasRoomForStreamFrame(QuicStreamId id,
+                             QuicStreamOffset offset,
+                             size_t data_size);
+
+  // Returns true if current open packet can accommodate a message frame of
+  // |length|.
+  // TODO(fayang): mark this const by moving RemoveSoftMaxPacketLength out.
+  bool HasRoomForMessageFrame(QuicByteCount length);
+
+  // Serializes all added frames into a single packet and invokes the delegate_
+  // to further process the SerializedPacket.
+  void FlushCurrentPacket();
+
+  // Optimized method to create a QuicStreamFrame and serialize it. Adds the
+  // QuicStreamFrame to the returned SerializedPacket.  Sets
+  // |num_bytes_consumed| to the number of bytes consumed to create the
+  // QuicStreamFrame.
+  void CreateAndSerializeStreamFrame(QuicStreamId id,
+                                     size_t write_length,
+                                     QuicStreamOffset iov_offset,
+                                     QuicStreamOffset stream_offset,
+                                     bool fin,
+                                     TransmissionType transmission_type,
+                                     size_t* num_bytes_consumed);
+
+  // Returns true if there are frames pending to be serialized.
+  bool HasPendingFrames() const;
+
+  // TODO(haoyuewang) Remove this debug utility.
+  // Returns the information of pending frames as a string.
+  std::string GetPendingFramesInfo() const;
+
+  // Returns true if there are retransmittable frames pending to be serialized.
+  bool HasPendingRetransmittableFrames() const;
+
+  // Returns true if there are stream frames for |id| pending to be serialized.
+  bool HasPendingStreamFramesOfStream(QuicStreamId id) const;
+
+  // Returns the number of bytes which are available to be used by additional
+  // frames in the packet.  Since stream frames are slightly smaller when they
+  // are the last frame in a packet, this method will return a different
+  // value than max_packet_size - PacketSize(), in this case.
+  size_t BytesFree() const;
+
+  // Returns the number of bytes that the packet will expand by if a new frame
+  // is added to the packet. If the last frame was a stream frame, it will
+  // expand slightly when a new frame is added, and this method returns the
+  // amount of expected expansion.
+  size_t ExpansionOnNewFrame() const;
+
+  // Returns the number of bytes that the packet will expand by when a new frame
+  // is going to be added. |last_frame| is the last frame of the packet.
+  static size_t ExpansionOnNewFrameWithLastFrame(const QuicFrame& last_frame,
+                                                 QuicTransportVersion version);
+
+  // Returns the number of bytes in the current packet, including the header,
+  // if serialized with the current frames.  Adding a frame to the packet
+  // may change the serialized length of existing frames, as per the comment
+  // in BytesFree.
+  size_t PacketSize() const;
+
+  // Tries to add |frame| to the packet creator's list of frames to be
+  // serialized. If the frame does not fit into the current packet, flushes the
+  // packet and returns false.
+  bool AddFrame(const QuicFrame& frame, TransmissionType transmission_type);
+
+  // Identical to AddSavedFrame, but allows the frame to be padded.
+  bool AddPaddedSavedFrame(const QuicFrame& frame,
+                           TransmissionType transmission_type);
+
+  // Creates a connectivity probing packet for versions prior to version 99.
+  std::unique_ptr<SerializedPacket> SerializeConnectivityProbingPacket();
+
+  // Create connectivity probing request and response packets using PATH
+  // CHALLENGE and PATH RESPONSE frames, respectively, for version 99/IETF QUIC.
+  // SerializePathChallengeConnectivityProbingPacket will pad the packet to be
+  // MTU bytes long.
+  std::unique_ptr<SerializedPacket>
+  SerializePathChallengeConnectivityProbingPacket(
+      const 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.
+  std::unique_ptr<SerializedPacket>
+  SerializePathResponseConnectivityProbingPacket(
+      const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
+      const bool is_padded);
+
+  // Add PATH_RESPONSE to current packet, flush before or afterwards if needed.
+  bool AddPathResponseFrame(const QuicPathFrameBuffer& data_buffer);
+
+  // Add PATH_CHALLENGE to current packet, flush before or afterwards if needed.
+  // This is a best effort adding. It may fail becasue of delegate state, but
+  // it's okay because of path validation retry mechanism.
+  void AddPathChallengeFrame(const QuicPathFrameBuffer& payload);
+
+  // Returns a dummy packet that is valid but contains no useful information.
+  static SerializedPacket NoPacket();
+
+  // Returns the server connection ID to send over the wire.
+  const QuicConnectionId& GetServerConnectionId() const {
+    return server_connection_id_;
+  }
+
+  // Returns the client connection ID to send over the wire.
+  const QuicConnectionId& GetClientConnectionId() const {
+    return client_connection_id_;
+  }
+
+  // Returns the destination connection ID to send over the wire.
+  QuicConnectionId GetDestinationConnectionId() const;
+
+  // Returns the source connection ID to send over the wire.
+  QuicConnectionId GetSourceConnectionId() const;
+
+  // Returns length of destination connection ID to send over the wire.
+  QuicConnectionIdLength GetDestinationConnectionIdLength() const;
+
+  // Returns length of source connection ID to send over the wire.
+  QuicConnectionIdLength GetSourceConnectionIdLength() const;
+
+  // Sets whether the server connection ID should be sent over the wire.
+  void SetServerConnectionIdIncluded(
+      QuicConnectionIdIncluded server_connection_id_included);
+
+  // 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);
+
+  // Sets the encryption level that will be applied to new packets.
+  void set_encryption_level(EncryptionLevel level);
+  EncryptionLevel encryption_level() { return packet_.encryption_level; }
+
+  // Sets whether initial packets are protected with chaos.
+  void set_chaos_protection_enabled(bool chaos_protection_enabled) {
+    chaos_protection_enabled_ = chaos_protection_enabled;
+  }
+
+  // packet number of the last created packet, or 0 if no packets have been
+  // created.
+  QuicPacketNumber packet_number() const { return packet_.packet_number; }
+
+  QuicByteCount max_packet_length() const { return max_packet_length_; }
+
+  bool has_ack() const { return packet_.has_ack; }
+
+  bool has_stop_waiting() const { return packet_.has_stop_waiting; }
+
+  // Sets the encrypter to use for the encryption level and updates the max
+  // plaintext size.
+  void SetEncrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicEncrypter> encrypter);
+
+  // Indicates whether the packet creator is in a state where it can change
+  // current maximum packet length.
+  bool CanSetMaxPacketLength() const;
+
+  // Sets the maximum packet length.
+  void SetMaxPacketLength(QuicByteCount length);
+
+  // Sets the maximum DATAGRAM/MESSAGE frame size we can send.
+  void SetMaxDatagramFrameSize(QuicByteCount max_datagram_frame_size);
+
+  // 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);
+
+  // Increases pending_padding_bytes by |size|. Pending padding will be sent by
+  // MaybeAddPadding().
+  void AddPendingPadding(QuicByteCount size);
+
+  // Sets the retry token to be sent over the wire in IETF Initial packets.
+  void SetRetryToken(absl::string_view retry_token);
+
+  // 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);
+
+  // 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);
+
+  // 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);
+
+  // Generates an MTU discovery packet of specified size.
+  void GenerateMtuDiscoveryPacket(QuicByteCount target_mtu);
+
+  // Called when there is data to be sent, Retrieves updated ACK frame from
+  // delegate_ and flushes it.
+  void MaybeBundleAckOpportunistically();
+
+  // Called to flush ACK and STOP_WAITING frames, returns false if the flush
+  // fails.
+  bool FlushAckFrame(const QuicFrames& frames);
+
+  // Adds a random amount of padding (between 1 to 256 bytes).
+  void AddRandomPadding();
+
+  // Attaches packet flusher.
+  void AttachPacketFlusher();
+
+  // Flushes everything, including current open packet and pending padding.
+  void Flush();
+
+  // Sends remaining pending padding.
+  // Pending paddings should only be sent when there is nothing else to send.
+  void SendRemainingPendingPadding();
+
+  // Set the minimum number of bytes for the server connection id length;
+  void SetServerConnectionIdLength(uint32_t length);
+
+  // Set transmission type of next constructed packets.
+  void SetTransmissionType(TransmissionType type);
+
+  // Tries to add a message frame containing |message| and returns the status.
+  MessageStatus AddMessageFrame(QuicMessageId message_id,
+                                absl::Span<quiche::QuicheMemSlice> message);
+
+  // Returns the largest payload that will fit into a single MESSAGE frame.
+  QuicPacketLength GetCurrentLargestMessagePayload() const;
+  // Returns the largest payload that will fit into a single MESSAGE frame at
+  // any point during the connection.  This assumes the version and
+  // connection ID lengths do not change.
+  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
+
+  // Packet number of next created packet.
+  QuicPacketNumber NextSendingPacketNumber() const;
+
+  void set_debug_delegate(DebugDelegate* debug_delegate) {
+    debug_delegate_ = debug_delegate;
+  }
+
+  QuicByteCount pending_padding_bytes() const { return pending_padding_bytes_; }
+
+  ParsedQuicVersion version() const { return framer_->version(); }
+
+  QuicTransportVersion transport_version() const {
+    return framer_->transport_version();
+  }
+
+  // Returns the minimum size that the plaintext of a packet must be.
+  static size_t MinPlaintextPacketSize(const ParsedQuicVersion& version);
+
+  // Indicates whether packet flusher is currently attached.
+  bool PacketFlusherAttached() const;
+
+  void set_fully_pad_crypto_handshake_packets(bool new_value) {
+    fully_pad_crypto_handshake_packets_ = new_value;
+  }
+
+  bool fully_pad_crypto_handshake_packets() const {
+    return fully_pad_crypto_handshake_packets_;
+  }
+
+  // Serialize a probing packet that uses IETF QUIC's PATH CHALLENGE frame. Also
+  // fills the packet with padding.
+  size_t BuildPaddedPathChallengePacket(const QuicPacketHeader& header,
+                                        char* buffer,
+                                        size_t packet_length,
+                                        const QuicPathFrameBuffer& payload,
+                                        EncryptionLevel level);
+
+  // Serialize a probing response packet that uses IETF QUIC's PATH RESPONSE
+  // frame. Also fills the packet with padding if |is_padded| is
+  // true. |payloads| is always emptied, even if the packet can not be
+  // successfully built.
+  size_t BuildPathResponsePacket(
+      const QuicPacketHeader& header,
+      char* buffer,
+      size_t packet_length,
+      const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
+      const bool is_padded,
+      EncryptionLevel level);
+
+  // Serializes a probing packet, which is a padded PING packet. Returns the
+  // length of the packet. Returns 0 if it fails to serialize.
+  size_t BuildConnectivityProbingPacket(const QuicPacketHeader& header,
+                                        char* buffer,
+                                        size_t packet_length,
+                                        EncryptionLevel level);
+
+  // 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);
+
+  // Returns true if max_packet_length_ is currently a soft value.
+  bool HasSoftMaxPacketLength() const;
+
+  // Use this address to sent to the peer from now on. If this address is
+  // different from the current one, flush all the queue frames first.
+  void SetDefaultPeerAddress(QuicSocketAddress address);
+
+  // Return true if retry_token_ is not empty.
+  bool HasRetryToken() const;
+
+  const QuicSocketAddress& peer_address() const { return packet_.peer_address; }
+
+  bool close_connection_if_fail_to_serialzie_coalesced_packet() const {
+    return close_connection_if_fail_to_serialzie_coalesced_packet_;
+  }
+
+ private:
+  friend class test::QuicPacketCreatorPeer;
+
+  // Used to 1) clear queued_frames_, 2) report unrecoverable error (if
+  // serialization fails) upon exiting the scope.
+  class QUIC_EXPORT_PRIVATE ScopedSerializationFailureHandler {
+   public:
+    explicit ScopedSerializationFailureHandler(QuicPacketCreator* creator);
+    ~ScopedSerializationFailureHandler();
+
+   private:
+    QuicPacketCreator* creator_;  // Unowned.
+  };
+
+  // Attempts to build a data packet with chaos protection. If this packet isn't
+  // supposed to be protected or if serialization fails then absl::nullopt is
+  // returned. Otherwise returns the serialized length.
+  absl::optional<size_t> MaybeBuildDataPacketWithChaosProtection(
+      const QuicPacketHeader& header,
+      char* buffer);
+
+  // Creates a stream frame which fits into the current open packet. If
+  // |data_size| is 0 and fin is true, the expected behavior is to consume
+  // the fin.
+  void CreateStreamFrame(QuicStreamId id,
+                         size_t data_size,
+                         QuicStreamOffset offset,
+                         bool fin,
+                         QuicFrame* frame);
+
+  // Creates a CRYPTO frame which fits into the current open packet. Returns
+  // false if there isn't enough room in the current open packet for a CRYPTO
+  // frame, and true if there is.
+  bool CreateCryptoFrame(EncryptionLevel level,
+                         size_t write_length,
+                         QuicStreamOffset offset,
+                         QuicFrame* frame);
+
+  void FillPacketHeader(QuicPacketHeader* header);
+
+  // Adds a padding frame to the current packet (if there is space) when (1)
+  // current packet needs full padding or (2) there are pending paddings.
+  void MaybeAddPadding();
+
+  // Serializes all frames which have been added and adds any which should be
+  // retransmitted to packet_.retransmittable_frames. All frames must fit into
+  // a single packet. Returns true on success, otherwise, returns false.
+  // Fails if |encrypted_buffer| is not large enough for the encrypted packet.
+  //
+  // Padding may be added if |allow_padding|. Currently, the only case where it
+  // is disallowed is reserializing a coalesced initial packet.
+  ABSL_MUST_USE_RESULT bool SerializePacket(
+      QuicOwnedPacketBuffer encrypted_buffer, size_t encrypted_buffer_len,
+      bool allow_padding);
+
+  // Called after a new SerialiedPacket is created to call the delegate's
+  // OnSerializedPacket and reset state.
+  void OnSerializedPacket();
+
+  // Clears all fields of packet_ that should be cleared between serializations.
+  void ClearPacket();
+
+  // Re-serialzes frames of ENCRYPTION_INITIAL packet in coalesced packet with
+  // the original packet's packet number and packet number length.
+  // |padding_size| indicates the size of necessary padding. Returns 0 if
+  // serialization fails.
+  size_t ReserializeInitialPacketInCoalescedPacket(
+      const SerializedPacket& packet,
+      size_t padding_size,
+      char* buffer,
+      size_t buffer_len);
+
+  // Tries to coalesce |frame| with the back of |queued_frames_|.
+  // Returns true on success.
+  bool MaybeCoalesceStreamFrame(const QuicStreamFrame& frame);
+
+  // Called to remove the soft max_packet_length and restores
+  // latched_hard_max_packet_length_ if the packet cannot accommodate a single
+  // frame. Returns true if the soft limit is successfully removed. Returns
+  // false if either there is no current soft limit or there are queued frames
+  // (such that the packet length cannot be changed).
+  bool RemoveSoftMaxPacketLength();
+
+  // Returns true if a diversification nonce should be included in the current
+  // packet's header.
+  bool IncludeNonceInPublicHeader() const;
+
+  // Returns true if version should be included in current packet's header.
+  bool IncludeVersionInHeader() const;
+
+  // Returns length of packet number to send over the wire.
+  // packet_.packet_number_length should never be read directly, use this
+  // function instead.
+  QuicPacketNumberLength GetPacketNumberLength() const;
+
+  // Returns the size in bytes of the packet header.
+  size_t PacketHeaderSize() const;
+
+  // Returns whether the destination connection ID is sent over the wire.
+  QuicConnectionIdIncluded GetDestinationConnectionIdIncluded() const;
+
+  // Returns whether the source connection ID is sent over the wire.
+  QuicConnectionIdIncluded GetSourceConnectionIdIncluded() const;
+
+  // Returns length of the retry token variable length integer to send over the
+  // wire. Is non-zero for v99 IETF Initial packets.
+  QuicVariableLengthIntegerLength GetRetryTokenLengthLength() const;
+
+  // Returns the retry token to send over the wire, only sent in
+  // v99 IETF Initial packets.
+  absl::string_view GetRetryToken() const;
+
+  // Returns length of the length variable length integer to send over the
+  // wire. Is non-zero for v99 IETF Initial, 0-RTT or Handshake packets.
+  QuicVariableLengthIntegerLength GetLengthLength() const;
+
+  // Returns true if |frame| is a ClientHello.
+  bool StreamFrameIsClientHello(const QuicStreamFrame& frame) const;
+
+  // Returns true if packet under construction has IETF long header.
+  bool HasIetfLongHeader() const;
+
+  // Get serialized frame length. Returns 0 if the frame does not fit into
+  // current packet.
+  size_t GetSerializedFrameLength(const QuicFrame& frame);
+
+  // Add extra padding to pending_padding_bytes_ to meet minimum plaintext
+  // packet size required for header protection.
+  void MaybeAddExtraPaddingForHeaderProtection();
+
+  // Returns true and close connection if it attempts to send unencrypted data.
+  bool AttemptingToSendUnencryptedStreamData();
+
+  // Add the given frame to the current packet with full padding. If the current
+  // packet doesn't have enough space, flush once and try again. Return false if
+  // fail to add.
+  bool AddPaddedFrameWithRetry(const QuicFrame& frame);
+
+  // Does not own these delegates or the framer.
+  DelegateInterface* delegate_;
+  DebugDelegate* debug_delegate_;
+  QuicFramer* framer_;
+  QuicRandom* random_;
+
+  // Controls whether version should be included while serializing the packet.
+  // send_version_in_packet_ should never be read directly, use
+  // IncludeVersionInHeader() instead.
+  bool send_version_in_packet_;
+  // If true, then |diversification_nonce_| will be included in the header of
+  // all packets created at the initial encryption level.
+  bool have_diversification_nonce_;
+  DiversificationNonce diversification_nonce_;
+  // Maximum length including headers and encryption (UDP payload length.)
+  QuicByteCount max_packet_length_;
+  size_t max_plaintext_size_;
+  // Whether the server_connection_id is sent over the wire.
+  QuicConnectionIdIncluded server_connection_id_included_;
+
+  // Frames to be added to the next SerializedPacket
+  QuicFrames queued_frames_;
+
+  // Serialization size of header + frames. If there is no queued frames,
+  // packet_size_ is 0.
+  // TODO(ianswett): Move packet_size_ into SerializedPacket once
+  // QuicEncryptedPacket has been flattened into SerializedPacket.
+  size_t packet_size_;
+  QuicConnectionId server_connection_id_;
+  QuicConnectionId client_connection_id_;
+
+  // Packet used to invoke OnSerializedPacket.
+  SerializedPacket packet_;
+
+  // Retry token to send over the wire in v99 IETF Initial packets.
+  std::string retry_token_;
+
+  // Pending padding bytes to send. Pending padding bytes will be sent in next
+  // packet(s) (after all other frames) if current constructed packet does not
+  // have room to send all of them.
+  QuicByteCount pending_padding_bytes_;
+
+  // Indicates whether current constructed packet needs full padding to max
+  // packet size. Please note, full padding does not consume pending padding
+  // bytes.
+  bool needs_full_padding_;
+
+  // Transmission type of the next serialized packet.
+  TransmissionType next_transmission_type_;
+
+  // True if packet flusher is currently attached.
+  bool flusher_attached_;
+
+  // 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_;
+
+  // If not 0, this latches the actual max_packet_length when
+  // SetSoftMaxPacketLength is called and max_packet_length_ gets
+  // set to a soft value.
+  QuicByteCount latched_hard_max_packet_length_;
+
+  // The maximum length of a MESSAGE/DATAGRAM frame that our peer is willing to
+  // accept. There is no limit for QUIC_CRYPTO connections, but QUIC+TLS
+  // negotiates this during the handshake.
+  QuicByteCount max_datagram_frame_size_;
+
+  // Whether to attempt protecting initial packets with chaos.
+  bool chaos_protection_enabled_;
+
+  const bool close_connection_if_fail_to_serialzie_coalesced_packet_ =
+      GetQuicReloadableFlag(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
diff --git a/quiche/quic/core/quic_packet_creator_test.cc b/quiche/quic/core/quic_packet_creator_test.cc
new file mode 100644
index 0000000..7bbd237
--- /dev/null
+++ b/quiche/quic/core/quic_packet_creator_test.cc
@@ -0,0 +1,3937 @@
+// 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 "quiche/quic/core/quic_packet_creator.h"
+
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_packet_creator_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_data_producer.h"
+#include "quiche/quic/test_tools/simple_quic_framer.h"
+#include "quiche/common/simple_buffer_allocator.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using ::testing::_;
+using ::testing::AtLeast;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const QuicPacketNumber kPacketNumber = QuicPacketNumber(UINT64_C(0x12345678));
+// Use fields in which each byte is distinct to ensure that every byte is
+// framed correctly. The values are otherwise arbitrary.
+QuicConnectionId CreateTestConnectionId() {
+  return TestConnectionId(UINT64_C(0xFEDCBA9876543210));
+}
+
+// Run tests with combinations of {ParsedQuicVersion,
+// ToggleVersionSerialization}.
+struct TestParams {
+  TestParams(ParsedQuicVersion version, bool version_serialization)
+      : version(version), version_serialization(version_serialization) {}
+
+  ParsedQuicVersion version;
+  bool version_serialization;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(ParsedQuicVersionToString(p.version), "_",
+                      (p.version_serialization ? "Include" : "No"), "Version");
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
+    params.push_back(TestParams(all_supported_versions[i], true));
+    params.push_back(TestParams(all_supported_versions[i], false));
+  }
+  return params;
+}
+
+class MockDebugDelegate : public QuicPacketCreator::DebugDelegate {
+ public:
+  ~MockDebugDelegate() override = default;
+
+  MOCK_METHOD(void, OnFrameAddedToPacket, (const QuicFrame& frame), (override));
+
+  MOCK_METHOD(void,
+              OnStreamFrameCoalesced,
+              (const QuicStreamFrame& frame),
+              (override));
+};
+
+class TestPacketCreator : public QuicPacketCreator {
+ public:
+  TestPacketCreator(QuicConnectionId connection_id,
+                    QuicFramer* framer,
+                    DelegateInterface* delegate,
+                    SimpleDataProducer* producer)
+      : QuicPacketCreator(connection_id, framer, delegate),
+        producer_(producer),
+        version_(framer->version()) {}
+
+  bool ConsumeDataToFillCurrentPacket(QuicStreamId id, absl::string_view data,
+                                      QuicStreamOffset offset, bool fin,
+                                      bool needs_full_padding,
+                                      TransmissionType transmission_type,
+                                      QuicFrame* frame) {
+    // Save data before data is consumed.
+    if (!data.empty()) {
+      producer_->SaveStreamData(id, data);
+    }
+    return QuicPacketCreator::ConsumeDataToFillCurrentPacket(
+        id, data.length(), offset, fin, needs_full_padding, transmission_type,
+        frame);
+  }
+
+  void StopSendingVersion() {
+    if (version_.HasIetfInvariantHeader()) {
+      set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+      return;
+    }
+    QuicPacketCreator::StopSendingVersion();
+  }
+
+  SimpleDataProducer* producer_;
+  ParsedQuicVersion version_;
+};
+
+class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> {
+ public:
+  void ClearSerializedPacketForTests(SerializedPacket /*serialized_packet*/) {
+    // serialized packet self-clears on destruction.
+  }
+
+  void SaveSerializedPacket(SerializedPacket serialized_packet) {
+    serialized_packet_.reset(CopySerializedPacket(
+        serialized_packet, &allocator_, /*copy_buffer=*/true));
+  }
+
+  void DeleteSerializedPacket() { serialized_packet_ = nullptr; }
+
+ protected:
+  QuicPacketCreatorTest()
+      : connection_id_(TestConnectionId(2)),
+        server_framer_(SupportedVersions(GetParam().version),
+                       QuicTime::Zero(),
+                       Perspective::IS_SERVER,
+                       connection_id_.length()),
+        client_framer_(SupportedVersions(GetParam().version),
+                       QuicTime::Zero(),
+                       Perspective::IS_CLIENT,
+                       connection_id_.length()),
+        data_("foo"),
+        creator_(connection_id_, &client_framer_, &delegate_, &producer_) {
+    EXPECT_CALL(delegate_, GetPacketBuffer())
+        .WillRepeatedly(Return(QuicPacketBuffer()));
+    EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
+        .WillRepeatedly(Return(SEND_TO_WRITER));
+    creator_.SetEncrypter(ENCRYPTION_INITIAL, std::make_unique<NullEncrypter>(
+                                                  Perspective::IS_CLIENT));
+    creator_.SetEncrypter(ENCRYPTION_HANDSHAKE, std::make_unique<NullEncrypter>(
+                                                    Perspective::IS_CLIENT));
+    creator_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>(
+                                                   Perspective::IS_CLIENT));
+    creator_.SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+    client_framer_.set_visitor(&framer_visitor_);
+    server_framer_.set_visitor(&framer_visitor_);
+    client_framer_.set_data_producer(&producer_);
+    if (server_framer_.version().KnowsWhichDecrypterToUse()) {
+      server_framer_.InstallDecrypter(
+          ENCRYPTION_INITIAL,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+      server_framer_.InstallDecrypter(
+          ENCRYPTION_ZERO_RTT,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+      server_framer_.InstallDecrypter(
+          ENCRYPTION_HANDSHAKE,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+      server_framer_.InstallDecrypter(
+          ENCRYPTION_FORWARD_SECURE,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+    } else {
+      server_framer_.SetDecrypter(
+          ENCRYPTION_INITIAL,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+    }
+  }
+
+  ~QuicPacketCreatorTest() override {}
+
+  SerializedPacket SerializeAllFrames(const QuicFrames& frames) {
+    SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames(
+        &creator_, frames, buffer_, kMaxOutgoingPacketSize);
+    EXPECT_EQ(QuicPacketCreatorPeer::GetEncryptionLevel(&creator_),
+              packet.encryption_level);
+    return packet;
+  }
+
+  void ProcessPacket(const SerializedPacket& packet) {
+    QuicEncryptedPacket encrypted_packet(packet.encrypted_buffer,
+                                         packet.encrypted_length);
+    server_framer_.ProcessPacket(encrypted_packet);
+  }
+
+  void CheckStreamFrame(const QuicFrame& frame,
+                        QuicStreamId stream_id,
+                        const std::string& data,
+                        QuicStreamOffset offset,
+                        bool fin) {
+    EXPECT_EQ(STREAM_FRAME, frame.type);
+    EXPECT_EQ(stream_id, frame.stream_frame.stream_id);
+    char buf[kMaxOutgoingPacketSize];
+    QuicDataWriter writer(kMaxOutgoingPacketSize, buf, quiche::HOST_BYTE_ORDER);
+    if (frame.stream_frame.data_length > 0) {
+      producer_.WriteStreamData(stream_id, frame.stream_frame.offset,
+                                frame.stream_frame.data_length, &writer);
+    }
+    EXPECT_EQ(data, absl::string_view(buf, frame.stream_frame.data_length));
+    EXPECT_EQ(offset, frame.stream_frame.offset);
+    EXPECT_EQ(fin, frame.stream_frame.fin);
+  }
+
+  // Returns the number of bytes consumed by the header of packet, including
+  // the version.
+  size_t GetPacketHeaderOverhead(QuicTransportVersion version) {
+    return GetPacketHeaderSize(
+        version, creator_.GetDestinationConnectionIdLength(),
+        creator_.GetSourceConnectionIdLength(),
+        QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+        !kIncludeDiversificationNonce,
+        QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+        QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
+        QuicPacketCreatorPeer::GetLengthLength(&creator_));
+  }
+
+  // Returns the number of bytes of overhead that will be added to a packet
+  // of maximum length.
+  size_t GetEncryptionOverhead() {
+    return creator_.max_packet_length() -
+           client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
+  }
+
+  // Returns the number of bytes consumed by the non-data fields of a stream
+  // frame, assuming it is the last frame in the packet
+  size_t GetStreamFrameOverhead(QuicTransportVersion version) {
+    return QuicFramer::GetMinStreamFrameSize(
+        version, GetNthClientInitiatedStreamId(1), kOffset, true,
+        /* data_length= */ 0);
+  }
+
+  bool IsDefaultTestConfiguration() {
+    TestParams p = GetParam();
+    return p.version == AllSupportedVersions()[0] && p.version_serialization;
+  }
+
+  QuicStreamId GetNthClientInitiatedStreamId(int n) const {
+    return QuicUtils::GetFirstBidirectionalStreamId(
+               creator_.transport_version(), Perspective::IS_CLIENT) +
+           n * 2;
+  }
+
+  void TestChaosProtection(bool enabled);
+
+  static constexpr QuicStreamOffset kOffset = 0u;
+
+  char buffer_[kMaxOutgoingPacketSize];
+  QuicConnectionId connection_id_;
+  QuicFrames frames_;
+  QuicFramer server_framer_;
+  QuicFramer client_framer_;
+  StrictMock<MockFramerVisitor> framer_visitor_;
+  StrictMock<MockPacketCreatorDelegate> delegate_;
+  std::string data_;
+  TestPacketCreator creator_;
+  std::unique_ptr<SerializedPacket> serialized_packet_;
+  SimpleDataProducer producer_;
+  quiche::SimpleBufferAllocator allocator_;
+};
+
+// Run all packet creator tests with all supported versions of QUIC, and with
+// and without version in the packet header, as well as doing a run for each
+// length of truncated connection id.
+INSTANTIATE_TEST_SUITE_P(QuicPacketCreatorTests,
+                         QuicPacketCreatorTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicPacketCreatorTest, SerializeFrames) {
+  for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    EncryptionLevel level = static_cast<EncryptionLevel>(i);
+    creator_.set_encryption_level(level);
+    if (level != ENCRYPTION_ZERO_RTT) {
+      frames_.push_back(QuicFrame(new QuicAckFrame(InitAckFrame(1))));
+    }
+    QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        client_framer_.transport_version(), Perspective::IS_CLIENT);
+    if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
+      frames_.push_back(QuicFrame(
+          QuicStreamFrame(stream_id, false, 0u, absl::string_view())));
+    }
+    SerializedPacket serialized = SerializeAllFrames(frames_);
+    EXPECT_EQ(level, serialized.encryption_level);
+    if (level != ENCRYPTION_ZERO_RTT) {
+      delete frames_[0].ack_frame;
+    }
+    frames_.clear();
+
+    {
+      InSequence s;
+      EXPECT_CALL(framer_visitor_, OnPacket());
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+      EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+      EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+      if (level != ENCRYPTION_ZERO_RTT) {
+        EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _))
+            .WillOnce(Return(true));
+        EXPECT_CALL(framer_visitor_,
+                    OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)))
+            .WillOnce(Return(true));
+        EXPECT_CALL(framer_visitor_, OnAckFrameEnd(QuicPacketNumber(1)))
+            .WillOnce(Return(true));
+      }
+      if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
+        EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+      }
+      if (client_framer_.version().HasHeaderProtection()) {
+        EXPECT_CALL(framer_visitor_, OnPaddingFrame(_))
+            .Times(testing::AnyNumber());
+      }
+      EXPECT_CALL(framer_visitor_, OnPacketComplete());
+    }
+    ProcessPacket(serialized);
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeConnectionClose) {
+  QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
+      creator_.transport_version(), QUIC_NO_ERROR, NO_IETF_QUIC_ERROR, "error",
+      /*transport_close_frame_type=*/0);
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame));
+  SerializedPacket serialized = SerializeAllFrames(frames);
+  EXPECT_EQ(ENCRYPTION_INITIAL, serialized.encryption_level);
+  ASSERT_EQ(QuicPacketNumber(1u), serialized.packet_number);
+  ASSERT_EQ(QuicPacketNumber(1u), creator_.packet_number());
+
+  InSequence s;
+  EXPECT_CALL(framer_visitor_, OnPacket());
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+  EXPECT_CALL(framer_visitor_, OnConnectionCloseFrame(_));
+  EXPECT_CALL(framer_visitor_, OnPacketComplete());
+
+  ProcessPacket(serialized);
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeCryptoDataToFillCurrentPacket) {
+  std::string data = "crypto data";
+  QuicFrame frame;
+  ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
+      ENCRYPTION_INITIAL, data.length(), 0,
+      /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+  EXPECT_EQ(frame.crypto_frame->data_length, data.length());
+  EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataToFillCurrentPacket) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  EXPECT_EQ(4u, consumed);
+  CheckStreamFrame(frame, stream_id, "test", 0u, false);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataFin) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, true, false, NOT_RETRANSMISSION, &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  EXPECT_EQ(4u, consumed);
+  CheckStreamFrame(frame, stream_id, "test", 0u, true);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataFinOnly) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, {}, 0u, true, false, NOT_RETRANSMISSION, &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  EXPECT_EQ(0u, consumed);
+  CheckStreamFrame(frame, stream_id, std::string(), 0u, true);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(absl::StartsWith(creator_.GetPendingFramesInfo(),
+                               "type { STREAM_FRAME }"));
+}
+
+TEST_P(QuicPacketCreatorTest, CreateAllFreeBytesForStreamFrames) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  const size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead();
+  for (size_t i = overhead + QuicPacketCreator::MinPlaintextPacketSize(
+                                 client_framer_.version());
+       i < overhead + 100; ++i) {
+    SCOPED_TRACE(i);
+    creator_.SetMaxPacketLength(i);
+    const bool should_have_room =
+        i >
+        overhead + GetStreamFrameOverhead(client_framer_.transport_version());
+    ASSERT_EQ(should_have_room,
+              creator_.HasRoomForStreamFrame(GetNthClientInitiatedStreamId(1),
+                                             kOffset, /* data_size=*/0xffff));
+    if (should_have_room) {
+      QuicFrame frame;
+      const std::string data("testdata");
+      EXPECT_CALL(delegate_, OnSerializedPacket(_))
+          .WillRepeatedly(Invoke(
+              this, &QuicPacketCreatorTest::ClearSerializedPacketForTests));
+      ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+          GetNthClientInitiatedStreamId(1), data, kOffset, false, false,
+          NOT_RETRANSMISSION, &frame));
+      size_t bytes_consumed = frame.stream_frame.data_length;
+      EXPECT_LT(0u, bytes_consumed);
+      creator_.FlushCurrentPacket();
+    }
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  // Compute the total overhead for a single frame in packet.
+  const size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead() +
+      GetStreamFrameOverhead(client_framer_.transport_version());
+  size_t capacity = kDefaultMaxPacketSize - overhead;
+  // Now, test various sizes around this size.
+  for (int delta = -5; delta <= 5; ++delta) {
+    std::string data(capacity + delta, 'A');
+    size_t bytes_free = delta > 0 ? 0 : 0 - delta;
+    QuicFrame frame;
+    ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+        GetNthClientInitiatedStreamId(1), data, kOffset, false, false,
+        NOT_RETRANSMISSION, &frame));
+
+    // BytesFree() returns bytes available for the next frame, which will
+    // be two bytes smaller since the stream frame would need to be grown.
+    EXPECT_EQ(2u, creator_.ExpansionOnNewFrame());
+    size_t expected_bytes_free = bytes_free < 3 ? 0 : bytes_free - 2;
+    EXPECT_EQ(expected_bytes_free, creator_.BytesFree()) << "delta: " << delta;
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+    creator_.FlushCurrentPacket();
+    ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+    DeleteSerializedPacket();
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) {
+  // This test serializes crypto payloads slightly larger than a packet, which
+  // Causes the multi-packet ClientHello check to fail.
+  SetQuicFlag(FLAGS_quic_enforce_single_packet_chlo, false);
+  // Compute the total overhead for a single frame in packet.
+  size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead();
+  if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    overhead +=
+        QuicFramer::GetMinCryptoFrameSize(kOffset, kMaxOutgoingPacketSize);
+  } else {
+    overhead += GetStreamFrameOverhead(client_framer_.transport_version());
+  }
+  ASSERT_GT(kMaxOutgoingPacketSize, overhead);
+  size_t capacity = kDefaultMaxPacketSize - overhead;
+  // Now, test various sizes around this size.
+  for (int delta = -5; delta <= 5; ++delta) {
+    SCOPED_TRACE(delta);
+    std::string data(capacity + delta, 'A');
+    size_t bytes_free = delta > 0 ? 0 : 0 - delta;
+
+    QuicFrame frame;
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillRepeatedly(
+            Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+    if (client_framer_.version().CanSendCoalescedPackets()) {
+      EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
+          .WillRepeatedly(Return(COALESCE));
+    }
+    if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+      ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+          QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
+          data, kOffset, false, true, NOT_RETRANSMISSION, &frame));
+      size_t bytes_consumed = frame.stream_frame.data_length;
+      EXPECT_LT(0u, bytes_consumed);
+    } else {
+      producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data);
+      ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
+          ENCRYPTION_INITIAL, data.length(), kOffset,
+          /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+      size_t bytes_consumed = frame.crypto_frame->data_length;
+      EXPECT_LT(0u, bytes_consumed);
+    }
+    creator_.FlushCurrentPacket();
+    ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+    // If there is not enough space in the packet to fit a padding frame
+    // (1 byte) and to expand the stream frame (another 2 bytes) the packet
+    // will not be padded.
+    // Padding is skipped when we try to send coalesced packets.
+    if ((bytes_free < 3 &&
+         !QuicVersionUsesCryptoFrames(client_framer_.transport_version())) ||
+        client_framer_.version().CanSendCoalescedPackets()) {
+      EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
+                serialized_packet_->encrypted_length);
+    } else {
+      EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_->encrypted_length);
+    }
+    DeleteSerializedPacket();
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  // Compute the total overhead for a single frame in packet.
+  const size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead() +
+      GetStreamFrameOverhead(client_framer_.transport_version());
+  ASSERT_GT(kDefaultMaxPacketSize, overhead);
+  size_t capacity = kDefaultMaxPacketSize - overhead;
+  // Now, test various sizes around this size.
+  for (int delta = -5; delta <= 5; ++delta) {
+    std::string data(capacity + delta, 'A');
+    size_t bytes_free = delta > 0 ? 0 : 0 - delta;
+
+    QuicFrame frame;
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+    ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+        GetNthClientInitiatedStreamId(1), data, kOffset, false, false,
+        NOT_RETRANSMISSION, &frame));
+    size_t bytes_consumed = frame.stream_frame.data_length;
+    EXPECT_LT(0u, bytes_consumed);
+    creator_.FlushCurrentPacket();
+    ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+    if (bytes_free > 0) {
+      EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
+                serialized_packet_->encrypted_length);
+    } else {
+      EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_->encrypted_length);
+    }
+    DeleteSerializedPacket();
+  }
+}
+
+// Test that the path challenge connectivity probing packet is serialized
+// correctly as a padded PATH CHALLENGE packet.
+TEST_P(QuicPacketCreatorTest, BuildPathChallengePacket) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  MockRandom randomizer;
+  QuicPathFrameBuffer payload;
+  randomizer.RandBytes(payload.data(), payload.size());
+
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // Path Challenge Frame type (IETF_PATH_CHALLENGE)
+    0x1a,
+    // 8 "random" bytes, MockRandom makes lots of r's
+    'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r',
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+
+  size_t length = creator_.BuildPaddedPathChallengePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payload,
+      ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+
+  // Payload has the random bytes that were generated. Copy them into packet,
+  // above, before checking that the generated packet is correct.
+  EXPECT_EQ(kQuicPathFrameBufferSize, payload.size());
+
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, BuildConnectivityProbingPacket) {
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ping frame)
+    0x07,
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type
+    0x07,
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet99[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PING frame)
+    0x01,
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t packet_size = ABSL_ARRAYSIZE(packet);
+  if (creator_.version().HasIetfQuicFrames()) {
+    p = packet99;
+    packet_size = ABSL_ARRAYSIZE(packet99);
+  } else if (creator_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    packet_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+
+  size_t length = creator_.BuildConnectivityProbingPacket(
+      header, buffer.get(), packet_size, ENCRYPTION_INITIAL);
+
+  EXPECT_NE(0u, length);
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(p), packet_size);
+}
+
+// Several tests that the path response connectivity probing packet is
+// serialized correctly as either a padded and unpadded PATH RESPONSE
+// packet. Also generates packets with 1 and 3 PATH_RESPONSES in them to
+// exercised the single- and multiple- payload cases.
+TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponseUnpadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicPathFrameBuffer payload0 = {
+      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+
+  // Build 1 PATH RESPONSE, not padded
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // Path Response Frame type (IETF_PATH_RESPONSE)
+    0x1b,
+    // 8 "random" bytes
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+  };
+  // clang-format on
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  size_t length = creator_.BuildPathResponsePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
+      /*is_padded=*/false, ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponsePadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicPathFrameBuffer payload0 = {
+      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+
+  // Build 1 PATH RESPONSE, padded
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // Path Response Frame type (IETF_PATH_RESPONSE)
+    0x1b,
+    // 8 "random" bytes
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    // Padding type and pad
+    0x00, 0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  size_t length = creator_.BuildPathResponsePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
+      /*is_padded=*/true, ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesUnpadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicPathFrameBuffer payload0 = {
+      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+  QuicPathFrameBuffer payload1 = {
+      {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}};
+  QuicPathFrameBuffer payload2 = {
+      {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28}};
+
+  // Build one packet with 3 PATH RESPONSES, no padding
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // 3 path response frames (IETF_PATH_RESPONSE type byte and payload)
+    0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    0x1b, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+    0x1b, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+  };
+  // clang-format on
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+  payloads.push_back(payload2);
+  size_t length = creator_.BuildPathResponsePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
+      /*is_padded=*/false, ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicPathFrameBuffer payload0 = {
+      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+  QuicPathFrameBuffer payload1 = {
+      {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}};
+  QuicPathFrameBuffer payload2 = {
+      {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28}};
+
+  // Build one packet with 3 PATH RESPONSES, with padding
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // 3 path response frames (IETF_PATH_RESPONSE byte and payload)
+    0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    0x1b, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+    0x1b, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+    // Padding
+    0x00, 0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+  payloads.push_back(payload2);
+  size_t length = creator_.BuildPathResponsePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
+      /*is_padded=*/true, ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeConnectivityProbingPacket) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  std::unique_ptr<SerializedPacket> encrypted;
+  if (VersionHasIetfQuicFrames(creator_.transport_version())) {
+    QuicPathFrameBuffer payload = {
+        {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
+    encrypted =
+        creator_.SerializePathChallengeConnectivityProbingPacket(payload);
+  } else {
+    encrypted = creator_.SerializeConnectivityProbingPacket();
+  }
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    if (VersionHasIetfQuicFrames(creator_.transport_version())) {
+      EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    } else {
+      EXPECT_CALL(framer_visitor_, OnPingFrame(_));
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializePathChallengeProbePacket) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathChallengeConnectivityProbingPacket(payload));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket1PayloadPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest,
+       SerializePathResponseProbePacket1PayloadUnPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket2PayloadsPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+  QuicPathFrameBuffer payload1 = {
+      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest,
+       SerializePathResponseProbePacket2PayloadsUnPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+  QuicPathFrameBuffer payload1 = {
+      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket3PayloadsPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+  QuicPathFrameBuffer payload1 = {
+      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
+  QuicPathFrameBuffer payload2 = {
+      {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+  payloads.push_back(payload2);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest,
+       SerializePathResponseProbePacket3PayloadsUnpadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+  QuicPathFrameBuffer payload1 = {
+      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
+  QuicPathFrameBuffer payload2 = {
+      {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+  payloads.push_back(payload2);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
+  InSequence s;
+  EXPECT_CALL(framer_visitor_, OnPacket());
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+  EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
+  EXPECT_CALL(framer_visitor_, OnPacketComplete());
+
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthLeastAwaiting) {
+  if (creator_.version().HasIetfInvariantHeader() &&
+      !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
+    EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  } else {
+    EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+  }
+
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256 * 256);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_,
+                                         UINT64_C(64) * 256 * 256 * 256 * 256);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+}
+
+TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthCwnd) {
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
+  if (creator_.version().HasIetfInvariantHeader() &&
+      !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
+    EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  } else {
+    EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+  }
+
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
+                                    10000 * 256 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
+                                    10000 * 256 * 256 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.UpdatePacketNumberLength(
+      QuicPacketNumber(1),
+      UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+}
+
+TEST_P(QuicPacketCreatorTest, SkipNPacketNumbers) {
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
+  if (creator_.version().HasIetfInvariantHeader() &&
+      !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
+    EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  } else {
+    EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+  }
+  creator_.SkipNPacketNumbers(63, QuicPacketNumber(2),
+                              10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(QuicPacketNumber(64), creator_.packet_number());
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.SkipNPacketNumbers(64 * 255, QuicPacketNumber(2),
+                              10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(QuicPacketNumber(64 * 256), creator_.packet_number());
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.SkipNPacketNumbers(64 * 256 * 255, QuicPacketNumber(2),
+                              10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(QuicPacketNumber(64 * 256 * 256), creator_.packet_number());
+  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeFrame) {
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  std::string data("test data");
+  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    QuicStreamFrame stream_frame(
+        QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
+        /*fin=*/false, 0u, absl::string_view());
+    frames_.push_back(QuicFrame(stream_frame));
+  } else {
+    producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
+    frames_.push_back(
+        QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
+  }
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+
+  QuicPacketHeader header;
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
+        .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
+    if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+      EXPECT_CALL(framer_visitor_, OnCryptoFrame(_));
+    } else {
+      EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  ProcessPacket(serialized);
+  EXPECT_EQ(GetParam().version_serialization, header.version_flag);
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeFrameShortData) {
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  std::string data("Hello World!");
+  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    QuicStreamFrame stream_frame(
+        QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
+        /*fin=*/false, 0u, absl::string_view());
+    frames_.push_back(QuicFrame(stream_frame));
+  } else {
+    producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
+    frames_.push_back(
+        QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
+  }
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+
+  QuicPacketHeader header;
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
+        .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
+    if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+      EXPECT_CALL(framer_visitor_, OnCryptoFrame(_));
+    } else {
+      EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  ProcessPacket(serialized);
+  EXPECT_EQ(GetParam().version_serialization, header.version_flag);
+}
+
+void QuicPacketCreatorTest::TestChaosProtection(bool enabled) {
+  if (!GetParam().version.UsesCryptoFrames()) {
+    return;
+  }
+  MockRandom mock_random(2);
+  QuicPacketCreatorPeer::SetRandom(&creator_, &mock_random);
+  creator_.set_chaos_protection_enabled(enabled);
+  std::string data("ChAoS_ThEoRy!");
+  producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
+  frames_.push_back(
+      QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
+  frames_.push_back(QuicFrame(QuicPaddingFrame(33)));
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+  EXPECT_CALL(framer_visitor_, OnPacket());
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+  if (enabled) {
+    EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)).Times(AtLeast(2));
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(AtLeast(2));
+    EXPECT_CALL(framer_visitor_, OnPingFrame(_)).Times(AtLeast(1));
+  } else {
+    EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)).Times(1);
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(1);
+    EXPECT_CALL(framer_visitor_, OnPingFrame(_)).Times(0);
+  }
+  EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  ProcessPacket(serialized);
+}
+
+TEST_P(QuicPacketCreatorTest, ChaosProtectionEnabled) {
+  TestChaosProtection(/*enabled=*/true);
+}
+
+TEST_P(QuicPacketCreatorTest, ChaosProtectionDisabled) {
+  TestChaosProtection(/*enabled=*/false);
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataLargerThanOneStreamFrame) {
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  // A string larger than fits into a frame.
+  QuicFrame frame;
+  size_t payload_length = creator_.max_packet_length();
+  const std::string too_long_payload(payload_length, 'a');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, too_long_payload, 0u, true, false, NOT_RETRANSMISSION,
+      &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  // The entire payload could not be consumed.
+  EXPECT_GT(payload_length, consumed);
+  creator_.FlushCurrentPacket();
+  DeleteSerializedPacket();
+}
+
+TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  const size_t max_plaintext_size =
+      client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    stream_id =
+        QuicUtils::GetCryptoStreamId(client_framer_.transport_version());
+  }
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
+  EXPECT_EQ(max_plaintext_size -
+                GetPacketHeaderSize(
+                    client_framer_.transport_version(),
+                    creator_.GetDestinationConnectionIdLength(),
+                    creator_.GetSourceConnectionIdLength(),
+                    QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+                    !kIncludeDiversificationNonce,
+                    QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+                    QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
+                    0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
+            creator_.BytesFree());
+  StrictMock<MockDebugDelegate> debug;
+  creator_.set_debug_delegate(&debug);
+
+  // Add a variety of frame types and then a padding frame.
+  QuicAckFrame ack_frame(InitAckFrame(10u));
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
+
+  QuicFrame frame;
+  const std::string data("test");
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  EXPECT_EQ(4u, consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id));
+
+  QuicPaddingFrame padding_frame;
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(padding_frame), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_EQ(0u, creator_.BytesFree());
+
+  // Packet is full. Creator will flush.
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  EXPECT_FALSE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
+
+  // Ensure the packet is successfully created.
+  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+  ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
+  const QuicFrames& retransmittable =
+      serialized_packet_->retransmittable_frames;
+  ASSERT_EQ(1u, retransmittable.size());
+  EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
+  EXPECT_TRUE(serialized_packet_->has_ack);
+  EXPECT_EQ(QuicPacketNumber(10u), serialized_packet_->largest_acked);
+  DeleteSerializedPacket();
+
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
+  EXPECT_EQ(max_plaintext_size -
+                GetPacketHeaderSize(
+                    client_framer_.transport_version(),
+                    creator_.GetDestinationConnectionIdLength(),
+                    creator_.GetSourceConnectionIdLength(),
+                    QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+                    !kIncludeDiversificationNonce,
+                    QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+                    QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
+                    0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
+            creator_.BytesFree());
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeAndSendStreamFrame) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  EXPECT_FALSE(creator_.HasPendingFrames());
+
+  const std::string data("test");
+  producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), data);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  size_t num_bytes_consumed;
+  StrictMock<MockDebugDelegate> debug;
+  creator_.set_debug_delegate(&debug);
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  creator_.CreateAndSerializeStreamFrame(
+      GetNthClientInitiatedStreamId(0), data.length(), 0, 0, true,
+      NOT_RETRANSMISSION, &num_bytes_consumed);
+  EXPECT_EQ(4u, num_bytes_consumed);
+
+  // Ensure the packet is successfully created.
+  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+  ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
+  const QuicFrames& retransmittable =
+      serialized_packet_->retransmittable_frames;
+  ASSERT_EQ(1u, retransmittable.size());
+  EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
+  DeleteSerializedPacket();
+
+  EXPECT_FALSE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeStreamFrameWithPadding) {
+  // Regression test to check that CreateAndSerializeStreamFrame uses a
+  // correctly formatted stream frame header when appending padding.
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  EXPECT_FALSE(creator_.HasPendingFrames());
+
+  // Send one byte of stream data.
+  const std::string data("a");
+  producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), data);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  size_t num_bytes_consumed;
+  creator_.CreateAndSerializeStreamFrame(
+      GetNthClientInitiatedStreamId(0), data.length(), 0, 0, true,
+      NOT_RETRANSMISSION, &num_bytes_consumed);
+  EXPECT_EQ(1u, num_bytes_consumed);
+
+  // Check that a packet is created.
+  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+  ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+    if (client_framer_.version().HasHeaderProtection()) {
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  ProcessPacket(*serialized_packet_);
+}
+
+TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  creator_.set_encryption_level(ENCRYPTION_INITIAL);
+  EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
+  QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0),
+                               /*fin=*/false, 0u, absl::string_view());
+  EXPECT_QUIC_BUG(
+      creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION),
+      "Cannot send stream data with level: ENCRYPTION_INITIAL");
+}
+
+TEST_P(QuicPacketCreatorTest, SendStreamDataWithEncryptionHandshake) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
+  QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0),
+                               /*fin=*/false, 0u, absl::string_view());
+  EXPECT_QUIC_BUG(
+      creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION),
+      "Cannot send stream data with level: ENCRYPTION_HANDSHAKE");
+}
+
+TEST_P(QuicPacketCreatorTest, ChloTooLarge) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  // This test only matters when the crypto handshake is sent in stream frames.
+  // TODO(b/128596274): Re-enable when this check is supported for CRYPTO
+  // frames.
+  if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    return;
+  }
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kCHLO);
+  message.set_minimum_size(kMaxOutgoingPacketSize);
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> message_data;
+  message_data = framer.ConstructHandshakeMessage(message);
+
+  QuicFrame frame;
+  EXPECT_CALL(delegate_, OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, _));
+  EXPECT_QUIC_BUG(
+      creator_.ConsumeDataToFillCurrentPacket(
+          QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
+          absl::string_view(message_data->data(), message_data->length()), 0u,
+          false, false, NOT_RETRANSMISSION, &frame),
+      "Client hello won't fit in a single packet.");
+}
+
+TEST_P(QuicPacketCreatorTest, PendingPadding) {
+  EXPECT_EQ(0u, creator_.pending_padding_bytes());
+  creator_.AddPendingPadding(kMaxNumRandomPaddingBytes * 10);
+  EXPECT_EQ(kMaxNumRandomPaddingBytes * 10, creator_.pending_padding_bytes());
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  // Flush all paddings.
+  while (creator_.pending_padding_bytes() > 0) {
+    creator_.FlushCurrentPacket();
+    {
+      InSequence s;
+      EXPECT_CALL(framer_visitor_, OnPacket());
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+      EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+      EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+      EXPECT_CALL(framer_visitor_, OnPacketComplete());
+    }
+    // Packet only contains padding.
+    ProcessPacket(*serialized_packet_);
+  }
+  EXPECT_EQ(0u, creator_.pending_padding_bytes());
+}
+
+TEST_P(QuicPacketCreatorTest, FullPaddingDoesNotConsumePendingPadding) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  creator_.AddPendingPadding(kMaxNumRandomPaddingBytes);
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false,
+      /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  creator_.FlushCurrentPacket();
+  EXPECT_EQ(kMaxNumRandomPaddingBytes, creator_.pending_padding_bytes());
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataAndRandomPadding) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  const QuicByteCount kStreamFramePayloadSize = 100u;
+  // Set the packet size be enough for one stream frame with 0 stream offset +
+  // 1.
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  size_t length =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead() +
+      QuicFramer::GetMinStreamFrameSize(
+          client_framer_.transport_version(), stream_id, 0,
+          /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) +
+      kStreamFramePayloadSize + 1;
+  creator_.SetMaxPacketLength(length);
+  creator_.AddPendingPadding(kMaxNumRandomPaddingBytes);
+  QuicByteCount pending_padding_bytes = creator_.pending_padding_bytes();
+  QuicFrame frame;
+  char buf[kStreamFramePayloadSize + 1] = {};
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  // Send stream frame of size kStreamFramePayloadSize.
+  creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, absl::string_view(buf, kStreamFramePayloadSize), 0u, false,
+      false, NOT_RETRANSMISSION, &frame);
+  creator_.FlushCurrentPacket();
+  // 1 byte padding is sent.
+  EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes());
+  // Send stream frame of size kStreamFramePayloadSize + 1.
+  creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, absl::string_view(buf, kStreamFramePayloadSize + 1),
+      kStreamFramePayloadSize, false, false, NOT_RETRANSMISSION, &frame);
+  // No padding is sent.
+  creator_.FlushCurrentPacket();
+  EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes());
+  // Flush all paddings.
+  while (creator_.pending_padding_bytes() > 0) {
+    creator_.FlushCurrentPacket();
+  }
+  EXPECT_EQ(0u, creator_.pending_padding_bytes());
+}
+
+TEST_P(QuicPacketCreatorTest, FlushWithExternalBuffer) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  char* buffer = new char[kMaxOutgoingPacketSize];
+  QuicPacketBuffer external_buffer = {buffer,
+                                      [](const char* p) { delete[] p; }};
+  EXPECT_CALL(delegate_, GetPacketBuffer()).WillOnce(Return(external_buffer));
+
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false,
+      /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke([&external_buffer](SerializedPacket serialized_packet) {
+        EXPECT_EQ(external_buffer.buffer, serialized_packet.encrypted_buffer);
+      }));
+  creator_.FlushCurrentPacket();
+}
+
+// Test for error found in
+// https://bugs.chromium.org/p/chromium/issues/detail?id=859949 where a gap
+// length that crosses an IETF VarInt length boundary would cause a
+// failure. While this test is not applicable to versions other than version 99,
+// it should still work. Hence, it is not made version-specific.
+TEST_P(QuicPacketCreatorTest, IetfAckGapErrorRegression) {
+  QuicAckFrame ack_frame =
+      InitAckFrame({{QuicPacketNumber(60), QuicPacketNumber(61)},
+                    {QuicPacketNumber(125), QuicPacketNumber(126)}});
+  frames_.push_back(QuicFrame(&ack_frame));
+  SerializeAllFrames(frames_);
+}
+
+TEST_P(QuicPacketCreatorTest, AddMessageFrame) {
+  if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
+    return;
+  }
+  if (client_framer_.version().UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .Times(3)
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacketForTests));
+  // Verify that there is enough room for the largest message payload.
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetCurrentLargestMessagePayload()));
+  std::string large_message(creator_.GetCurrentLargestMessagePayload(), 'a');
+  QuicMessageFrame* message_frame =
+      new QuicMessageFrame(1, MemSliceFromString(large_message));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(message_frame), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  creator_.FlushCurrentPacket();
+
+  QuicMessageFrame* frame2 =
+      new QuicMessageFrame(2, MemSliceFromString("message"));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame2), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  // Verify if a new frame is added, 1 byte message length will be added.
+  EXPECT_EQ(1u, creator_.ExpansionOnNewFrame());
+  QuicMessageFrame* frame3 =
+      new QuicMessageFrame(3, MemSliceFromString("message2"));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame3), NOT_RETRANSMISSION));
+  EXPECT_EQ(1u, creator_.ExpansionOnNewFrame());
+  creator_.FlushCurrentPacket();
+
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  EXPECT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  QuicMessageFrame* frame4 =
+      new QuicMessageFrame(4, MemSliceFromString("message"));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame4), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  // Verify there is not enough room for largest payload.
+  EXPECT_FALSE(creator_.HasRoomForMessageFrame(
+      creator_.GetCurrentLargestMessagePayload()));
+  // Add largest message will causes the flush of the stream frame.
+  QuicMessageFrame frame5(5, MemSliceFromString(large_message));
+  EXPECT_FALSE(creator_.AddFrame(QuicFrame(&frame5), NOT_RETRANSMISSION));
+  EXPECT_FALSE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, MessageFrameConsumption) {
+  if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
+    return;
+  }
+  if (client_framer_.version().UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  std::string message_data(kDefaultMaxPacketSize, 'a');
+  // Test all possible encryption levels of message frames.
+  for (EncryptionLevel level :
+       {ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
+    creator_.set_encryption_level(level);
+    // Test all possible sizes of message frames.
+    for (size_t message_size = 0;
+         message_size <= creator_.GetCurrentLargestMessagePayload();
+         ++message_size) {
+      QuicMessageFrame* frame =
+          new QuicMessageFrame(0, MemSliceFromString(absl::string_view(
+                                      message_data.data(), message_size)));
+      EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame), NOT_RETRANSMISSION));
+      EXPECT_TRUE(creator_.HasPendingFrames());
+
+      size_t expansion_bytes = message_size >= 64 ? 2 : 1;
+      EXPECT_EQ(expansion_bytes, creator_.ExpansionOnNewFrame());
+      // Verify BytesFree returns bytes available for the next frame, which
+      // should subtract the message length.
+      size_t expected_bytes_free =
+          creator_.GetCurrentLargestMessagePayload() - message_size <
+                  expansion_bytes
+              ? 0
+              : creator_.GetCurrentLargestMessagePayload() - expansion_bytes -
+                    message_size;
+      EXPECT_EQ(expected_bytes_free, creator_.BytesFree());
+      EXPECT_LE(creator_.GetGuaranteedLargestMessagePayload(),
+                creator_.GetCurrentLargestMessagePayload());
+      EXPECT_CALL(delegate_, OnSerializedPacket(_))
+          .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+      creator_.FlushCurrentPacket();
+      ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+      DeleteSerializedPacket();
+    }
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, GetGuaranteedLargestMessagePayload) {
+  ParsedQuicVersion version = GetParam().version;
+  if (!version.SupportsMessageFrames()) {
+    return;
+  }
+  if (version.UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  QuicPacketLength expected_largest_payload = 1219;
+  if (version.HasLongHeaderLengths()) {
+    expected_largest_payload -= 2;
+  }
+  if (version.HasLengthPrefixedConnectionIds()) {
+    expected_largest_payload -= 1;
+  }
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetGuaranteedLargestMessagePayload());
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetGuaranteedLargestMessagePayload()));
+
+  // Now test whether SetMaxDatagramFrameSize works.
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload + 1 +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetGuaranteedLargestMessagePayload());
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetGuaranteedLargestMessagePayload()));
+
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetGuaranteedLargestMessagePayload());
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetGuaranteedLargestMessagePayload()));
+
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload - 1 +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload - 1,
+            creator_.GetGuaranteedLargestMessagePayload());
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetGuaranteedLargestMessagePayload()));
+
+  constexpr QuicPacketLength kFrameSizeLimit = 1000;
+  constexpr QuicPacketLength kPayloadSizeLimit =
+      kFrameSizeLimit - kQuicFrameTypeSize;
+  creator_.SetMaxDatagramFrameSize(kFrameSizeLimit);
+  EXPECT_EQ(creator_.GetGuaranteedLargestMessagePayload(), kPayloadSizeLimit);
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(kPayloadSizeLimit));
+  EXPECT_FALSE(creator_.HasRoomForMessageFrame(kPayloadSizeLimit + 1));
+}
+
+TEST_P(QuicPacketCreatorTest, GetCurrentLargestMessagePayload) {
+  ParsedQuicVersion version = GetParam().version;
+  if (!version.SupportsMessageFrames()) {
+    return;
+  }
+  if (version.UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  QuicPacketLength expected_largest_payload = 1219;
+  if (version.SendsVariableLengthPacketNumberInLongHeader()) {
+    expected_largest_payload += 3;
+  }
+  if (version.HasLongHeaderLengths()) {
+    expected_largest_payload -= 2;
+  }
+  if (version.HasLengthPrefixedConnectionIds()) {
+    expected_largest_payload -= 1;
+  }
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetCurrentLargestMessagePayload());
+
+  // Now test whether SetMaxDatagramFrameSize works.
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload + 1 +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetCurrentLargestMessagePayload());
+
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetCurrentLargestMessagePayload());
+
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload - 1 +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload - 1,
+            creator_.GetCurrentLargestMessagePayload());
+}
+
+TEST_P(QuicPacketCreatorTest, PacketTransmissionType) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  QuicAckFrame temp_ack_frame = InitAckFrame(1);
+  QuicFrame ack_frame(&temp_ack_frame);
+  ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(ack_frame.type));
+
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  QuicFrame stream_frame(QuicStreamFrame(stream_id,
+                                         /*fin=*/false, 0u,
+                                         absl::string_view()));
+  ASSERT_TRUE(QuicUtils::IsRetransmittableFrame(stream_frame.type));
+
+  QuicFrame padding_frame{QuicPaddingFrame()};
+  ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(padding_frame.type));
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+
+  EXPECT_TRUE(creator_.AddFrame(ack_frame, LOSS_RETRANSMISSION));
+  ASSERT_EQ(serialized_packet_, nullptr);
+
+  EXPECT_TRUE(creator_.AddFrame(stream_frame, RTO_RETRANSMISSION));
+  ASSERT_EQ(serialized_packet_, nullptr);
+
+  EXPECT_TRUE(creator_.AddFrame(padding_frame, TLP_RETRANSMISSION));
+  creator_.FlushCurrentPacket();
+  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+
+  // The last retransmittable frame on packet is a stream frame, the packet's
+  // transmission type should be the same as the stream frame's.
+  EXPECT_EQ(serialized_packet_->transmission_type, RTO_RETRANSMISSION);
+  DeleteSerializedPacket();
+}
+
+TEST_P(QuicPacketCreatorTest, RetryToken) {
+  if (!GetParam().version_serialization ||
+      !QuicVersionHasLongHeaderLengths(client_framer_.transport_version())) {
+    return;
+  }
+
+  char retry_token_bytes[] = {1, 2,  3,  4,  5,  6,  7,  8,
+                              9, 10, 11, 12, 13, 14, 15, 16};
+
+  creator_.SetRetryToken(
+      std::string(retry_token_bytes, sizeof(retry_token_bytes)));
+
+  frames_.push_back(QuicFrame(QuicPingFrame()));
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+
+  QuicPacketHeader header;
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
+        .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
+    EXPECT_CALL(framer_visitor_, OnPingFrame(_));
+    if (client_framer_.version().HasHeaderProtection()) {
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  ProcessPacket(serialized);
+  ASSERT_TRUE(header.version_flag);
+  ASSERT_EQ(header.long_packet_type, INITIAL);
+  ASSERT_EQ(header.retry_token.length(), sizeof(retry_token_bytes));
+  quiche::test::CompareCharArraysWithHexError(
+      "retry token", header.retry_token.data(), header.retry_token.length(),
+      retry_token_bytes, sizeof(retry_token_bytes));
+}
+
+TEST_P(QuicPacketCreatorTest, GetConnectionId) {
+  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
+  EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
+}
+
+TEST_P(QuicPacketCreatorTest, ClientConnectionId) {
+  if (!client_framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
+  EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
+  creator_.SetClientConnectionId(TestConnectionId(0x33));
+  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
+  EXPECT_EQ(TestConnectionId(0x33), creator_.GetSourceConnectionId());
+}
+
+TEST_P(QuicPacketCreatorTest, CoalesceStreamFrames) {
+  InSequence s;
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  const size_t max_plaintext_size =
+      client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicStreamId stream_id1 = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  QuicStreamId stream_id2 = GetNthClientInitiatedStreamId(1);
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id1));
+  EXPECT_EQ(max_plaintext_size -
+                GetPacketHeaderSize(
+                    client_framer_.transport_version(),
+                    creator_.GetDestinationConnectionIdLength(),
+                    creator_.GetSourceConnectionIdLength(),
+                    QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+                    !kIncludeDiversificationNonce,
+                    QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+                    QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
+                    0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
+            creator_.BytesFree());
+  StrictMock<MockDebugDelegate> debug;
+  creator_.set_debug_delegate(&debug);
+
+  QuicFrame frame;
+  const std::string data1("test");
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id1, data1, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id1));
+
+  const std::string data2("coalesce");
+  // frame will be coalesced with the first frame.
+  const auto previous_size = creator_.PacketSize();
+  QuicStreamFrame target(stream_id1, true, 0, data1.length() + data2.length());
+  EXPECT_CALL(debug, OnStreamFrameCoalesced(target));
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id1, data2, 4u, true, false, NOT_RETRANSMISSION, &frame));
+  EXPECT_EQ(frame.stream_frame.data_length,
+            creator_.PacketSize() - previous_size);
+
+  // frame is for another stream, so it won't be coalesced.
+  const auto length = creator_.BytesFree() - 10u;
+  const std::string data3(length, 'x');
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id2, data3, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id2));
+
+  // The packet doesn't have enough free bytes for all data, but will still be
+  // able to consume and coalesce part of them.
+  EXPECT_CALL(debug, OnStreamFrameCoalesced(_));
+  const std::string data4("somerandomdata");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id2, data4, length, false, false, NOT_RETRANSMISSION, &frame));
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  creator_.FlushCurrentPacket();
+  EXPECT_CALL(framer_visitor_, OnPacket());
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+  // The packet should only have 2 stream frames.
+  EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+  EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+  EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  ProcessPacket(*serialized_packet_);
+}
+
+TEST_P(QuicPacketCreatorTest, SaveNonRetransmittableFrames) {
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  frames_.push_back(QuicFrame(&ack_frame));
+  frames_.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+  ASSERT_EQ(2u, serialized.nonretransmittable_frames.size());
+  EXPECT_EQ(ACK_FRAME, serialized.nonretransmittable_frames[0].type);
+  EXPECT_EQ(PADDING_FRAME, serialized.nonretransmittable_frames[1].type);
+  // Verify full padding frame is translated to a padding frame with actual
+  // bytes of padding.
+  EXPECT_LT(
+      0,
+      serialized.nonretransmittable_frames[1].padding_frame.num_padding_bytes);
+  frames_.clear();
+
+  // Serialize another packet with the same frames.
+  SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames(
+      &creator_, serialized.nonretransmittable_frames, buffer_,
+      kMaxOutgoingPacketSize);
+  // Verify the packet length of both packets are equal.
+  EXPECT_EQ(serialized.encrypted_length, packet.encrypted_length);
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeCoalescedPacket) {
+  QuicCoalescedPacket coalesced;
+  quiche::SimpleBufferAllocator allocator;
+  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
+  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    EncryptionLevel level = static_cast<EncryptionLevel>(i);
+    creator_.set_encryption_level(level);
+    QuicAckFrame ack_frame(InitAckFrame(1));
+    if (level != ENCRYPTION_ZERO_RTT) {
+      frames_.push_back(QuicFrame(&ack_frame));
+    }
+    if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
+      frames_.push_back(
+          QuicFrame(QuicStreamFrame(1, false, 0u, absl::string_view())));
+    }
+    SerializedPacket serialized = SerializeAllFrames(frames_);
+    EXPECT_EQ(level, serialized.encryption_level);
+    frames_.clear();
+    ASSERT_TRUE(coalesced.MaybeCoalescePacket(serialized, self_address,
+                                              peer_address, &allocator,
+                                              creator_.max_packet_length()));
+  }
+  char buffer[kMaxOutgoingPacketSize];
+  size_t coalesced_length = creator_.SerializeCoalescedPacket(
+      coalesced, buffer, kMaxOutgoingPacketSize);
+  // Verify packet is padded to full.
+  ASSERT_EQ(coalesced.max_packet_length(), coalesced_length);
+  if (!QuicVersionHasLongHeaderLengths(server_framer_.transport_version())) {
+    return;
+  }
+  // Verify packet process.
+  std::unique_ptr<QuicEncryptedPacket> packets[NUM_ENCRYPTION_LEVELS];
+  packets[ENCRYPTION_INITIAL] =
+      std::make_unique<QuicEncryptedPacket>(buffer, coalesced_length);
+  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    if (i < ENCRYPTION_FORWARD_SECURE) {
+      // Save coalesced packet.
+      EXPECT_CALL(framer_visitor_, OnCoalescedPacket(_))
+          .WillOnce(Invoke([i, &packets](const QuicEncryptedPacket& packet) {
+            packets[i + 1] = packet.Clone();
+          }));
+    }
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    if (i != ENCRYPTION_ZERO_RTT) {
+      EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _))
+          .WillOnce(Return(true));
+      EXPECT_CALL(framer_visitor_,
+                  OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)))
+          .WillOnce(Return(true));
+      EXPECT_CALL(framer_visitor_, OnAckFrameEnd(_)).WillOnce(Return(true));
+    }
+    if (i == ENCRYPTION_INITIAL) {
+      // Verify padding is added.
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    } else if (i != ENCRYPTION_ZERO_RTT) {
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(testing::AtMost(1));
+    }
+    if (i != ENCRYPTION_INITIAL && i != ENCRYPTION_HANDSHAKE) {
+      EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+    }
+    if (i == ENCRYPTION_ZERO_RTT) {
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+
+    server_framer_.ProcessPacket(*packets[i]);
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, SoftMaxPacketLength) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicByteCount previous_max_packet_length = creator_.max_packet_length();
+  const size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      QuicPacketCreator::MinPlaintextPacketSize(client_framer_.version()) +
+      GetEncryptionOverhead();
+  // Make sure a length which cannot accommodate header (includes header
+  // protection minimal length) gets rejected.
+  creator_.SetSoftMaxPacketLength(overhead - 1);
+  EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
+
+  creator_.SetSoftMaxPacketLength(overhead);
+  EXPECT_EQ(overhead, creator_.max_packet_length());
+
+  // Verify creator has room for stream frame because max_packet_length_ gets
+  // restored.
+  ASSERT_TRUE(creator_.HasRoomForStreamFrame(
+      GetNthClientInitiatedStreamId(1), kMaxIetfVarInt,
+      std::numeric_limits<uint32_t>::max()));
+  EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
+
+  // Same for message frame.
+  if (VersionSupportsMessageFrames(client_framer_.transport_version())) {
+    creator_.SetSoftMaxPacketLength(overhead);
+    if (client_framer_.version().UsesTls()) {
+      creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+    }
+    // Verify GetCurrentLargestMessagePayload is based on the actual
+    // max_packet_length.
+    EXPECT_LT(1u, creator_.GetCurrentLargestMessagePayload());
+    EXPECT_EQ(overhead, creator_.max_packet_length());
+    ASSERT_TRUE(creator_.HasRoomForMessageFrame(
+        creator_.GetCurrentLargestMessagePayload()));
+    EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
+  }
+
+  // Verify creator can consume crypto data because max_packet_length_ gets
+  // restored.
+  creator_.SetSoftMaxPacketLength(overhead);
+  EXPECT_EQ(overhead, creator_.max_packet_length());
+  const std::string data = "crypto data";
+  QuicFrame frame;
+  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+        QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), data,
+        kOffset, false, true, NOT_RETRANSMISSION, &frame));
+    size_t bytes_consumed = frame.stream_frame.data_length;
+    EXPECT_LT(0u, bytes_consumed);
+  } else {
+    producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data);
+    ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
+        ENCRYPTION_INITIAL, data.length(), kOffset,
+        /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+    size_t bytes_consumed = frame.crypto_frame->data_length;
+    EXPECT_LT(0u, bytes_consumed);
+  }
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  creator_.FlushCurrentPacket();
+
+  // Verify ACK frame can be consumed.
+  creator_.SetSoftMaxPacketLength(overhead);
+  EXPECT_EQ(overhead, creator_.max_packet_length());
+  QuicAckFrame ack_frame(InitAckFrame(10u));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest,
+       ChangingEncryptionLevelRemovesSoftMaxPacketLength) {
+  if (!client_framer_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  // First set encryption level to forward secure which has the shortest header.
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  const QuicByteCount previous_max_packet_length = creator_.max_packet_length();
+  const size_t min_acceptable_packet_size =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      QuicPacketCreator::MinPlaintextPacketSize(client_framer_.version()) +
+      GetEncryptionOverhead();
+  // Then set the soft max packet length to the lowest allowed value.
+  creator_.SetSoftMaxPacketLength(min_acceptable_packet_size);
+  // Make sure that the low value was accepted.
+  EXPECT_EQ(creator_.max_packet_length(), min_acceptable_packet_size);
+  // Now set the encryption level to handshake which increases the header size.
+  creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
+  // Make sure that adding a frame removes the the soft max packet length.
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  frames_.push_back(QuicFrame(&ack_frame));
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+  EXPECT_EQ(serialized.encryption_level, ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(creator_.max_packet_length(), previous_max_packet_length);
+}
+
+class MockDelegate : public QuicPacketCreator::DelegateInterface {
+ public:
+  MockDelegate() {}
+  MockDelegate(const MockDelegate&) = delete;
+  MockDelegate& operator=(const MockDelegate&) = delete;
+  ~MockDelegate() override {}
+
+  MOCK_METHOD(bool,
+              ShouldGeneratePacket,
+              (HasRetransmittableData retransmittable, IsHandshake handshake),
+              (override));
+  MOCK_METHOD(const QuicFrames,
+              MaybeBundleAckOpportunistically,
+              (),
+              (override));
+  MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
+  MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
+  MOCK_METHOD(void,
+              OnUnrecoverableError,
+              (QuicErrorCode, const std::string&),
+              (override));
+  MOCK_METHOD(SerializedPacketFate,
+              GetSerializedPacketFate,
+              (bool, EncryptionLevel),
+              (override));
+
+  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,
+                                       absl::string_view data) {
+    // Save data before data is consumed.
+    if (!data.empty()) {
+      producer_->SaveStreamData(id, data);
+    }
+    return QuicPacketCreator::ConsumeDataFastPath(id, data.length(),
+                                                  /* offset = */ 0,
+                                                  /* fin = */ true, 0);
+  }
+
+  QuicConsumedData ConsumeData(QuicStreamId id, absl::string_view data,
+                               QuicStreamOffset offset,
+                               StreamSendingState state) {
+    // Save data before data is consumed.
+    if (!data.empty()) {
+      producer_->SaveStreamData(id, data);
+    }
+    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                                      NOT_HANDSHAKE)) {
+      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
+    }
+    return QuicPacketCreator::ConsumeData(id, data.length(), offset, state);
+  }
+
+  MessageStatus AddMessageFrame(QuicMessageId message_id,
+                                quiche::QuicheMemSlice message) {
+    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                                      NOT_HANDSHAKE)) {
+      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
+    }
+    return QuicPacketCreator::AddMessageFrame(message_id,
+                                              absl::MakeSpan(&message, 1));
+  }
+
+  size_t ConsumeCryptoData(EncryptionLevel level,
+                           absl::string_view 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(QuicPacketBuffer()));
+    EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
+        .WillRepeatedly(Return(SEND_TO_WRITER));
+    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 {}
+
+  void SavePacket(SerializedPacket packet) {
+    QUICHE_DCHECK(packet.release_encrypted_buffer == nullptr);
+    packet.encrypted_buffer = CopyBuffer(packet);
+    packet.release_encrypted_buffer = [](const char* p) { delete[] p; };
+    packets_.push_back(std::move(packet));
+  }
+
+ 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);
+    }
+  }
+
+  QuicFramer framer_;
+  MockRandom random_creator_;
+  StrictMock<MockDelegate> delegate_;
+  MultiplePacketsTestPacketCreator creator_;
+  SimpleQuicFramer simple_framer_;
+  std::vector<SerializedPacket> packets_;
+  QuicAckFrame ack_frame_;
+  struct iovec iov_;
+  quiche::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,
+       WrongEncryptionLevelForStreamDataFastPath) {
+  creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
+  delegate_.SetCanWriteAnything();
+  const std::string data(10000, '?');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
+  EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
+  EXPECT_QUIC_BUG(creator_.ConsumeDataFastPath(
+                      QuicUtils::GetFirstBidirectionalStreamId(
+                          framer_.transport_version(), Perspective::IS_CLIENT),
+                      data),
+                  "");
+}
+
+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,
+       ConsumeCryptoDataCheckShouldGeneratePacket) {
+  delegate_.SetCanNotWrite();
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
+  std::string data = "crypto data";
+  size_t consumed_bytes =
+      creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
+  creator_.Flush();
+  EXPECT_EQ(0u, consumed_bytes);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_NotWritable) {
+  delegate_.SetCanNotWrite();
+
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 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();
+
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 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));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 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));
+  const std::string data = "foo bar";
+  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()), data,
+                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));
+  const std::string data = "foo";
+  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()), data,
+                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),
+                      {}, 0, NO_FIN),
+                  "Attempt to consume empty data without FIN.");
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
+  delegate_.SetCanWriteAnything();
+
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       "foo", 0, FIN);
+  QuicConsumedData consumed = creator_.ConsumeData(3, "quux", 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();
+
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       "foo", 0, NO_FIN);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "quux", 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 = 1;
+  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.
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 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.
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "bar", 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);
+
+  const std::string data(10000, '?');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeDataFastPath(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data);
+  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();
+
+  const std::string data(10000, '?');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data, 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);
+
+  const std::string data(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),
+      data, 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) {
+  delegate_.SetCanNotWrite();
+  delegate_.SetCanWriteAnything();
+
+  const std::string data(10000, '?');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data, 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
+  creator_.ConsumeData(3, "quux", 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;
+  const std::string data(data_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(3, data, 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 = 1224;
+  const std::string data(data_len, '?');
+  QuicStreamId stream1_id = QuicUtils::GetFirstBidirectionalStreamId(
+      framer_.transport_version(), Perspective::IS_CLIENT);
+  QuicConsumedData consumed = creator_.ConsumeData(stream1_id, data, 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, data, 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 (framer_.version().HasIetfInvariantHeader()) {
+      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));
+  const std::string data(data_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data,
+      /*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.
+  const std::string data(data_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data,
+      /*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.
+  creator_.AttachPacketFlusher();
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data, 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.
+  const std::string first_write(first_write_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      first_write,
+      /*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.
+  const std::string second_write(second_write_len, '?');
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      second_write,
+      /*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();
+
+  std::unique_ptr<SerializedPacket> 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.
+  const std::string data(data_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data,
+      /*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.
+  creator_.AttachPacketFlusher();
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data,
+      /*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] = {};
+  absl::string_view error_details(buf, 2000);
+  const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR;
+
+  QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
+      framer_.transport_version(), kQuicErrorCode, NO_IETF_QUIC_ERROR,
+      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));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      kDataStreamId, absl::string_view(buf, kStreamFramePayloadSize), 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));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      kDataStreamId, absl::string_view(buf, kStreamFramePayloadSize), 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));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      kDataStreamId1, absl::string_view(buf, kStreamFramePayloadSize), 0,
+      FIN_AND_PADDING);
+  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
+  consumed = creator_.ConsumeData(
+      kDataStreamId2, absl::string_view(buf, kStreamFramePayloadSize), 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;
+  }
+  if (framer_.version().UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  delegate_.SetCanWriteAnything();
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       "foo", 0, FIN);
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
+            creator_.AddMessageFrame(1, MemSliceFromString("message")));
+  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, MemSliceFromString(std::string(
+                       creator_.GetCurrentLargestMessagePayload(), 'a'))));
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+
+  // Failed to send messages which cannot fit into one packet.
+  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
+            creator_.AddMessageFrame(
+                3, MemSliceFromString(std::string(
+                       creator_.GetCurrentLargestMessagePayload() + 10, 'a'))));
+}
+
+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());
+}
+
+// Regresstion test for b/159812345.
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ExtraPaddingNeeded) {
+  if (!framer_.version().HasHeaderProtection()) {
+    return;
+  }
+  delegate_.SetCanWriteAnything();
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       "a", 0, FIN);
+  creator_.Flush();
+  ASSERT_FALSE(packets_[0].nonretransmittable_frames.empty());
+  QuicFrame padding = packets_[0].nonretransmittable_frames[0];
+  // Verify stream frame expansion is excluded.
+  padding.padding_frame.num_padding_bytes = 3;
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       PeerAddressContextWithSameAddress) {
+  QuicConnectionId client_connection_id = TestConnectionId(1);
+  QuicConnectionId server_connection_id = TestConnectionId(2);
+  QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
+  creator_.SetDefaultPeerAddress(peer_addr);
+  creator_.SetClientConnectionId(client_connection_id);
+  creator_.SetServerConnectionId(server_connection_id);
+  // Send some stream data.
+  EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
+      .WillRepeatedly(Return(true));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, NO_FIN);
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  {
+    // Set the same address via context which should not trigger flush.
+    QuicPacketCreator::ScopedPeerAddressContext context(
+        &creator_, peer_addr, client_connection_id, server_connection_id,
+        /*update_connection_id=*/true);
+    ASSERT_EQ(client_connection_id, creator_.GetClientConnectionId());
+    ASSERT_EQ(server_connection_id, creator_.GetServerConnectionId());
+    EXPECT_TRUE(creator_.HasPendingFrames());
+    // Queue another STREAM_FRAME.
+    QuicConsumedData consumed = creator_.ConsumeData(
+        QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                                 Perspective::IS_CLIENT),
+        "foo", 0, FIN);
+    EXPECT_EQ(3u, consumed.bytes_consumed);
+  }
+  // After exiting the scope, the last queued frame should be flushed.
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr, packet.peer_address);
+        ASSERT_EQ(2u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.back().type);
+      }));
+  creator_.FlushCurrentPacket();
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       PeerAddressContextWithDifferentAddress) {
+  QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
+  creator_.SetDefaultPeerAddress(peer_addr);
+  // Send some stream data.
+  EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
+      .WillRepeatedly(Return(true));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, NO_FIN);
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+
+  QuicSocketAddress peer_addr1(QuicIpAddress::Any4(), 12346);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr, packet.peer_address);
+        ASSERT_EQ(1u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+      }))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr1, packet.peer_address);
+        ASSERT_EQ(1u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+      }));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  {
+    QuicConnectionId client_connection_id = TestConnectionId(1);
+    QuicConnectionId server_connection_id = TestConnectionId(2);
+    // Set a different address via context which should trigger flush.
+    QuicPacketCreator::ScopedPeerAddressContext context(
+        &creator_, peer_addr1, client_connection_id, server_connection_id,
+        /*update_connection_id=*/true);
+    ASSERT_EQ(client_connection_id, creator_.GetClientConnectionId());
+    ASSERT_EQ(server_connection_id, creator_.GetServerConnectionId());
+    EXPECT_FALSE(creator_.HasPendingFrames());
+    // Queue another STREAM_FRAME.
+    QuicConsumedData consumed = creator_.ConsumeData(
+        QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                                 Perspective::IS_CLIENT),
+        "foo", 0, FIN);
+    EXPECT_EQ(3u, consumed.bytes_consumed);
+    EXPECT_TRUE(creator_.HasPendingFrames());
+  }
+  // After exiting the scope, the last queued frame should be flushed.
+  EXPECT_FALSE(creator_.HasPendingFrames());
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       NestedPeerAddressContextWithDifferentAddress) {
+  QuicConnectionId client_connection_id1 = creator_.GetClientConnectionId();
+  QuicConnectionId server_connection_id1 = creator_.GetServerConnectionId();
+  QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
+  creator_.SetDefaultPeerAddress(peer_addr);
+  QuicPacketCreator::ScopedPeerAddressContext context(
+      &creator_, peer_addr, client_connection_id1, server_connection_id1,
+      /*update_connection_id=*/true);
+  ASSERT_EQ(client_connection_id1, creator_.GetClientConnectionId());
+  ASSERT_EQ(server_connection_id1, creator_.GetServerConnectionId());
+
+  // Send some stream data.
+  EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
+      .WillRepeatedly(Return(true));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, NO_FIN);
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+
+  QuicSocketAddress peer_addr1(QuicIpAddress::Any4(), 12346);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr, packet.peer_address);
+        ASSERT_EQ(1u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+
+        QuicConnectionId client_connection_id2 = TestConnectionId(3);
+        QuicConnectionId server_connection_id2 = TestConnectionId(4);
+        // Set up another context with a different address.
+        QuicPacketCreator::ScopedPeerAddressContext context(
+            &creator_, peer_addr1, client_connection_id2, server_connection_id2,
+            /*update_connection_id=*/true);
+        ASSERT_EQ(client_connection_id2, creator_.GetClientConnectionId());
+        ASSERT_EQ(server_connection_id2, creator_.GetServerConnectionId());
+        EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
+            .WillRepeatedly(Return(true));
+        QuicConsumedData consumed = creator_.ConsumeData(
+            QuicUtils::GetFirstBidirectionalStreamId(
+                creator_.transport_version(), Perspective::IS_CLIENT),
+            "foo", 0, NO_FIN);
+        EXPECT_EQ(3u, consumed.bytes_consumed);
+        EXPECT_TRUE(creator_.HasPendingFrames());
+        // This should trigger another OnSerializedPacket() with the 2nd
+        // address.
+        creator_.FlushCurrentPacket();
+      }))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr1, packet.peer_address);
+        ASSERT_EQ(1u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+      }));
+  creator_.FlushCurrentPacket();
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_number.cc b/quiche/quic/core/quic_packet_number.cc
new file mode 100644
index 0000000..ab220bf
--- /dev/null
+++ b/quiche/quic/core/quic_packet_number.cc
@@ -0,0 +1,111 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_packet_number.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "absl/strings/str_cat.h"
+
+namespace quic {
+
+void QuicPacketNumber::Clear() {
+  packet_number_ = UninitializedPacketNumber();
+}
+
+void QuicPacketNumber::UpdateMax(QuicPacketNumber new_value) {
+  if (!new_value.IsInitialized()) {
+    return;
+  }
+  if (!IsInitialized()) {
+    packet_number_ = new_value.ToUint64();
+  } else {
+    packet_number_ = std::max(packet_number_, new_value.ToUint64());
+  }
+}
+
+uint64_t QuicPacketNumber::Hash() const {
+  QUICHE_DCHECK(IsInitialized());
+  return packet_number_;
+}
+
+uint64_t QuicPacketNumber::ToUint64() const {
+  QUICHE_DCHECK(IsInitialized());
+  return packet_number_;
+}
+
+bool QuicPacketNumber::IsInitialized() const {
+  return packet_number_ != UninitializedPacketNumber();
+}
+
+QuicPacketNumber& QuicPacketNumber::operator++() {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_LT(ToUint64(), std::numeric_limits<uint64_t>::max() - 1);
+#endif
+  packet_number_++;
+  return *this;
+}
+
+QuicPacketNumber QuicPacketNumber::operator++(int) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_LT(ToUint64(), std::numeric_limits<uint64_t>::max() - 1);
+#endif
+  QuicPacketNumber previous(*this);
+  packet_number_++;
+  return previous;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator--() {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_GE(ToUint64(), 1UL);
+#endif
+  packet_number_--;
+  return *this;
+}
+
+QuicPacketNumber QuicPacketNumber::operator--(int) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_GE(ToUint64(), 1UL);
+#endif
+  QuicPacketNumber previous(*this);
+  packet_number_--;
+  return previous;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator+=(uint64_t delta) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_GT(std::numeric_limits<uint64_t>::max() - ToUint64(), delta);
+#endif
+  packet_number_ += delta;
+  return *this;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator-=(uint64_t delta) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_GE(ToUint64(), delta);
+#endif
+  packet_number_ -= delta;
+  return *this;
+}
+
+std::string QuicPacketNumber::ToString() const {
+  if (!IsInitialized()) {
+    return "uninitialized";
+  }
+  return absl::StrCat(ToUint64());
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicPacketNumber& p) {
+  os << p.ToString();
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_number.h b/quiche/quic/core/quic_packet_number.h
new file mode 100644
index 0000000..0cd94c9
--- /dev/null
+++ b/quiche/quic/core/quic_packet_number.h
@@ -0,0 +1,165 @@
+// Copyright (c) 2019 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_PACKET_NUMBER_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
+
+#include <limits>
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// QuicPacketNumber can either initialized or uninitialized. An initialized
+// packet number is simply an ordinal number. A sentinel value is used to
+// represent an uninitialized packet number.
+class QUIC_EXPORT_PRIVATE QuicPacketNumber {
+ public:
+  // Construct an uninitialized packet number.
+  constexpr QuicPacketNumber() : packet_number_(UninitializedPacketNumber()) {}
+
+  // Construct a packet number from uint64_t. |packet_number| cannot equal the
+  // sentinel value.
+  explicit constexpr QuicPacketNumber(uint64_t packet_number)
+      : packet_number_(packet_number) {
+    QUICHE_DCHECK_NE(UninitializedPacketNumber(), packet_number)
+        << "Use default constructor for uninitialized packet number";
+  }
+
+  // The sentinel value representing an uninitialized packet number.
+  static constexpr uint64_t UninitializedPacketNumber() {
+    return std::numeric_limits<uint64_t>::max();
+  }
+
+  // Packet number becomes uninitialized after calling this function.
+  void Clear();
+
+  // Updates this packet number to be |new_value| if it is greater than current
+  // value.
+  void UpdateMax(QuicPacketNumber new_value);
+
+  // REQUIRES: IsInitialized() == true.
+  uint64_t Hash() const;
+
+  // Converts packet number to uint64_t.
+  // REQUIRES: IsInitialized() == true.
+  uint64_t ToUint64() const;
+
+  // Returns true if packet number is considered initialized.
+  bool IsInitialized() const;
+
+  // REQUIRES: IsInitialized() == true && ToUint64() <
+  // numeric_limits<uint64_t>::max() - 1.
+  QuicPacketNumber& operator++();
+  QuicPacketNumber operator++(int);
+  // REQUIRES: IsInitialized() == true && ToUint64() >= 1.
+  QuicPacketNumber& operator--();
+  QuicPacketNumber operator--(int);
+
+  // REQUIRES: IsInitialized() == true && numeric_limits<uint64_t>::max() -
+  // ToUint64() > |delta|.
+  QuicPacketNumber& operator+=(uint64_t delta);
+  // REQUIRES: IsInitialized() == true && ToUint64() >= |delta|.
+  QuicPacketNumber& operator-=(uint64_t delta);
+
+  // Human-readable representation suitable for logging.
+  std::string ToString() const;
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPacketNumber& p);
+
+ private:
+  // All following operators REQUIRE operands.Initialized() == true.
+  friend inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs);
+
+  // REQUIRES: numeric_limits<uint64_t>::max() - lhs.ToUint64() > |delta|.
+  friend inline QuicPacketNumber operator+(QuicPacketNumber lhs,
+                                           uint64_t delta);
+  // REQUIRES: lhs.ToUint64() >= |delta|.
+  friend inline QuicPacketNumber operator-(QuicPacketNumber lhs,
+                                           uint64_t delta);
+  // REQUIRES: lhs >= rhs.
+  friend inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs);
+
+  uint64_t packet_number_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicPacketNumberHash {
+ public:
+  uint64_t operator()(QuicPacketNumber packet_number) const noexcept {
+    return packet_number.Hash();
+  }
+};
+
+inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ == rhs.packet_number_;
+}
+
+inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ != rhs.packet_number_;
+}
+
+inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ < rhs.packet_number_;
+}
+
+inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ <= rhs.packet_number_;
+}
+
+inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ > rhs.packet_number_;
+}
+
+inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ >= rhs.packet_number_;
+}
+
+inline QuicPacketNumber operator+(QuicPacketNumber lhs, uint64_t delta) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(lhs.IsInitialized());
+  QUICHE_DCHECK_GT(std::numeric_limits<uint64_t>::max() - lhs.ToUint64(),
+                   delta);
+#endif
+  return QuicPacketNumber(lhs.packet_number_ + delta);
+}
+
+inline QuicPacketNumber operator-(QuicPacketNumber lhs, uint64_t delta) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(lhs.IsInitialized());
+  QUICHE_DCHECK_GE(lhs.ToUint64(), delta);
+#endif
+  return QuicPacketNumber(lhs.packet_number_ - delta);
+}
+
+inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized() && lhs >= rhs)
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ - rhs.packet_number_;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
diff --git a/quiche/quic/core/quic_packet_number_test.cc b/quiche/quic/core/quic_packet_number_test.cc
new file mode 100644
index 0000000..084a435
--- /dev/null
+++ b/quiche/quic/core/quic_packet_number_test.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_packet_number.h"
+
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+TEST(QuicPacketNumberTest, BasicTest) {
+  QuicPacketNumber num;
+  EXPECT_FALSE(num.IsInitialized());
+
+  QuicPacketNumber num2(10);
+  EXPECT_TRUE(num2.IsInitialized());
+  EXPECT_EQ(10u, num2.ToUint64());
+  EXPECT_EQ(10u, num2.Hash());
+  num2.UpdateMax(num);
+  EXPECT_EQ(10u, num2.ToUint64());
+  num2.UpdateMax(QuicPacketNumber(9));
+  EXPECT_EQ(10u, num2.ToUint64());
+  num2.UpdateMax(QuicPacketNumber(11));
+  EXPECT_EQ(11u, num2.ToUint64());
+  num2.Clear();
+  EXPECT_FALSE(num2.IsInitialized());
+  num2.UpdateMax(QuicPacketNumber(9));
+  EXPECT_EQ(9u, num2.ToUint64());
+
+  QuicPacketNumber num4(0);
+  EXPECT_TRUE(num4.IsInitialized());
+  EXPECT_EQ(0u, num4.ToUint64());
+  EXPECT_EQ(0u, num4.Hash());
+  num4.Clear();
+  EXPECT_FALSE(num4.IsInitialized());
+}
+
+TEST(QuicPacketNumberTest, Operators) {
+  QuicPacketNumber num(100);
+  EXPECT_EQ(QuicPacketNumber(100), num++);
+  EXPECT_EQ(QuicPacketNumber(101), num);
+  EXPECT_EQ(QuicPacketNumber(101), num--);
+  EXPECT_EQ(QuicPacketNumber(100), num);
+
+  EXPECT_EQ(QuicPacketNumber(101), ++num);
+  EXPECT_EQ(QuicPacketNumber(100), --num);
+
+  QuicPacketNumber num3(0);
+  EXPECT_EQ(QuicPacketNumber(0), num3++);
+  EXPECT_EQ(QuicPacketNumber(1), num3);
+  EXPECT_EQ(QuicPacketNumber(2), ++num3);
+
+  EXPECT_EQ(QuicPacketNumber(2), num3--);
+  EXPECT_EQ(QuicPacketNumber(1), num3);
+  EXPECT_EQ(QuicPacketNumber(0), --num3);
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_reader.cc b/quiche/quic/core/quic_packet_reader.cc
new file mode 100644
index 0000000..e6c1d2d
--- /dev/null
+++ b/quiche/quic/core/quic_packet_reader.cc
@@ -0,0 +1,135 @@
+// Copyright 2015 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 "quiche/quic/core/quic_packet_reader.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_process_packet_interface.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+QuicPacketReader::QuicPacketReader()
+    : read_buffers_(kNumPacketsPerReadMmsgCall),
+      read_results_(kNumPacketsPerReadMmsgCall) {
+  QUICHE_DCHECK_EQ(read_buffers_.size(), read_results_.size());
+  for (size_t i = 0; i < read_results_.size(); ++i) {
+    read_results_[i].packet_buffer.buffer = read_buffers_[i].packet_buffer;
+    read_results_[i].packet_buffer.buffer_len =
+        sizeof(read_buffers_[i].packet_buffer);
+
+    read_results_[i].control_buffer.buffer = read_buffers_[i].control_buffer;
+    read_results_[i].control_buffer.buffer_len =
+        sizeof(read_buffers_[i].control_buffer);
+  }
+}
+
+QuicPacketReader::~QuicPacketReader() = default;
+
+bool QuicPacketReader::ReadAndDispatchPackets(
+    int fd,
+    int port,
+    const QuicClock& clock,
+    ProcessPacketInterface* processor,
+    QuicPacketCount* /*packets_dropped*/) {
+  // Reset all read_results for reuse.
+  for (size_t i = 0; i < read_results_.size(); ++i) {
+    read_results_[i].Reset(
+        /*packet_buffer_length=*/sizeof(read_buffers_[i].packet_buffer));
+  }
+
+  // Use clock.Now() as the packet receipt time, the time between packet
+  // arriving at the host and now is considered part of the network delay.
+  QuicTime now = clock.Now();
+
+  size_t packets_read = socket_api_.ReadMultiplePackets(
+      fd,
+      BitMask64(QuicUdpPacketInfoBit::DROPPED_PACKETS,
+                QuicUdpPacketInfoBit::PEER_ADDRESS,
+                QuicUdpPacketInfoBit::V4_SELF_IP,
+                QuicUdpPacketInfoBit::V6_SELF_IP,
+                QuicUdpPacketInfoBit::RECV_TIMESTAMP, QuicUdpPacketInfoBit::TTL,
+                QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER),
+      &read_results_);
+  for (size_t i = 0; i < packets_read; ++i) {
+    auto& result = read_results_[i];
+    if (!result.ok) {
+      QUIC_CODE_COUNT(quic_packet_reader_read_failure);
+      continue;
+    }
+
+    if (!result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
+      QUIC_BUG(quic_bug_10329_1) << "Unable to get peer socket address.";
+      continue;
+    }
+
+    QuicSocketAddress peer_address =
+        result.packet_info.peer_address().Normalized();
+
+    QuicIpAddress self_ip = GetSelfIpFromPacketInfo(
+        result.packet_info, peer_address.host().IsIPv6());
+    if (!self_ip.IsInitialized()) {
+      QUIC_BUG(quic_bug_10329_2) << "Unable to get self IP address.";
+      continue;
+    }
+
+    bool has_ttl = result.packet_info.HasValue(QuicUdpPacketInfoBit::TTL);
+    int ttl = has_ttl ? result.packet_info.ttl() : 0;
+    if (!has_ttl) {
+      QUIC_CODE_COUNT(quic_packet_reader_no_ttl);
+    }
+
+    char* headers = nullptr;
+    size_t headers_length = 0;
+    if (result.packet_info.HasValue(
+            QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
+      headers = result.packet_info.google_packet_headers().buffer;
+      headers_length = result.packet_info.google_packet_headers().buffer_len;
+    } else {
+      QUIC_CODE_COUNT(quic_packet_reader_no_google_packet_header);
+    }
+
+    QuicReceivedPacket packet(
+        result.packet_buffer.buffer, result.packet_buffer.buffer_len, now,
+        /*owns_buffer=*/false, ttl, has_ttl, headers, headers_length,
+        /*owns_header_buffer=*/false);
+
+    QuicSocketAddress self_address(self_ip, port);
+    processor->ProcessPacket(self_address, peer_address, packet);
+  }
+
+  // We may not have read all of the packets available on the socket.
+  return packets_read == kNumPacketsPerReadMmsgCall;
+}
+
+// static
+QuicIpAddress QuicPacketReader::GetSelfIpFromPacketInfo(
+    const QuicUdpPacketInfo& packet_info,
+    bool prefer_v6_ip) {
+  if (prefer_v6_ip) {
+    if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
+      return packet_info.self_v6_ip();
+    }
+    if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
+      return packet_info.self_v4_ip();
+    }
+  } else {
+    if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
+      return packet_info.self_v4_ip();
+    }
+    if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
+      return packet_info.self_v6_ip();
+    }
+  }
+  return QuicIpAddress();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_reader.h b/quiche/quic/core/quic_packet_reader.h
new file mode 100644
index 0000000..18b78d7
--- /dev/null
+++ b/quiche/quic/core/quic_packet_reader.h
@@ -0,0 +1,67 @@
+// Copyright 2015 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.
+
+// A class to read incoming QUIC packets from the UDP socket.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
+
+#include "absl/base/optimization.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_process_packet_interface.h"
+#include "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// Read in larger batches to minimize recvmmsg overhead.
+const int kNumPacketsPerReadMmsgCall = 16;
+
+class QUIC_EXPORT_PRIVATE QuicPacketReader {
+ public:
+  QuicPacketReader();
+  QuicPacketReader(const QuicPacketReader&) = delete;
+  QuicPacketReader& operator=(const QuicPacketReader&) = delete;
+
+  virtual ~QuicPacketReader();
+
+  // Reads a number of packets from the given fd, and then passes them off to
+  // the PacketProcessInterface.  Returns true if there may be additional
+  // packets available on the socket.
+  // Populates |packets_dropped| if it is non-null and the socket is configured
+  // to track dropped packets and some packets are read.
+  // If the socket has timestamping enabled, the per packet timestamps will be
+  // passed to the processor. Otherwise, |clock| will be used.
+  virtual bool ReadAndDispatchPackets(int fd,
+                                      int port,
+                                      const QuicClock& clock,
+                                      ProcessPacketInterface* processor,
+                                      QuicPacketCount* packets_dropped);
+
+ private:
+  // Return the self ip from |packet_info|.
+  // For dual stack sockets, |packet_info| may contain both a v4 and a v6 ip, in
+  // that case, |prefer_v6_ip| is used to determine which one is used as the
+  // return value. If neither v4 nor v6 ip exists, return an uninitialized ip.
+  static QuicIpAddress GetSelfIpFromPacketInfo(
+      const QuicUdpPacketInfo& packet_info,
+      bool prefer_v6_ip);
+
+  struct QUIC_EXPORT_PRIVATE ReadBuffer {
+    ABSL_CACHELINE_ALIGNED char
+        control_buffer[kDefaultUdpPacketControlBufferSize];  // For ancillary
+                                                             // data.
+    ABSL_CACHELINE_ALIGNED char packet_buffer[kMaxIncomingPacketSize];
+  };
+
+  QuicUdpSocketApi socket_api_;
+  std::vector<ReadBuffer> read_buffers_;
+  QuicUdpSocketApi::ReadPacketResults read_results_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
diff --git a/quiche/quic/core/quic_packet_writer.h b/quiche/quic/core/quic_packet_writer.h
new file mode 100644
index 0000000..1406c19
--- /dev/null
+++ b/quiche/quic/core/quic_packet_writer.h
@@ -0,0 +1,170 @@
+// Copyright 2013 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_PACKET_WRITER_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
+
+#include <cstddef>
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+struct WriteResult;
+
+struct QUIC_EXPORT_PRIVATE PerPacketOptions {
+  virtual ~PerPacketOptions() {}
+
+  // Returns a heap-allocated copy of |this|.
+  //
+  // The subclass implementation of this method should look like this:
+  //   return std::make_unique<MyAwesomePerPacketOptions>(*this);
+  //
+  // This method is declared pure virtual in order to ensure the subclasses
+  // would not forget to override it.
+  virtual std::unique_ptr<PerPacketOptions> Clone() const = 0;
+
+  // Specifies ideal release time delay for this packet.
+  QuicTime::Delta release_time_delay = QuicTime::Delta::Zero();
+  // Whether it is allowed to send this packet without |release_time_delay|.
+  bool allow_burst = false;
+};
+
+// An interface between writers and the entity managing the
+// socket (in our case the QuicDispatcher).  This allows the Dispatcher to
+// control writes, and manage any writers who end up write blocked.
+// A concrete writer works in one of the two modes:
+// - PassThrough mode. This is the default mode. Caller calls WritePacket with
+//   caller-allocated packet buffer. Unless the writer is blocked, each call to
+//   WritePacket triggers a write using the underlying socket API.
+//
+// - Batch mode. In this mode, a call to WritePacket may not cause a packet to
+//   be sent using the underlying socket API. Instead, multiple packets are
+//   saved in the writer's internal buffer until they are flushed. The flush can
+//   be explicit, by calling Flush, or implicit, e.g. by calling
+//   WritePacket when the internal buffer is near full.
+//
+// Buffer management:
+// In Batch mode, a writer manages an internal buffer, which is large enough to
+// hold multiple packets' data. If the caller calls WritePacket with a
+// caller-allocated packet buffer, the writer will memcpy the buffer into the
+// internal buffer. Caller can also avoid this memcpy by:
+// 1. Call GetNextWriteLocation to get a pointer P into the internal buffer.
+// 2. Serialize the packet directly to P.
+// 3. Call WritePacket with P as the |buffer|.
+class QUIC_EXPORT_PRIVATE QuicPacketWriter {
+ public:
+  virtual ~QuicPacketWriter() {}
+
+  // PassThrough mode:
+  // Sends the packet out to the peer, with some optional per-packet options.
+  // If the write succeeded, the result's status is WRITE_STATUS_OK and
+  // bytes_written is populated. If the write failed, the result's status is
+  // WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR and error_code is populated.
+  //
+  // Batch mode:
+  // If the writer is blocked, return WRITE_STATUS_BLOCKED immediately.
+  // If the packet can be batched with other buffered packets, save the packet
+  // to the internal buffer.
+  // If the packet can not be batched, or the internal buffer is near full after
+  // it is buffered, the internal buffer is flushed to free up space.
+  // Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) on success. When
+  // <bytes_flushed> is zero, it means the packet is buffered and not flushed.
+  // Return WRITE_STATUS_BLOCKED if the packet is not buffered and the socket is
+  // blocked while flushing.
+  // Otherwise return an error status.
+  //
+  // Options must be either null, or created for the particular QuicPacketWriter
+  // implementation. Options may be ignored, depending on the implementation.
+  //
+  // Some comment about memory management if |buffer| was previously acquired
+  // by a call to "GetNextWriteLocation()":
+  //
+  // a) When WRITE_STATUS_OK is returned, the caller expects the writer owns the
+  // packet buffers and they will be released when the write finishes.
+  //
+  // b) When this function returns any status >= WRITE_STATUS_ERROR, the caller
+  // expects the writer releases the buffer (if needed) before the function
+  // returns.
+  //
+  // c) When WRITE_STATUS_BLOCKED is returned, the caller makes a copy of the
+  // buffer and will retry after unblock, so if |payload| is allocated from
+  // GetNextWriteLocation(), it
+  //    1) needs to be released before return, and
+  //    2) the content of |payload| should not change after return.
+  //
+  // d) When WRITE_STATUS_BLOCKED_DATA_BUFFERED is returned, the caller expects
+  // 1) the writer owns the packet buffers, and 2) the writer will re-send the
+  // packet when it unblocks.
+  virtual WriteResult WritePacket(const char* buffer,
+                                  size_t buf_len,
+                                  const QuicIpAddress& self_address,
+                                  const QuicSocketAddress& peer_address,
+                                  PerPacketOptions* options) = 0;
+
+  // Returns true if the network socket is not writable.
+  virtual bool IsWriteBlocked() const = 0;
+
+  // Records that the socket has become writable, for example when an EPOLLOUT
+  // is received or an asynchronous write completes.
+  virtual void SetWritable() = 0;
+
+  // The error code used by the writer to indicate that the write failed due to
+  // supplied packet being too big.  This is equivalent to returning
+  // WRITE_STATUS_MSG_TOO_BIG as a status.
+  virtual absl::optional<int> MessageTooBigErrorCode() const = 0;
+
+  // Returns the maximum size of the packet which can be written using this
+  // writer for the supplied peer address.  This size may actually exceed the
+  // size of a valid QUIC packet.
+  virtual QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& peer_address) const = 0;
+
+  // Returns true if the socket supports release timestamp.
+  virtual bool SupportsReleaseTime() const = 0;
+
+  // True=Batch mode. False=PassThrough mode.
+  virtual bool IsBatchMode() const = 0;
+
+  // PassThrough mode: Return {nullptr, nullptr}
+  //
+  // Batch mode:
+  // Return the QuicPacketBuffer for the next packet. A minimum of
+  // kMaxOutgoingPacketSize is guaranteed to be available from the returned
+  // address. If the internal buffer does not have enough space,
+  // {nullptr, nullptr} is returned. All arguments should be identical to the
+  // follow-up call to |WritePacket|, they are here to allow advanced packet
+  // memory management in packet writers, e.g. one packet buffer pool per
+  // |peer_address|.
+  //
+  // If QuicPacketBuffer.release_buffer is !nullptr, it should be called iff
+  // the caller does not call WritePacket for the returned buffer.
+  virtual QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& self_address,
+      const QuicSocketAddress& peer_address) = 0;
+
+  // PassThrough mode: Return WriteResult(WRITE_STATUS_OK, 0).
+  //
+  // Batch mode:
+  // Try send all buffered packets.
+  // - Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered
+  //   packets were sent successfully.
+  // - Return WRITE_STATUS_BLOCKED if the underlying socket is blocked while
+  //   sending. Some packets may have been sent, packets not sent will stay in
+  //   the internal buffer.
+  // - Return a status >= WRITE_STATUS_ERROR if an error was encuontered while
+  //   sending. As this is not a re-tryable error, any batched packets which
+  //   were on memory acquired via GetNextWriteLocation() should be released and
+  //   the batch should be dropped.
+  virtual WriteResult Flush() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
diff --git a/quiche/quic/core/quic_packet_writer_wrapper.cc b/quiche/quic/core/quic_packet_writer_wrapper.cc
new file mode 100644
index 0000000..522f6bf
--- /dev/null
+++ b/quiche/quic/core/quic_packet_writer_wrapper.cc
@@ -0,0 +1,83 @@
+// 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 "quiche/quic/core/quic_packet_writer_wrapper.h"
+
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+QuicPacketWriterWrapper::QuicPacketWriterWrapper() = default;
+
+QuicPacketWriterWrapper::~QuicPacketWriterWrapper() {
+  unset_writer();
+}
+
+WriteResult QuicPacketWriterWrapper::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  return writer_->WritePacket(buffer, buf_len, self_address, peer_address,
+                              options);
+}
+
+bool QuicPacketWriterWrapper::IsWriteBlocked() const {
+  return writer_->IsWriteBlocked();
+}
+
+void QuicPacketWriterWrapper::SetWritable() {
+  writer_->SetWritable();
+}
+
+absl::optional<int> QuicPacketWriterWrapper::MessageTooBigErrorCode() const {
+  return writer_->MessageTooBigErrorCode();
+}
+
+QuicByteCount QuicPacketWriterWrapper::GetMaxPacketSize(
+    const QuicSocketAddress& peer_address) const {
+  return writer_->GetMaxPacketSize(peer_address);
+}
+
+bool QuicPacketWriterWrapper::SupportsReleaseTime() const {
+  return writer_->SupportsReleaseTime();
+}
+
+bool QuicPacketWriterWrapper::IsBatchMode() const {
+  return writer_->IsBatchMode();
+}
+
+QuicPacketBuffer QuicPacketWriterWrapper::GetNextWriteLocation(
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address) {
+  return writer_->GetNextWriteLocation(self_address, peer_address);
+}
+
+WriteResult QuicPacketWriterWrapper::Flush() {
+  return writer_->Flush();
+}
+
+void QuicPacketWriterWrapper::set_writer(QuicPacketWriter* writer) {
+  unset_writer();
+  writer_ = writer;
+  owns_writer_ = true;
+}
+
+void QuicPacketWriterWrapper::set_non_owning_writer(QuicPacketWriter* writer) {
+  unset_writer();
+  writer_ = writer;
+  owns_writer_ = false;
+}
+
+void QuicPacketWriterWrapper::unset_writer() {
+  if (owns_writer_) {
+    delete writer_;
+  }
+
+  owns_writer_ = false;
+  writer_ = nullptr;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_writer_wrapper.h b/quiche/quic/core/quic_packet_writer_wrapper.h
new file mode 100644
index 0000000..4f8ab61
--- /dev/null
+++ b/quiche/quic/core/quic_packet_writer_wrapper.h
@@ -0,0 +1,63 @@
+// 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_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "quiche/quic/core/quic_packet_writer.h"
+
+namespace quic {
+
+// Wraps a writer object to allow dynamically extending functionality. Use
+// cases: replace writer while dispatcher and connections hold on to the
+// wrapper; mix in monitoring; mix in mocks in unit tests.
+class QUIC_NO_EXPORT QuicPacketWriterWrapper : public QuicPacketWriter {
+ public:
+  QuicPacketWriterWrapper();
+  QuicPacketWriterWrapper(const QuicPacketWriterWrapper&) = delete;
+  QuicPacketWriterWrapper& operator=(const QuicPacketWriterWrapper&) = delete;
+  ~QuicPacketWriterWrapper() override;
+
+  // Default implementation of the QuicPacketWriter interface. Passes everything
+  // to |writer_|.
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+  bool IsWriteBlocked() const override;
+  void SetWritable() override;
+  absl::optional<int> MessageTooBigErrorCode() const override;
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& peer_address) const override;
+  bool SupportsReleaseTime() const override;
+  bool IsBatchMode() const override;
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& self_address,
+      const QuicSocketAddress& peer_address) override;
+  WriteResult Flush() override;
+
+  // Takes ownership of |writer|.
+  void set_writer(QuicPacketWriter* writer);
+
+  // Does not take ownership of |writer|.
+  void set_non_owning_writer(QuicPacketWriter* writer);
+
+  virtual void set_peer_address(const QuicSocketAddress& /*peer_address*/) {}
+
+  QuicPacketWriter* writer() { return writer_; }
+
+ private:
+  void unset_writer();
+
+  QuicPacketWriter* writer_ = nullptr;
+  bool owns_writer_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
diff --git a/quiche/quic/core/quic_packets.cc b/quiche/quic/core/quic_packets.cc
new file mode 100644
index 0000000..d3db3b7
--- /dev/null
+++ b/quiche/quic/core/quic_packets.cc
@@ -0,0 +1,596 @@
+// 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 "quiche/quic/core/quic_packets.h"
+
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicConnectionId GetServerConnectionIdAsRecipient(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_SERVER) {
+    return header.destination_connection_id;
+  }
+  return header.source_connection_id;
+}
+
+QuicConnectionId GetClientConnectionIdAsRecipient(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.destination_connection_id;
+  }
+  return header.source_connection_id;
+}
+
+QuicConnectionId GetServerConnectionIdAsSender(const QuicPacketHeader& header,
+                                               Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.destination_connection_id;
+  }
+  return header.source_connection_id;
+}
+
+QuicConnectionIdIncluded GetServerConnectionIdIncludedAsSender(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.destination_connection_id_included;
+  }
+  return header.source_connection_id_included;
+}
+
+QuicConnectionId GetClientConnectionIdAsSender(const QuicPacketHeader& header,
+                                               Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.source_connection_id;
+  }
+  return header.destination_connection_id;
+}
+
+QuicConnectionIdIncluded GetClientConnectionIdIncludedAsSender(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.source_connection_id_included;
+  }
+  return header.destination_connection_id_included;
+}
+
+QuicConnectionIdLength GetIncludedConnectionIdLength(
+    QuicConnectionId connection_id,
+    QuicConnectionIdIncluded connection_id_included) {
+  QUICHE_DCHECK(connection_id_included == CONNECTION_ID_PRESENT ||
+                connection_id_included == CONNECTION_ID_ABSENT);
+  return connection_id_included == CONNECTION_ID_PRESENT
+             ? static_cast<QuicConnectionIdLength>(connection_id.length())
+             : PACKET_0BYTE_CONNECTION_ID;
+}
+
+QuicConnectionIdLength GetIncludedDestinationConnectionIdLength(
+    const QuicPacketHeader& header) {
+  return GetIncludedConnectionIdLength(
+      header.destination_connection_id,
+      header.destination_connection_id_included);
+}
+
+QuicConnectionIdLength GetIncludedSourceConnectionIdLength(
+    const QuicPacketHeader& header) {
+  return GetIncludedConnectionIdLength(header.source_connection_id,
+                                       header.source_connection_id_included);
+}
+
+size_t GetPacketHeaderSize(QuicTransportVersion version,
+                           const QuicPacketHeader& header) {
+  return GetPacketHeaderSize(
+      version, GetIncludedDestinationConnectionIdLength(header),
+      GetIncludedSourceConnectionIdLength(header), header.version_flag,
+      header.nonce != nullptr, header.packet_number_length,
+      header.retry_token_length_length, header.retry_token.length(),
+      header.length_length);
+}
+
+size_t GetPacketHeaderSize(
+    QuicTransportVersion version,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool include_version,
+    bool include_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicByteCount retry_token_length,
+    QuicVariableLengthIntegerLength length_length) {
+  if (VersionHasIetfInvariantHeader(version)) {
+    if (include_version) {
+      // Long header.
+      size_t size = kPacketHeaderTypeSize + kConnectionIdLengthSize +
+                    destination_connection_id_length +
+                    source_connection_id_length + packet_number_length +
+                    kQuicVersionSize;
+      if (include_diversification_nonce) {
+        size += kDiversificationNonceSize;
+      }
+      if (VersionHasLengthPrefixedConnectionIds(version)) {
+        size += kConnectionIdLengthSize;
+      }
+      QUICHE_DCHECK(
+          QuicVersionHasLongHeaderLengths(version) ||
+          retry_token_length_length + retry_token_length + length_length == 0);
+      if (QuicVersionHasLongHeaderLengths(version)) {
+        size += retry_token_length_length + retry_token_length + length_length;
+      }
+      return size;
+    }
+    // Short header.
+    return kPacketHeaderTypeSize + destination_connection_id_length +
+           packet_number_length;
+  }
+  // Google QUIC versions <= 43 can only carry one connection ID.
+  QUICHE_DCHECK(destination_connection_id_length == 0 ||
+                source_connection_id_length == 0);
+  return kPublicFlagsSize + destination_connection_id_length +
+         source_connection_id_length +
+         (include_version ? kQuicVersionSize : 0) + packet_number_length +
+         (include_diversification_nonce ? kDiversificationNonceSize : 0);
+}
+
+size_t GetStartOfEncryptedData(QuicTransportVersion version,
+                               const QuicPacketHeader& header) {
+  return GetPacketHeaderSize(version, header);
+}
+
+size_t GetStartOfEncryptedData(
+    QuicTransportVersion version,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool include_version,
+    bool include_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicByteCount retry_token_length,
+    QuicVariableLengthIntegerLength length_length) {
+  // Encryption starts before private flags.
+  return GetPacketHeaderSize(
+      version, destination_connection_id_length, source_connection_id_length,
+      include_version, include_diversification_nonce, packet_number_length,
+      retry_token_length_length, retry_token_length, length_length);
+}
+
+QuicPacketHeader::QuicPacketHeader()
+    : destination_connection_id(EmptyQuicConnectionId()),
+      destination_connection_id_included(CONNECTION_ID_PRESENT),
+      source_connection_id(EmptyQuicConnectionId()),
+      source_connection_id_included(CONNECTION_ID_ABSENT),
+      reset_flag(false),
+      version_flag(false),
+      has_possible_stateless_reset_token(false),
+      packet_number_length(PACKET_4BYTE_PACKET_NUMBER),
+      version(UnsupportedQuicVersion()),
+      nonce(nullptr),
+      form(GOOGLE_QUIC_PACKET),
+      long_packet_type(INITIAL),
+      possible_stateless_reset_token({}),
+      retry_token_length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
+      retry_token(absl::string_view()),
+      length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
+      remaining_packet_length(0) {}
+
+QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
+
+QuicPacketHeader::~QuicPacketHeader() {}
+
+QuicPacketHeader& QuicPacketHeader::operator=(const QuicPacketHeader& other) =
+    default;
+
+QuicPublicResetPacket::QuicPublicResetPacket()
+    : connection_id(EmptyQuicConnectionId()), nonce_proof(0) {}
+
+QuicPublicResetPacket::QuicPublicResetPacket(QuicConnectionId connection_id)
+    : connection_id(connection_id), nonce_proof(0) {}
+
+QuicVersionNegotiationPacket::QuicVersionNegotiationPacket()
+    : connection_id(EmptyQuicConnectionId()) {}
+
+QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
+    QuicConnectionId connection_id)
+    : connection_id(connection_id) {}
+
+QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
+    const QuicVersionNegotiationPacket& other) = default;
+
+QuicVersionNegotiationPacket::~QuicVersionNegotiationPacket() {}
+
+QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket()
+    : stateless_reset_token({}) {}
+
+QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
+    const QuicPacketHeader& header,
+    StatelessResetToken token)
+    : header(header), stateless_reset_token(token) {}
+
+QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
+    const QuicIetfStatelessResetPacket& other) = default;
+
+QuicIetfStatelessResetPacket::~QuicIetfStatelessResetPacket() {}
+
+std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
+  os << "{ destination_connection_id: " << header.destination_connection_id
+     << " ("
+     << (header.destination_connection_id_included == CONNECTION_ID_PRESENT
+             ? "present"
+             : "absent")
+     << "), source_connection_id: " << header.source_connection_id << " ("
+     << (header.source_connection_id_included == CONNECTION_ID_PRESENT
+             ? "present"
+             : "absent")
+     << "), packet_number_length: "
+     << static_cast<int>(header.packet_number_length)
+     << ", reset_flag: " << header.reset_flag
+     << ", version_flag: " << header.version_flag;
+  if (header.version_flag) {
+    os << ", version: " << ParsedQuicVersionToString(header.version);
+    if (header.long_packet_type != INVALID_PACKET_TYPE) {
+      os << ", long_packet_type: "
+         << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
+    }
+    if (header.retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+      os << ", retry_token_length_length: "
+         << static_cast<int>(header.retry_token_length_length);
+    }
+    if (header.retry_token.length() != 0) {
+      os << ", retry_token_length: " << header.retry_token.length();
+    }
+    if (header.length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+      os << ", length_length: " << static_cast<int>(header.length_length);
+    }
+    if (header.remaining_packet_length != 0) {
+      os << ", remaining_packet_length: " << header.remaining_packet_length;
+    }
+  }
+  if (header.nonce != nullptr) {
+    os << ", diversification_nonce: "
+       << absl::BytesToHexString(
+              absl::string_view(header.nonce->data(), header.nonce->size()));
+  }
+  os << ", packet_number: " << header.packet_number << " }\n";
+  return os;
+}
+
+QuicData::QuicData(const char* buffer, size_t length)
+    : buffer_(buffer), length_(length), owns_buffer_(false) {}
+
+QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer)
+    : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {}
+
+QuicData::QuicData(absl::string_view packet_data)
+    : buffer_(packet_data.data()),
+      length_(packet_data.length()),
+      owns_buffer_(false) {}
+
+QuicData::~QuicData() {
+  if (owns_buffer_) {
+    delete[] const_cast<char*>(buffer_);
+  }
+}
+
+QuicPacket::QuicPacket(
+    char* buffer,
+    size_t length,
+    bool owns_buffer,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool includes_version,
+    bool includes_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicByteCount retry_token_length,
+    QuicVariableLengthIntegerLength length_length)
+    : QuicData(buffer, length, owns_buffer),
+      buffer_(buffer),
+      destination_connection_id_length_(destination_connection_id_length),
+      source_connection_id_length_(source_connection_id_length),
+      includes_version_(includes_version),
+      includes_diversification_nonce_(includes_diversification_nonce),
+      packet_number_length_(packet_number_length),
+      retry_token_length_length_(retry_token_length_length),
+      retry_token_length_(retry_token_length),
+      length_length_(length_length) {}
+
+QuicPacket::QuicPacket(QuicTransportVersion /*version*/,
+                       char* buffer,
+                       size_t length,
+                       bool owns_buffer,
+                       const QuicPacketHeader& header)
+    : QuicPacket(buffer,
+                 length,
+                 owns_buffer,
+                 GetIncludedDestinationConnectionIdLength(header),
+                 GetIncludedSourceConnectionIdLength(header),
+                 header.version_flag,
+                 header.nonce != nullptr,
+                 header.packet_number_length,
+                 header.retry_token_length_length,
+                 header.retry_token.length(),
+                 header.length_length) {}
+
+QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length)
+    : QuicData(buffer, length) {}
+
+QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer,
+                                         size_t length,
+                                         bool owns_buffer)
+    : QuicData(buffer, length, owns_buffer) {}
+
+QuicEncryptedPacket::QuicEncryptedPacket(absl::string_view data)
+    : QuicData(data) {}
+
+std::unique_ptr<QuicEncryptedPacket> QuicEncryptedPacket::Clone() const {
+  char* buffer = new char[this->length()];
+  memcpy(buffer, this->data(), this->length());
+  return std::make_unique<QuicEncryptedPacket>(buffer, this->length(), true);
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicEncryptedPacket& s) {
+  os << s.length() << "-byte data";
+  return os;
+}
+
+QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
+                                       size_t length,
+                                       QuicTime receipt_time)
+    : QuicReceivedPacket(buffer,
+                         length,
+                         receipt_time,
+                         false /* owns_buffer */) {}
+
+QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
+                                       size_t length,
+                                       QuicTime receipt_time,
+                                       bool owns_buffer)
+    : QuicReceivedPacket(buffer,
+                         length,
+                         receipt_time,
+                         owns_buffer,
+                         0 /* ttl */,
+                         true /* ttl_valid */) {}
+
+QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
+                                       size_t length,
+                                       QuicTime receipt_time,
+                                       bool owns_buffer,
+                                       int ttl,
+                                       bool ttl_valid)
+    : quic::QuicReceivedPacket(buffer,
+                               length,
+                               receipt_time,
+                               owns_buffer,
+                               ttl,
+                               ttl_valid,
+                               nullptr /* packet_headers */,
+                               0 /* headers_length */,
+                               false /* owns_header_buffer */) {}
+
+QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
+                                       size_t length,
+                                       QuicTime receipt_time,
+                                       bool owns_buffer,
+                                       int ttl,
+                                       bool ttl_valid,
+                                       char* packet_headers,
+                                       size_t headers_length,
+                                       bool owns_header_buffer)
+    : QuicEncryptedPacket(buffer, length, owns_buffer),
+      receipt_time_(receipt_time),
+      ttl_(ttl_valid ? ttl : -1),
+      packet_headers_(packet_headers),
+      headers_length_(headers_length),
+      owns_header_buffer_(owns_header_buffer) {}
+
+QuicReceivedPacket::~QuicReceivedPacket() {
+  if (owns_header_buffer_) {
+    delete[] static_cast<char*>(packet_headers_);
+  }
+}
+
+std::unique_ptr<QuicReceivedPacket> QuicReceivedPacket::Clone() const {
+  char* buffer = new char[this->length()];
+  memcpy(buffer, this->data(), this->length());
+  if (this->packet_headers()) {
+    char* headers_buffer = new char[this->headers_length()];
+    memcpy(headers_buffer, this->packet_headers(), this->headers_length());
+    return std::make_unique<QuicReceivedPacket>(
+        buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0,
+        headers_buffer, this->headers_length(), true);
+  }
+
+  return std::make_unique<QuicReceivedPacket>(
+      buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0);
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) {
+  os << s.length() << "-byte data";
+  return os;
+}
+
+absl::string_view QuicPacket::AssociatedData(
+    QuicTransportVersion version) const {
+  return absl::string_view(
+      data(),
+      GetStartOfEncryptedData(version, destination_connection_id_length_,
+                              source_connection_id_length_, includes_version_,
+                              includes_diversification_nonce_,
+                              packet_number_length_, retry_token_length_length_,
+                              retry_token_length_, length_length_));
+}
+
+absl::string_view QuicPacket::Plaintext(QuicTransportVersion version) const {
+  const size_t start_of_encrypted_data = GetStartOfEncryptedData(
+      version, destination_connection_id_length_, source_connection_id_length_,
+      includes_version_, includes_diversification_nonce_, packet_number_length_,
+      retry_token_length_length_, retry_token_length_, length_length_);
+  return absl::string_view(data() + start_of_encrypted_data,
+                           length() - start_of_encrypted_data);
+}
+
+SerializedPacket::SerializedPacket(QuicPacketNumber packet_number,
+                                   QuicPacketNumberLength packet_number_length,
+                                   const char* encrypted_buffer,
+                                   QuicPacketLength encrypted_length,
+                                   bool has_ack,
+                                   bool has_stop_waiting)
+    : encrypted_buffer(encrypted_buffer),
+      encrypted_length(encrypted_length),
+      has_crypto_handshake(NOT_HANDSHAKE),
+      packet_number(packet_number),
+      packet_number_length(packet_number_length),
+      encryption_level(ENCRYPTION_INITIAL),
+      has_ack(has_ack),
+      has_stop_waiting(has_stop_waiting),
+      transmission_type(NOT_RETRANSMISSION),
+      has_ack_frame_copy(false),
+      has_ack_frequency(false),
+      has_message(false),
+      fate(SEND_TO_WRITER) {}
+
+SerializedPacket::SerializedPacket(SerializedPacket&& other)
+    : has_crypto_handshake(other.has_crypto_handshake),
+      packet_number(other.packet_number),
+      packet_number_length(other.packet_number_length),
+      encryption_level(other.encryption_level),
+      has_ack(other.has_ack),
+      has_stop_waiting(other.has_stop_waiting),
+      transmission_type(other.transmission_type),
+      largest_acked(other.largest_acked),
+      has_ack_frame_copy(other.has_ack_frame_copy),
+      has_ack_frequency(other.has_ack_frequency),
+      has_message(other.has_message),
+      fate(other.fate),
+      peer_address(other.peer_address) {
+  if (this != &other) {
+    if (release_encrypted_buffer && encrypted_buffer != nullptr) {
+      release_encrypted_buffer(encrypted_buffer);
+    }
+    encrypted_buffer = other.encrypted_buffer;
+    encrypted_length = other.encrypted_length;
+    release_encrypted_buffer = std::move(other.release_encrypted_buffer);
+    other.release_encrypted_buffer = nullptr;
+
+    retransmittable_frames.swap(other.retransmittable_frames);
+    nonretransmittable_frames.swap(other.nonretransmittable_frames);
+  }
+}
+
+SerializedPacket::~SerializedPacket() {
+  if (release_encrypted_buffer && encrypted_buffer != nullptr) {
+    release_encrypted_buffer(encrypted_buffer);
+  }
+
+  if (!retransmittable_frames.empty()) {
+    DeleteFrames(&retransmittable_frames);
+  }
+  for (auto& frame : nonretransmittable_frames) {
+    if (!has_ack_frame_copy && frame.type == ACK_FRAME) {
+      // Do not delete ack frame if the packet does not own a copy of it.
+      continue;
+    }
+    DeleteFrame(&frame);
+  }
+}
+
+SerializedPacket* CopySerializedPacket(const SerializedPacket& serialized,
+                                       quiche::QuicheBufferAllocator* allocator,
+                                       bool copy_buffer) {
+  SerializedPacket* copy = new SerializedPacket(
+      serialized.packet_number, serialized.packet_number_length,
+      serialized.encrypted_buffer, serialized.encrypted_length,
+      serialized.has_ack, serialized.has_stop_waiting);
+  copy->has_crypto_handshake = serialized.has_crypto_handshake;
+  copy->encryption_level = serialized.encryption_level;
+  copy->transmission_type = serialized.transmission_type;
+  copy->largest_acked = serialized.largest_acked;
+  copy->has_ack_frequency = serialized.has_ack_frequency;
+  copy->has_message = serialized.has_message;
+  copy->fate = serialized.fate;
+  copy->peer_address = serialized.peer_address;
+
+  if (copy_buffer) {
+    copy->encrypted_buffer = CopyBuffer(serialized);
+    copy->release_encrypted_buffer = [](const char* p) { delete[] p; };
+  }
+  // Copy underlying frames.
+  copy->retransmittable_frames =
+      CopyQuicFrames(allocator, serialized.retransmittable_frames);
+  QUICHE_DCHECK(copy->nonretransmittable_frames.empty());
+  for (const auto& frame : serialized.nonretransmittable_frames) {
+    if (frame.type == ACK_FRAME) {
+      copy->has_ack_frame_copy = true;
+    }
+    copy->nonretransmittable_frames.push_back(CopyQuicFrame(allocator, frame));
+  }
+  return copy;
+}
+
+char* CopyBuffer(const SerializedPacket& packet) {
+  return CopyBuffer(packet.encrypted_buffer, packet.encrypted_length);
+}
+
+char* CopyBuffer(const char* encrypted_buffer,
+                 QuicPacketLength encrypted_length) {
+  char* dst_buffer = new char[encrypted_length];
+  memcpy(dst_buffer, encrypted_buffer, encrypted_length);
+  return dst_buffer;
+}
+
+ReceivedPacketInfo::ReceivedPacketInfo(const QuicSocketAddress& self_address,
+                                       const QuicSocketAddress& peer_address,
+                                       const QuicReceivedPacket& packet)
+    : self_address(self_address),
+      peer_address(peer_address),
+      packet(packet),
+      form(GOOGLE_QUIC_PACKET),
+      long_packet_type(INVALID_PACKET_TYPE),
+      version_flag(false),
+      use_length_prefix(false),
+      version_label(0),
+      version(ParsedQuicVersion::Unsupported()),
+      destination_connection_id(EmptyQuicConnectionId()),
+      source_connection_id(EmptyQuicConnectionId()) {}
+
+ReceivedPacketInfo::~ReceivedPacketInfo() {}
+
+std::string ReceivedPacketInfo::ToString() const {
+  std::string output =
+      absl::StrCat("{ self_address: ", self_address.ToString(),
+                   ", peer_address: ", peer_address.ToString(),
+                   ", packet_length: ", packet.length(),
+                   ", header_format: ", form, ", version_flag: ", version_flag);
+  if (version_flag) {
+    absl::StrAppend(&output, ", version: ", ParsedQuicVersionToString(version));
+  }
+  absl::StrAppend(
+      &output,
+      ", destination_connection_id: ", destination_connection_id.ToString(),
+      ", source_connection_id: ", source_connection_id.ToString(), " }\n");
+  return output;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ReceivedPacketInfo& packet_info) {
+  os << packet_info.ToString();
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packets.h b/quiche/quic/core/quic_packets.h
new file mode 100644
index 0000000..98ab413
--- /dev/null
+++ b/quiche/quic/core/quic_packets.h
@@ -0,0 +1,462 @@
+// 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_PACKETS_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKETS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_ack_listener_interface.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+class QuicPacket;
+struct QuicPacketHeader;
+
+// Returns the destination connection ID of |header| when |perspective| is
+// server, and the source connection ID when |perspective| is client.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetServerConnectionIdAsRecipient(const QuicPacketHeader& header,
+                                 Perspective perspective);
+
+// Returns the destination connection ID of |header| when |perspective| is
+// client, and the source connection ID when |perspective| is server.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetClientConnectionIdAsRecipient(const QuicPacketHeader& header,
+                                 Perspective perspective);
+
+// Returns the destination connection ID of |header| when |perspective| is
+// client, and the source connection ID when |perspective| is server.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetServerConnectionIdAsSender(const QuicPacketHeader& header,
+                              Perspective perspective);
+
+// Returns the destination connection ID included of |header| when |perspective|
+// is client, and the source connection ID included when |perspective| is
+// server.
+QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
+GetServerConnectionIdIncludedAsSender(const QuicPacketHeader& header,
+                                      Perspective perspective);
+
+// Returns the destination connection ID of |header| when |perspective| is
+// server, and the source connection ID when |perspective| is client.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetClientConnectionIdAsSender(const QuicPacketHeader& header,
+                              Perspective perspective);
+
+// Returns the destination connection ID included of |header| when |perspective|
+// is server, and the source connection ID included when |perspective| is
+// client.
+QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
+GetClientConnectionIdIncludedAsSender(const QuicPacketHeader& header,
+                                      Perspective perspective);
+
+// Number of connection ID bytes that are actually included over the wire.
+QUIC_EXPORT_PRIVATE QuicConnectionIdLength
+GetIncludedConnectionIdLength(QuicConnectionId connection_id,
+                              QuicConnectionIdIncluded connection_id_included);
+
+// Number of destination connection ID bytes that are actually included over the
+// wire for this particular header.
+QUIC_EXPORT_PRIVATE QuicConnectionIdLength
+GetIncludedDestinationConnectionIdLength(const QuicPacketHeader& header);
+
+// Number of source connection ID bytes that are actually included over the
+// wire for this particular header.
+QUIC_EXPORT_PRIVATE QuicConnectionIdLength
+GetIncludedSourceConnectionIdLength(const QuicPacketHeader& header);
+
+// Size in bytes of the data packet header.
+QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicTransportVersion version,
+                                               const QuicPacketHeader& header);
+
+QUIC_EXPORT_PRIVATE size_t
+GetPacketHeaderSize(QuicTransportVersion version,
+                    QuicConnectionIdLength destination_connection_id_length,
+                    QuicConnectionIdLength source_connection_id_length,
+                    bool include_version,
+                    bool include_diversification_nonce,
+                    QuicPacketNumberLength packet_number_length,
+                    QuicVariableLengthIntegerLength retry_token_length_length,
+                    QuicByteCount retry_token_length,
+                    QuicVariableLengthIntegerLength length_length);
+
+// Index of the first byte in a QUIC packet of encrypted data.
+QUIC_EXPORT_PRIVATE size_t
+GetStartOfEncryptedData(QuicTransportVersion version,
+                        const QuicPacketHeader& header);
+
+QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData(
+    QuicTransportVersion version,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool include_version,
+    bool include_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicByteCount retry_token_length,
+    QuicVariableLengthIntegerLength length_length);
+
+struct QUIC_EXPORT_PRIVATE QuicPacketHeader {
+  QuicPacketHeader();
+  QuicPacketHeader(const QuicPacketHeader& other);
+  ~QuicPacketHeader();
+
+  QuicPacketHeader& operator=(const QuicPacketHeader& other);
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPacketHeader& header);
+
+  // Universal header. All QuicPacket headers will have a connection_id and
+  // public flags.
+  QuicConnectionId destination_connection_id;
+  QuicConnectionIdIncluded destination_connection_id_included;
+  QuicConnectionId source_connection_id;
+  QuicConnectionIdIncluded source_connection_id_included;
+  // This is only used for Google QUIC.
+  bool reset_flag;
+  // For Google QUIC, version flag in packets from the server means version
+  // negotiation packet. For IETF QUIC, version flag means long header.
+  bool version_flag;
+  // Indicates whether |possible_stateless_reset_token| contains a valid value
+  // parsed from the packet buffer. IETF QUIC only, always false for GQUIC.
+  bool has_possible_stateless_reset_token;
+  QuicPacketNumberLength packet_number_length;
+  uint8_t type_byte;
+  ParsedQuicVersion version;
+  // nonce contains an optional, 32-byte nonce value. If not included in the
+  // packet, |nonce| will be empty.
+  DiversificationNonce* nonce;
+  QuicPacketNumber packet_number;
+  // Format of this header.
+  PacketHeaderFormat form;
+  // Short packet type is reflected in packet_number_length.
+  QuicLongHeaderType long_packet_type;
+  // Only valid if |has_possible_stateless_reset_token| is true.
+  // Stores last 16 bytes of a this packet, used to check whether this packet is
+  // a stateless reset packet on decryption failure.
+  StatelessResetToken possible_stateless_reset_token;
+  // Length of the retry token length variable length integer field,
+  // carried only by v99 IETF Initial packets.
+  QuicVariableLengthIntegerLength retry_token_length_length;
+  // Retry token, carried only by v99 IETF Initial packets.
+  absl::string_view retry_token;
+  // Length of the length variable length integer field,
+  // carried only by v99 IETF Initial, 0-RTT and Handshake packets.
+  QuicVariableLengthIntegerLength length_length;
+  // Length of the packet number and payload, carried only by v99 IETF Initial,
+  // 0-RTT and Handshake packets. Also includes the length of the
+  // diversification nonce in server to client 0-RTT packets.
+  QuicByteCount remaining_packet_length;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicPublicResetPacket {
+  QuicPublicResetPacket();
+  explicit QuicPublicResetPacket(QuicConnectionId connection_id);
+
+  QuicConnectionId connection_id;
+  QuicPublicResetNonceProof nonce_proof;
+  QuicSocketAddress client_address;
+  // An arbitrary string to identify an endpoint. Used by clients to
+  // differentiate traffic from Google servers vs Non-google servers.
+  // Will not be used if empty().
+  std::string endpoint_id;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicVersionNegotiationPacket {
+  QuicVersionNegotiationPacket();
+  explicit QuicVersionNegotiationPacket(QuicConnectionId connection_id);
+  QuicVersionNegotiationPacket(const QuicVersionNegotiationPacket& other);
+  ~QuicVersionNegotiationPacket();
+
+  QuicConnectionId connection_id;
+  ParsedQuicVersionVector versions;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicIetfStatelessResetPacket {
+  QuicIetfStatelessResetPacket();
+  QuicIetfStatelessResetPacket(const QuicPacketHeader& header,
+                               StatelessResetToken token);
+  QuicIetfStatelessResetPacket(const QuicIetfStatelessResetPacket& other);
+  ~QuicIetfStatelessResetPacket();
+
+  QuicPacketHeader header;
+  StatelessResetToken stateless_reset_token;
+};
+
+class QUIC_EXPORT_PRIVATE QuicData {
+ public:
+  // Creates a QuicData from a buffer and length. Does not own the buffer.
+  QuicData(const char* buffer, size_t length);
+  // Creates a QuicData from a buffer and length,
+  // optionally taking ownership of the buffer.
+  QuicData(const char* buffer, size_t length, bool owns_buffer);
+  // Creates a QuicData from a absl::string_view. Does not own the
+  // buffer.
+  QuicData(absl::string_view data);
+  QuicData(const QuicData&) = delete;
+  QuicData& operator=(const QuicData&) = delete;
+  virtual ~QuicData();
+
+  absl::string_view AsStringPiece() const {
+    return absl::string_view(data(), length());
+  }
+
+  const char* data() const { return buffer_; }
+  size_t length() const { return length_; }
+
+ private:
+  const char* buffer_;
+  size_t length_;
+  bool owns_buffer_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData {
+ public:
+  QuicPacket(char* buffer,
+             size_t length,
+             bool owns_buffer,
+             QuicConnectionIdLength destination_connection_id_length,
+             QuicConnectionIdLength source_connection_id_length,
+             bool includes_version,
+             bool includes_diversification_nonce,
+             QuicPacketNumberLength packet_number_length,
+             QuicVariableLengthIntegerLength retry_token_length_length,
+             QuicByteCount retry_token_length,
+             QuicVariableLengthIntegerLength length_length);
+  QuicPacket(QuicTransportVersion version,
+             char* buffer,
+             size_t length,
+             bool owns_buffer,
+             const QuicPacketHeader& header);
+  QuicPacket(const QuicPacket&) = delete;
+  QuicPacket& operator=(const QuicPacket&) = delete;
+
+  absl::string_view AssociatedData(QuicTransportVersion version) const;
+  absl::string_view Plaintext(QuicTransportVersion version) const;
+
+  char* mutable_data() { return buffer_; }
+
+ private:
+  char* buffer_;
+  const QuicConnectionIdLength destination_connection_id_length_;
+  const QuicConnectionIdLength source_connection_id_length_;
+  const bool includes_version_;
+  const bool includes_diversification_nonce_;
+  const QuicPacketNumberLength packet_number_length_;
+  const QuicVariableLengthIntegerLength retry_token_length_length_;
+  const QuicByteCount retry_token_length_;
+  const QuicVariableLengthIntegerLength length_length_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
+ public:
+  // Creates a QuicEncryptedPacket from a buffer and length.
+  // Does not own the buffer.
+  QuicEncryptedPacket(const char* buffer, size_t length);
+  // Creates a QuicEncryptedPacket from a buffer and length,
+  // optionally taking ownership of the buffer.
+  QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer);
+  // Creates a QuicEncryptedPacket from a absl::string_view.
+  // Does not own the buffer.
+  QuicEncryptedPacket(absl::string_view data);
+
+  QuicEncryptedPacket(const QuicEncryptedPacket&) = delete;
+  QuicEncryptedPacket& operator=(const QuicEncryptedPacket&) = delete;
+
+  // Clones the packet into a new packet which owns the buffer.
+  std::unique_ptr<QuicEncryptedPacket> Clone() const;
+
+  // By default, gtest prints the raw bytes of an object. The bool data
+  // member (in the base class QuicData) causes this object to have padding
+  // bytes, which causes the default gtest object printer to read
+  // uninitialize memory. So we need to teach gtest how to print this object.
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicEncryptedPacket& s);
+};
+
+// A received encrypted QUIC packet, with a recorded time of receipt.
+class QUIC_EXPORT_PRIVATE QuicReceivedPacket : public QuicEncryptedPacket {
+ public:
+  QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time);
+  QuicReceivedPacket(const char* buffer,
+                     size_t length,
+                     QuicTime receipt_time,
+                     bool owns_buffer);
+  QuicReceivedPacket(const char* buffer,
+                     size_t length,
+                     QuicTime receipt_time,
+                     bool owns_buffer,
+                     int ttl,
+                     bool ttl_valid);
+  QuicReceivedPacket(const char* buffer,
+                     size_t length,
+                     QuicTime receipt_time,
+                     bool owns_buffer,
+                     int ttl,
+                     bool ttl_valid,
+                     char* packet_headers,
+                     size_t headers_length,
+                     bool owns_header_buffer);
+  ~QuicReceivedPacket();
+  QuicReceivedPacket(const QuicReceivedPacket&) = delete;
+  QuicReceivedPacket& operator=(const QuicReceivedPacket&) = delete;
+
+  // Clones the packet into a new packet which owns the buffer.
+  std::unique_ptr<QuicReceivedPacket> Clone() const;
+
+  // Returns the time at which the packet was received.
+  QuicTime receipt_time() const { return receipt_time_; }
+
+  // This is the TTL of the packet, assuming ttl_vaild_ is true.
+  int ttl() const { return ttl_; }
+
+  // Start of packet headers.
+  char* packet_headers() const { return packet_headers_; }
+
+  // Length of packet headers.
+  int headers_length() const { return headers_length_; }
+
+  // By default, gtest prints the raw bytes of an object. The bool data
+  // member (in the base class QuicData) causes this object to have padding
+  // bytes, which causes the default gtest object printer to read
+  // uninitialize memory. So we need to teach gtest how to print this object.
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicReceivedPacket& s);
+
+ private:
+  const QuicTime receipt_time_;
+  int ttl_;
+  // Points to the start of packet headers.
+  char* packet_headers_;
+  // Length of packet headers.
+  int headers_length_;
+  // Whether owns the buffer for packet headers.
+  bool owns_header_buffer_;
+};
+
+// SerializedPacket contains information of a serialized(encrypted) packet.
+//
+// WARNING:
+//
+//   If you add a member field to this class, please make sure it is properly
+//   copied in |CopySerializedPacket|.
+//
+struct QUIC_EXPORT_PRIVATE SerializedPacket {
+  SerializedPacket(QuicPacketNumber packet_number,
+                   QuicPacketNumberLength packet_number_length,
+                   const char* encrypted_buffer,
+                   QuicPacketLength encrypted_length,
+                   bool has_ack,
+                   bool has_stop_waiting);
+
+  // Copy constructor & assignment are deleted. Use |CopySerializedPacket| to
+  // make a copy.
+  SerializedPacket(const SerializedPacket& other) = delete;
+  SerializedPacket& operator=(const SerializedPacket& other) = delete;
+  SerializedPacket(SerializedPacket&& other);
+  ~SerializedPacket();
+
+  // TODO(wub): replace |encrypted_buffer|+|release_encrypted_buffer| by a
+  // QuicOwnedPacketBuffer.
+  // Not owned if |release_encrypted_buffer| is nullptr. Otherwise it is
+  // released by |release_encrypted_buffer| on destruction.
+  const char* encrypted_buffer;
+  QuicPacketLength encrypted_length;
+  std::function<void(const char*)> release_encrypted_buffer;
+
+  QuicFrames retransmittable_frames;
+  QuicFrames nonretransmittable_frames;
+  IsHandshake has_crypto_handshake;
+  QuicPacketNumber packet_number;
+  QuicPacketNumberLength packet_number_length;
+  EncryptionLevel encryption_level;
+  // TODO(fayang): Remove has_ack and has_stop_waiting.
+  bool has_ack;
+  bool has_stop_waiting;
+  TransmissionType transmission_type;
+  // The largest acked of the AckFrame in this packet if has_ack is true,
+  // 0 otherwise.
+  QuicPacketNumber largest_acked;
+  // Indicates whether this packet has a copy of ack frame in
+  // nonretransmittable_frames.
+  bool has_ack_frame_copy;
+  bool has_ack_frequency;
+  bool has_message;
+  SerializedPacketFate fate;
+  QuicSocketAddress peer_address;
+};
+
+// Make a copy of |serialized| (including the underlying frames). |copy_buffer|
+// indicates whether the encrypted buffer should be copied.
+QUIC_EXPORT_PRIVATE SerializedPacket* CopySerializedPacket(
+    const SerializedPacket& serialized,
+    quiche::QuicheBufferAllocator* allocator, bool copy_buffer);
+
+// Allocates a new char[] of size |packet.encrypted_length| and copies in
+// |packet.encrypted_buffer|.
+QUIC_EXPORT_PRIVATE char* CopyBuffer(const SerializedPacket& packet);
+// Allocates a new char[] of size |encrypted_length| and copies in
+// |encrypted_buffer|.
+QUIC_EXPORT_PRIVATE char* CopyBuffer(const char* encrypted_buffer,
+                                     QuicPacketLength encrypted_length);
+
+// Context for an incoming packet.
+struct QUIC_EXPORT_PRIVATE QuicPerPacketContext {
+  virtual ~QuicPerPacketContext() {}
+};
+
+// ReceivedPacketInfo comprises information obtained by parsing the unencrypted
+// bytes of a received packet.
+struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
+  ReceivedPacketInfo(const QuicSocketAddress& self_address,
+                     const QuicSocketAddress& peer_address,
+                     const QuicReceivedPacket& packet);
+  ReceivedPacketInfo(const ReceivedPacketInfo& other) = default;
+
+  ~ReceivedPacketInfo();
+
+  std::string ToString() const;
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const ReceivedPacketInfo& packet_info);
+
+  const QuicSocketAddress& self_address;
+  const QuicSocketAddress& peer_address;
+  const QuicReceivedPacket& packet;
+
+  PacketHeaderFormat form;
+  // This is only used if the form is IETF_QUIC_LONG_HEADER_PACKET.
+  QuicLongHeaderType long_packet_type;
+  bool version_flag;
+  bool use_length_prefix;
+  QuicVersionLabel version_label;
+  ParsedQuicVersion version;
+  QuicConnectionId destination_connection_id;
+  QuicConnectionId source_connection_id;
+  absl::optional<absl::string_view> retry_token;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKETS_H_
diff --git a/quiche/quic/core/quic_packets_test.cc b/quiche/quic/core/quic_packets_test.cc
new file mode 100644
index 0000000..f0a7e7f
--- /dev/null
+++ b/quiche/quic/core/quic_packets_test.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_packets.h"
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+QuicPacketHeader CreateFakePacketHeader() {
+  QuicPacketHeader header;
+  header.destination_connection_id = TestConnectionId(1);
+  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+  header.source_connection_id = TestConnectionId(2);
+  header.source_connection_id_included = CONNECTION_ID_ABSENT;
+  return header;
+}
+
+class QuicPacketsTest : public QuicTest {};
+
+TEST_F(QuicPacketsTest, GetServerConnectionIdAsRecipient) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(TestConnectionId(1),
+            GetServerConnectionIdAsRecipient(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(2),
+            GetServerConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetServerConnectionIdAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(TestConnectionId(2),
+            GetServerConnectionIdAsSender(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(1),
+            GetServerConnectionIdAsSender(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetServerConnectionIdIncludedAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(CONNECTION_ID_ABSENT, GetServerConnectionIdIncludedAsSender(
+                                      header, Perspective::IS_SERVER));
+  EXPECT_EQ(CONNECTION_ID_PRESENT, GetServerConnectionIdIncludedAsSender(
+                                       header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetClientConnectionIdIncludedAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(CONNECTION_ID_PRESENT, GetClientConnectionIdIncludedAsSender(
+                                       header, Perspective::IS_SERVER));
+  EXPECT_EQ(CONNECTION_ID_ABSENT, GetClientConnectionIdIncludedAsSender(
+                                      header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetClientConnectionIdAsRecipient) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(TestConnectionId(2),
+            GetClientConnectionIdAsRecipient(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(1),
+            GetClientConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetClientConnectionIdAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(TestConnectionId(1),
+            GetClientConnectionIdAsSender(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(2),
+            GetClientConnectionIdAsSender(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, CopySerializedPacket) {
+  std::string buffer(1000, 'a');
+  quiche::SimpleBufferAllocator allocator;
+  SerializedPacket packet(QuicPacketNumber(1), PACKET_1BYTE_PACKET_NUMBER,
+                          buffer.data(), buffer.length(), /*has_ack=*/false,
+                          /*has_stop_waiting=*/false);
+  packet.retransmittable_frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
+  packet.retransmittable_frames.push_back(QuicFrame(QuicStreamFrame()));
+
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  packet.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
+  packet.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+
+  std::unique_ptr<SerializedPacket> copy = absl::WrapUnique<SerializedPacket>(
+      CopySerializedPacket(packet, &allocator, /*copy_buffer=*/true));
+  EXPECT_EQ(quic::QuicPacketNumber(1), copy->packet_number);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, copy->packet_number_length);
+  ASSERT_EQ(2u, copy->retransmittable_frames.size());
+  EXPECT_EQ(WINDOW_UPDATE_FRAME, copy->retransmittable_frames[0].type);
+  EXPECT_EQ(STREAM_FRAME, copy->retransmittable_frames[1].type);
+
+  ASSERT_EQ(2u, copy->nonretransmittable_frames.size());
+  EXPECT_EQ(ACK_FRAME, copy->nonretransmittable_frames[0].type);
+  EXPECT_EQ(PADDING_FRAME, copy->nonretransmittable_frames[1].type);
+  EXPECT_EQ(1000u, copy->encrypted_length);
+  quiche::test::CompareCharArraysWithHexError(
+      "encrypted_buffer", copy->encrypted_buffer, copy->encrypted_length,
+      packet.encrypted_buffer, packet.encrypted_length);
+
+  std::unique_ptr<SerializedPacket> copy2 = absl::WrapUnique<SerializedPacket>(
+      CopySerializedPacket(packet, &allocator, /*copy_buffer=*/false));
+  EXPECT_EQ(packet.encrypted_buffer, copy2->encrypted_buffer);
+  EXPECT_EQ(1000u, copy2->encrypted_length);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_path_validator.cc b/quiche/quic/core/quic_path_validator.cc
new file mode 100644
index 0000000..279ac0f
--- /dev/null
+++ b/quiche/quic/core/quic_path_validator.cc
@@ -0,0 +1,148 @@
+// Copyright (c) 2020 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 "quiche/quic/core/quic_path_validator.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+class RetryAlarmDelegate : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit RetryAlarmDelegate(QuicPathValidator* path_validator,
+                              QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context),
+        path_validator_(path_validator) {}
+  RetryAlarmDelegate(const RetryAlarmDelegate&) = delete;
+  RetryAlarmDelegate& operator=(const RetryAlarmDelegate&) = delete;
+
+  void OnAlarm() override { path_validator_->OnRetryTimeout(); }
+
+ private:
+  QuicPathValidator* path_validator_;
+};
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicPathValidationContext& context) {
+  return os << " from " << context.self_address_ << " to "
+            << context.peer_address_;
+}
+
+QuicPathValidator::QuicPathValidator(QuicAlarmFactory* alarm_factory,
+                                     QuicConnectionArena* arena,
+                                     SendDelegate* send_delegate,
+                                     QuicRandom* random,
+                                     QuicConnectionContext* context)
+    : send_delegate_(send_delegate),
+      random_(random),
+      retry_timer_(alarm_factory->CreateAlarm(
+          arena->New<RetryAlarmDelegate>(this, context), arena)),
+      retry_count_(0u) {}
+
+void QuicPathValidator::OnPathResponse(const QuicPathFrameBuffer& probing_data,
+                                       QuicSocketAddress self_address) {
+  if (!HasPendingPathValidation()) {
+    return;
+  }
+
+  QUIC_DVLOG(1) << "Match PATH_RESPONSE received on " << self_address;
+  QUIC_BUG_IF(quic_bug_12402_1, !path_context_->self_address().IsInitialized())
+      << "Self address should have been known by now";
+  if (self_address != path_context_->self_address()) {
+    QUIC_DVLOG(1) << "Expect the response to be received on "
+                  << path_context_->self_address();
+    return;
+  }
+  // This iterates at most 3 times.
+  if (std::find(probing_data_.begin(), probing_data_.end(), probing_data) !=
+      probing_data_.end()) {
+    result_delegate_->OnPathValidationSuccess(std::move(path_context_));
+    ResetPathValidation();
+  } else {
+    QUIC_DVLOG(1) << "PATH_RESPONSE with payload " << probing_data.data()
+                  << " doesn't match the probing data.";
+  }
+}
+
+void QuicPathValidator::StartPathValidation(
+    std::unique_ptr<QuicPathValidationContext> context,
+    std::unique_ptr<ResultDelegate> result_delegate) {
+  QUICHE_DCHECK(context);
+  QUIC_DLOG(INFO) << "Start validating path " << *context
+                  << " via writer: " << context->WriterToUse();
+  if (path_context_ != nullptr) {
+    QUIC_BUG(quic_bug_10876_1)
+        << "There is an on-going validation on path " << *path_context_;
+    ResetPathValidation();
+  }
+
+  path_context_ = std::move(context);
+  result_delegate_ = std::move(result_delegate);
+  SendPathChallengeAndSetAlarm();
+}
+
+void QuicPathValidator::ResetPathValidation() {
+  path_context_ = nullptr;
+  result_delegate_ = nullptr;
+  retry_timer_->Cancel();
+  retry_count_ = 0;
+}
+
+void QuicPathValidator::CancelPathValidation() {
+  if (path_context_ == nullptr) {
+    return;
+  }
+  QUIC_DVLOG(1) << "Cancel validation on path" << *path_context_;
+  result_delegate_->OnPathValidationFailure(std::move(path_context_));
+  ResetPathValidation();
+}
+
+bool QuicPathValidator::HasPendingPathValidation() const {
+  return path_context_ != nullptr;
+}
+
+QuicPathValidationContext* QuicPathValidator::GetContext() const {
+  return path_context_.get();
+}
+
+const QuicPathFrameBuffer& QuicPathValidator::GeneratePathChallengePayload() {
+  probing_data_.push_back(QuicPathFrameBuffer());
+  random_->RandBytes(probing_data_.back().data(), sizeof(QuicPathFrameBuffer));
+  return probing_data_.back();
+}
+
+void QuicPathValidator::OnRetryTimeout() {
+  ++retry_count_;
+  if (retry_count_ > kMaxRetryTimes) {
+    CancelPathValidation();
+    return;
+  }
+  QUIC_DVLOG(1) << "Send another PATH_CHALLENGE on path " << *path_context_;
+  SendPathChallengeAndSetAlarm();
+}
+
+void QuicPathValidator::SendPathChallengeAndSetAlarm() {
+  bool should_continue = send_delegate_->SendPathChallenge(
+      GeneratePathChallengePayload(), path_context_->self_address(),
+      path_context_->peer_address(), path_context_->effective_peer_address(),
+      path_context_->WriterToUse());
+
+  if (!should_continue) {
+    // The delegate doesn't want to continue the path validation.
+    CancelPathValidation();
+    return;
+  }
+  retry_timer_->Set(send_delegate_->GetRetryTimeout(
+      path_context_->peer_address(), path_context_->WriterToUse()));
+}
+
+bool QuicPathValidator::IsValidatingPeerAddress(
+    const QuicSocketAddress& effective_peer_address) {
+  return path_context_ != nullptr &&
+         path_context_->effective_peer_address() == effective_peer_address;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_path_validator.h b/quiche/quic/core/quic_path_validator.h
new file mode 100644
index 0000000..5c9c85e
--- /dev/null
+++ b/quiche/quic/core/quic_path_validator.h
@@ -0,0 +1,160 @@
+// Copyright (c) 2020 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_PATH_VALIDATOR_H_
+#define QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
+
+#include <ostream>
+
+#include "absl/container/inlined_vector.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_arena_scoped_ptr.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+namespace test {
+class QuicPathValidatorPeer;
+}
+
+class QuicConnection;
+
+// Interface to provide the information of the path to be validated.
+class QUIC_EXPORT_PRIVATE QuicPathValidationContext {
+ public:
+  QuicPathValidationContext(const QuicSocketAddress& self_address,
+                            const QuicSocketAddress& peer_address)
+      : self_address_(self_address),
+        peer_address_(peer_address),
+        effective_peer_address_(peer_address) {}
+
+  QuicPathValidationContext(const QuicSocketAddress& self_address,
+                            const QuicSocketAddress& peer_address,
+                            const QuicSocketAddress& effective_peer_address)
+      : self_address_(self_address),
+        peer_address_(peer_address),
+        effective_peer_address_(effective_peer_address) {}
+
+  virtual ~QuicPathValidationContext() = default;
+
+  virtual QuicPacketWriter* WriterToUse() = 0;
+
+  const QuicSocketAddress& self_address() const { return self_address_; }
+  const QuicSocketAddress& peer_address() const { return peer_address_; }
+  const QuicSocketAddress& effective_peer_address() const {
+    return effective_peer_address_;
+  }
+
+ private:
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPathValidationContext& context);
+
+  QuicSocketAddress self_address_;
+  // The address to send PATH_CHALLENGE.
+  QuicSocketAddress peer_address_;
+  // The actual peer address which is different from |peer_address_| if the peer
+  // is behind a proxy.
+  QuicSocketAddress effective_peer_address_;
+};
+
+// Used to validate a path by sending up to 3 PATH_CHALLENGE frames before
+// declaring a path validation failure.
+class QUIC_EXPORT_PRIVATE QuicPathValidator {
+ public:
+  static const uint16_t kMaxRetryTimes = 2;
+
+  // Used to write PATH_CHALLENGE on the path to be validated and to get retry
+  // timeout.
+  class QUIC_EXPORT_PRIVATE SendDelegate {
+   public:
+    virtual ~SendDelegate() = default;
+
+    // Send a PATH_CHALLENGE with |data_buffer| as the frame payload using given
+    // path information. Return false if the delegate doesn't want to continue
+    // the validation.
+    virtual bool SendPathChallenge(
+        const QuicPathFrameBuffer& data_buffer,
+        const QuicSocketAddress& self_address,
+        const QuicSocketAddress& peer_address,
+        const QuicSocketAddress& effective_peer_address,
+        QuicPacketWriter* writer) = 0;
+    // Return the time to retry sending PATH_CHALLENGE again based on given peer
+    // address and writer.
+    virtual QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address,
+                                     QuicPacketWriter* writer) const = 0;
+  };
+
+  // Handles the validation result.
+  // TODO(danzh) consider to simplify this interface and its life time to
+  // outlive a validation.
+  class QUIC_EXPORT_PRIVATE ResultDelegate {
+   public:
+    virtual ~ResultDelegate() = default;
+
+    virtual void OnPathValidationSuccess(
+        std::unique_ptr<QuicPathValidationContext> context) = 0;
+
+    virtual void OnPathValidationFailure(
+        std::unique_ptr<QuicPathValidationContext> context) = 0;
+  };
+
+  QuicPathValidator(QuicAlarmFactory* alarm_factory, QuicConnectionArena* arena,
+                    SendDelegate* delegate, QuicRandom* random,
+                    QuicConnectionContext* context);
+
+  // Send PATH_CHALLENGE and start the retry timer.
+  void StartPathValidation(std::unique_ptr<QuicPathValidationContext> context,
+                           std::unique_ptr<ResultDelegate> result_delegate);
+
+  // Called when a PATH_RESPONSE frame has been received. Matches the received
+  // PATH_RESPONSE payload with the payloads previously sent in PATH_CHALLANGE
+  // frames and the self address on which it was sent.
+  void OnPathResponse(const QuicPathFrameBuffer& probing_data,
+                      QuicSocketAddress self_address);
+
+  // Cancel the retry timer and reset the path and result delegate.
+  void CancelPathValidation();
+
+  bool HasPendingPathValidation() const;
+
+  QuicPathValidationContext* GetContext() const;
+
+  // Send another PATH_CHALLENGE on the same path. After retrying
+  // |kMaxRetryTimes| times, fail the current path validation.
+  void OnRetryTimeout();
+
+  bool IsValidatingPeerAddress(const QuicSocketAddress& effective_peer_address);
+
+ private:
+  friend class test::QuicPathValidatorPeer;
+
+  // Return the payload to be used in the next PATH_CHALLENGE frame.
+  const QuicPathFrameBuffer& GeneratePathChallengePayload();
+
+  void SendPathChallengeAndSetAlarm();
+
+  void ResetPathValidation();
+
+  // Has at most 3 entries due to validation timeout.
+  absl::InlinedVector<QuicPathFrameBuffer, 3> probing_data_;
+  SendDelegate* send_delegate_;
+  QuicRandom* random_;
+  std::unique_ptr<QuicPathValidationContext> path_context_;
+  std::unique_ptr<ResultDelegate> result_delegate_;
+  QuicArenaScopedPtr<QuicAlarm> retry_timer_;
+  size_t retry_count_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
diff --git a/quiche/quic/core/quic_path_validator_test.cc b/quiche/quic/core/quic_path_validator_test.cc
new file mode 100644
index 0000000..a9e0da4
--- /dev/null
+++ b/quiche/quic/core/quic_path_validator_test.cc
@@ -0,0 +1,254 @@
+// Copyright (c) 2020 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 "quiche/quic/core/quic_path_validator.h"
+
+#include <memory>
+
+#include "quiche/quic/core/frames/quic_path_challenge_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_path_validator_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_transport_test_tools.h"
+
+using testing::_;
+using testing::Invoke;
+using testing::Return;
+
+namespace quic {
+namespace test {
+
+class MockSendDelegate : public QuicPathValidator::SendDelegate {
+ public:
+  // Send a PATH_CHALLENGE frame using given path information and populate
+  // |data_buffer| with the frame payload. Return true if the validator should
+  // move forward in validation, i.e. arm the retry timer.
+  MOCK_METHOD(bool,
+              SendPathChallenge,
+              (const QuicPathFrameBuffer&,
+               const QuicSocketAddress&,
+               const QuicSocketAddress&,
+               const QuicSocketAddress&,
+               QuicPacketWriter*),
+              (override));
+
+  MOCK_METHOD(QuicTime,
+              GetRetryTimeout,
+              (const QuicSocketAddress&, QuicPacketWriter*),
+              (const, override));
+};
+
+class QuicPathValidatorTest : public QuicTest {
+ public:
+  QuicPathValidatorTest()
+      : path_validator_(&alarm_factory_, &arena_, &send_delegate_, &random_,
+                        /*context=*/nullptr),
+        context_(new MockQuicPathValidationContext(
+            self_address_, peer_address_, effective_peer_address_, &writer_)),
+        result_delegate_(
+            new testing::StrictMock<MockQuicPathValidationResultDelegate>()) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+    ON_CALL(send_delegate_, GetRetryTimeout(_, _))
+        .WillByDefault(
+            Return(clock_.ApproximateNow() +
+                   3 * QuicTime::Delta::FromMilliseconds(kInitialRttMs)));
+  }
+
+ protected:
+  quic::test::MockAlarmFactory alarm_factory_;
+  MockSendDelegate send_delegate_;
+  MockRandom random_;
+  MockClock clock_;
+  QuicConnectionArena arena_;
+  QuicPathValidator path_validator_;
+  QuicSocketAddress self_address_{QuicIpAddress::Any4(), 443};
+  QuicSocketAddress peer_address_{QuicIpAddress::Loopback4(), 443};
+  QuicSocketAddress effective_peer_address_{QuicIpAddress::Loopback4(), 12345};
+  MockPacketWriter writer_;
+  MockQuicPathValidationContext* context_;
+  MockQuicPathValidationResultDelegate* result_delegate_;
+};
+
+TEST_F(QuicPathValidatorTest, PathValidationSuccessOnFirstRound) {
+  QuicPathFrameBuffer challenge_data;
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_));
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+  EXPECT_TRUE(path_validator_.HasPendingPathValidation());
+  EXPECT_TRUE(path_validator_.IsValidatingPeerAddress(effective_peer_address_));
+  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_))
+      .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
+        EXPECT_EQ(context.get(), context_);
+      }));
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
+}
+
+TEST_F(QuicPathValidatorTest, RespondWithDifferentSelfAddress) {
+  QuicPathFrameBuffer challenge_data;
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_));
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+
+  // Reception of a PATH_RESPONSE on a different self address should be ignored.
+  const QuicSocketAddress kAlternativeSelfAddress(QuicIpAddress::Any6(), 54321);
+  EXPECT_NE(kAlternativeSelfAddress, self_address_);
+  path_validator_.OnPathResponse(challenge_data, kAlternativeSelfAddress);
+
+  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_))
+      .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
+        EXPECT_EQ(context->self_address(), self_address_);
+      }));
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+}
+
+TEST_F(QuicPathValidatorTest, RespondAfter1stRetry) {
+  QuicPathFrameBuffer challenge_data;
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        // Store up the 1st PATH_CHALLANGE payload.
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        EXPECT_NE(payload, challenge_data);
+        return true;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
+      .Times(2u);
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  random_.ChangeValue();
+  alarm_factory_.FireAlarm(
+      QuicPathValidatorPeer::retry_timer(&path_validator_));
+
+  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_));
+  // Respond to the 1st PATH_CHALLENGE should complete the validation.
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
+}
+
+TEST_F(QuicPathValidatorTest, RespondToRetryChallenge) {
+  QuicPathFrameBuffer challenge_data;
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        EXPECT_NE(challenge_data, payload);
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
+      .Times(2u);
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  random_.ChangeValue();
+  alarm_factory_.FireAlarm(
+      QuicPathValidatorPeer::retry_timer(&path_validator_));
+
+  // Respond to the 2nd PATH_CHALLENGE should complete the validation.
+  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_));
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
+}
+
+TEST_F(QuicPathValidatorTest, ValidationTimeOut) {
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .Times(3u)
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
+      .Times(3u);
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+
+  QuicPathFrameBuffer challenge_data;
+  memset(challenge_data.data(), 'a', challenge_data.size());
+  // Reception of a PATH_RESPONSE with different payload should be ignored.
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+
+  // Retry 3 times. The 3rd time should fail the validation.
+  EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_))
+      .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
+        EXPECT_EQ(context_, context.get());
+      }));
+  for (size_t i = 0; i <= QuicPathValidator::kMaxRetryTimes; ++i) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+    alarm_factory_.FireAlarm(
+        QuicPathValidatorPeer::retry_timer(&path_validator_));
+  }
+}
+
+TEST_F(QuicPathValidatorTest, SendPathChallengeError) {
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           QuicPacketWriter*) {
+        // Abandon this validation in the call stack shouldn't cause crash and
+        // should cancel the alarm.
+        path_validator_.CancelPathValidation();
+        return false;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
+      .Times(0u);
+  EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_));
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
+  EXPECT_FALSE(QuicPathValidatorPeer::retry_timer(&path_validator_)->IsSet());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_process_packet_interface.h b/quiche/quic/core/quic_process_packet_interface.h
new file mode 100644
index 0000000..30bd071
--- /dev/null
+++ b/quiche/quic/core/quic_process_packet_interface.h
@@ -0,0 +1,24 @@
+// Copyright 2015 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_PROCESS_PACKET_INTERFACE_H_
+#define QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// A class to process each incoming packet.
+class QUIC_NO_EXPORT ProcessPacketInterface {
+ public:
+  virtual ~ProcessPacketInterface() {}
+  virtual void ProcessPacket(const QuicSocketAddress& self_address,
+                             const QuicSocketAddress& peer_address,
+                             const QuicReceivedPacket& packet) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
diff --git a/quiche/quic/core/quic_protocol_flags_list.h b/quiche/quic/core/quic_protocol_flags_list.h
new file mode 100644
index 0000000..42b6c9e
--- /dev/null
+++ b/quiche/quic/core/quic_protocol_flags_list.h
@@ -0,0 +1,293 @@
+// Copyright (c) 2020 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.
+
+// NOLINT(build/header_guard)
+// This file intentionally does not have header guards, it's intended to be
+// included multiple times, each time with a different definition of
+// QUIC_PROTOCOL_FLAG.
+
+#if defined(QUIC_PROTOCOL_FLAG)
+
+QUIC_PROTOCOL_FLAG(
+    bool,
+    quic_allow_chlo_buffering,
+    true,
+    "If true, allows packets to be buffered in anticipation of a "
+    "future CHLO, and allow CHLO packets to be buffered until next "
+    "iteration of the event loop.")
+
+QUIC_PROTOCOL_FLAG(bool,
+                   quic_disable_pacing_for_perf_tests,
+                   false,
+                   "If true, disable pacing in QUIC")
+
+// Note that single-packet CHLOs are only enforced for Google QUIC versions that
+// do not use CRYPTO frames. This currently means only Q043 and Q046. All other
+// versions of QUIC (both Google QUIC and IETF) allow multi-packet CHLOs
+// regardless of the value of this flag.
+QUIC_PROTOCOL_FLAG(bool, quic_enforce_single_packet_chlo, true,
+                   "If true, enforce that sent QUIC CHLOs fit in one packet. "
+                   "Only applies to Q043 and Q046.")
+
+// Currently, this number is quite conservative.  At a hypothetical 1000 qps,
+// this means that the longest time-wait list we should see is:
+//   200 seconds * 1000 qps = 200000.
+// Of course, there are usually many queries per QUIC connection, so we allow a
+// factor of 3 leeway.
+QUIC_PROTOCOL_FLAG(int64_t,
+                   quic_time_wait_list_max_connections,
+                   600000,
+                   "Maximum number of connections on the time-wait list.  "
+                   "A negative value implies no configured limit.")
+
+QUIC_PROTOCOL_FLAG(int64_t,
+                   quic_time_wait_list_seconds,
+                   200,
+                   "Time period for which a given connection_id should live in "
+                   "the time-wait state.")
+
+// This number is relatively conservative. For example, there are at most 1K
+// queued stateless resets, which consume 1K * 21B = 21KB.
+QUIC_PROTOCOL_FLAG(
+    uint64_t, quic_time_wait_list_max_pending_packets, 1024,
+    "Upper limit of pending packets in time wait list when writer is blocked.")
+
+// Stop sending a reset if the recorded number of addresses that server has
+// recently sent stateless reset to exceeds this limit.
+QUIC_PROTOCOL_FLAG(uint64_t, quic_max_recent_stateless_reset_addresses, 1024,
+                   "Max number of recorded recent reset addresses.")
+
+// After this timeout, recent reset addresses will be cleared.
+// FLAGS_quic_max_recent_stateless_reset_addresses * (1000ms /
+// FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms) is roughly the max
+// reset per second. For example, 1024 * (1000ms / 1000ms) = 1K reset per
+// second.
+QUIC_PROTOCOL_FLAG(
+    uint64_t, quic_recent_stateless_reset_addresses_lifetime_ms, 1000,
+    "Max time that a client address lives in recent reset addresses set.")
+
+QUIC_PROTOCOL_FLAG(double,
+                   quic_bbr_cwnd_gain,
+                   2.0f,
+                   "Congestion window gain for QUIC BBR during PROBE_BW phase.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_buffered_data_threshold,
+    8 * 1024,
+    "If buffered data in QUIC stream is less than this "
+    "threshold, buffers all provided data or asks upper layer for more data")
+
+QUIC_PROTOCOL_FLAG(
+    uint64_t,
+    quic_send_buffer_max_data_slice_size,
+    4 * 1024,
+    "Max size of data slice in bytes for QUIC stream send buffer.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_lumpy_pacing_size,
+    2,
+    "Number of packets that the pacing sender allows in bursts during "
+    "pacing. This flag is ignored if a flow's estimated bandwidth is "
+    "lower than 1200 kbps.")
+
+QUIC_PROTOCOL_FLAG(
+    double,
+    quic_lumpy_pacing_cwnd_fraction,
+    0.25f,
+    "Congestion window fraction that the pacing sender allows in bursts "
+    "during pacing.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t, quic_lumpy_pacing_min_bandwidth_kbps, 1200,
+    "The minimum estimated client bandwidth below which the pacing sender will "
+    "not allow bursts.")
+
+QUIC_PROTOCOL_FLAG(int32_t,
+                   quic_max_pace_time_into_future_ms,
+                   10,
+                   "Max time that QUIC can pace packets into the future in ms.")
+
+QUIC_PROTOCOL_FLAG(
+    double,
+    quic_pace_time_into_future_srtt_fraction,
+    0.125f,  // One-eighth smoothed RTT
+    "Smoothed RTT fraction that a connection can pace packets into the future.")
+
+QUIC_PROTOCOL_FLAG(bool,
+                   quic_export_write_path_stats_at_server,
+                   false,
+                   "If true, export detailed write path statistics at server.")
+
+QUIC_PROTOCOL_FLAG(bool,
+                   quic_disable_version_negotiation_grease_randomness,
+                   false,
+                   "If true, use predictable version negotiation versions.")
+
+QUIC_PROTOCOL_FLAG(bool,
+                   quic_enable_http3_grease_randomness,
+                   true,
+                   "If true, use random greased settings and frames.")
+
+QUIC_PROTOCOL_FLAG(
+    bool, quic_enable_chaos_protection, true,
+    "If true, use chaos protection to randomize client initials.")
+
+QUIC_PROTOCOL_FLAG(int64_t,
+                   quic_max_tracked_packet_count,
+                   10000,
+                   "Maximum number of tracked packets.")
+
+QUIC_PROTOCOL_FLAG(
+    bool,
+    quic_client_convert_http_header_name_to_lowercase,
+    true,
+    "If true, HTTP request header names sent from QuicSpdyClientBase(and "
+    "descendents) will be automatically converted to lower case.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_bbr2_default_probe_bw_base_duration_ms,
+    2000,
+    "The default minimum duration for BBRv2-native probes, in milliseconds.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_bbr2_default_probe_bw_max_rand_duration_ms,
+    1000,
+    "The default upper bound of the random amount of BBRv2-native "
+    "probes, in milliseconds.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_bbr2_default_probe_rtt_period_ms,
+    10000,
+    "The default period for entering PROBE_RTT, in milliseconds.")
+
+QUIC_PROTOCOL_FLAG(
+    double,
+    quic_bbr2_default_loss_threshold,
+    0.02,
+    "The default loss threshold for QUIC BBRv2, should be a value "
+    "between 0 and 1.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_bbr2_default_startup_full_loss_count,
+    8,
+    "The default minimum number of loss marking events to exit STARTUP.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_bbr2_default_probe_bw_full_loss_count,
+    2,
+    "The default minimum number of loss marking events to exit PROBE_UP phase.")
+
+QUIC_PROTOCOL_FLAG(
+    double,
+    quic_bbr2_default_inflight_hi_headroom,
+    0.15,
+    "The default fraction of unutilized headroom to try to leave in path "
+    "upon high loss.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_bbr2_default_initial_ack_height_filter_window,
+    10,
+    "The default initial value of the max ack height filter's window length.")
+
+QUIC_PROTOCOL_FLAG(
+    double,
+    quic_ack_aggregation_bandwidth_threshold,
+    1.0,
+    "If the bandwidth during ack aggregation is smaller than (estimated "
+    "bandwidth * this flag), consider the current aggregation completed "
+    "and starts a new one.")
+
+// TODO(b/153892665): Change the default value of
+// quic_anti_amplification_factor back to 3 when cert compression is
+// supported.
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_anti_amplification_factor,
+    5,
+    3,
+    "Anti-amplification factor. Before address validation, server will "
+    "send no more than factor times bytes received.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_max_buffered_crypto_bytes,
+    16 * 1024,  // 16 KB
+    "The maximum amount of CRYPTO frame data that can be buffered.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_max_aggressive_retransmittable_on_wire_ping_count,
+    5,
+    "Maximum number of consecutive pings that can be sent with the "
+    "aggressive initial retransmittable on the wire timeout if there is "
+    "no new stream data received. After this limit, the timeout will be "
+    "doubled each ping until it exceeds the default ping timeout.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_max_retransmittable_on_wire_ping_count,
+    1000,
+    "Maximum number of pings that can be sent with the retransmittable "
+    "on the wire timeout, over the lifetime of a connection. After this "
+    "limit, the timeout will be the default ping timeout.")
+
+QUIC_PROTOCOL_FLAG(int32_t,
+                   quic_max_congestion_window,
+                   2000,
+                   "The maximum congestion window in packets.")
+
+QUIC_PROTOCOL_FLAG(
+    int32_t,
+    quic_max_streams_window_divisor,
+    2,
+    "The divisor that controls how often MAX_STREAMS frame is sent.")
+
+QUIC_PROTOCOL_FLAG(
+    uint64_t,
+    quic_key_update_confidentiality_limit,
+    0,
+    "If non-zero and key update is allowed, the maximum number of "
+    "packets sent for each key phase before initiating a key update.")
+
+QUIC_PROTOCOL_FLAG(bool,
+                   quic_disable_client_tls_zero_rtt,
+                   false,
+                   "If true, QUIC client with TLS will not try 0-RTT.")
+
+QUIC_PROTOCOL_FLAG(bool,
+                   quic_disable_server_tls_resumption,
+                   false,
+                   "If true, QUIC server will disable TLS resumption by not "
+                   "issuing or processing session tickets.")
+
+QUIC_PROTOCOL_FLAG(bool,
+                   quic_defer_send_in_response,
+                   true,
+                   "If true, QUIC servers will defer sending in response to "
+                   "incoming packets by default.")
+
+QUIC_PROTOCOL_FLAG(
+    bool,
+    quic_header_size_limit_includes_overhead,
+    true,
+    "If true, QUIC QPACK decoder includes 32-bytes overheader per entry while "
+    "comparing request/response header size against its upper limit.")
+
+QUIC_PROTOCOL_FLAG(
+    bool,
+    quic_reject_retry_token_in_initial_packet,
+    false,
+    "If true, always reject retry_token received in INITIAL packets")
+
+QUIC_PROTOCOL_FLAG(bool, quic_use_lower_server_response_mtu_for_test, false,
+                   "If true, cap server response packet size at 1250.")
+#endif
diff --git a/quiche/quic/core/quic_received_packet_manager.cc b/quiche/quic/core/quic_received_packet_manager.cc
new file mode 100644
index 0000000..f8bcb13
--- /dev/null
+++ b/quiche/quic/core/quic_received_packet_manager.cc
@@ -0,0 +1,354 @@
+// Copyright 2013 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 "quiche/quic/core/quic_received_packet_manager.h"
+
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// The maximum number of packets to ack immediately after a missing packet for
+// fast retransmission to kick in at the sender.  This limit is created to
+// reduce the number of acks sent that have no benefit for fast retransmission.
+// Set to the number of nacks needed for fast retransmit plus one for protection
+// against an ack loss
+const size_t kMaxPacketsAfterNewMissing = 4;
+
+// One eighth RTT delay when doing ack decimation.
+const float kShortAckDecimationDelay = 0.125;
+}  // namespace
+
+QuicReceivedPacketManager::QuicReceivedPacketManager()
+    : QuicReceivedPacketManager(nullptr) {}
+
+QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
+    : ack_frame_updated_(false),
+      max_ack_ranges_(0),
+      time_largest_observed_(QuicTime::Zero()),
+      save_timestamps_(false),
+      save_timestamps_for_in_order_packets_(false),
+      stats_(stats),
+      num_retransmittable_packets_received_since_last_ack_sent_(0),
+      min_received_before_ack_decimation_(kMinReceivedBeforeAckDecimation),
+      ack_frequency_(kDefaultRetransmittablePacketsBeforeAck),
+      ack_decimation_delay_(kAckDecimationDelay),
+      unlimited_ack_decimation_(false),
+      one_immediate_ack_(false),
+      ignore_order_(false),
+      local_max_ack_delay_(
+          QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
+      ack_timeout_(QuicTime::Zero()),
+      time_of_previous_received_packet_(QuicTime::Zero()),
+      was_last_packet_missing_(false),
+      last_ack_frequency_frame_sequence_number_(-1) {}
+
+QuicReceivedPacketManager::~QuicReceivedPacketManager() {}
+
+void QuicReceivedPacketManager::SetFromConfig(const QuicConfig& config,
+                                              Perspective perspective) {
+  if (config.HasClientSentConnectionOption(kAKD3, perspective)) {
+    ack_decimation_delay_ = kShortAckDecimationDelay;
+  }
+  if (config.HasClientSentConnectionOption(kAKDU, perspective)) {
+    unlimited_ack_decimation_ = true;
+  }
+  if (config.HasClientSentConnectionOption(k1ACK, perspective)) {
+    one_immediate_ack_ = true;
+  }
+}
+
+void QuicReceivedPacketManager::RecordPacketReceived(
+    const QuicPacketHeader& header,
+    QuicTime receipt_time) {
+  const QuicPacketNumber packet_number = header.packet_number;
+  QUICHE_DCHECK(IsAwaitingPacket(packet_number))
+      << " packet_number:" << packet_number;
+  was_last_packet_missing_ = IsMissing(packet_number);
+  if (!ack_frame_updated_) {
+    ack_frame_.received_packet_times.clear();
+  }
+  ack_frame_updated_ = true;
+
+  // Whether |packet_number| is received out of order.
+  bool packet_reordered = false;
+  if (LargestAcked(ack_frame_).IsInitialized() &&
+      LargestAcked(ack_frame_) > packet_number) {
+    // Record how out of order stats.
+    packet_reordered = true;
+    ++stats_->packets_reordered;
+    stats_->max_sequence_reordering =
+        std::max(stats_->max_sequence_reordering,
+                 LargestAcked(ack_frame_) - packet_number);
+    int64_t reordering_time_us =
+        (receipt_time - time_largest_observed_).ToMicroseconds();
+    stats_->max_time_reordering_us =
+        std::max(stats_->max_time_reordering_us, reordering_time_us);
+  }
+  if (!LargestAcked(ack_frame_).IsInitialized() ||
+      packet_number > LargestAcked(ack_frame_)) {
+    ack_frame_.largest_acked = packet_number;
+    time_largest_observed_ = receipt_time;
+  }
+  ack_frame_.packets.Add(packet_number);
+
+  if (save_timestamps_) {
+    // The timestamp format only handles packets in time order.
+    if (save_timestamps_for_in_order_packets_ && packet_reordered) {
+      QUIC_DLOG(WARNING) << "Not saving receive timestamp for packet "
+                         << packet_number;
+    } else if (!ack_frame_.received_packet_times.empty() &&
+               ack_frame_.received_packet_times.back().second > receipt_time) {
+      QUIC_LOG(WARNING)
+          << "Receive time went backwards from: "
+          << ack_frame_.received_packet_times.back().second.ToDebuggingValue()
+          << " to " << receipt_time.ToDebuggingValue();
+    } else {
+      ack_frame_.received_packet_times.push_back(
+          std::make_pair(packet_number, receipt_time));
+    }
+  }
+
+  if (least_received_packet_number_.IsInitialized()) {
+    least_received_packet_number_ =
+        std::min(least_received_packet_number_, packet_number);
+  } else {
+    least_received_packet_number_ = packet_number;
+  }
+}
+
+bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) {
+  return LargestAcked(ack_frame_).IsInitialized() &&
+         packet_number < LargestAcked(ack_frame_) &&
+         !ack_frame_.packets.Contains(packet_number);
+}
+
+bool QuicReceivedPacketManager::IsAwaitingPacket(
+    QuicPacketNumber packet_number) const {
+  return quic::IsAwaitingPacket(ack_frame_, packet_number,
+                                peer_least_packet_awaiting_ack_);
+}
+
+const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame(
+    QuicTime approximate_now) {
+  if (time_largest_observed_ == QuicTime::Zero()) {
+    // We have received no packets.
+    ack_frame_.ack_delay_time = QuicTime::Delta::Infinite();
+  } else {
+    // Ensure the delta is zero if approximate now is "in the past".
+    ack_frame_.ack_delay_time = approximate_now < time_largest_observed_
+                                    ? QuicTime::Delta::Zero()
+                                    : approximate_now - time_largest_observed_;
+  }
+  while (max_ack_ranges_ > 0 &&
+         ack_frame_.packets.NumIntervals() > max_ack_ranges_) {
+    ack_frame_.packets.RemoveSmallestInterval();
+  }
+  // Clear all packet times if any are too far from largest observed.
+  // It's expected this is extremely rare.
+  for (auto it = ack_frame_.received_packet_times.begin();
+       it != ack_frame_.received_packet_times.end();) {
+    if (LargestAcked(ack_frame_) - it->first >=
+        std::numeric_limits<uint8_t>::max()) {
+      it = ack_frame_.received_packet_times.erase(it);
+    } else {
+      ++it;
+    }
+  }
+
+#if QUIC_FRAME_DEBUG
+  QuicFrame frame = QuicFrame(&ack_frame_);
+  frame.delete_forbidden = true;
+  return frame;
+#else  // QUIC_FRAME_DEBUG
+  return QuicFrame(&ack_frame_);
+#endif  // QUIC_FRAME_DEBUG
+}
+
+void QuicReceivedPacketManager::DontWaitForPacketsBefore(
+    QuicPacketNumber least_unacked) {
+  if (!least_unacked.IsInitialized()) {
+    return;
+  }
+  // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks.
+  QUICHE_DCHECK(!peer_least_packet_awaiting_ack_.IsInitialized() ||
+                peer_least_packet_awaiting_ack_ <= least_unacked);
+  if (!peer_least_packet_awaiting_ack_.IsInitialized() ||
+      least_unacked > peer_least_packet_awaiting_ack_) {
+    peer_least_packet_awaiting_ack_ = least_unacked;
+    bool packets_updated = ack_frame_.packets.RemoveUpTo(least_unacked);
+    if (packets_updated) {
+      // Ack frame gets updated because packets set is updated because of stop
+      // waiting frame.
+      ack_frame_updated_ = true;
+    }
+  }
+  QUICHE_DCHECK(ack_frame_.packets.Empty() ||
+                !peer_least_packet_awaiting_ack_.IsInitialized() ||
+                ack_frame_.packets.Min() >= peer_least_packet_awaiting_ack_);
+}
+
+QuicTime::Delta QuicReceivedPacketManager::GetMaxAckDelay(
+    QuicPacketNumber last_received_packet_number,
+    const RttStats& rtt_stats) const {
+  if (AckFrequencyFrameReceived() ||
+      last_received_packet_number < PeerFirstSendingPacketNumber() +
+                                        min_received_before_ack_decimation_) {
+    return local_max_ack_delay_;
+  }
+
+  // Wait for the minimum of the ack decimation delay or the delayed ack time
+  // before sending an ack.
+  QuicTime::Delta ack_delay = std::min(
+      local_max_ack_delay_, rtt_stats.min_rtt() * ack_decimation_delay_);
+  return std::max(ack_delay, kAlarmGranularity);
+}
+
+void QuicReceivedPacketManager::MaybeUpdateAckFrequency(
+    QuicPacketNumber last_received_packet_number) {
+  if (AckFrequencyFrameReceived()) {
+    // Skip Ack Decimation below after receiving an AckFrequencyFrame from the
+    // other end point.
+    return;
+  }
+  if (last_received_packet_number <
+      PeerFirstSendingPacketNumber() + min_received_before_ack_decimation_) {
+    return;
+  }
+  ack_frequency_ = unlimited_ack_decimation_
+                       ? std::numeric_limits<size_t>::max()
+                       : kMaxRetransmittablePacketsBeforeAck;
+}
+
+void QuicReceivedPacketManager::MaybeUpdateAckTimeout(
+    bool should_last_packet_instigate_acks,
+    QuicPacketNumber last_received_packet_number,
+    QuicTime last_packet_receipt_time, QuicTime now,
+    const RttStats* rtt_stats) {
+  if (!ack_frame_updated_) {
+    // ACK frame has not been updated, nothing to do.
+    return;
+  }
+
+  if (!ignore_order_ && was_last_packet_missing_ &&
+      last_sent_largest_acked_.IsInitialized() &&
+      last_received_packet_number < last_sent_largest_acked_) {
+    // Only ack immediately if an ACK frame was sent with a larger largest acked
+    // than the newly received packet number.
+    ack_timeout_ = now;
+    return;
+  }
+
+  if (!should_last_packet_instigate_acks) {
+    return;
+  }
+
+  ++num_retransmittable_packets_received_since_last_ack_sent_;
+
+  MaybeUpdateAckFrequency(last_received_packet_number);
+  if (num_retransmittable_packets_received_since_last_ack_sent_ >=
+      ack_frequency_) {
+    ack_timeout_ = now;
+    return;
+  }
+
+  if (!ignore_order_ && HasNewMissingPackets()) {
+    ack_timeout_ = now;
+    return;
+  }
+
+  QuicTime ack_timeout_base = now;
+  const bool quic_update_ack_timeout_on_receipt_time =
+      GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time);
+  if (quic_update_ack_timeout_on_receipt_time) {
+    if (last_packet_receipt_time <= now) {
+      QUIC_CODE_COUNT(quic_update_ack_timeout_on_receipt_time);
+      ack_timeout_base = last_packet_receipt_time;
+    } else {
+      QUIC_CODE_COUNT(quic_update_ack_timeout_on_now);
+      ack_timeout_base = now;
+    }
+  }
+  QuicTime updated_ack_time =
+      ack_timeout_base +
+      GetMaxAckDelay(last_received_packet_number, *rtt_stats);
+  if (quic_update_ack_timeout_on_receipt_time) {
+    updated_ack_time = std::max(now, updated_ack_time);
+  }
+  if (!ack_timeout_.IsInitialized() || ack_timeout_ > updated_ack_time) {
+    ack_timeout_ = updated_ack_time;
+  }
+}
+
+void QuicReceivedPacketManager::ResetAckStates() {
+  ack_frame_updated_ = false;
+  ack_timeout_ = QuicTime::Zero();
+  num_retransmittable_packets_received_since_last_ack_sent_ = 0;
+  last_sent_largest_acked_ = LargestAcked(ack_frame_);
+}
+
+bool QuicReceivedPacketManager::HasMissingPackets() const {
+  if (ack_frame_.packets.Empty()) {
+    return false;
+  }
+  if (ack_frame_.packets.NumIntervals() > 1) {
+    return true;
+  }
+  return peer_least_packet_awaiting_ack_.IsInitialized() &&
+         ack_frame_.packets.Min() > peer_least_packet_awaiting_ack_;
+}
+
+bool QuicReceivedPacketManager::HasNewMissingPackets() const {
+  if (one_immediate_ack_) {
+    return HasMissingPackets() && ack_frame_.packets.LastIntervalLength() == 1;
+  }
+  return HasMissingPackets() &&
+         ack_frame_.packets.LastIntervalLength() <= kMaxPacketsAfterNewMissing;
+}
+
+bool QuicReceivedPacketManager::ack_frame_updated() const {
+  return ack_frame_updated_;
+}
+
+QuicPacketNumber QuicReceivedPacketManager::GetLargestObserved() const {
+  return LargestAcked(ack_frame_);
+}
+
+QuicPacketNumber QuicReceivedPacketManager::PeerFirstSendingPacketNumber()
+    const {
+  if (!least_received_packet_number_.IsInitialized()) {
+    QUIC_BUG(quic_bug_10849_1) << "No packets have been received yet";
+    return QuicPacketNumber(1);
+  }
+  return least_received_packet_number_;
+}
+
+bool QuicReceivedPacketManager::IsAckFrameEmpty() const {
+  return ack_frame_.packets.Empty();
+}
+
+void QuicReceivedPacketManager::OnAckFrequencyFrame(
+    const QuicAckFrequencyFrame& frame) {
+  int64_t new_sequence_number = frame.sequence_number;
+  if (new_sequence_number <= last_ack_frequency_frame_sequence_number_) {
+    // Ignore old ACK_FREQUENCY frames.
+    return;
+  }
+  last_ack_frequency_frame_sequence_number_ = new_sequence_number;
+  ack_frequency_ = frame.packet_tolerance;
+  local_max_ack_delay_ = frame.max_ack_delay;
+  ignore_order_ = frame.ignore_order;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_received_packet_manager.h b/quiche/quic/core/quic_received_packet_manager.h
new file mode 100644
index 0000000..cf08f22
--- /dev/null
+++ b/quiche/quic/core/quic_received_packet_manager.h
@@ -0,0 +1,218 @@
+// Copyright 2013 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_RECEIVED_PACKET_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
+
+#include <cstddef>
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class RttStats;
+
+namespace test {
+class QuicConnectionPeer;
+class QuicReceivedPacketManagerPeer;
+class UberReceivedPacketManagerPeer;
+}  // namespace test
+
+struct QuicConnectionStats;
+
+// Records all received packets by a connection.
+class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager {
+ public:
+  QuicReceivedPacketManager();
+  explicit QuicReceivedPacketManager(QuicConnectionStats* stats);
+  QuicReceivedPacketManager(const QuicReceivedPacketManager&) = delete;
+  QuicReceivedPacketManager& operator=(const QuicReceivedPacketManager&) =
+      delete;
+  virtual ~QuicReceivedPacketManager();
+
+  void SetFromConfig(const QuicConfig& config, Perspective perspective);
+
+  // Updates the internal state concerning which packets have been received.
+  // header: the packet header.
+  // timestamp: the arrival time of the packet.
+  virtual void RecordPacketReceived(const QuicPacketHeader& header,
+                                    QuicTime receipt_time);
+
+  // Checks whether |packet_number| is missing and less than largest observed.
+  virtual bool IsMissing(QuicPacketNumber packet_number);
+
+  // Checks if we're still waiting for the packet with |packet_number|.
+  virtual bool IsAwaitingPacket(QuicPacketNumber packet_number) const;
+
+  // Retrieves a frame containing a QuicAckFrame.  The ack frame may not be
+  // changed outside QuicReceivedPacketManager and must be serialized before
+  // another packet is received, or it will change.
+  const QuicFrame GetUpdatedAckFrame(QuicTime approximate_now);
+
+  // Deletes all missing packets before least unacked. The connection won't
+  // process any packets with packet number before |least_unacked| that it
+  // received after this call.
+  void DontWaitForPacketsBefore(QuicPacketNumber least_unacked);
+
+  // Called to update ack_timeout_ to the time when an ACK needs to be sent. A
+  // caller can decide whether and when to send an ACK by retrieving
+  // ack_timeout_. If ack_timeout_ is not initialized, no ACK needs to be sent.
+  // Otherwise, ACK needs to be sent by the specified time.
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             QuicPacketNumber last_received_packet_number,
+                             QuicTime last_packet_receipt_time, QuicTime now,
+                             const RttStats* rtt_stats);
+
+  // Resets ACK related states, called after an ACK is successfully sent.
+  void ResetAckStates();
+
+  // Returns true if there are any missing packets.
+  bool HasMissingPackets() const;
+
+  // Returns true when there are new missing packets to be reported within 3
+  // packets of the largest observed.
+  virtual bool HasNewMissingPackets() const;
+
+  QuicPacketNumber peer_least_packet_awaiting_ack() const {
+    return peer_least_packet_awaiting_ack_;
+  }
+
+  virtual bool ack_frame_updated() const;
+
+  QuicPacketNumber GetLargestObserved() const;
+
+  // Returns peer first sending packet number to our best knowledge. Considers
+  // least_received_packet_number_ as peer first sending packet number. Please
+  // note, this function should only be called when at least one packet has been
+  // received.
+  QuicPacketNumber PeerFirstSendingPacketNumber() const;
+
+  // Returns true if ack frame is empty.
+  bool IsAckFrameEmpty() const;
+
+  void set_connection_stats(QuicConnectionStats* stats) { stats_ = stats; }
+
+  // For logging purposes.
+  const QuicAckFrame& ack_frame() const { return ack_frame_; }
+
+  void set_max_ack_ranges(size_t max_ack_ranges) {
+    max_ack_ranges_ = max_ack_ranges;
+  }
+
+  void set_save_timestamps(bool save_timestamps, bool in_order_packets_only) {
+    save_timestamps_ = save_timestamps;
+    save_timestamps_for_in_order_packets_ = in_order_packets_only;
+  }
+
+  size_t min_received_before_ack_decimation() const {
+    return min_received_before_ack_decimation_;
+  }
+  void set_min_received_before_ack_decimation(size_t new_value) {
+    min_received_before_ack_decimation_ = new_value;
+  }
+
+  void set_ack_frequency(size_t new_value) {
+    QUICHE_DCHECK_GT(new_value, 0u);
+    ack_frequency_ = new_value;
+  }
+
+  void set_local_max_ack_delay(QuicTime::Delta local_max_ack_delay) {
+    local_max_ack_delay_ = local_max_ack_delay;
+  }
+
+  QuicTime ack_timeout() const { return ack_timeout_; }
+
+  void OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame);
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::QuicReceivedPacketManagerPeer;
+  friend class test::UberReceivedPacketManagerPeer;
+
+  // Sets ack_timeout_ to |time| if ack_timeout_ is not initialized or > time.
+  void MaybeUpdateAckTimeoutTo(QuicTime time);
+
+  // Maybe update ack_frequency_ when condition meets.
+  void MaybeUpdateAckFrequency(QuicPacketNumber last_received_packet_number);
+
+  QuicTime::Delta GetMaxAckDelay(QuicPacketNumber last_received_packet_number,
+                                 const RttStats& rtt_stats) const;
+
+  bool AckFrequencyFrameReceived() const {
+    return last_ack_frequency_frame_sequence_number_ >= 0;
+  }
+
+  // Least packet number of the the packet sent by the peer for which it
+  // hasn't received an ack.
+  QuicPacketNumber peer_least_packet_awaiting_ack_;
+
+  // Received packet information used to produce acks.
+  QuicAckFrame ack_frame_;
+
+  // True if |ack_frame_| has been updated since UpdateReceivedPacketInfo was
+  // last called.
+  bool ack_frame_updated_;
+
+  // Maximum number of ack ranges allowed to be stored in the ack frame.
+  size_t max_ack_ranges_;
+
+  // The time we received the largest_observed packet number, or zero if
+  // no packet numbers have been received since UpdateReceivedPacketInfo.
+  // Needed for calculating ack_delay_time.
+  QuicTime time_largest_observed_;
+
+  // If true, save timestamps in the ack_frame_.
+  bool save_timestamps_;
+
+  // If true and |save_timestamps_|, only save timestamps for packets that are
+  // received in order.
+  bool save_timestamps_for_in_order_packets_;
+
+  // Least packet number received from peer.
+  QuicPacketNumber least_received_packet_number_;
+
+  QuicConnectionStats* stats_;
+
+  // How many retransmittable packets have arrived without sending an ack.
+  QuicPacketCount num_retransmittable_packets_received_since_last_ack_sent_;
+  // Ack decimation will start happening after this many packets are received.
+  size_t min_received_before_ack_decimation_;
+  // Ack every n-th packet.
+  size_t ack_frequency_;
+  // The max delay in fraction of min_rtt to use when sending decimated acks.
+  float ack_decimation_delay_;
+  // When true, removes ack decimation's max number of packets(10) before
+  // sending an ack.
+  bool unlimited_ack_decimation_;
+  // When true, only send 1 immediate ACK when reordering is detected.
+  bool one_immediate_ack_;
+  // When true, do not ack immediately upon observation of packet reordering.
+  bool ignore_order_;
+
+  // The local node's maximum ack delay time. This is the maximum amount of
+  // time to wait before sending an acknowledgement.
+  QuicTime::Delta local_max_ack_delay_;
+  // Time that an ACK needs to be sent. 0 means no ACK is pending. Used when
+  // decide_when_to_send_acks_ is true.
+  QuicTime ack_timeout_;
+
+  // The time the previous ack-instigating packet was received and processed.
+  QuicTime time_of_previous_received_packet_;
+  // Whether the most recent packet was missing before it was received.
+  bool was_last_packet_missing_;
+
+  // Last sent largest acked, which gets updated when ACK was successfully sent.
+  QuicPacketNumber last_sent_largest_acked_;
+
+  // The sequence number of the last received AckFrequencyFrame. Negative if
+  // none received.
+  int64_t last_ack_frequency_frame_sequence_number_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
diff --git a/quiche/quic/core/quic_received_packet_manager_test.cc b/quiche/quic/core/quic_received_packet_manager_test.cc
new file mode 100644
index 0000000..65cfa86
--- /dev/null
+++ b/quiche/quic/core/quic_received_packet_manager_test.cc
@@ -0,0 +1,691 @@
+// Copyright 2013 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 "quiche/quic/core/quic_received_packet_manager.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <ostream>
+#include <vector>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class QuicReceivedPacketManagerPeer {
+ public:
+  static void SetOneImmediateAck(QuicReceivedPacketManager* manager,
+                                 bool one_immediate_ack) {
+    manager->one_immediate_ack_ = one_immediate_ack;
+  }
+
+  static void SetAckDecimationDelay(QuicReceivedPacketManager* manager,
+                                    float ack_decimation_delay) {
+    manager->ack_decimation_delay_ = ack_decimation_delay;
+  }
+};
+
+namespace {
+
+const bool kInstigateAck = true;
+const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
+const QuicTime::Delta kDelayedAckTime =
+    QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+class QuicReceivedPacketManagerTest : public QuicTest {
+ protected:
+  QuicReceivedPacketManagerTest() : received_manager_(&stats_) {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    rtt_stats_.UpdateRtt(kMinRttMs, QuicTime::Delta::Zero(), QuicTime::Zero());
+    received_manager_.set_save_timestamps(true, false);
+  }
+
+  void RecordPacketReceipt(uint64_t packet_number) {
+    RecordPacketReceipt(packet_number, QuicTime::Zero());
+  }
+
+  void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
+    QuicPacketHeader header;
+    header.packet_number = QuicPacketNumber(packet_number);
+    received_manager_.RecordPacketReceived(header, receipt_time);
+  }
+
+  bool HasPendingAck() {
+    return received_manager_.ack_timeout().IsInitialized();
+  }
+
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             uint64_t last_received_packet_number) {
+    received_manager_.MaybeUpdateAckTimeout(
+        should_last_packet_instigate_acks,
+        QuicPacketNumber(last_received_packet_number),
+        /*last_packet_receipt_time=*/clock_.ApproximateNow(),
+        /*now=*/clock_.ApproximateNow(), &rtt_stats_);
+  }
+
+  void CheckAckTimeout(QuicTime time) {
+    QUICHE_DCHECK(HasPendingAck());
+    QUICHE_DCHECK_EQ(received_manager_.ack_timeout(), time);
+    if (time <= clock_.ApproximateNow()) {
+      // ACK timeout expires, send an ACK.
+      received_manager_.ResetAckStates();
+      QUICHE_DCHECK(!HasPendingAck());
+    }
+  }
+
+  MockClock clock_;
+  RttStats rtt_stats_;
+  QuicConnectionStats stats_;
+  QuicReceivedPacketManager received_manager_;
+};
+
+TEST_F(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) {
+  QuicPacketHeader header;
+  header.packet_number = QuicPacketNumber(2u);
+  received_manager_.RecordPacketReceived(header, QuicTime::Zero());
+  header.packet_number = QuicPacketNumber(7u);
+  received_manager_.RecordPacketReceived(header, QuicTime::Zero());
+  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
+  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
+  received_manager_.DontWaitForPacketsBefore(QuicPacketNumber(4));
+  EXPECT_FALSE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
+  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
+}
+
+TEST_F(QuicReceivedPacketManagerTest, GetUpdatedAckFrame) {
+  QuicPacketHeader header;
+  header.packet_number = QuicPacketNumber(2u);
+  QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  received_manager_.RecordPacketReceived(header, two_ms);
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+
+  QuicFrame ack = received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
+  received_manager_.ResetAckStates();
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  // When UpdateReceivedPacketInfo with a time earlier than the time of the
+  // largest observed packet, make sure that the delta is 0, not negative.
+  EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
+  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
+
+  QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
+  ack = received_manager_.GetUpdatedAckFrame(four_ms);
+  received_manager_.ResetAckStates();
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  // When UpdateReceivedPacketInfo after not having received a new packet,
+  // the delta should still be accurate.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
+            ack.ack_frame->ack_delay_time);
+  // And received packet times won't have change.
+  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
+
+  header.packet_number = QuicPacketNumber(999u);
+  received_manager_.RecordPacketReceived(header, two_ms);
+  header.packet_number = QuicPacketNumber(4u);
+  received_manager_.RecordPacketReceived(header, two_ms);
+  header.packet_number = QuicPacketNumber(1000u);
+  received_manager_.RecordPacketReceived(header, two_ms);
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+  ack = received_manager_.GetUpdatedAckFrame(two_ms);
+  received_manager_.ResetAckStates();
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  // UpdateReceivedPacketInfo should discard any times which can't be
+  // expressed on the wire.
+  EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  RecordPacketReceipt(1);
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+  RecordPacketReceipt(6);
+  RecordPacketReceipt(2,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+
+  EXPECT_EQ(4u, stats_.max_sequence_reordering);
+  EXPECT_EQ(1000, stats_.max_time_reordering_us);
+  EXPECT_EQ(1u, stats_.packets_reordered);
+}
+
+TEST_F(QuicReceivedPacketManagerTest, LimitAckRanges) {
+  received_manager_.set_max_ack_ranges(10);
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  for (int i = 0; i < 100; ++i) {
+    RecordPacketReceipt(1 + 2 * i);
+    EXPECT_TRUE(received_manager_.ack_frame_updated());
+    received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
+    EXPECT_GE(10u, received_manager_.ack_frame().packets.NumIntervals());
+    EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
+              received_manager_.ack_frame().packets.Max());
+    for (int j = 0; j < std::min(10, i + 1); ++j) {
+      ASSERT_GE(i, j);
+      EXPECT_TRUE(received_manager_.ack_frame().packets.Contains(
+          QuicPacketNumber(1 + (i - j) * 2)));
+      if (i > j) {
+        EXPECT_FALSE(received_manager_.ack_frame().packets.Contains(
+            QuicPacketNumber((i - j) * 2)));
+      }
+    }
+  }
+}
+
+TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  RecordPacketReceipt(1, QuicTime::Zero());
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+  EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
+  RecordPacketReceipt(2,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+  RecordPacketReceipt(3, QuicTime::Zero());
+  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderPackets) {
+  received_manager_.set_save_timestamps(true, true);
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  RecordPacketReceipt(1, QuicTime::Zero());
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+  EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
+  RecordPacketReceipt(4,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+
+  RecordPacketReceipt(3,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(3));
+  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, HasMissingPackets) {
+  EXPECT_QUIC_BUG(received_manager_.PeerFirstSendingPacketNumber(),
+                  "No packets have been received yet");
+  RecordPacketReceipt(4, QuicTime::Zero());
+  EXPECT_EQ(QuicPacketNumber(4),
+            received_manager_.PeerFirstSendingPacketNumber());
+  EXPECT_FALSE(received_manager_.HasMissingPackets());
+  RecordPacketReceipt(3, QuicTime::Zero());
+  EXPECT_FALSE(received_manager_.HasMissingPackets());
+  EXPECT_EQ(QuicPacketNumber(3),
+            received_manager_.PeerFirstSendingPacketNumber());
+  RecordPacketReceipt(1, QuicTime::Zero());
+  EXPECT_EQ(QuicPacketNumber(1),
+            received_manager_.PeerFirstSendingPacketNumber());
+  EXPECT_TRUE(received_manager_.HasMissingPackets());
+  RecordPacketReceipt(2, QuicTime::Zero());
+  EXPECT_EQ(QuicPacketNumber(1),
+            received_manager_.PeerFirstSendingPacketNumber());
+  EXPECT_FALSE(received_manager_.HasMissingPackets());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 5);
+  // Immediate ack is sent.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(6, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 6);
+  // Immediate ack is scheduled, because 4 is still missing.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  // Should ack immediately, since this fills the last hole.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(7, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 7);
+  // Immediate ack is scheduled, because 4 is still missing.
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent1Ack) {
+  QuicReceivedPacketManagerPeer::SetOneImmediateAck(&received_manager_, true);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 5);
+  // Immediate ack is sent.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(6, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 6);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  // Should ack immediately, since this fills the last hole.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(7, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 7);
+  // Delayed ack is scheduled, even though 4 is still missing.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+}
+
+TEST_F(QuicReceivedPacketManagerTest, OutOfOrderAckReceiptCausesNoAck) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 2);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 1);
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, AckReceiptCausesAckSend) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 1);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 2);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  clock_.AdvanceTime(kDelayedAckTime);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 4);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 5);
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, AckSentEveryNthPacket) {
+  EXPECT_FALSE(HasPendingAck());
+  received_manager_.set_ack_frequency(3);
+
+  // Receives packets 1 - 39.
+  for (size_t i = 1; i <= 39; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 3 == 0) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+}
+
+TEST_F(QuicReceivedPacketManagerTest, AckDecimationReducesAcks) {
+  EXPECT_FALSE(HasPendingAck());
+
+  // Start ack decimation from 10th packet.
+  received_manager_.set_min_received_before_ack_decimation(10);
+
+  // Receives packets 1 - 29.
+  for (size_t i = 1; i <= 29; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i <= 10) {
+      // For packets 1-10, ack every 2 packets.
+      if (i % 2 == 0) {
+        CheckAckTimeout(clock_.ApproximateNow());
+      } else {
+        CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+      }
+      continue;
+    }
+    // ack at 20.
+    if (i == 20) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kMinRttMs * 0.25);
+    }
+  }
+
+  // We now receive the 30th packet, and so we send an ack.
+  RecordPacketReceipt(30, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 30);
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimation) {
+  EXPECT_FALSE(HasPendingAck());
+  // The ack time should be based on min_rtt * 1/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimationMin1ms) {
+  EXPECT_FALSE(HasPendingAck());
+  // Seed the min_rtt with a kAlarmGranularity signal.
+  rtt_stats_.UpdateRtt(kAlarmGranularity, QuicTime::Delta::Zero(),
+                       clock_.ApproximateNow());
+  // The ack time should be based on kAlarmGranularity, since the RTT is 1ms.
+  QuicTime ack_time = clock_.ApproximateNow() + kAlarmGranularity;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       SendDelayedAckDecimationUnlimitedAggregation) {
+  EXPECT_FALSE(HasPendingAck());
+  QuicConfig config;
+  QuicTagVector connection_options;
+  // No limit on the number of packets received before sending an ack.
+  connection_options.push_back(kAKDU);
+  config.SetConnectionOptionsToSend(connection_options);
+  received_manager_.SetFromConfig(config, Perspective::IS_CLIENT);
+
+  // The ack time should be based on min_rtt/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // 18 packets will not cause an ack to be sent.  19 will because when
+  // stop waiting frames are in use, we ack every 20 packets no matter what.
+  for (int i = 1; i <= 18; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(ack_time);
+}
+
+TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimationEighthRtt) {
+  EXPECT_FALSE(HasPendingAck());
+  QuicReceivedPacketManagerPeer::SetAckDecimationDelay(&received_manager_,
+                                                       0.125);
+
+  // The ack time should be based on min_rtt/8, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.125;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       UpdateMaxAckDelayAndAckFrequencyFromAckFrequencyFrame) {
+  EXPECT_FALSE(HasPendingAck());
+
+  QuicAckFrequencyFrame frame;
+  frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(10);
+  frame.packet_tolerance = 5;
+  received_manager_.OnAckFrequencyFrame(frame);
+
+  for (int i = 1; i <= 50; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % frame.packet_tolerance == 0) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + frame.max_ack_delay);
+    }
+  }
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       DisableOutOfOrderAckByIgnoreOrderFromAckFrequencyFrame) {
+  EXPECT_FALSE(HasPendingAck());
+
+  QuicAckFrequencyFrame frame;
+  frame.max_ack_delay = kDelayedAckTime;
+  frame.packet_tolerance = 2;
+  frame.ignore_order = true;
+  received_manager_.OnAckFrequencyFrame(frame);
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 4);
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 5);
+  // Immediate ack is sent as this is the 2nd packet of every two packets.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Don't ack as ignore_order is set by AckFrequencyFrame.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  // Immediate ack is sent as this is the 2nd packet of every two packets.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  // Don't ack as ignore_order is set by AckFrequencyFrame.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       DisableMissingPaketsAckByIgnoreOrderFromAckFrequencyFrame) {
+  EXPECT_FALSE(HasPendingAck());
+  QuicConfig config;
+  config.SetConnectionOptionsToSend({kAFFE});
+  received_manager_.SetFromConfig(config, Perspective::IS_CLIENT);
+
+  QuicAckFrequencyFrame frame;
+  frame.max_ack_delay = kDelayedAckTime;
+  frame.packet_tolerance = 2;
+  frame.ignore_order = true;
+  received_manager_.OnAckFrequencyFrame(frame);
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  // Immediate ack is sent as this is the 2nd packet of every two packets.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 4);
+  // Don't ack even if packet 3 is newly missing as ignore_order is set by
+  // AckFrequencyFrame.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 5);
+  // Immediate ack is sent as this is the 2nd packet of every two packets.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(7, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 7);
+  // Don't ack even if packet 6 is newly missing as ignore_order is set by
+  // AckFrequencyFrame.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       AckDecimationDisabledWhenAckFrequencyFrameIsReceived) {
+  EXPECT_FALSE(HasPendingAck());
+
+  QuicAckFrequencyFrame frame;
+  frame.max_ack_delay = kDelayedAckTime;
+  frame.packet_tolerance = 3;
+  frame.ignore_order = true;
+  received_manager_.OnAckFrequencyFrame(frame);
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  uint64_t FiftyPacketsAfterAckDecimation = kFirstDecimatedPacket + 50;
+  for (uint64_t i = 1; i < FiftyPacketsAfterAckDecimation; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 3 == 0) {
+      // Ack every 3 packets as decimation is disabled.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      // Ack at default delay as decimation is disabled.
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+}
+
+TEST_F(QuicReceivedPacketManagerTest, UpdateAckTimeoutOnPacketReceiptTime) {
+  EXPECT_FALSE(HasPendingAck());
+
+  // Received packets 3 and 4.
+  QuicTime packet_receipt_time3 = clock_.ApproximateNow();
+  // Packet 3 gets processed after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  RecordPacketReceipt(3, packet_receipt_time3);
+  received_manager_.MaybeUpdateAckTimeout(
+      kInstigateAck, QuicPacketNumber(3),
+      /*last_packet_receipt_time=*/packet_receipt_time3,
+      clock_.ApproximateNow(), &rtt_stats_);
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Make sure ACK timeout is based on receipt time.
+    CheckAckTimeout(packet_receipt_time3 + kDelayedAckTime);
+  } else {
+    // Make sure ACK timeout is based on now.
+    CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  }
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 4);
+  // Immediate ack is sent.
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       UpdateAckTimeoutOnPacketReceiptTimeLongerQueuingTime) {
+  EXPECT_FALSE(HasPendingAck());
+
+  // Received packets 3 and 4.
+  QuicTime packet_receipt_time3 = clock_.ApproximateNow();
+  // Packet 3 gets processed after 100ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  RecordPacketReceipt(3, packet_receipt_time3);
+  received_manager_.MaybeUpdateAckTimeout(
+      kInstigateAck, QuicPacketNumber(3),
+      /*last_packet_receipt_time=*/packet_receipt_time3,
+      clock_.ApproximateNow(), &rtt_stats_);
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Given 100ms > ack delay, verify immediate ACK.
+    CheckAckTimeout(clock_.ApproximateNow());
+  } else {
+    // Make sure ACK timeout is based on now.
+    CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_sent_packet_manager.cc b/quiche/quic/core/quic_sent_packet_manager.cc
new file mode 100644
index 0000000..a77dddb
--- /dev/null
+++ b/quiche/quic/core/quic_sent_packet_manager.cc
@@ -0,0 +1,1872 @@
+// Copyright 2013 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 "quiche/quic/core/quic_sent_packet_manager.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <string>
+
+#include "quiche/quic/core/congestion_control/general_loss_algorithm.h"
+#include "quiche/quic/core/congestion_control/pacing_sender.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_transmission_info.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/print_elements.h"
+
+namespace quic {
+
+namespace {
+static const int64_t kDefaultRetransmissionTimeMs = 500;
+static const int64_t kMaxRetransmissionTimeMs = 60000;
+// Maximum number of exponential backoffs used for RTO timeouts.
+static const size_t kMaxRetransmissions = 10;
+// Maximum number of packets retransmitted upon an RTO.
+static const size_t kMaxRetransmissionsOnTimeout = 2;
+// The path degrading delay is the sum of this number of consecutive RTO delays.
+const size_t kNumRetransmissionDelaysForPathDegradingDelay = 2;
+
+// Ensure the handshake timer isnt't faster than 10ms.
+// This limits the tenth retransmitted packet to 10s after the initial CHLO.
+static const int64_t kMinHandshakeTimeoutMs = 10;
+
+// Sends up to two tail loss probes before firing an RTO,
+// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
+static const size_t kDefaultMaxTailLossProbes = 2;
+
+// Returns true of retransmissions of the specified type should retransmit
+// the frames directly (as opposed to resulting in a loss notification).
+inline bool ShouldForceRetransmission(TransmissionType transmission_type) {
+  return transmission_type == HANDSHAKE_RETRANSMISSION ||
+         transmission_type == TLP_RETRANSMISSION ||
+         transmission_type == PROBING_RETRANSMISSION ||
+         transmission_type == RTO_RETRANSMISSION ||
+         transmission_type == PTO_RETRANSMISSION;
+}
+
+// If pacing rate is accurate, > 2 burst token is not likely to help first ACK
+// to arrive earlier, and overly large burst token could cause incast packet
+// losses.
+static const uint32_t kConservativeUnpacedBurst = 2;
+
+}  // namespace
+
+#define ENDPOINT                                                         \
+  (unacked_packets_.perspective() == Perspective::IS_SERVER ? "Server: " \
+                                                            : "Client: ")
+
+QuicSentPacketManager::QuicSentPacketManager(
+    Perspective perspective, const QuicClock* clock, QuicRandom* random,
+    QuicConnectionStats* stats, CongestionControlType congestion_control_type)
+    : unacked_packets_(perspective),
+      clock_(clock),
+      random_(random),
+      stats_(stats),
+      debug_delegate_(nullptr),
+      network_change_visitor_(nullptr),
+      initial_congestion_window_(kInitialCongestionWindow),
+      loss_algorithm_(&uber_loss_algorithm_),
+      consecutive_rto_count_(0),
+      consecutive_tlp_count_(0),
+      consecutive_crypto_retransmission_count_(0),
+      pending_timer_transmission_count_(0),
+      max_tail_loss_probes_(kDefaultMaxTailLossProbes),
+      max_rto_packets_(kMaxRetransmissionsOnTimeout),
+      using_pacing_(false),
+      use_new_rto_(false),
+      conservative_handshake_retransmits_(false),
+      min_tlp_timeout_(
+          QuicTime::Delta::FromMilliseconds(kMinTailLossProbeTimeoutMs)),
+      min_rto_timeout_(
+          QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs)),
+      largest_mtu_acked_(0),
+      handshake_finished_(false),
+      peer_max_ack_delay_(
+          QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
+      rtt_updated_(false),
+      acked_packets_iter_(last_ack_frame_.packets.rbegin()),
+      pto_enabled_(GetQuicRestartFlag(quic_default_on_pto2)),
+      max_probe_packets_per_pto_(2),
+      consecutive_pto_count_(0),
+      handshake_mode_disabled_(false),
+      skip_packet_number_for_pto_(false),
+      always_include_max_ack_delay_for_pto_timeout_(true),
+      pto_exponential_backoff_start_point_(0),
+      pto_rttvar_multiplier_(4),
+      num_tlp_timeout_ptos_(0),
+      handshake_packet_acked_(false),
+      zero_rtt_packet_acked_(false),
+      one_rtt_packet_acked_(false),
+      first_pto_srtt_multiplier_(0),
+      use_standard_deviation_for_pto_(false),
+      pto_multiplier_without_rtt_samples_(3),
+      num_ptos_for_path_degrading_(0),
+      ignore_pings_(false),
+      ignore_ack_delay_(false) {
+  SetSendAlgorithm(congestion_control_type);
+  if (pto_enabled_) {
+    QUIC_RESTART_FLAG_COUNT_N(quic_default_on_pto2, 1, 2);
+    // TODO(fayang): change the default values when deprecating
+    // quic_default_on_pto2.
+    // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO
+    // with max of earliest in flight sent time + PTO delay and 1.5 * srtt from
+    // last in flight packet.
+    max_probe_packets_per_pto_ = 1;
+    skip_packet_number_for_pto_ = true;
+    first_pto_srtt_multiplier_ = 1.5;
+    pto_rttvar_multiplier_ = 2;
+  }
+}
+
+QuicSentPacketManager::~QuicSentPacketManager() {}
+
+void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
+  const Perspective perspective = unacked_packets_.perspective();
+  if (config.HasReceivedInitialRoundTripTimeUs() &&
+      config.ReceivedInitialRoundTripTimeUs() > 0) {
+    if (!config.HasClientSentConnectionOption(kNRTT, perspective)) {
+      SetInitialRtt(QuicTime::Delta::FromMicroseconds(
+                        config.ReceivedInitialRoundTripTimeUs()),
+                    /*trusted=*/false);
+    }
+  } else if (config.HasInitialRoundTripTimeUsToSend() &&
+             config.GetInitialRoundTripTimeUsToSend() > 0) {
+    SetInitialRtt(QuicTime::Delta::FromMicroseconds(
+                      config.GetInitialRoundTripTimeUsToSend()),
+                  /*trusted=*/false);
+  }
+  if (config.HasReceivedMaxAckDelayMs()) {
+    peer_max_ack_delay_ =
+        QuicTime::Delta::FromMilliseconds(config.ReceivedMaxAckDelayMs());
+  }
+  if (GetQuicReloadableFlag(quic_can_send_ack_frequency) &&
+      perspective == Perspective::IS_SERVER) {
+    if (config.HasReceivedMinAckDelayMs()) {
+      peer_min_ack_delay_ =
+          QuicTime::Delta::FromMilliseconds(config.ReceivedMinAckDelayMs());
+    }
+    if (config.HasClientSentConnectionOption(kAFF1, perspective)) {
+      use_smoothed_rtt_in_ack_delay_ = true;
+    }
+  }
+  if (config.HasClientSentConnectionOption(kMAD0, perspective)) {
+    ignore_ack_delay_ = true;
+  }
+  if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
+    // Set the minimum to the alarm granularity.
+    min_tlp_timeout_ = kAlarmGranularity;
+  }
+  if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
+    // Set the minimum to the alarm granularity.
+    min_rto_timeout_ = kAlarmGranularity;
+  }
+
+  if (!GetQuicRestartFlag(quic_default_on_pto2)) {
+    if (config.HasClientSentConnectionOption(k2PTO, perspective)) {
+      pto_enabled_ = true;
+    }
+    if (config.HasClientSentConnectionOption(k1PTO, perspective)) {
+      pto_enabled_ = true;
+      max_probe_packets_per_pto_ = 1;
+    }
+
+    if (config.HasClientSentConnectionOption(kPTOS, perspective)) {
+      if (!pto_enabled_) {
+        QUIC_PEER_BUG(quic_peer_bug_12552_1)
+            << "PTO is not enabled when receiving PTOS connection option.";
+        pto_enabled_ = true;
+        max_probe_packets_per_pto_ = 1;
+      }
+      skip_packet_number_for_pto_ = true;
+    }
+    if (pto_enabled_) {
+      if (config.HasClientSentConnectionOption(kPTOA, perspective)) {
+        always_include_max_ack_delay_for_pto_timeout_ = false;
+      }
+      if (config.HasClientSentConnectionOption(kPEB1, perspective)) {
+        StartExponentialBackoffAfterNthPto(1);
+      }
+      if (config.HasClientSentConnectionOption(kPEB2, perspective)) {
+        StartExponentialBackoffAfterNthPto(2);
+      }
+      if (config.HasClientSentConnectionOption(kPVS1, perspective)) {
+        pto_rttvar_multiplier_ = 2;
+      }
+      if (config.HasClientSentConnectionOption(kPAG1, perspective)) {
+        QUIC_CODE_COUNT(one_aggressive_pto);
+        num_tlp_timeout_ptos_ = 1;
+      }
+      if (config.HasClientSentConnectionOption(kPAG2, perspective)) {
+        QUIC_CODE_COUNT(two_aggressive_ptos);
+        num_tlp_timeout_ptos_ = 2;
+      }
+      if (config.HasClientSentConnectionOption(kPLE1, perspective)) {
+        first_pto_srtt_multiplier_ = 0.5;
+      } else if (config.HasClientSentConnectionOption(kPLE2, perspective)) {
+        first_pto_srtt_multiplier_ = 1.5;
+      }
+      if (config.HasClientSentConnectionOption(kAPTO, perspective)) {
+        pto_multiplier_without_rtt_samples_ = 1.5;
+      }
+      if (config.HasClientSentConnectionOption(kPSDA, perspective)) {
+        use_standard_deviation_for_pto_ = true;
+        rtt_stats_.EnableStandardDeviationCalculation();
+      }
+    }
+  }
+
+  if (pto_enabled_) {
+    if (config.HasClientRequestedIndependentOption(kPDP1, perspective)) {
+      num_ptos_for_path_degrading_ = 1;
+    }
+    if (config.HasClientRequestedIndependentOption(kPDP2, perspective)) {
+      num_ptos_for_path_degrading_ = 2;
+    }
+    if (config.HasClientRequestedIndependentOption(kPDP3, perspective)) {
+      num_ptos_for_path_degrading_ = 3;
+    }
+    if (config.HasClientRequestedIndependentOption(kPDP4, perspective)) {
+      num_ptos_for_path_degrading_ = 4;
+    }
+    if (config.HasClientRequestedIndependentOption(kPDP5, perspective)) {
+      num_ptos_for_path_degrading_ = 5;
+    }
+  }
+
+  // Configure congestion control.
+  if (config.HasClientRequestedIndependentOption(kTBBR, perspective)) {
+    SetSendAlgorithm(kBBR);
+  }
+  if (GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
+      config.HasClientRequestedIndependentOption(kB2ON, perspective)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_allow_client_enabled_bbr_v2);
+    SetSendAlgorithm(kBBRv2);
+  }
+
+  if (config.HasClientRequestedIndependentOption(kRENO, perspective)) {
+    SetSendAlgorithm(kRenoBytes);
+  } else if (config.HasClientRequestedIndependentOption(kBYTE, perspective) ||
+             (GetQuicReloadableFlag(quic_default_to_bbr) &&
+              config.HasClientRequestedIndependentOption(kQBIC, perspective))) {
+    SetSendAlgorithm(kCubicBytes);
+  }
+
+  // Initial window.
+  if (GetQuicReloadableFlag(quic_unified_iw_options)) {
+    if (config.HasClientRequestedIndependentOption(kIW03, perspective)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 1, 4);
+      initial_congestion_window_ = 3;
+      send_algorithm_->SetInitialCongestionWindowInPackets(3);
+    }
+    if (config.HasClientRequestedIndependentOption(kIW10, perspective)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 2, 4);
+      initial_congestion_window_ = 10;
+      send_algorithm_->SetInitialCongestionWindowInPackets(10);
+    }
+    if (config.HasClientRequestedIndependentOption(kIW20, perspective)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 3, 4);
+      initial_congestion_window_ = 20;
+      send_algorithm_->SetInitialCongestionWindowInPackets(20);
+    }
+    if (config.HasClientRequestedIndependentOption(kIW50, perspective)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 4, 4);
+      initial_congestion_window_ = 50;
+      send_algorithm_->SetInitialCongestionWindowInPackets(50);
+    }
+  }
+  if (config.HasClientRequestedIndependentOption(kBWS5, perspective)) {
+    initial_congestion_window_ = 10;
+    send_algorithm_->SetInitialCongestionWindowInPackets(10);
+  }
+
+  if (config.HasClientRequestedIndependentOption(kIGNP, perspective)) {
+    ignore_pings_ = true;
+  }
+
+  using_pacing_ = !GetQuicFlag(FLAGS_quic_disable_pacing_for_perf_tests);
+
+  if (config.HasClientSentConnectionOption(kNTLP, perspective)) {
+    max_tail_loss_probes_ = 0;
+  }
+  if (config.HasClientSentConnectionOption(k1TLP, perspective)) {
+    max_tail_loss_probes_ = 1;
+  }
+  if (config.HasClientSentConnectionOption(k1RTO, perspective)) {
+    max_rto_packets_ = 1;
+  }
+  if (config.HasClientSentConnectionOption(kNRTO, perspective)) {
+    use_new_rto_ = true;
+  }
+  // Configure loss detection.
+  if (config.HasClientRequestedIndependentOption(kILD0, perspective)) {
+    uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
+    uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
+  }
+  if (config.HasClientRequestedIndependentOption(kILD1, perspective)) {
+    uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
+    uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
+  }
+  if (config.HasClientRequestedIndependentOption(kILD2, perspective)) {
+    uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
+    uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
+  }
+  if (config.HasClientRequestedIndependentOption(kILD3, perspective)) {
+    uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
+    uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
+  }
+  if (config.HasClientRequestedIndependentOption(kILD4, perspective)) {
+    uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
+    uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
+    uber_loss_algorithm_.EnableAdaptiveTimeThreshold();
+  }
+  if (config.HasClientRequestedIndependentOption(kRUNT, perspective)) {
+    uber_loss_algorithm_.DisablePacketThresholdForRuntPackets();
+  }
+  if (config.HasClientSentConnectionOption(kCONH, perspective)) {
+    conservative_handshake_retransmits_ = true;
+  }
+  send_algorithm_->SetFromConfig(config, perspective);
+  loss_algorithm_->SetFromConfig(config, perspective);
+
+  if (network_change_visitor_ != nullptr) {
+    network_change_visitor_->OnCongestionChange();
+  }
+
+  if (debug_delegate_ != nullptr) {
+    DebugDelegate::SendParameters parameters;
+    parameters.congestion_control_type =
+        send_algorithm_->GetCongestionControlType();
+    parameters.use_pacing = using_pacing_;
+    parameters.initial_congestion_window = initial_congestion_window_;
+    debug_delegate_->OnConfigProcessed(parameters);
+  }
+}
+
+void QuicSentPacketManager::ApplyConnectionOptions(
+    const QuicTagVector& connection_options) {
+  absl::optional<CongestionControlType> cc_type;
+  if (ContainsQuicTag(connection_options, kB2ON)) {
+    cc_type = kBBRv2;
+  } else if (ContainsQuicTag(connection_options, kTBBR)) {
+    cc_type = kBBR;
+  } else if (ContainsQuicTag(connection_options, kRENO)) {
+    cc_type = kRenoBytes;
+  } else if (ContainsQuicTag(connection_options, kQBIC)) {
+    cc_type = kCubicBytes;
+  }
+
+  if (cc_type.has_value()) {
+    SetSendAlgorithm(*cc_type);
+  }
+
+  send_algorithm_->ApplyConnectionOptions(connection_options);
+}
+
+void QuicSentPacketManager::ResumeConnectionState(
+    const CachedNetworkParameters& cached_network_params,
+    bool max_bandwidth_resumption) {
+  QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
+      max_bandwidth_resumption
+          ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
+          : cached_network_params.bandwidth_estimate_bytes_per_second());
+  QuicTime::Delta rtt =
+      QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
+  // This calls the old AdjustNetworkParameters interface, and fills certain
+  // fields in SendAlgorithmInterface::NetworkParams
+  // (e.g., quic_bbr_fix_pacing_rate) using GFE flags.
+  SendAlgorithmInterface::NetworkParams params(
+      bandwidth, rtt, /*allow_cwnd_to_decrease = */ false);
+  // The rtt is trusted because it's a min_rtt measured from a previous
+  // connection with the same network path between client and server.
+  params.is_rtt_trusted = true;
+  AdjustNetworkParameters(params);
+}
+
+void QuicSentPacketManager::AdjustNetworkParameters(
+    const SendAlgorithmInterface::NetworkParams& params) {
+  if (params.burst_token != 0) {
+    if (using_pacing_) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_set_burst_token);
+      int old_burst_size = pacing_sender_.initial_burst_size();
+      pacing_sender_.SetBurstTokens(params.burst_token);
+      if (debug_delegate_ != nullptr) {
+        debug_delegate_->OnAdjustBurstSize(old_burst_size,
+                                           pacing_sender_.initial_burst_size());
+      }
+    }
+    return;
+  }
+  const QuicBandwidth& bandwidth = params.bandwidth;
+  const QuicTime::Delta& rtt = params.rtt;
+
+  if (use_lower_min_irtt()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_lower_min_for_trusted_irtt, 2, 2);
+    if (!rtt.IsZero()) {
+      if (params.is_rtt_trusted) {
+        // Always set initial rtt if it's trusted.
+        SetInitialRtt(rtt, /*trusted=*/true);
+      } else if (rtt_stats_.initial_rtt() ==
+                 QuicTime::Delta::FromMilliseconds(kInitialRttMs)) {
+        // Only set initial rtt if we are using the default. This avoids
+        // overwriting a trusted initial rtt by an untrusted one.
+        SetInitialRtt(rtt, /*trusted=*/false);
+      }
+    }
+  } else {
+    if (!rtt.IsZero()) {
+      SetInitialRtt(rtt, /*trusted=*/false);
+    }
+  }
+  const QuicByteCount old_cwnd = send_algorithm_->GetCongestionWindow();
+  if (GetQuicReloadableFlag(quic_conservative_bursts) && using_pacing_ &&
+      !bandwidth.IsZero()) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_bursts);
+    pacing_sender_.SetBurstTokens(kConservativeUnpacedBurst);
+  }
+  send_algorithm_->AdjustNetworkParameters(params);
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnAdjustNetworkParameters(
+        bandwidth, rtt.IsZero() ? rtt_stats_.MinOrInitialRtt() : rtt, old_cwnd,
+        send_algorithm_->GetCongestionWindow());
+  }
+}
+
+void QuicSentPacketManager::SetLossDetectionTuner(
+    std::unique_ptr<LossDetectionTunerInterface> tuner) {
+  uber_loss_algorithm_.SetLossDetectionTuner(std::move(tuner));
+}
+
+void QuicSentPacketManager::OnConfigNegotiated() {
+  loss_algorithm_->OnConfigNegotiated();
+}
+
+void QuicSentPacketManager::OnConnectionClosed() {
+  loss_algorithm_->OnConnectionClosed();
+}
+
+void QuicSentPacketManager::SetHandshakeConfirmed() {
+  if (!handshake_finished_) {
+    handshake_finished_ = true;
+    NeuterHandshakePackets();
+  }
+}
+
+void QuicSentPacketManager::PostProcessNewlyAckedPackets(
+    QuicPacketNumber ack_packet_number,
+    EncryptionLevel ack_decrypted_level,
+    const QuicAckFrame& ack_frame,
+    QuicTime ack_receive_time,
+    bool rtt_updated,
+    QuicByteCount prior_bytes_in_flight) {
+  unacked_packets_.NotifyAggregatedStreamFrameAcked(
+      last_ack_frame_.ack_delay_time);
+  InvokeLossDetection(ack_receive_time);
+  // Ignore losses in RTO mode.
+  if (consecutive_rto_count_ > 0 && !use_new_rto_) {
+    packets_lost_.clear();
+  }
+  MaybeInvokeCongestionEvent(rtt_updated, prior_bytes_in_flight,
+                             ack_receive_time);
+  unacked_packets_.RemoveObsoletePackets();
+
+  sustained_bandwidth_recorder_.RecordEstimate(
+      send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
+      send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
+      rtt_stats_.smoothed_rtt());
+
+  // Anytime we are making forward progress and have a new RTT estimate, reset
+  // the backoff counters.
+  if (rtt_updated) {
+    if (consecutive_rto_count_ > 0) {
+      // If the ack acknowledges data sent prior to the RTO,
+      // the RTO was spurious.
+      if (LargestAcked(ack_frame) < first_rto_transmission_) {
+        // Replace SRTT with latest_rtt and increase the variance to prevent
+        // a spurious RTO from happening again.
+        rtt_stats_.ExpireSmoothedMetrics();
+      } else {
+        if (!use_new_rto_) {
+          send_algorithm_->OnRetransmissionTimeout(true);
+        }
+      }
+    }
+    // Records the max consecutive RTO or PTO before forward progress has been
+    // made.
+    if (consecutive_rto_count_ >
+        stats_->max_consecutive_rto_with_forward_progress) {
+      stats_->max_consecutive_rto_with_forward_progress =
+          consecutive_rto_count_;
+    } else if (consecutive_pto_count_ >
+               stats_->max_consecutive_rto_with_forward_progress) {
+      stats_->max_consecutive_rto_with_forward_progress =
+          consecutive_pto_count_;
+    }
+    // Reset all retransmit counters any time a new packet is acked.
+    consecutive_rto_count_ = 0;
+    consecutive_tlp_count_ = 0;
+    consecutive_pto_count_ = 0;
+    consecutive_crypto_retransmission_count_ = 0;
+  }
+
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnIncomingAck(
+        ack_packet_number, ack_decrypted_level, ack_frame, ack_receive_time,
+        LargestAcked(ack_frame), rtt_updated, GetLeastUnacked());
+  }
+  // Remove packets below least unacked from all_packets_acked_ and
+  // last_ack_frame_.
+  last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked());
+  last_ack_frame_.received_packet_times.clear();
+}
+
+void QuicSentPacketManager::MaybeInvokeCongestionEvent(
+    bool rtt_updated,
+    QuicByteCount prior_in_flight,
+    QuicTime event_time) {
+  if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
+    return;
+  }
+  const bool overshooting_detected =
+      stats_->overshooting_detected_with_network_parameters_adjusted;
+  if (using_pacing_) {
+    pacing_sender_.OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
+                                     packets_acked_, packets_lost_);
+  } else {
+    send_algorithm_->OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
+                                       packets_acked_, packets_lost_);
+  }
+  if (debug_delegate_ != nullptr && !overshooting_detected &&
+      stats_->overshooting_detected_with_network_parameters_adjusted) {
+    debug_delegate_->OnOvershootingDetected();
+  }
+  packets_acked_.clear();
+  packets_lost_.clear();
+  if (network_change_visitor_ != nullptr) {
+    network_change_visitor_->OnCongestionChange();
+  }
+}
+
+void QuicSentPacketManager::MarkInitialPacketsForRetransmission() {
+  if (unacked_packets_.empty()) {
+    return;
+  }
+  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+  QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
+  for (; packet_number <= largest_sent_packet; ++packet_number) {
+    QuicTransmissionInfo* transmission_info =
+        unacked_packets_.GetMutableTransmissionInfo(packet_number);
+    if (transmission_info->encryption_level == ENCRYPTION_INITIAL) {
+      if (transmission_info->in_flight) {
+        unacked_packets_.RemoveFromInFlight(transmission_info);
+      }
+      if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
+        MarkForRetransmission(packet_number, ALL_INITIAL_RETRANSMISSION);
+      }
+    }
+  }
+}
+
+void QuicSentPacketManager::MarkZeroRttPacketsForRetransmission() {
+  if (unacked_packets_.empty()) {
+    return;
+  }
+  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+  QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
+  for (; packet_number <= largest_sent_packet; ++packet_number) {
+    QuicTransmissionInfo* transmission_info =
+        unacked_packets_.GetMutableTransmissionInfo(packet_number);
+    if (transmission_info->encryption_level == ENCRYPTION_ZERO_RTT) {
+      if (transmission_info->in_flight) {
+        // Remove 0-RTT packets and packets of the wrong version from flight,
+        // because neither can be processed by the peer.
+        unacked_packets_.RemoveFromInFlight(transmission_info);
+      }
+      if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
+        MarkForRetransmission(packet_number, ALL_ZERO_RTT_RETRANSMISSION);
+      }
+    }
+  }
+}
+
+void QuicSentPacketManager::NeuterUnencryptedPackets() {
+  for (QuicPacketNumber packet_number :
+       unacked_packets_.NeuterUnencryptedPackets()) {
+    send_algorithm_->OnPacketNeutered(packet_number);
+  }
+  if (handshake_mode_disabled_) {
+    consecutive_pto_count_ = 0;
+    uber_loss_algorithm_.ResetLossDetection(INITIAL_DATA);
+  }
+}
+
+void QuicSentPacketManager::NeuterHandshakePackets() {
+  for (QuicPacketNumber packet_number :
+       unacked_packets_.NeuterHandshakePackets()) {
+    send_algorithm_->OnPacketNeutered(packet_number);
+  }
+  if (handshake_mode_disabled_) {
+    consecutive_pto_count_ = 0;
+    uber_loss_algorithm_.ResetLossDetection(HANDSHAKE_DATA);
+  }
+}
+
+bool QuicSentPacketManager::ShouldAddMaxAckDelay(
+    PacketNumberSpace space) const {
+  QUICHE_DCHECK(pto_enabled_);
+  if (supports_multiple_packet_number_spaces() && space != APPLICATION_DATA) {
+    // When the PTO is armed for Initial or Handshake packet number spaces,
+    // the max_ack_delay is 0.
+    return false;
+  }
+  if (always_include_max_ack_delay_for_pto_timeout_) {
+    return true;
+  }
+  if (!unacked_packets_
+           .GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
+           .IsInitialized() ||
+      unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+          APPLICATION_DATA) <
+          FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation - 1) {
+    // Peer is doing TCP style acking. Expect an immediate ACK if more than 1
+    // packet are outstanding.
+    if (unacked_packets_.packets_in_flight() >=
+        kDefaultRetransmittablePacketsBeforeAck) {
+      return false;
+    }
+  } else if (unacked_packets_.packets_in_flight() >=
+             kMaxRetransmittablePacketsBeforeAck) {
+    // Peer is doing ack decimation. Expect an immediate ACK if >= 10
+    // packets are outstanding.
+    return false;
+  }
+  if (skip_packet_number_for_pto_ && consecutive_pto_count_ > 0) {
+    // An immediate ACK is expected when doing PTOS. Please note, this will miss
+    // cases when PTO fires and turns out to be spurious.
+    return false;
+  }
+  return true;
+}
+
+QuicTime QuicSentPacketManager::GetEarliestPacketSentTimeForPto(
+    PacketNumberSpace* packet_number_space) const {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
+  QuicTime earliest_sent_time = QuicTime::Zero();
+  for (int8_t i = 0; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    const QuicTime sent_time = unacked_packets_.GetLastInFlightPacketSentTime(
+        static_cast<PacketNumberSpace>(i));
+    if (!handshake_finished_ && i == APPLICATION_DATA) {
+      // Do not arm PTO for application data until handshake gets confirmed.
+      continue;
+    }
+    if (!sent_time.IsInitialized() || (earliest_sent_time.IsInitialized() &&
+                                       earliest_sent_time <= sent_time)) {
+      continue;
+    }
+    earliest_sent_time = sent_time;
+    *packet_number_space = static_cast<PacketNumberSpace>(i);
+  }
+
+  return earliest_sent_time;
+}
+
+void QuicSentPacketManager::MarkForRetransmission(
+    QuicPacketNumber packet_number,
+    TransmissionType transmission_type) {
+  QuicTransmissionInfo* transmission_info =
+      unacked_packets_.GetMutableTransmissionInfo(packet_number);
+  // A previous RTO retransmission may cause connection close; packets without
+  // retransmittable frames can be marked for loss retransmissions.
+  QUIC_BUG_IF(quic_bug_12552_2, transmission_type != LOSS_RETRANSMISSION &&
+                                    transmission_type != RTO_RETRANSMISSION &&
+                                    !unacked_packets_.HasRetransmittableFrames(
+                                        *transmission_info))
+      << "packet number " << packet_number
+      << " transmission_type: " << transmission_type << " transmission_info "
+      << transmission_info->DebugString();
+  // Handshake packets should never be sent as probing retransmissions.
+  QUICHE_DCHECK(!transmission_info->has_crypto_handshake ||
+                transmission_type != PROBING_RETRANSMISSION);
+  if (ShouldForceRetransmission(transmission_type)) {
+    const bool retransmitted = unacked_packets_.RetransmitFrames(
+        QuicFrames(transmission_info->retransmittable_frames),
+        transmission_type);
+    if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted)) {
+      QUIC_RESTART_FLAG_COUNT(quic_set_packet_state_if_all_data_retransmitted);
+      if (!retransmitted) {
+        // Do not set packet state if the data is not fully retransmitted.
+        // This should only happen if packet payload size decreases which can be
+        // caused by:
+        // 1) connection tries to opportunistically retransmit data
+        // when sending a packet of a different packet number space, or
+        // 2) path MTU decreases, or
+        // 3) packet header size increases (e.g., packet number length
+        // increases).
+        QUIC_CODE_COUNT(quic_retransmit_frames_failed);
+        return;
+      }
+      QUIC_CODE_COUNT(quic_retransmit_frames_succeeded);
+    }
+  } else {
+    unacked_packets_.NotifyFramesLost(*transmission_info, transmission_type);
+
+    if (!transmission_info->retransmittable_frames.empty()) {
+      if (transmission_type == LOSS_RETRANSMISSION) {
+        // Record the first packet sent after loss, which allows to wait 1
+        // more RTT before giving up on this lost packet.
+        transmission_info->first_sent_after_loss =
+            unacked_packets_.largest_sent_packet() + 1;
+      } else {
+        // Clear the recorded first packet sent after loss when version or
+        // encryption changes.
+        transmission_info->first_sent_after_loss.Clear();
+      }
+    }
+  }
+
+  // Get the latest transmission_info here as it can be invalidated after
+  // HandleRetransmission adding new sent packets into unacked_packets_.
+  transmission_info =
+      unacked_packets_.GetMutableTransmissionInfo(packet_number);
+
+  // Update packet state according to transmission type.
+  transmission_info->state =
+      QuicUtils::RetransmissionTypeToPacketState(transmission_type);
+}
+
+void QuicSentPacketManager::RecordOneSpuriousRetransmission(
+    const QuicTransmissionInfo& info) {
+  stats_->bytes_spuriously_retransmitted += info.bytes_sent;
+  ++stats_->packets_spuriously_retransmitted;
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
+                                                    info.bytes_sent);
+  }
+}
+
+void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
+                                              QuicTransmissionInfo* info,
+                                              QuicTime ack_receive_time,
+                                              QuicTime::Delta ack_delay_time,
+                                              QuicTime receive_timestamp) {
+  if (info->has_ack_frequency) {
+    for (const auto& frame : info->retransmittable_frames) {
+      if (frame.type == ACK_FREQUENCY_FRAME) {
+        OnAckFrequencyFrameAcked(*frame.ack_frequency_frame);
+      }
+    }
+  }
+  // Try to aggregate acked stream frames if acked packet is not a
+  // retransmission.
+  if (info->transmission_type == NOT_RETRANSMISSION) {
+    unacked_packets_.MaybeAggregateAckedStreamFrame(*info, ack_delay_time,
+                                                    receive_timestamp);
+  } else {
+    unacked_packets_.NotifyAggregatedStreamFrameAcked(ack_delay_time);
+    const bool new_data_acked = unacked_packets_.NotifyFramesAcked(
+        *info, ack_delay_time, receive_timestamp);
+    if (!new_data_acked && info->transmission_type != NOT_RETRANSMISSION) {
+      // Record as a spurious retransmission if this packet is a
+      // retransmission and no new data gets acked.
+      QUIC_DVLOG(1) << "Detect spurious retransmitted packet " << packet_number
+                    << " transmission type: " << info->transmission_type;
+      RecordOneSpuriousRetransmission(*info);
+    }
+  }
+  if (info->state == LOST) {
+    // Record as a spurious loss as a packet previously declared lost gets
+    // acked.
+    const PacketNumberSpace packet_number_space =
+        unacked_packets_.GetPacketNumberSpace(info->encryption_level);
+    const QuicPacketNumber previous_largest_acked =
+        supports_multiple_packet_number_spaces()
+            ? unacked_packets_.GetLargestAckedOfPacketNumberSpace(
+                  packet_number_space)
+            : unacked_packets_.largest_acked();
+    QUIC_DVLOG(1) << "Packet " << packet_number
+                  << " was detected lost spuriously, "
+                     "previous_largest_acked: "
+                  << previous_largest_acked;
+    loss_algorithm_->SpuriousLossDetected(unacked_packets_, rtt_stats_,
+                                          ack_receive_time, packet_number,
+                                          previous_largest_acked);
+    ++stats_->packet_spuriously_detected_lost;
+  }
+
+  if (network_change_visitor_ != nullptr &&
+      info->bytes_sent > largest_mtu_acked_) {
+    largest_mtu_acked_ = info->bytes_sent;
+    network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_);
+  }
+  unacked_packets_.RemoveFromInFlight(info);
+  unacked_packets_.RemoveRetransmittability(info);
+  info->state = ACKED;
+}
+
+bool QuicSentPacketManager::CanSendAckFrequency() const {
+  return !peer_min_ack_delay_.IsInfinite() && handshake_finished_;
+}
+
+QuicAckFrequencyFrame QuicSentPacketManager::GetUpdatedAckFrequencyFrame()
+    const {
+  QuicAckFrequencyFrame frame;
+  if (!CanSendAckFrequency()) {
+    QUIC_BUG(quic_bug_10750_1)
+        << "New AckFrequencyFrame is created while it shouldn't.";
+    return frame;
+  }
+
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 1, 3);
+  frame.packet_tolerance = kMaxRetransmittablePacketsBeforeAck;
+  auto rtt = use_smoothed_rtt_in_ack_delay_ ? rtt_stats_.SmoothedOrInitialRtt()
+                                            : rtt_stats_.MinOrInitialRtt();
+  frame.max_ack_delay = rtt * kAckDecimationDelay;
+  frame.max_ack_delay = std::max(frame.max_ack_delay, peer_min_ack_delay_);
+  // TODO(haoyuewang) Remove this once kDefaultMinAckDelayTimeMs is updated to
+  // 5 ms on the client side.
+  frame.max_ack_delay =
+      std::max(frame.max_ack_delay,
+               QuicTime::Delta::FromMilliseconds(kDefaultMinAckDelayTimeMs));
+  return frame;
+}
+
+bool QuicSentPacketManager::OnPacketSent(
+    SerializedPacket* mutable_packet,
+    QuicTime sent_time,
+    TransmissionType transmission_type,
+    HasRetransmittableData has_retransmittable_data,
+    bool measure_rtt) {
+  const SerializedPacket& packet = *mutable_packet;
+  QuicPacketNumber packet_number = packet.packet_number;
+  QUICHE_DCHECK_LE(FirstSendingPacketNumber(), packet_number);
+  QUICHE_DCHECK(!unacked_packets_.IsUnacked(packet_number));
+  QUIC_BUG_IF(quic_bug_10750_2, packet.encrypted_length == 0)
+      << "Cannot send empty packets.";
+  if (pending_timer_transmission_count_ > 0) {
+    --pending_timer_transmission_count_;
+  }
+
+  bool in_flight = has_retransmittable_data == HAS_RETRANSMITTABLE_DATA;
+  if (ignore_pings_ && mutable_packet->retransmittable_frames.size() == 1 &&
+      mutable_packet->retransmittable_frames[0].type == PING_FRAME) {
+    // Dot not use PING only packet for RTT measure or congestion control.
+    in_flight = false;
+    measure_rtt = false;
+  }
+  if (using_pacing_) {
+    pacing_sender_.OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
+                                packet_number, packet.encrypted_length,
+                                has_retransmittable_data);
+  } else {
+    send_algorithm_->OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
+                                  packet_number, packet.encrypted_length,
+                                  has_retransmittable_data);
+  }
+
+  // Deallocate message data in QuicMessageFrame immediately after packet
+  // sent.
+  if (packet.has_message) {
+    for (auto& frame : mutable_packet->retransmittable_frames) {
+      if (frame.type == MESSAGE_FRAME) {
+        frame.message_frame->message_data.clear();
+        frame.message_frame->message_length = 0;
+      }
+    }
+  }
+
+  if (packet.has_ack_frequency) {
+    for (const auto& frame : packet.retransmittable_frames) {
+      if (frame.type == ACK_FREQUENCY_FRAME) {
+        OnAckFrequencyFrameSent(*frame.ack_frequency_frame);
+      }
+    }
+  }
+  unacked_packets_.AddSentPacket(mutable_packet, transmission_type, sent_time,
+                                 in_flight, measure_rtt);
+  // Reset the retransmission timer anytime a pending packet is sent.
+  return in_flight;
+}
+
+QuicSentPacketManager::RetransmissionTimeoutMode
+QuicSentPacketManager::OnRetransmissionTimeout() {
+  QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
+                (handshake_mode_disabled_ && !handshake_finished_));
+  QUICHE_DCHECK_EQ(0u, pending_timer_transmission_count_);
+  // Handshake retransmission, timer based loss detection, TLP, and RTO are
+  // implemented with a single alarm. The handshake alarm is set when the
+  // handshake has not completed, the loss alarm is set when the loss detection
+  // algorithm says to, and the TLP and  RTO alarms are set after that.
+  // The TLP alarm is always set to run for under an RTO.
+  switch (GetRetransmissionMode()) {
+    case HANDSHAKE_MODE:
+      QUICHE_DCHECK(!handshake_mode_disabled_);
+      ++stats_->crypto_retransmit_count;
+      RetransmitCryptoPackets();
+      return HANDSHAKE_MODE;
+    case LOSS_MODE: {
+      ++stats_->loss_timeout_count;
+      QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight();
+      const QuicTime now = clock_->Now();
+      InvokeLossDetection(now);
+      MaybeInvokeCongestionEvent(false, prior_in_flight, now);
+      return LOSS_MODE;
+    }
+    case TLP_MODE:
+      ++stats_->tlp_count;
+      ++consecutive_tlp_count_;
+      pending_timer_transmission_count_ = 1;
+      // TLPs prefer sending new data instead of retransmitting data, so
+      // give the connection a chance to write before completing the TLP.
+      return TLP_MODE;
+    case RTO_MODE:
+      ++stats_->rto_count;
+      RetransmitRtoPackets();
+      return RTO_MODE;
+    case PTO_MODE:
+      QUIC_DVLOG(1) << ENDPOINT << "PTO mode";
+      ++stats_->pto_count;
+      if (handshake_mode_disabled_ && !handshake_finished_) {
+        ++stats_->crypto_retransmit_count;
+      }
+      ++consecutive_pto_count_;
+      pending_timer_transmission_count_ = max_probe_packets_per_pto_;
+      return PTO_MODE;
+  }
+  QUIC_BUG(quic_bug_10750_3)
+      << "Unknown retransmission mode " << GetRetransmissionMode();
+  return GetRetransmissionMode();
+}
+
+void QuicSentPacketManager::RetransmitCryptoPackets() {
+  QUICHE_DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
+  ++consecutive_crypto_retransmission_count_;
+  bool packet_retransmitted = false;
+  std::vector<QuicPacketNumber> crypto_retransmissions;
+  if (!unacked_packets_.empty()) {
+    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+    QuicPacketNumber largest_sent_packet =
+        unacked_packets_.largest_sent_packet();
+    for (; packet_number <= largest_sent_packet; ++packet_number) {
+      QuicTransmissionInfo* transmission_info =
+          unacked_packets_.GetMutableTransmissionInfo(packet_number);
+      // Only retransmit frames which are in flight, and therefore have been
+      // sent.
+      if (!transmission_info->in_flight ||
+          transmission_info->state != OUTSTANDING ||
+          !transmission_info->has_crypto_handshake ||
+          !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
+        continue;
+      }
+      packet_retransmitted = true;
+      crypto_retransmissions.push_back(packet_number);
+      ++pending_timer_transmission_count_;
+    }
+  }
+  QUICHE_DCHECK(packet_retransmitted)
+      << "No crypto packets found to retransmit.";
+  for (QuicPacketNumber retransmission : crypto_retransmissions) {
+    MarkForRetransmission(retransmission, HANDSHAKE_RETRANSMISSION);
+  }
+}
+
+bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
+  QUICHE_DCHECK(!pto_enabled_);
+  if (pending_timer_transmission_count_ == 0) {
+    return false;
+  }
+  if (!MaybeRetransmitOldestPacket(TLP_RETRANSMISSION)) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) {
+  if (!unacked_packets_.empty()) {
+    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+    QuicPacketNumber largest_sent_packet =
+        unacked_packets_.largest_sent_packet();
+    for (; packet_number <= largest_sent_packet; ++packet_number) {
+      QuicTransmissionInfo* transmission_info =
+          unacked_packets_.GetMutableTransmissionInfo(packet_number);
+      // Only retransmit frames which are in flight, and therefore have been
+      // sent.
+      if (!transmission_info->in_flight ||
+          transmission_info->state != OUTSTANDING ||
+          !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
+        continue;
+      }
+      MarkForRetransmission(packet_number, type);
+      return true;
+    }
+  }
+  QUIC_DVLOG(1)
+      << "No retransmittable packets, so RetransmitOldestPacket failed.";
+  return false;
+}
+
+void QuicSentPacketManager::RetransmitRtoPackets() {
+  QUICHE_DCHECK(!pto_enabled_);
+  QUIC_BUG_IF(quic_bug_12552_3, pending_timer_transmission_count_ > 0)
+      << "Retransmissions already queued:" << pending_timer_transmission_count_;
+  // Mark two packets for retransmission.
+  std::vector<QuicPacketNumber> retransmissions;
+  if (!unacked_packets_.empty()) {
+    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+    QuicPacketNumber largest_sent_packet =
+        unacked_packets_.largest_sent_packet();
+    for (; packet_number <= largest_sent_packet; ++packet_number) {
+      QuicTransmissionInfo* transmission_info =
+          unacked_packets_.GetMutableTransmissionInfo(packet_number);
+      if (transmission_info->state == OUTSTANDING &&
+          unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
+          pending_timer_transmission_count_ < max_rto_packets_) {
+        QUICHE_DCHECK(transmission_info->in_flight);
+        retransmissions.push_back(packet_number);
+        ++pending_timer_transmission_count_;
+      }
+    }
+  }
+  if (pending_timer_transmission_count_ > 0) {
+    if (consecutive_rto_count_ == 0) {
+      first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
+    }
+    ++consecutive_rto_count_;
+  }
+  for (QuicPacketNumber retransmission : retransmissions) {
+    MarkForRetransmission(retransmission, RTO_RETRANSMISSION);
+  }
+  if (retransmissions.empty()) {
+    QUIC_BUG_IF(quic_bug_12552_4, pending_timer_transmission_count_ != 0);
+    // No packets to be RTO retransmitted, raise up a credit to allow
+    // connection to send.
+    QUIC_CODE_COUNT(no_packets_to_be_rto_retransmitted);
+    pending_timer_transmission_count_ = 1;
+  }
+}
+
+void QuicSentPacketManager::MaybeSendProbePackets() {
+  if (pending_timer_transmission_count_ == 0) {
+    return;
+  }
+  PacketNumberSpace packet_number_space;
+  if (supports_multiple_packet_number_spaces()) {
+    // Find out the packet number space to send probe packets.
+    if (!GetEarliestPacketSentTimeForPto(&packet_number_space)
+             .IsInitialized()) {
+      QUIC_BUG_IF(quic_earliest_sent_time_not_initialized,
+                  unacked_packets_.perspective() == Perspective::IS_SERVER)
+          << "earliest_sent_time not initialized when trying to send PTO "
+             "retransmissions";
+      return;
+    }
+  }
+  std::vector<QuicPacketNumber> probing_packets;
+  if (!unacked_packets_.empty()) {
+    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+    QuicPacketNumber largest_sent_packet =
+        unacked_packets_.largest_sent_packet();
+    for (; packet_number <= largest_sent_packet; ++packet_number) {
+      QuicTransmissionInfo* transmission_info =
+          unacked_packets_.GetMutableTransmissionInfo(packet_number);
+      if (transmission_info->state == OUTSTANDING &&
+          unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
+          (!supports_multiple_packet_number_spaces() ||
+           unacked_packets_.GetPacketNumberSpace(
+               transmission_info->encryption_level) == packet_number_space)) {
+        QUICHE_DCHECK(transmission_info->in_flight);
+        probing_packets.push_back(packet_number);
+        if (probing_packets.size() == pending_timer_transmission_count_) {
+          break;
+        }
+      }
+    }
+  }
+
+  for (QuicPacketNumber retransmission : probing_packets) {
+    QUIC_DVLOG(1) << ENDPOINT << "Marking " << retransmission
+                  << " for probing retransmission";
+    MarkForRetransmission(retransmission, PTO_RETRANSMISSION);
+  }
+  // It is possible that there is not enough outstanding data for probing.
+}
+
+void QuicSentPacketManager::AdjustPendingTimerTransmissions() {
+  if (pending_timer_transmission_count_ < max_probe_packets_per_pto_) {
+    // There are packets sent already, clear credit.
+    pending_timer_transmission_count_ = 0;
+    return;
+  }
+  // No packet gets sent, leave 1 credit to allow data to be write eventually.
+  pending_timer_transmission_count_ = 1;
+}
+
+void QuicSentPacketManager::EnableIetfPtoAndLossDetection() {
+  if (pto_enabled_) {
+    QUIC_RESTART_FLAG_COUNT_N(quic_default_on_pto2, 2, 2);
+    // Disable handshake mode.
+    handshake_mode_disabled_ = true;
+    return;
+  }
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    QUIC_BUG(pto_not_enabled)
+        << "PTO is not enabled while quic_default_on_pto2 is true";
+    return;
+  }
+  pto_enabled_ = true;
+  handshake_mode_disabled_ = true;
+  // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO
+  // with max of earliest in flight sent time + PTO delay and 1.5 * srtt from
+  // last in flight packet.
+  max_probe_packets_per_pto_ = 1;
+  skip_packet_number_for_pto_ = true;
+  first_pto_srtt_multiplier_ = 1.5;
+  pto_rttvar_multiplier_ = 2;
+}
+
+void QuicSentPacketManager::StartExponentialBackoffAfterNthPto(
+    size_t exponential_backoff_start_point) {
+  pto_exponential_backoff_start_point_ = exponential_backoff_start_point;
+}
+
+void QuicSentPacketManager::RetransmitDataOfSpaceIfAny(
+    PacketNumberSpace space) {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
+  if (!unacked_packets_.GetLastInFlightPacketSentTime(space).IsInitialized()) {
+    // No in flight data of space.
+    return;
+  }
+  if (unacked_packets_.empty()) {
+    return;
+  }
+  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+  QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
+  for (; packet_number <= largest_sent_packet; ++packet_number) {
+    QuicTransmissionInfo* transmission_info =
+        unacked_packets_.GetMutableTransmissionInfo(packet_number);
+    if (transmission_info->state == OUTSTANDING &&
+        unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
+        unacked_packets_.GetPacketNumberSpace(
+            transmission_info->encryption_level) == space) {
+      QUICHE_DCHECK(transmission_info->in_flight);
+      if (pending_timer_transmission_count_ == 0) {
+        pending_timer_transmission_count_ = 1;
+      }
+      MarkForRetransmission(packet_number, PTO_RETRANSMISSION);
+      return;
+    }
+  }
+}
+
+QuicSentPacketManager::RetransmissionTimeoutMode
+QuicSentPacketManager::GetRetransmissionMode() const {
+  QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
+                (handshake_mode_disabled_ && !handshake_finished_));
+  if (!handshake_mode_disabled_ && !handshake_finished_ &&
+      unacked_packets_.HasPendingCryptoPackets()) {
+    return HANDSHAKE_MODE;
+  }
+  if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
+    return LOSS_MODE;
+  }
+  if (pto_enabled_) {
+    return PTO_MODE;
+  }
+  if (consecutive_tlp_count_ < max_tail_loss_probes_) {
+    if (unacked_packets_.HasUnackedRetransmittableFrames()) {
+      return TLP_MODE;
+    }
+  }
+  return RTO_MODE;
+}
+
+void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
+  if (!packets_acked_.empty()) {
+    QUICHE_DCHECK_LE(packets_acked_.front().packet_number,
+                     packets_acked_.back().packet_number);
+    largest_newly_acked_ = packets_acked_.back().packet_number;
+  }
+  LossDetectionInterface::DetectionStats detection_stats =
+      loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
+                                    largest_newly_acked_, packets_acked_,
+                                    &packets_lost_);
+
+  if (detection_stats.sent_packets_max_sequence_reordering >
+      stats_->sent_packets_max_sequence_reordering) {
+    stats_->sent_packets_max_sequence_reordering =
+        detection_stats.sent_packets_max_sequence_reordering;
+  }
+
+  stats_->sent_packets_num_borderline_time_reorderings +=
+      detection_stats.sent_packets_num_borderline_time_reorderings;
+
+  stats_->total_loss_detection_response_time +=
+      detection_stats.total_loss_detection_response_time;
+
+  for (const LostPacket& packet : packets_lost_) {
+    QuicTransmissionInfo* info =
+        unacked_packets_.GetMutableTransmissionInfo(packet.packet_number);
+    ++stats_->packets_lost;
+    if (debug_delegate_ != nullptr) {
+      debug_delegate_->OnPacketLoss(packet.packet_number,
+                                    info->encryption_level, LOSS_RETRANSMISSION,
+                                    time);
+    }
+    unacked_packets_.RemoveFromInFlight(info);
+
+    MarkForRetransmission(packet.packet_number, LOSS_RETRANSMISSION);
+  }
+}
+
+bool QuicSentPacketManager::MaybeUpdateRTT(QuicPacketNumber largest_acked,
+                                           QuicTime::Delta ack_delay_time,
+                                           QuicTime ack_receive_time) {
+  // We rely on ack_delay_time to compute an RTT estimate, so we
+  // only update rtt when the largest observed gets acked and the acked packet
+  // is not useless.
+  if (!unacked_packets_.IsUnacked(largest_acked)) {
+    return false;
+  }
+  // We calculate the RTT based on the highest ACKed packet number, the lower
+  // packet numbers will include the ACK aggregation delay.
+  const QuicTransmissionInfo& transmission_info =
+      unacked_packets_.GetTransmissionInfo(largest_acked);
+  // Ensure the packet has a valid sent time.
+  if (transmission_info.sent_time == QuicTime::Zero()) {
+    QUIC_BUG(quic_bug_10750_4)
+        << "Acked packet has zero sent time, largest_acked:" << largest_acked;
+    return false;
+  }
+  if (transmission_info.state == NOT_CONTRIBUTING_RTT) {
+    return false;
+  }
+  if (transmission_info.sent_time > ack_receive_time) {
+    QUIC_CODE_COUNT(quic_receive_acked_before_sending);
+  }
+
+  QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
+  const bool min_rtt_available = !rtt_stats_.min_rtt().IsZero();
+  rtt_stats_.UpdateRtt(send_delta, ack_delay_time, ack_receive_time);
+
+  if (!min_rtt_available && !rtt_stats_.min_rtt().IsZero()) {
+    loss_algorithm_->OnMinRttAvailable();
+  }
+
+  return true;
+}
+
+QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now) const {
+  // The TLP logic is entirely contained within QuicSentPacketManager, so the
+  // send algorithm does not need to be consulted.
+  if (pending_timer_transmission_count_ > 0) {
+    return QuicTime::Delta::Zero();
+  }
+
+  if (using_pacing_) {
+    return pacing_sender_.TimeUntilSend(now,
+                                        unacked_packets_.bytes_in_flight());
+  }
+
+  return send_algorithm_->CanSend(unacked_packets_.bytes_in_flight())
+             ? QuicTime::Delta::Zero()
+             : QuicTime::Delta::Infinite();
+}
+
+const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
+  if (!unacked_packets_.HasInFlightPackets() &&
+      PeerCompletedAddressValidation()) {
+    return QuicTime::Zero();
+  }
+  if (pending_timer_transmission_count_ > 0) {
+    // Do not set the timer if there is any credit left.
+    return QuicTime::Zero();
+  }
+  PacketNumberSpace packet_number_space;
+  if (!simplify_set_retransmission_alarm_ &&
+      supports_multiple_packet_number_spaces() &&
+      unacked_packets_.perspective() == Perspective::IS_SERVER &&
+      !GetEarliestPacketSentTimeForPto(&packet_number_space).IsInitialized()) {
+    // Do not set the timer on the server side if the only in flight packets are
+    // half RTT data.
+    return QuicTime::Zero();
+  }
+  switch (GetRetransmissionMode()) {
+    case HANDSHAKE_MODE:
+      return unacked_packets_.GetLastCryptoPacketSentTime() +
+             GetCryptoRetransmissionDelay();
+    case LOSS_MODE:
+      return loss_algorithm_->GetLossTimeout();
+    case TLP_MODE: {
+      QUICHE_DCHECK(!pto_enabled_);
+      // TODO(ianswett): When CWND is available, it would be preferable to
+      // set the timer based on the earliest retransmittable packet.
+      // Base the updated timer on the send time of the last packet.
+      const QuicTime sent_time =
+          unacked_packets_.GetLastInFlightPacketSentTime();
+      const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
+      // Ensure the TLP timer never gets set to a time in the past.
+      return std::max(clock_->ApproximateNow(), tlp_time);
+    }
+    case RTO_MODE: {
+      QUICHE_DCHECK(!pto_enabled_);
+      // The RTO is based on the first outstanding packet.
+      const QuicTime sent_time =
+          unacked_packets_.GetLastInFlightPacketSentTime();
+      QuicTime rto_time = sent_time + GetRetransmissionDelay();
+      // Wait for TLP packets to be acked before an RTO fires.
+      QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
+      return std::max(tlp_time, rto_time);
+    }
+    case PTO_MODE: {
+      if (!supports_multiple_packet_number_spaces()) {
+        if (first_pto_srtt_multiplier_ > 0 &&
+            unacked_packets_.HasInFlightPackets() &&
+            consecutive_pto_count_ == 0) {
+          // Arm 1st PTO with earliest in flight sent time, and make sure at
+          // least first_pto_srtt_multiplier_ * RTT has been passed since last
+          // in flight packet.
+          return std::max(
+              clock_->ApproximateNow(),
+              std::max(unacked_packets_.GetFirstInFlightTransmissionInfo()
+                               ->sent_time +
+                           GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES),
+                       unacked_packets_.GetLastInFlightPacketSentTime() +
+                           first_pto_srtt_multiplier_ *
+                               rtt_stats_.SmoothedOrInitialRtt()));
+        }
+        // Ensure PTO never gets set to a time in the past.
+        return std::max(clock_->ApproximateNow(),
+                        unacked_packets_.GetLastInFlightPacketSentTime() +
+                            GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES));
+      }
+
+      PacketNumberSpace packet_number_space = NUM_PACKET_NUMBER_SPACES;
+      // earliest_right_edge is the earliest sent time of the last in flight
+      // packet of all packet number spaces.
+      QuicTime earliest_right_edge =
+          GetEarliestPacketSentTimeForPto(&packet_number_space);
+      if (!earliest_right_edge.IsInitialized()) {
+        // Arm PTO from now if there is no in flight packets.
+        earliest_right_edge = clock_->ApproximateNow();
+      }
+      if (first_pto_srtt_multiplier_ > 0 &&
+          packet_number_space == APPLICATION_DATA &&
+          consecutive_pto_count_ == 0) {
+        const QuicTransmissionInfo* first_application_info =
+            unacked_packets_.GetFirstInFlightTransmissionInfoOfSpace(
+                APPLICATION_DATA);
+        if (first_application_info != nullptr) {
+          // Arm 1st PTO with earliest in flight sent time, and make sure at
+          // least first_pto_srtt_multiplier_ * RTT has been passed since last
+          // in flight packet. Only do this for application data.
+          return std::max(
+              clock_->ApproximateNow(),
+              std::max(
+                  first_application_info->sent_time +
+                      GetProbeTimeoutDelay(packet_number_space),
+                  earliest_right_edge + first_pto_srtt_multiplier_ *
+                                            rtt_stats_.SmoothedOrInitialRtt()));
+        }
+      }
+      return std::max(
+          clock_->ApproximateNow(),
+          earliest_right_edge + GetProbeTimeoutDelay(packet_number_space));
+    }
+  }
+  QUICHE_DCHECK(false);
+  return QuicTime::Zero();
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
+  if (num_ptos_for_path_degrading_ > 0) {
+    return num_ptos_for_path_degrading_ * GetPtoDelay();
+  }
+  return GetNConsecutiveRetransmissionTimeoutDelay(
+      max_tail_loss_probes_ + kNumRetransmissionDelaysForPathDegradingDelay);
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetNetworkBlackholeDelay(
+    int8_t num_rtos_for_blackhole_detection) const {
+  return GetNConsecutiveRetransmissionTimeoutDelay(
+      max_tail_loss_probes_ + num_rtos_for_blackhole_detection);
+}
+
+QuicTime::Delta QuicSentPacketManager::GetMtuReductionDelay(
+    int8_t num_rtos_for_blackhole_detection) const {
+  return GetNetworkBlackholeDelay(num_rtos_for_blackhole_detection / 2);
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
+    const {
+  // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
+  // because crypto handshake messages don't incur a delayed ack time.
+  QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
+  int64_t delay_ms;
+  if (conservative_handshake_retransmits_) {
+    // Using the delayed ack time directly could cause conservative handshake
+    // retransmissions to actually be more aggressive than the default.
+    delay_ms = std::max(peer_max_ack_delay_.ToMilliseconds(),
+                        static_cast<int64_t>(2 * srtt.ToMilliseconds()));
+  } else {
+    delay_ms = std::max(kMinHandshakeTimeoutMs,
+                        static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
+  }
+  return QuicTime::Delta::FromMilliseconds(
+      delay_ms << consecutive_crypto_retransmission_count_);
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
+  QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
+  if (!unacked_packets_.HasMultipleInFlightPackets()) {
+    // This expression really should be using the delayed ack time, but in TCP
+    // MinRTO was traditionally set to 2x the delayed ack timer and this
+    // expression assumed QUIC did the same.
+    return std::max(2 * srtt, 1.5 * srtt + (min_rto_timeout_ * 0.5));
+  }
+  return std::max(min_tlp_timeout_, 2 * srtt);
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
+  QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
+  if (rtt_stats_.smoothed_rtt().IsZero()) {
+    // We are in the initial state, use default timeout values.
+    retransmission_delay =
+        QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
+  } else {
+    retransmission_delay =
+        rtt_stats_.smoothed_rtt() + 4 * rtt_stats_.mean_deviation();
+    if (retransmission_delay < min_rto_timeout_) {
+      retransmission_delay = min_rto_timeout_;
+    }
+  }
+
+  // Calculate exponential back off.
+  retransmission_delay =
+      retransmission_delay *
+      (1 << std::min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
+
+  if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
+    return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
+  }
+  return retransmission_delay;
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetProbeTimeoutDelay(
+    PacketNumberSpace space) const {
+  QUICHE_DCHECK(pto_enabled_);
+  if (rtt_stats_.smoothed_rtt().IsZero()) {
+    // Respect kMinHandshakeTimeoutMs to avoid a potential amplification attack.
+    QUIC_BUG_IF(quic_bug_12552_6, rtt_stats_.initial_rtt().IsZero());
+    return std::max(
+               pto_multiplier_without_rtt_samples_ * rtt_stats_.initial_rtt(),
+               QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) *
+           (1 << consecutive_pto_count_);
+  }
+  const QuicTime::Delta rtt_var = use_standard_deviation_for_pto_
+                                      ? rtt_stats_.GetStandardOrMeanDeviation()
+                                      : rtt_stats_.mean_deviation();
+  QuicTime::Delta pto_delay =
+      rtt_stats_.smoothed_rtt() +
+      std::max(pto_rttvar_multiplier_ * rtt_var, kAlarmGranularity) +
+      (ShouldAddMaxAckDelay(space) ? peer_max_ack_delay_
+                                   : QuicTime::Delta::Zero());
+  pto_delay =
+      pto_delay * (1 << (consecutive_pto_count_ -
+                         std::min(consecutive_pto_count_,
+                                  pto_exponential_backoff_start_point_)));
+  if (consecutive_pto_count_ < num_tlp_timeout_ptos_) {
+    // Make first n PTOs similar to TLPs.
+    if (pto_delay > 2 * rtt_stats_.smoothed_rtt()) {
+      QUIC_CODE_COUNT(quic_delayed_pto);
+      pto_delay = std::max(kAlarmGranularity, 2 * rtt_stats_.smoothed_rtt());
+    } else {
+      QUIC_CODE_COUNT(quic_faster_pto);
+    }
+  }
+  return pto_delay;
+}
+
+QuicTime::Delta QuicSentPacketManager::GetSlowStartDuration() const {
+  if (send_algorithm_->GetCongestionControlType() == kBBR ||
+      send_algorithm_->GetCongestionControlType() == kBBRv2) {
+    return stats_->slowstart_duration.GetTotalElapsedTime(
+        clock_->ApproximateNow());
+  }
+  return QuicTime::Delta::Infinite();
+}
+
+QuicByteCount QuicSentPacketManager::GetAvailableCongestionWindowInBytes()
+    const {
+  QuicByteCount congestion_window = GetCongestionWindowInBytes();
+  QuicByteCount bytes_in_flight = GetBytesInFlight();
+  return congestion_window - std::min(congestion_window, bytes_in_flight);
+}
+
+std::string QuicSentPacketManager::GetDebugState() const {
+  return send_algorithm_->GetDebugState();
+}
+
+void QuicSentPacketManager::SetSendAlgorithm(
+    CongestionControlType congestion_control_type) {
+  if (send_algorithm_ &&
+      send_algorithm_->GetCongestionControlType() == congestion_control_type) {
+    return;
+  }
+
+  SetSendAlgorithm(SendAlgorithmInterface::Create(
+      clock_, &rtt_stats_, &unacked_packets_, congestion_control_type, random_,
+      stats_, initial_congestion_window_, send_algorithm_.get()));
+}
+
+void QuicSentPacketManager::SetSendAlgorithm(
+    SendAlgorithmInterface* send_algorithm) {
+  send_algorithm_.reset(send_algorithm);
+  pacing_sender_.set_sender(send_algorithm);
+}
+
+std::unique_ptr<SendAlgorithmInterface>
+QuicSentPacketManager::OnConnectionMigration(bool reset_send_algorithm) {
+  consecutive_rto_count_ = 0;
+  consecutive_tlp_count_ = 0;
+  consecutive_pto_count_ = 0;
+  rtt_stats_.OnConnectionMigration();
+  if (!reset_send_algorithm) {
+    send_algorithm_->OnConnectionMigration();
+    return nullptr;
+  }
+
+  std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
+      std::move(send_algorithm_);
+  SetSendAlgorithm(old_send_algorithm->GetCongestionControlType());
+  // Treat all in flight packets sent to the old peer address as lost and
+  // retransmit them.
+  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+  for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
+       ++it, ++packet_number) {
+    if (it->in_flight) {
+      // Proactively retransmit any packet which is in flight on the old path.
+      // As a result, these packets will not contribute to congestion control.
+      unacked_packets_.RemoveFromInFlight(packet_number);
+      // Retransmitting these packets with PATH_CHANGE_RETRANSMISSION will mark
+      // them as useless, thus not contributing to RTT stats.
+      if (unacked_packets_.HasRetransmittableFrames(packet_number)) {
+        MarkForRetransmission(packet_number, PATH_RETRANSMISSION);
+        QUICHE_DCHECK_EQ(it->state, NOT_CONTRIBUTING_RTT);
+      }
+    }
+    it->state = NOT_CONTRIBUTING_RTT;
+  }
+  return old_send_algorithm;
+}
+
+void QuicSentPacketManager::OnAckFrameStart(QuicPacketNumber largest_acked,
+                                            QuicTime::Delta ack_delay_time,
+                                            QuicTime ack_receive_time) {
+  QUICHE_DCHECK(packets_acked_.empty());
+  QUICHE_DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
+  // Ignore peer_max_ack_delay and use received ack_delay during
+  // handshake when supporting multiple packet number spaces.
+  if (!supports_multiple_packet_number_spaces() || handshake_finished_) {
+    if (ack_delay_time > peer_max_ack_delay()) {
+      ack_delay_time = peer_max_ack_delay();
+    }
+    if (ignore_ack_delay_) {
+      ack_delay_time = QuicTime::Delta::Zero();
+    }
+  }
+  rtt_updated_ =
+      MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
+  last_ack_frame_.ack_delay_time = ack_delay_time;
+  acked_packets_iter_ = last_ack_frame_.packets.rbegin();
+}
+
+void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
+                                       QuicPacketNumber end) {
+  if (!last_ack_frame_.largest_acked.IsInitialized() ||
+      end > last_ack_frame_.largest_acked + 1) {
+    // Largest acked increases.
+    unacked_packets_.IncreaseLargestAcked(end - 1);
+    last_ack_frame_.largest_acked = end - 1;
+  }
+  // Drop ack ranges which ack packets below least_unacked.
+  QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
+  if (least_unacked.IsInitialized() && end <= least_unacked) {
+    return;
+  }
+  start = std::max(start, least_unacked);
+  do {
+    QuicPacketNumber newly_acked_start = start;
+    if (acked_packets_iter_ != last_ack_frame_.packets.rend()) {
+      newly_acked_start = std::max(start, acked_packets_iter_->max());
+    }
+    for (QuicPacketNumber acked = end - 1; acked >= newly_acked_start;
+         --acked) {
+      // Check if end is above the current range. If so add newly acked packets
+      // in descending order.
+      packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
+      if (acked == FirstSendingPacketNumber()) {
+        break;
+      }
+    }
+    if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
+        start > acked_packets_iter_->min()) {
+      // Finish adding all newly acked packets.
+      return;
+    }
+    end = std::min(end, acked_packets_iter_->min());
+    ++acked_packets_iter_;
+  } while (start < end);
+}
+
+void QuicSentPacketManager::OnAckTimestamp(QuicPacketNumber packet_number,
+                                           QuicTime timestamp) {
+  last_ack_frame_.received_packet_times.push_back({packet_number, timestamp});
+  for (AckedPacket& packet : packets_acked_) {
+    if (packet.packet_number == packet_number) {
+      packet.receive_timestamp = timestamp;
+      return;
+    }
+  }
+}
+
+AckResult QuicSentPacketManager::OnAckFrameEnd(
+    QuicTime ack_receive_time,
+    QuicPacketNumber ack_packet_number,
+    EncryptionLevel ack_decrypted_level) {
+  QuicByteCount prior_bytes_in_flight = unacked_packets_.bytes_in_flight();
+  // Reverse packets_acked_ so that it is in ascending order.
+  std::reverse(packets_acked_.begin(), packets_acked_.end());
+  for (AckedPacket& acked_packet : packets_acked_) {
+    QuicTransmissionInfo* info =
+        unacked_packets_.GetMutableTransmissionInfo(acked_packet.packet_number);
+    if (!QuicUtils::IsAckable(info->state)) {
+      if (info->state == ACKED) {
+        QUIC_BUG(quic_bug_10750_5)
+            << "Trying to ack an already acked packet: "
+            << acked_packet.packet_number
+            << ", last_ack_frame_: " << last_ack_frame_
+            << ", least_unacked: " << unacked_packets_.GetLeastUnacked()
+            << ", packets_acked_: " << quiche::PrintElements(packets_acked_);
+      } else {
+        QUIC_PEER_BUG(quic_peer_bug_10750_6)
+            << "Received " << ack_decrypted_level
+            << " ack for unackable packet: " << acked_packet.packet_number
+            << " with state: "
+            << QuicUtils::SentPacketStateToString(info->state);
+        if (supports_multiple_packet_number_spaces()) {
+          if (info->state == NEVER_SENT) {
+            return UNSENT_PACKETS_ACKED;
+          }
+          return UNACKABLE_PACKETS_ACKED;
+        }
+      }
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Got an " << ack_decrypted_level
+                  << " ack for packet " << acked_packet.packet_number
+                  << " , state: "
+                  << QuicUtils::SentPacketStateToString(info->state);
+    const PacketNumberSpace packet_number_space =
+        unacked_packets_.GetPacketNumberSpace(info->encryption_level);
+    if (supports_multiple_packet_number_spaces() &&
+        QuicUtils::GetPacketNumberSpace(ack_decrypted_level) !=
+            packet_number_space) {
+      return PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE;
+    }
+    last_ack_frame_.packets.Add(acked_packet.packet_number);
+    if (info->encryption_level == ENCRYPTION_HANDSHAKE) {
+      handshake_packet_acked_ = true;
+    } else if (info->encryption_level == ENCRYPTION_ZERO_RTT) {
+      zero_rtt_packet_acked_ = true;
+    } else if (info->encryption_level == ENCRYPTION_FORWARD_SECURE) {
+      one_rtt_packet_acked_ = true;
+    }
+    largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked);
+    if (supports_multiple_packet_number_spaces()) {
+      largest_packets_peer_knows_is_acked_[packet_number_space].UpdateMax(
+          info->largest_acked);
+    }
+    // If data is associated with the most recent transmission of this
+    // packet, then inform the caller.
+    if (info->in_flight) {
+      acked_packet.bytes_acked = info->bytes_sent;
+    } else {
+      // Unackable packets are skipped earlier.
+      largest_newly_acked_ = acked_packet.packet_number;
+    }
+    unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+        packet_number_space, acked_packet.packet_number);
+    MarkPacketHandled(acked_packet.packet_number, info, ack_receive_time,
+                      last_ack_frame_.ack_delay_time,
+                      acked_packet.receive_timestamp);
+  }
+  const bool acked_new_packet = !packets_acked_.empty();
+  PostProcessNewlyAckedPackets(ack_packet_number, ack_decrypted_level,
+                               last_ack_frame_, ack_receive_time, rtt_updated_,
+                               prior_bytes_in_flight);
+
+  return acked_new_packet ? PACKETS_NEWLY_ACKED : NO_PACKETS_NEWLY_ACKED;
+}
+
+void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
+  debug_delegate_ = debug_delegate;
+}
+
+void QuicSentPacketManager::OnApplicationLimited() {
+  if (using_pacing_) {
+    pacing_sender_.OnApplicationLimited();
+  }
+  send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight());
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnApplicationLimited();
+  }
+}
+
+NextReleaseTimeResult QuicSentPacketManager::GetNextReleaseTime() const {
+  if (!using_pacing_) {
+    return {QuicTime::Zero(), false};
+  }
+
+  return pacing_sender_.GetNextReleaseTime();
+}
+
+void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt, bool trusted) {
+  const QuicTime::Delta min_rtt = QuicTime::Delta::FromMicroseconds(
+      trusted ? kMinTrustedInitialRoundTripTimeUs
+              : kMinUntrustedInitialRoundTripTimeUs);
+  QuicTime::Delta max_rtt =
+      QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
+  rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt)));
+}
+
+void QuicSentPacketManager::EnableMultiplePacketNumberSpacesSupport() {
+  EnableIetfPtoAndLossDetection();
+  unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
+}
+
+QuicPacketNumber QuicSentPacketManager::GetLargestAckedPacket(
+    EncryptionLevel decrypted_packet_level) const {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
+  return unacked_packets_.GetLargestAckedOfPacketNumberSpace(
+      QuicUtils::GetPacketNumberSpace(decrypted_packet_level));
+}
+
+QuicPacketNumber QuicSentPacketManager::GetLeastPacketAwaitedByPeer(
+    EncryptionLevel encryption_level) const {
+  QuicPacketNumber largest_acked;
+  if (supports_multiple_packet_number_spaces()) {
+    largest_acked = GetLargestAckedPacket(encryption_level);
+  } else {
+    largest_acked = GetLargestObserved();
+  }
+  if (!largest_acked.IsInitialized()) {
+    // If no packets have been acked, return the first sent packet to ensure
+    // we use a large enough packet number length.
+    return FirstSendingPacketNumber();
+  }
+  QuicPacketNumber least_awaited = largest_acked + 1;
+  QuicPacketNumber least_unacked = GetLeastUnacked();
+  if (least_unacked.IsInitialized() && least_unacked < least_awaited) {
+    least_awaited = least_unacked;
+  }
+  return least_awaited;
+}
+
+QuicPacketNumber QuicSentPacketManager::GetLargestPacketPeerKnowsIsAcked(
+    EncryptionLevel decrypted_packet_level) const {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
+  return largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace(
+      decrypted_packet_level)];
+}
+
+QuicTime::Delta
+QuicSentPacketManager::GetNConsecutiveRetransmissionTimeoutDelay(
+    int num_timeouts) const {
+  QuicTime::Delta total_delay = QuicTime::Delta::Zero();
+  const QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
+  int num_tlps =
+      std::min(num_timeouts, static_cast<int>(max_tail_loss_probes_));
+  num_timeouts -= num_tlps;
+  if (num_tlps > 0) {
+    const QuicTime::Delta tlp_delay =
+        std::max(2 * srtt, unacked_packets_.HasMultipleInFlightPackets()
+                               ? min_tlp_timeout_
+                               : (1.5 * srtt + (min_rto_timeout_ * 0.5)));
+    total_delay = total_delay + num_tlps * tlp_delay;
+  }
+  if (num_timeouts == 0) {
+    return total_delay;
+  }
+
+  const QuicTime::Delta retransmission_delay =
+      rtt_stats_.smoothed_rtt().IsZero()
+          ? QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs)
+          : std::max(srtt + 4 * rtt_stats_.mean_deviation(), min_rto_timeout_);
+  total_delay = total_delay + ((1 << num_timeouts) - 1) * retransmission_delay;
+  return total_delay;
+}
+
+bool QuicSentPacketManager::PeerCompletedAddressValidation() const {
+  if (unacked_packets_.perspective() == Perspective::IS_SERVER ||
+      !handshake_mode_disabled_) {
+    return true;
+  }
+
+  // To avoid handshake deadlock due to anti-amplification limit, client needs
+  // to set PTO timer until server successfully processed any HANDSHAKE packet.
+  return handshake_finished_ || handshake_packet_acked_;
+}
+
+bool QuicSentPacketManager::IsLessThanThreePTOs(QuicTime::Delta timeout) const {
+  return timeout < 3 * GetPtoDelay();
+}
+
+QuicTime::Delta QuicSentPacketManager::GetPtoDelay() const {
+  return pto_enabled_ ? GetProbeTimeoutDelay(APPLICATION_DATA)
+                      : GetRetransmissionDelay();
+}
+
+void QuicSentPacketManager::OnAckFrequencyFrameSent(
+    const QuicAckFrequencyFrame& ack_frequency_frame) {
+  in_use_sent_ack_delays_.emplace_back(ack_frequency_frame.max_ack_delay,
+                                       ack_frequency_frame.sequence_number);
+  if (ack_frequency_frame.max_ack_delay > peer_max_ack_delay_) {
+    peer_max_ack_delay_ = ack_frequency_frame.max_ack_delay;
+  }
+}
+
+void QuicSentPacketManager::OnAckFrequencyFrameAcked(
+    const QuicAckFrequencyFrame& ack_frequency_frame) {
+  int stale_entry_count = 0;
+  for (auto it = in_use_sent_ack_delays_.cbegin();
+       it != in_use_sent_ack_delays_.cend(); ++it) {
+    if (it->second < ack_frequency_frame.sequence_number) {
+      ++stale_entry_count;
+    } else {
+      break;
+    }
+  }
+  if (stale_entry_count > 0) {
+    in_use_sent_ack_delays_.pop_front_n(stale_entry_count);
+  }
+  if (in_use_sent_ack_delays_.empty()) {
+    QUIC_BUG(quic_bug_10750_7) << "in_use_sent_ack_delays_ is empty.";
+    return;
+  }
+  peer_max_ack_delay_ = std::max_element(in_use_sent_ack_delays_.cbegin(),
+                                         in_use_sent_ack_delays_.cend())
+                            ->first;
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_sent_packet_manager.h b/quiche/quic/core/quic_sent_packet_manager.h
new file mode 100644
index 0000000..4be38bb
--- /dev/null
+++ b/quiche/quic/core/quic_sent_packet_manager.h
@@ -0,0 +1,784 @@
+// Copyright 2013 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_SENT_PACKET_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "quiche/quic/core/congestion_control/pacing_sender.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/uber_loss_algorithm.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_sustained_bandwidth_recorder.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_transmission_info.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class QuicConnectionPeer;
+class QuicSentPacketManagerPeer;
+}  // namespace test
+
+class QuicClock;
+class QuicConfig;
+struct QuicConnectionStats;
+
+// Class which tracks the set of packets sent on a QUIC connection and contains
+// a send algorithm to decide when to send new packets.  It keeps track of any
+// retransmittable data associated with each packet. If a packet is
+// retransmitted, it will keep track of each version of a packet so that if a
+// previous transmission is acked, the data will not be retransmitted.
+class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
+ public:
+  // Interface which gets callbacks from the QuicSentPacketManager at
+  // interesting points.  Implementations must not mutate the state of
+  // the packet manager or connection as a result of these callbacks.
+  class QUIC_EXPORT_PRIVATE DebugDelegate {
+   public:
+    struct QUIC_EXPORT_PRIVATE SendParameters {
+      CongestionControlType congestion_control_type;
+      bool use_pacing;
+      QuicPacketCount initial_congestion_window;
+    };
+
+    virtual ~DebugDelegate() {}
+
+    // Called when a spurious retransmission is detected.
+    virtual void OnSpuriousPacketRetransmission(
+        TransmissionType /*transmission_type*/,
+        QuicByteCount /*byte_size*/) {}
+
+    virtual void OnIncomingAck(QuicPacketNumber /*ack_packet_number*/,
+                               EncryptionLevel /*ack_decrypted_level*/,
+                               const QuicAckFrame& /*ack_frame*/,
+                               QuicTime /*ack_receive_time*/,
+                               QuicPacketNumber /*largest_observed*/,
+                               bool /*rtt_updated*/,
+                               QuicPacketNumber /*least_unacked_sent_packet*/) {
+    }
+
+    virtual void OnPacketLoss(QuicPacketNumber /*lost_packet_number*/,
+                              EncryptionLevel /*encryption_level*/,
+                              TransmissionType /*transmission_type*/,
+                              QuicTime /*detection_time*/) {}
+
+    virtual void OnApplicationLimited() {}
+
+    virtual void OnAdjustNetworkParameters(QuicBandwidth /*bandwidth*/,
+                                           QuicTime::Delta /*rtt*/,
+                                           QuicByteCount /*old_cwnd*/,
+                                           QuicByteCount /*new_cwnd*/) {}
+
+    virtual void OnAdjustBurstSize(int /*old_burst_size*/,
+                                   int /*new_burst_size*/) {}
+
+    virtual void OnOvershootingDetected() {}
+
+    virtual void OnConfigProcessed(const SendParameters& /*parameters*/) {}
+  };
+
+  // Interface which gets callbacks from the QuicSentPacketManager when
+  // network-related state changes. Implementations must not mutate the
+  // state of the packet manager as a result of these callbacks.
+  class QUIC_EXPORT_PRIVATE NetworkChangeVisitor {
+   public:
+    virtual ~NetworkChangeVisitor() {}
+
+    // Called when congestion window or RTT may have changed.
+    virtual void OnCongestionChange() = 0;
+
+    // Called when the Path MTU may have increased.
+    virtual void OnPathMtuIncreased(QuicPacketLength packet_size) = 0;
+  };
+
+  // The retransmission timer is a single timer which switches modes depending
+  // upon connection state.
+  enum RetransmissionTimeoutMode {
+    // A conventional TCP style RTO.
+    RTO_MODE,
+    // A tail loss probe.  By default, QUIC sends up to two before RTOing.
+    TLP_MODE,
+    // Retransmission of handshake packets prior to handshake completion.
+    HANDSHAKE_MODE,
+    // Re-invoke the loss detection when a packet is not acked before the
+    // loss detection algorithm expects.
+    LOSS_MODE,
+    // A probe timeout. At least one probe packet must be sent when timer
+    // expires.
+    PTO_MODE,
+  };
+
+  QuicSentPacketManager(Perspective perspective,
+                        const QuicClock* clock,
+                        QuicRandom* random,
+                        QuicConnectionStats* stats,
+                        CongestionControlType congestion_control_type);
+  QuicSentPacketManager(const QuicSentPacketManager&) = delete;
+  QuicSentPacketManager& operator=(const QuicSentPacketManager&) = delete;
+  virtual ~QuicSentPacketManager();
+
+  virtual void SetFromConfig(const QuicConfig& config);
+
+  void ReserveUnackedPacketsInitialCapacity(int initial_capacity) {
+    unacked_packets_.ReserveInitialCapacity(initial_capacity);
+  }
+
+  void ApplyConnectionOptions(const QuicTagVector& connection_options);
+
+  // Pass the CachedNetworkParameters to the send algorithm.
+  void ResumeConnectionState(
+      const CachedNetworkParameters& cached_network_params,
+      bool max_bandwidth_resumption);
+
+  void SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
+    pacing_sender_.set_max_pacing_rate(max_pacing_rate);
+  }
+
+  QuicBandwidth MaxPacingRate() const {
+    return pacing_sender_.max_pacing_rate();
+  }
+
+  // Called to mark the handshake state complete, and all handshake packets are
+  // neutered.
+  // TODO(fayang): Rename this function to OnHandshakeComplete.
+  void SetHandshakeConfirmed();
+
+  // Requests retransmission of all unacked 0-RTT packets.
+  // Only 0-RTT encrypted packets will be retransmitted. This can happen,
+  // for example, when a CHLO has been rejected and the previously encrypted
+  // data needs to be encrypted with a new key.
+  void MarkZeroRttPacketsForRetransmission();
+
+  // Request retransmission of all unacked INITIAL packets.
+  void MarkInitialPacketsForRetransmission();
+
+  // Notify the sent packet manager of an external network measurement or
+  // prediction for either |bandwidth| or |rtt|; either can be empty.
+  void AdjustNetworkParameters(
+      const SendAlgorithmInterface::NetworkParams& params);
+
+  void SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface> tuner);
+  void OnConfigNegotiated();
+  void OnConnectionClosed();
+
+  // Retransmits the oldest pending packet there is still a tail loss probe
+  // pending.  Invoked after OnRetransmissionTimeout.
+  bool MaybeRetransmitTailLossProbe();
+
+  // Retransmits the oldest pending packet.
+  bool MaybeRetransmitOldestPacket(TransmissionType type);
+
+  // Removes the retransmittable frames from all unencrypted packets to ensure
+  // they don't get retransmitted.
+  void NeuterUnencryptedPackets();
+
+  // Returns true if there's outstanding crypto data.
+  bool HasUnackedCryptoPackets() const {
+    return unacked_packets_.HasPendingCryptoPackets();
+  }
+
+  // Returns true if there are packets in flight expecting to be acknowledged.
+  bool HasInFlightPackets() const {
+    return unacked_packets_.HasInFlightPackets();
+  }
+
+  // Returns the smallest packet number of a serialized packet which has not
+  // been acked by the peer.
+  QuicPacketNumber GetLeastUnacked() const {
+    return unacked_packets_.GetLeastUnacked();
+  }
+
+  // Called when we have sent bytes to the peer.  This informs the manager both
+  // the number of bytes sent and if they were retransmitted and if this packet
+  // is used for rtt measuring.  Returns true if the sender should reset the
+  // retransmission timer.
+  bool OnPacketSent(SerializedPacket* mutable_packet,
+                    QuicTime sent_time,
+                    TransmissionType transmission_type,
+                    HasRetransmittableData has_retransmittable_data,
+                    bool measure_rtt);
+
+  bool CanSendAckFrequency() const;
+
+  QuicAckFrequencyFrame GetUpdatedAckFrequencyFrame() const;
+
+  // Called when the retransmission timer expires and returns the retransmission
+  // mode.
+  RetransmissionTimeoutMode OnRetransmissionTimeout();
+
+  // Calculate the time until we can send the next packet to the wire.
+  // Note 1: When kUnknownWaitTime is returned, there is no need to poll
+  // TimeUntilSend again until we receive an OnIncomingAckFrame event.
+  // Note 2: Send algorithms may or may not use |retransmit| in their
+  // calculations.
+  QuicTime::Delta TimeUntilSend(QuicTime now) const;
+
+  // Returns the current delay for the retransmission timer, which may send
+  // either a tail loss probe or do a full RTO.  Returns QuicTime::Zero() if
+  // there are no retransmittable packets.
+  const QuicTime GetRetransmissionTime() const;
+
+  // Returns the current delay for the path degrading timer, which is used to
+  // notify the session that this connection is degrading.
+  const QuicTime::Delta GetPathDegradingDelay() const;
+
+  // Returns the current delay for detecting network blackhole.
+  const QuicTime::Delta GetNetworkBlackholeDelay(
+      int8_t num_rtos_for_blackhole_detection) const;
+
+  // Returns the delay before reducing max packet size. This delay is guranteed
+  // to be smaller than the network blackhole delay.
+  QuicTime::Delta GetMtuReductionDelay(
+      int8_t num_rtos_for_blackhole_detection) const;
+
+  const RttStats* GetRttStats() const { return &rtt_stats_; }
+
+  void SetRttStats(const RttStats& rtt_stats) {
+    rtt_stats_.CloneFrom(rtt_stats);
+  }
+
+  // Returns the estimated bandwidth calculated by the congestion algorithm.
+  QuicBandwidth BandwidthEstimate() const {
+    return send_algorithm_->BandwidthEstimate();
+  }
+
+  const QuicSustainedBandwidthRecorder* SustainedBandwidthRecorder() const {
+    return &sustained_bandwidth_recorder_;
+  }
+
+  // Returns the size of the current congestion window in number of
+  // kDefaultTCPMSS-sized segments. Note, this is not the *available* window.
+  // Some send algorithms may not use a congestion window and will return 0.
+  QuicPacketCount GetCongestionWindowInTcpMss() const {
+    return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS;
+  }
+
+  // Returns the number of packets of length |max_packet_length| which fit in
+  // the current congestion window. More packets may end up in flight if the
+  // congestion window has been recently reduced, of if non-full packets are
+  // sent.
+  QuicPacketCount EstimateMaxPacketsInFlight(
+      QuicByteCount max_packet_length) const {
+    return send_algorithm_->GetCongestionWindow() / max_packet_length;
+  }
+
+  // Returns the size of the current congestion window size in bytes.
+  QuicByteCount GetCongestionWindowInBytes() const {
+    return send_algorithm_->GetCongestionWindow();
+  }
+
+  // Returns the difference between current congestion window and bytes in
+  // flight. Returns 0 if bytes in flight is bigger than the current congestion
+  // window.
+  QuicByteCount GetAvailableCongestionWindowInBytes() const;
+
+  QuicBandwidth GetPacingRate() const {
+    return send_algorithm_->PacingRate(GetBytesInFlight());
+  }
+
+  // Returns the size of the slow start congestion window in nume of 1460 byte
+  // TCP segments, aka ssthresh.  Some send algorithms do not define a slow
+  // start threshold and will return 0.
+  QuicPacketCount GetSlowStartThresholdInTcpMss() const {
+    return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS;
+  }
+
+  // Return the total time spent in slow start so far. If the sender is
+  // currently in slow start, the return value will include the duration between
+  // the most recent entry to slow start and now.
+  //
+  // Only implemented for BBR. Return QuicTime::Delta::Infinite() for other
+  // congestion controllers.
+  QuicTime::Delta GetSlowStartDuration() const;
+
+  // Returns debugging information about the state of the congestion controller.
+  std::string GetDebugState() const;
+
+  // Returns the number of bytes that are considered in-flight, i.e. not lost or
+  // acknowledged.
+  QuicByteCount GetBytesInFlight() const {
+    return unacked_packets_.bytes_in_flight();
+  }
+
+  // Called when peer address changes. Must be called IFF the address change is
+  // not NAT rebinding. If reset_send_algorithm is true, switch to a new send
+  // algorithm object and retransmit all the in-flight packets. Return the send
+  // algorithm object used on the previous path.
+  std::unique_ptr<SendAlgorithmInterface> OnConnectionMigration(
+      bool reset_send_algorithm);
+
+  // Called when an ack frame is initially parsed.
+  void OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time,
+                       QuicTime ack_receive_time);
+
+  // Called when ack range [start, end) is received. Populates packets_acked_
+  // with newly acked packets.
+  void OnAckRange(QuicPacketNumber start, QuicPacketNumber end);
+
+  // Called when a timestamp is processed.  If it's present in packets_acked_,
+  // the timestamp field is set.  Otherwise, the timestamp is ignored.
+  void OnAckTimestamp(QuicPacketNumber packet_number, QuicTime timestamp);
+
+  // Called when an ack frame is parsed completely.
+  AckResult OnAckFrameEnd(QuicTime ack_receive_time,
+                          QuicPacketNumber ack_packet_number,
+                          EncryptionLevel ack_decrypted_level);
+
+  void EnableMultiplePacketNumberSpacesSupport();
+
+  void SetDebugDelegate(DebugDelegate* debug_delegate);
+
+  void SetPacingAlarmGranularity(QuicTime::Delta alarm_granularity) {
+    pacing_sender_.set_alarm_granularity(alarm_granularity);
+  }
+
+  QuicPacketNumber GetLargestObserved() const {
+    return unacked_packets_.largest_acked();
+  }
+
+  QuicPacketNumber GetLargestAckedPacket(
+      EncryptionLevel decrypted_packet_level) const;
+
+  QuicPacketNumber GetLargestSentPacket() const {
+    return unacked_packets_.largest_sent_packet();
+  }
+
+  // Returns the lowest of the largest acknowledged packet and the least
+  // unacked packet. This is designed to be used when computing the packet
+  // number length to send.
+  QuicPacketNumber GetLeastPacketAwaitedByPeer(
+      EncryptionLevel encryption_level) const;
+
+  QuicPacketNumber GetLargestPacketPeerKnowsIsAcked(
+      EncryptionLevel decrypted_packet_level) const;
+
+  void SetNetworkChangeVisitor(NetworkChangeVisitor* visitor) {
+    QUICHE_DCHECK(!network_change_visitor_);
+    QUICHE_DCHECK(visitor);
+    network_change_visitor_ = visitor;
+  }
+
+  bool InSlowStart() const { return send_algorithm_->InSlowStart(); }
+
+  size_t GetConsecutiveRtoCount() const { return consecutive_rto_count_; }
+
+  size_t GetConsecutiveTlpCount() const { return consecutive_tlp_count_; }
+
+  size_t GetConsecutivePtoCount() const { return consecutive_pto_count_; }
+
+  void OnApplicationLimited();
+
+  const SendAlgorithmInterface* GetSendAlgorithm() const {
+    return send_algorithm_.get();
+  }
+
+  void SetSessionNotifier(SessionNotifierInterface* session_notifier) {
+    unacked_packets_.SetSessionNotifier(session_notifier);
+  }
+
+  NextReleaseTimeResult GetNextReleaseTime() const;
+
+  QuicPacketCount initial_congestion_window() const {
+    return initial_congestion_window_;
+  }
+
+  QuicPacketNumber largest_packet_peer_knows_is_acked() const {
+    QUICHE_DCHECK(!supports_multiple_packet_number_spaces());
+    return largest_packet_peer_knows_is_acked_;
+  }
+
+  size_t pending_timer_transmission_count() const {
+    return pending_timer_transmission_count_;
+  }
+
+  QuicTime::Delta peer_max_ack_delay() const { return peer_max_ack_delay_; }
+
+  void set_peer_max_ack_delay(QuicTime::Delta peer_max_ack_delay) {
+    // The delayed ack time should never be more than one half the min RTO time.
+    QUICHE_DCHECK_LE(peer_max_ack_delay, (min_rto_timeout_ * 0.5));
+    peer_max_ack_delay_ = peer_max_ack_delay;
+  }
+
+  const QuicUnackedPacketMap& unacked_packets() const {
+    return unacked_packets_;
+  }
+
+  const UberLossAlgorithm* uber_loss_algorithm() const {
+    return &uber_loss_algorithm_;
+  }
+
+  // Sets the send algorithm to the given congestion control type and points the
+  // pacing sender at |send_algorithm_|. Can be called any number of times.
+  void SetSendAlgorithm(CongestionControlType congestion_control_type);
+
+  // Sets the send algorithm to |send_algorithm| and points the pacing sender at
+  // |send_algorithm_|. Takes ownership of |send_algorithm|. Can be called any
+  // number of times.
+  // Setting the send algorithm once the connection is underway is dangerous.
+  void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm);
+
+  // Sends up to max_probe_packets_per_pto_ probe packets.
+  void MaybeSendProbePackets();
+
+  // Called to adjust pending_timer_transmission_count_ accordingly.
+  void AdjustPendingTimerTransmissions();
+
+  // Called to disable HANDSHAKE_MODE, and only PTO and LOSS modes are used.
+  // Also enable IETF loss detection.
+  void EnableIetfPtoAndLossDetection();
+
+  // Called to set the start point of doing exponential backoff when calculating
+  // PTO timeout.
+  void StartExponentialBackoffAfterNthPto(
+      size_t exponential_backoff_start_point);
+
+  // Called to retransmit in flight packet of |space| if any.
+  void RetransmitDataOfSpaceIfAny(PacketNumberSpace space);
+
+  // Returns true if |timeout| is less than 3 * RTO/PTO delay.
+  bool IsLessThanThreePTOs(QuicTime::Delta timeout) const;
+
+  // Returns current PTO delay.
+  QuicTime::Delta GetPtoDelay() const;
+
+  bool supports_multiple_packet_number_spaces() const {
+    return unacked_packets_.supports_multiple_packet_number_spaces();
+  }
+
+  bool pto_enabled() const { return pto_enabled_; }
+
+  bool handshake_mode_disabled() const { return handshake_mode_disabled_; }
+
+  bool skip_packet_number_for_pto() const {
+    return skip_packet_number_for_pto_;
+  }
+
+  bool zero_rtt_packet_acked() const { return zero_rtt_packet_acked_; }
+
+  bool one_rtt_packet_acked() const { return one_rtt_packet_acked_; }
+
+  void OnUserAgentIdKnown() { loss_algorithm_->OnUserAgentIdKnown(); }
+
+  // Gets the earliest in flight packet sent time to calculate PTO. Also
+  // updates |packet_number_space| if a PTO timer should be armed.
+  QuicTime GetEarliestPacketSentTimeForPto(
+      PacketNumberSpace* packet_number_space) const;
+
+  void set_num_ptos_for_path_degrading(int num_ptos_for_path_degrading) {
+    num_ptos_for_path_degrading_ = num_ptos_for_path_degrading;
+  }
+
+  // Sets the initial RTT of the connection. The inital RTT is clamped to
+  // - A maximum of kMaxInitialRoundTripTimeUs.
+  // - A minimum of kMinTrustedInitialRoundTripTimeUs if |trusted|, or
+  // kMinUntrustedInitialRoundTripTimeUs if not |trusted|.
+  void SetInitialRtt(QuicTime::Delta rtt, bool trusted);
+
+  bool use_lower_min_irtt() const { return use_lower_min_irtt_; }
+
+  bool simplify_set_retransmission_alarm() const {
+    return simplify_set_retransmission_alarm_;
+  }
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::QuicSentPacketManagerPeer;
+
+  // Returns the current retransmission mode.
+  RetransmissionTimeoutMode GetRetransmissionMode() const;
+
+  // Retransmits all crypto stream packets.
+  void RetransmitCryptoPackets();
+
+  // Retransmits two packets for an RTO and removes any non-retransmittable
+  // packets from flight.
+  void RetransmitRtoPackets();
+
+  // Returns the timeout for retransmitting crypto handshake packets.
+  const QuicTime::Delta GetCryptoRetransmissionDelay() const;
+
+  // Calls GetTailLossProbeDelay() with values from the current state of this
+  // packet manager as its params.
+  const QuicTime::Delta GetTailLossProbeDelay() const;
+
+  // Calls GetRetransmissionDelay() with values from the current state of this
+  // packet manager as its params.
+  const QuicTime::Delta GetRetransmissionDelay() const;
+
+  // Returns the probe timeout.
+  const QuicTime::Delta GetProbeTimeoutDelay(PacketNumberSpace space) const;
+
+  // Update the RTT if the ack is for the largest acked packet number.
+  // Returns true if the rtt was updated.
+  bool MaybeUpdateRTT(QuicPacketNumber largest_acked,
+                      QuicTime::Delta ack_delay_time,
+                      QuicTime ack_receive_time);
+
+  // Invokes the loss detection algorithm and loses and retransmits packets if
+  // necessary.
+  void InvokeLossDetection(QuicTime time);
+
+  // Invokes OnCongestionEvent if |rtt_updated| is true, there are pending acks,
+  // or pending losses.  Clears pending acks and pending losses afterwards.
+  // |prior_in_flight| is the number of bytes in flight before the losses or
+  // acks, |event_time| is normally the timestamp of the ack packet which caused
+  // the event, although it can be the time at which loss detection was
+  // triggered.
+  void MaybeInvokeCongestionEvent(bool rtt_updated,
+                                  QuicByteCount prior_in_flight,
+                                  QuicTime event_time);
+
+  // Removes the retransmittability and in flight properties from the packet at
+  // |info| due to receipt by the peer.
+  void MarkPacketHandled(QuicPacketNumber packet_number,
+                         QuicTransmissionInfo* info,
+                         QuicTime ack_receive_time,
+                         QuicTime::Delta ack_delay_time,
+                         QuicTime receive_timestamp);
+
+  // Request that |packet_number| be retransmitted after the other pending
+  // retransmissions.  Does not add it to the retransmissions if it's already
+  // a pending retransmission. Do not reuse iterator of the underlying
+  // unacked_packets_ after calling this function as it can be invalidated.
+  void MarkForRetransmission(QuicPacketNumber packet_number,
+                             TransmissionType transmission_type);
+
+  // Called after packets have been marked handled with last received ack frame.
+  void PostProcessNewlyAckedPackets(QuicPacketNumber ack_packet_number,
+                                    EncryptionLevel ack_decrypted_level,
+                                    const QuicAckFrame& ack_frame,
+                                    QuicTime ack_receive_time,
+                                    bool rtt_updated,
+                                    QuicByteCount prior_bytes_in_flight);
+
+  // Notify observers that packet with QuicTransmissionInfo |info| is a spurious
+  // retransmission. It is caller's responsibility to guarantee the packet with
+  // QuicTransmissionInfo |info| is a spurious retransmission before calling
+  // this function.
+  void RecordOneSpuriousRetransmission(const QuicTransmissionInfo& info);
+
+  // Called when handshake is confirmed to remove the retransmittable frames
+  // from all packets of HANDSHAKE_DATA packet number space to ensure they don't
+  // get retransmitted and will eventually be removed from unacked packets map.
+  void NeuterHandshakePackets();
+
+  // Indicates whether including peer_max_ack_delay_ when calculating PTO
+  // timeout.
+  bool ShouldAddMaxAckDelay(PacketNumberSpace space) const;
+
+  // A helper function to return total delay of |num_timeouts| retransmission
+  // timeout with TLP and RTO mode.
+  QuicTime::Delta GetNConsecutiveRetransmissionTimeoutDelay(
+      int num_timeouts) const;
+
+  // Returns true if peer has finished address validation, such that
+  // retransmission timer is not armed if there is no packets in flight.
+  bool PeerCompletedAddressValidation() const;
+
+  // Called when an AckFrequencyFrame is sent.
+  void OnAckFrequencyFrameSent(
+      const QuicAckFrequencyFrame& ack_frequency_frame);
+
+  // Called when an AckFrequencyFrame is acked.
+  void OnAckFrequencyFrameAcked(
+      const QuicAckFrequencyFrame& ack_frequency_frame);
+
+  // Newly serialized retransmittable packets are added to this map, which
+  // contains owning pointers to any contained frames.  If a packet is
+  // retransmitted, this map will contain entries for both the old and the new
+  // packet. The old packet's retransmittable frames entry will be nullptr,
+  // while the new packet's entry will contain the frames to retransmit.
+  // If the old packet is acked before the new packet, then the old entry will
+  // be removed from the map and the new entry's retransmittable frames will be
+  // set to nullptr.
+  QuicUnackedPacketMap unacked_packets_;
+
+  const QuicClock* clock_;
+  QuicRandom* random_;
+  QuicConnectionStats* stats_;
+
+  DebugDelegate* debug_delegate_;
+  NetworkChangeVisitor* network_change_visitor_;
+  QuicPacketCount initial_congestion_window_;
+  RttStats rtt_stats_;
+  std::unique_ptr<SendAlgorithmInterface> send_algorithm_;
+  // Not owned. Always points to |uber_loss_algorithm_| outside of tests.
+  LossDetectionInterface* loss_algorithm_;
+  UberLossAlgorithm uber_loss_algorithm_;
+
+  // Tracks the first RTO packet.  If any packet before that packet gets acked,
+  // it indicates the RTO was spurious and should be reversed(F-RTO).
+  QuicPacketNumber first_rto_transmission_;
+  // Number of times the RTO timer has fired in a row without receiving an ack.
+  size_t consecutive_rto_count_;
+  // Number of times the tail loss probe has been sent.
+  size_t consecutive_tlp_count_;
+  // Number of times the crypto handshake has been retransmitted.
+  size_t consecutive_crypto_retransmission_count_;
+  // Number of pending transmissions of TLP, RTO, or crypto packets.
+  size_t pending_timer_transmission_count_;
+  // Maximum number of tail loss probes to send before firing an RTO.
+  size_t max_tail_loss_probes_;
+  // Maximum number of packets to send upon RTO.
+  QuicPacketCount max_rto_packets_;
+  // If true, send the TLP at 0.5 RTT.
+  bool using_pacing_;
+  // If true, use the new RTO with loss based CWND reduction instead of the send
+  // algorithms's OnRetransmissionTimeout to reduce the congestion window.
+  bool use_new_rto_;
+  // If true, use a more conservative handshake retransmission policy.
+  bool conservative_handshake_retransmits_;
+  // The minimum TLP timeout.
+  QuicTime::Delta min_tlp_timeout_;
+  // The minimum RTO.
+  QuicTime::Delta min_rto_timeout_;
+
+  // Vectors packets acked and lost as a result of the last congestion event.
+  AckedPacketVector packets_acked_;
+  LostPacketVector packets_lost_;
+  // Largest newly acknowledged packet.
+  QuicPacketNumber largest_newly_acked_;
+  // Largest packet in bytes ever acknowledged.
+  QuicPacketLength largest_mtu_acked_;
+
+  // Replaces certain calls to |send_algorithm_| when |using_pacing_| is true.
+  // Calls into |send_algorithm_| for the underlying congestion control.
+  PacingSender pacing_sender_;
+
+  // Indicates whether handshake is finished. This is purely used to determine
+  // retransmission mode. DONOT use this to infer handshake state.
+  bool handshake_finished_;
+
+  // Records bandwidth from server to client in normal operation, over periods
+  // of time with no loss events.
+  QuicSustainedBandwidthRecorder sustained_bandwidth_recorder_;
+
+  // The largest acked value that was sent in an ack, which has then been acked.
+  QuicPacketNumber largest_packet_peer_knows_is_acked_;
+  // The largest acked value that was sent in an ack, which has then been acked
+  // for per packet number space. Only used when connection supports multiple
+  // packet number spaces.
+  QuicPacketNumber
+      largest_packets_peer_knows_is_acked_[NUM_PACKET_NUMBER_SPACES];
+
+  // The maximum ACK delay time that the peer might uses. Initialized to be the
+  // same as local_max_ack_delay_, may be changed via transport parameter
+  // negotiation or subsequently by AckFrequencyFrame.
+  QuicTime::Delta peer_max_ack_delay_;
+
+  // Peer sends min_ack_delay in TransportParameter to advertise its support for
+  // AckFrequencyFrame.
+  QuicTime::Delta peer_min_ack_delay_ = QuicTime::Delta::Infinite();
+
+  // Use smoothed RTT for computing max_ack_delay in AckFrequency frame.
+  bool use_smoothed_rtt_in_ack_delay_ = false;
+
+  // The history of outstanding max_ack_delays sent to peer. Outstanding means
+  // a max_ack_delay is sent as part of the last acked AckFrequencyFrame or
+  // an unacked AckFrequencyFrame after that.
+  quiche::QuicheCircularDeque<
+      std::pair<QuicTime::Delta, /*sequence_number=*/uint64_t>>
+      in_use_sent_ack_delays_;
+
+  // Latest received ack frame.
+  QuicAckFrame last_ack_frame_;
+
+  // Record whether RTT gets updated by last largest acked..
+  bool rtt_updated_;
+
+  // A reverse iterator of last_ack_frame_.packets. This is reset in
+  // OnAckRangeStart, and gradually moves in OnAckRange..
+  PacketNumberQueue::const_reverse_iterator acked_packets_iter_;
+
+  // Indicates whether PTO mode has been enabled. PTO mode unifies TLP and RTO
+  // modes.
+  bool pto_enabled_;
+
+  // Maximum number of probes to send when PTO fires.
+  size_t max_probe_packets_per_pto_;
+
+  // Number of times the PTO timer has fired in a row without receiving an ack.
+  size_t consecutive_pto_count_;
+
+  // True if HANDSHAKE mode has been disabled.
+  bool handshake_mode_disabled_;
+
+  // If true, skip packet number before sending the last PTO retransmission.
+  bool skip_packet_number_for_pto_;
+
+  // If true, always include peer_max_ack_delay_ when calculating PTO timeout.
+  bool always_include_max_ack_delay_for_pto_timeout_;
+
+  // When calculating PTO timeout, the start point of doing exponential backoff.
+  // For example, 0 : always do exponential backoff. n : do exponential backoff
+  // since nth PTO.
+  size_t pto_exponential_backoff_start_point_;
+
+  // The multiplier of rttvar when calculating PTO timeout.
+  int pto_rttvar_multiplier_;
+
+  // Number of PTOs similar to TLPs.
+  size_t num_tlp_timeout_ptos_;
+
+  // True if any ENCRYPTION_HANDSHAKE packet gets acknowledged.
+  bool handshake_packet_acked_;
+
+  // True if any 0-RTT packet gets acknowledged.
+  bool zero_rtt_packet_acked_;
+
+  // True if any 1-RTT packet gets acknowledged.
+  bool one_rtt_packet_acked_;
+
+  // If > 0, arm the 1st PTO with max of earliest in flight sent time + PTO
+  // delay and multiplier * srtt from last in flight packet.
+  float first_pto_srtt_multiplier_;
+
+  // If true, use standard deviation (instead of mean deviation) when
+  // calculating PTO timeout.
+  bool use_standard_deviation_for_pto_;
+
+  // The multiplier for caculating PTO timeout before any RTT sample is
+  // available.
+  float pto_multiplier_without_rtt_samples_;
+
+  // The number of PTOs needed for path degrading alarm. If equals to 0, the
+  // traditional path degrading mechanism will be used.
+  int num_ptos_for_path_degrading_;
+
+  // If true, do not use PING only packets for RTT measurement or congestion
+  // control.
+  bool ignore_pings_;
+
+  // Whether to ignore the ack_delay in received ACKs.
+  bool ignore_ack_delay_;
+
+  // Latched value of --quic_use_lower_min_for_trusted_irtt.
+  bool use_lower_min_irtt_ =
+      GetQuicReloadableFlag(quic_use_lower_min_for_trusted_irtt);
+
+  const bool simplify_set_retransmission_alarm_ =
+      GetQuicReloadableFlag(quic_simplify_set_retransmission_alarm);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
diff --git a/quiche/quic/core/quic_sent_packet_manager_test.cc b/quiche/quic/core/quic_sent_packet_manager_test.cc
new file mode 100644
index 0000000..61e7f2a
--- /dev/null
+++ b/quiche/quic/core/quic_sent_packet_manager_test.cc
@@ -0,0 +1,4744 @@
+// Copyright 2013 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 "quiche/quic/core/quic_sent_packet_manager.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::IsEmpty;
+using testing::Not;
+using testing::Pointwise;
+using testing::Return;
+using testing::StrictMock;
+using testing::WithArgs;
+
+namespace quic {
+namespace test {
+namespace {
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+// Stream ID for data sent in CreatePacket().
+const QuicStreamId kStreamId = 7;
+
+// Matcher to check that the packet number matches the second argument.
+MATCHER(PacketNumberEq, "") {
+  return std::get<0>(arg).packet_number == QuicPacketNumber(std::get<1>(arg));
+}
+
+class MockDebugDelegate : public QuicSentPacketManager::DebugDelegate {
+ public:
+  MOCK_METHOD(void, OnSpuriousPacketRetransmission,
+              (TransmissionType transmission_type, QuicByteCount byte_size),
+              (override));
+  MOCK_METHOD(void, OnPacketLoss,
+              (QuicPacketNumber lost_packet_number,
+               EncryptionLevel encryption_level,
+               TransmissionType transmission_type, QuicTime detection_time),
+              (override));
+};
+
+class QuicSentPacketManagerTest : public QuicTest {
+ public:
+  bool RetransmitCryptoPacket(uint64_t packet_number) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.retransmittable_frames.push_back(
+        QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view())));
+    packet.has_crypto_handshake = IS_HANDSHAKE;
+    manager_.OnPacketSent(&packet, clock_.Now(), HANDSHAKE_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, true);
+    return true;
+  }
+
+  bool RetransmitDataPacket(uint64_t packet_number, TransmissionType type,
+                            EncryptionLevel level) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, true));
+    packet.encryption_level = level;
+    manager_.OnPacketSent(&packet, clock_.Now(), type, HAS_RETRANSMITTABLE_DATA,
+                          true);
+    return true;
+  }
+
+  bool RetransmitDataPacket(uint64_t packet_number, TransmissionType type) {
+    return RetransmitDataPacket(packet_number, type, ENCRYPTION_INITIAL);
+  }
+
+ protected:
+  const CongestionControlType kInitialCongestionControlType = kCubicBytes;
+  QuicSentPacketManagerTest()
+      : manager_(Perspective::IS_SERVER, &clock_, QuicRandom::GetInstance(),
+                 &stats_, kInitialCongestionControlType),
+        send_algorithm_(new StrictMock<MockSendAlgorithm>),
+        network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>) {
+    QuicSentPacketManagerPeer::SetSendAlgorithm(&manager_, send_algorithm_);
+    // Disable tail loss probes for most tests.
+    QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 0);
+    // Advance the time 1s so the send times are never QuicTime::Zero.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+    manager_.SetNetworkChangeVisitor(network_change_visitor_.get());
+    manager_.SetSessionNotifier(&notifier_);
+
+    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
+        .WillRepeatedly(Return(kInitialCongestionControlType));
+    EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(QuicBandwidth::Zero()));
+    EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, OnPacketNeutered(_)).Times(AnyNumber());
+    EXPECT_CALL(*network_change_visitor_, OnPathMtuIncreased(1000))
+        .Times(AnyNumber());
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+    EXPECT_CALL(notifier_, HasUnackedCryptoData())
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(notifier_, OnStreamFrameRetransmitted(_)).Times(AnyNumber());
+    EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillRepeatedly(Return(true));
+  }
+
+  ~QuicSentPacketManagerTest() override {}
+
+  QuicByteCount BytesInFlight() { return manager_.GetBytesInFlight(); }
+  void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
+    if (num_packets == 0) {
+      EXPECT_TRUE(manager_.unacked_packets().empty());
+      EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
+                        &manager_));
+      return;
+    }
+
+    EXPECT_FALSE(manager_.unacked_packets().empty());
+    EXPECT_EQ(QuicPacketNumber(packets[0]), manager_.GetLeastUnacked());
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(
+          manager_.unacked_packets().IsUnacked(QuicPacketNumber(packets[i])))
+          << packets[i];
+    }
+  }
+
+  void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
+    EXPECT_EQ(
+        num_packets,
+        QuicSentPacketManagerPeer::GetNumRetransmittablePackets(&manager_));
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(QuicSentPacketManagerPeer::HasRetransmittableFrames(
+          &manager_, packets[i]))
+          << " packets[" << i << "]:" << packets[i];
+    }
+  }
+
+  void ExpectAck(uint64_t largest_observed) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        // Ensure the AckedPacketVector argument contains largest_observed.
+        OnCongestionEvent(true, _, _,
+                          Pointwise(PacketNumberEq(), {largest_observed}),
+                          IsEmpty()));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  }
+
+  void ExpectUpdatedRtt(uint64_t /*largest_observed*/) {
+    EXPECT_CALL(*send_algorithm_,
+                OnCongestionEvent(true, _, _, IsEmpty(), IsEmpty()));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  }
+
+  void ExpectAckAndLoss(bool rtt_updated, uint64_t largest_observed,
+                        uint64_t lost_packet) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnCongestionEvent(rtt_updated, _, _,
+                          Pointwise(PacketNumberEq(), {largest_observed}),
+                          Pointwise(PacketNumberEq(), {lost_packet})));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  }
+
+  // |packets_acked| and |packets_lost| should be in packet number order.
+  void ExpectAcksAndLosses(bool rtt_updated, uint64_t* packets_acked,
+                           size_t num_packets_acked, uint64_t* packets_lost,
+                           size_t num_packets_lost) {
+    std::vector<QuicPacketNumber> ack_vector;
+    for (size_t i = 0; i < num_packets_acked; ++i) {
+      ack_vector.push_back(QuicPacketNumber(packets_acked[i]));
+    }
+    std::vector<QuicPacketNumber> lost_vector;
+    for (size_t i = 0; i < num_packets_lost; ++i) {
+      lost_vector.push_back(QuicPacketNumber(packets_lost[i]));
+    }
+    EXPECT_CALL(*send_algorithm_,
+                OnCongestionEvent(rtt_updated, _, _,
+                                  Pointwise(PacketNumberEq(), ack_vector),
+                                  Pointwise(PacketNumberEq(), lost_vector)));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
+        .Times(AnyNumber());
+  }
+
+  void RetransmitAndSendPacket(uint64_t old_packet_number,
+                               uint64_t new_packet_number) {
+    RetransmitAndSendPacket(old_packet_number, new_packet_number,
+                            TLP_RETRANSMISSION);
+  }
+
+  void RetransmitAndSendPacket(uint64_t old_packet_number,
+                               uint64_t new_packet_number,
+                               TransmissionType transmission_type) {
+    bool is_lost = false;
+    if (transmission_type == HANDSHAKE_RETRANSMISSION ||
+        transmission_type == TLP_RETRANSMISSION ||
+        transmission_type == RTO_RETRANSMISSION ||
+        transmission_type == PROBING_RETRANSMISSION) {
+      EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+          .WillOnce(WithArgs<1>(
+              Invoke([this, new_packet_number](TransmissionType type) {
+                return RetransmitDataPacket(new_packet_number, type);
+              })));
+    } else {
+      EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+      is_lost = true;
+    }
+    QuicSentPacketManagerPeer::MarkForRetransmission(
+        &manager_, old_packet_number, transmission_type);
+    if (!is_lost) {
+      return;
+    }
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(new_packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(new_packet_number, true));
+    manager_.OnPacketSent(&packet, clock_.Now(), transmission_type,
+                          HAS_RETRANSMITTABLE_DATA, true);
+  }
+
+  SerializedPacket CreateDataPacket(uint64_t packet_number) {
+    return CreatePacket(packet_number, true);
+  }
+
+  SerializedPacket CreatePacket(uint64_t packet_number, bool retransmittable) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+    if (retransmittable) {
+      packet.retransmittable_frames.push_back(
+          QuicFrame(QuicStreamFrame(kStreamId, false, 0, absl::string_view())));
+    }
+    return packet;
+  }
+
+  SerializedPacket CreatePingPacket(uint64_t packet_number) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+    packet.retransmittable_frames.push_back(QuicFrame(QuicPingFrame()));
+    return packet;
+  }
+
+  void SendDataPacket(uint64_t packet_number) {
+    SendDataPacket(packet_number, ENCRYPTION_INITIAL);
+  }
+
+  void SendDataPacket(uint64_t packet_number,
+                      EncryptionLevel encryption_level) {
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(),
+                             QuicPacketNumber(packet_number), _, _));
+    SerializedPacket packet(CreateDataPacket(packet_number));
+    packet.encryption_level = encryption_level;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, true);
+  }
+
+  void SendPingPacket(uint64_t packet_number,
+                      EncryptionLevel encryption_level) {
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(),
+                             QuicPacketNumber(packet_number), _, _));
+    SerializedPacket packet(CreatePingPacket(packet_number));
+    packet.encryption_level = encryption_level;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, true);
+  }
+
+  void SendCryptoPacket(uint64_t packet_number) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.retransmittable_frames.push_back(
+        QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view())));
+    packet.has_crypto_handshake = IS_HANDSHAKE;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, true);
+    EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(true));
+  }
+
+  void SendAckPacket(uint64_t packet_number, uint64_t largest_acked) {
+    SendAckPacket(packet_number, largest_acked, ENCRYPTION_INITIAL);
+  }
+
+  void SendAckPacket(uint64_t packet_number, uint64_t largest_acked,
+                     EncryptionLevel level) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, NO_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.largest_acked = QuicPacketNumber(largest_acked);
+    packet.encryption_level = level;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          NO_RETRANSMITTABLE_DATA, true);
+  }
+
+  void EnablePto(QuicTag tag) {
+    QuicConfig config;
+    QuicTagVector options;
+    options.push_back(tag);
+    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+    manager_.SetFromConfig(config);
+    EXPECT_TRUE(manager_.pto_enabled());
+  }
+
+  int GetPtoRttvarMultiplier() {
+    if (GetQuicRestartFlag(quic_default_on_pto2) ||
+        manager_.handshake_mode_disabled()) {
+      return 2;
+    }
+    return 4;
+  }
+
+  quiche::SimpleBufferAllocator allocator_;
+  QuicSentPacketManager manager_;
+  MockClock clock_;
+  QuicConnectionStats stats_;
+  MockSendAlgorithm* send_algorithm_;
+  std::unique_ptr<MockNetworkChangeVisitor> network_change_visitor_;
+  StrictMock<MockSessionNotifier> notifier_;
+};
+
+TEST_F(QuicSentPacketManagerTest, IsUnacked) {
+  VerifyUnackedPackets(nullptr, 0);
+  SendDataPacket(1);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+}
+
+TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_, 2));
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  std::vector<uint64_t> retransmittable = {1, 2};
+  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  // Ack 2 but not 1.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  // Packet 1 is unacked, pending, but not retransmittable.
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
+  SendDataPacket(1);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(2, type);
+      })));
+  QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
+                                                   TLP_RETRANSMISSION);
+  // Ack 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  // We do not know packet 2 is a spurious retransmission until it gets acked.
+  VerifyRetransmittablePackets(nullptr, 0);
+  EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenStopRetransmittingBeforeSend) {
+  SendDataPacket(1);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _)).WillRepeatedly(Return(true));
+  QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
+                                                   TLP_RETRANSMISSION);
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+  EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
+  clock_.AdvanceTime(rtt);
+
+  // Ack 1 but not 2.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  // 2 remains unacked, but no packets have retransmittable data.
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+  // Ack 2 causes 2 be considered as spurious retransmission.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillOnce(Return(false));
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
+  clock_.AdvanceTime(rtt);
+
+  // First, ACK packet 1 which makes packet 2 non-retransmittable.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  SendDataPacket(3);
+  SendDataPacket(4);
+  SendDataPacket(5);
+  clock_.AdvanceTime(rtt);
+
+  // Next, NACK packet 2 three times.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  ExpectAckAndLoss(true, 3, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+
+  ExpectAck(4);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_INITIAL));
+
+  ExpectAck(5);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_INITIAL));
+
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  // Verify that the retransmission alarm would not fire,
+  // since there is no retransmittable data outstanding.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       DISABLED_RetransmitTwiceThenAckPreviousBeforeSend) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  // Fire the RTO, which will mark 2 for retransmission (but will not send it).
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.OnRetransmissionTimeout();
+
+  // Ack 1 but not 2, before 2 is able to be sent.
+  // Since 1 has been retransmitted, it has already been lost, and so the
+  // send algorithm is not informed that it has been ACK'd.
+  ExpectUpdatedRtt(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT.
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  // Verify that the retransmission alarm would not fire,
+  // since there is no retransmittable data outstanding.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
+  StrictMock<MockDebugDelegate> debug_delegate;
+  EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(TLP_RETRANSMISSION,
+                                                             kDefaultLength))
+      .Times(1);
+  manager_.SetDebugDelegate(&debug_delegate);
+
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+  RetransmitAndSendPacket(2, 3);
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
+  clock_.AdvanceTime(rtt);
+
+  // Ack 1 but not 2 or 3.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  // Frames in packets 2 and 3 are acked.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_))
+      .Times(2)
+      .WillRepeatedly(Return(false));
+
+  // 2 and 3 remain unacked, but no packets have retransmittable data.
+  uint64_t unacked[] = {2, 3};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  // Ensure packet 2 is lost when 4 is sent and 3 and 4 are acked.
+  SendDataPacket(4);
+  // No new data gets acked in packet 3.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
+      .WillOnce(Return(false))
+      .WillRepeatedly(Return(true));
+  uint64_t acked[] = {3, 4};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+
+  uint64_t unacked2[] = {2};
+  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+
+  SendDataPacket(5);
+  ExpectAckAndLoss(true, 5, 2);
+  EXPECT_CALL(debug_delegate,
+              OnPacketLoss(QuicPacketNumber(2), _, LOSS_RETRANSMISSION, _));
+  // Frames in all packets are acked.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  // Notify session that stream frame in packet 2 gets lost although it is
+  // not outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_INITIAL));
+
+  uint64_t unacked3[] = {2};
+  VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3));
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  // Spurious retransmission is detected when packet 3 gets acked. We cannot
+  // know packet 2 is a spurious until it gets acked.
+  EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
+  EXPECT_EQ(1u, stats_.packets_lost);
+  EXPECT_LT(0.0, stats_.total_loss_detection_response_time);
+  EXPECT_LE(1u, stats_.sent_packets_max_sequence_reordering);
+}
+
+TEST_F(QuicSentPacketManagerTest, AckOriginalTransmission) {
+  auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
+  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
+
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  // Ack original transmission, but that wasn't lost via fast retransmit,
+  // so no call on OnSpuriousRetransmission is expected.
+  {
+    ExpectAck(1);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_EQ(PACKETS_NEWLY_ACKED,
+              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                     ENCRYPTION_INITIAL));
+  }
+
+  SendDataPacket(3);
+  SendDataPacket(4);
+  // Ack 4, which causes 3 to be retransmitted.
+  {
+    ExpectAck(4);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_EQ(PACKETS_NEWLY_ACKED,
+              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                     ENCRYPTION_INITIAL));
+    RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
+  }
+
+  // Ack 3, which causes SpuriousRetransmitDetected to be called.
+  {
+    uint64_t acked[] = {3};
+    ExpectAcksAndLosses(false, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    EXPECT_CALL(*loss_algorithm,
+                SpuriousLossDetected(_, _, _, QuicPacketNumber(3),
+                                     QuicPacketNumber(4)));
+    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_EQ(0u, stats_.packet_spuriously_detected_lost);
+    EXPECT_EQ(PACKETS_NEWLY_ACKED,
+              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                     ENCRYPTION_INITIAL));
+    EXPECT_EQ(1u, stats_.packet_spuriously_detected_lost);
+    // Ack 3 will not cause 5 be considered as a spurious retransmission. Ack
+    // 5 will cause 5 be considered as a spurious retransmission as no new
+    // data gets acked.
+    ExpectAck(5);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillOnce(Return(false));
+    manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_EQ(PACKETS_NEWLY_ACKED,
+              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                     ENCRYPTION_INITIAL));
+  }
+}
+
+TEST_F(QuicSentPacketManagerTest, GetLeastUnacked) {
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetLeastUnackedUnacked) {
+  SendDataPacket(1);
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
+}
+
+TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
+  EXPECT_FALSE(manager_.largest_packet_peer_knows_is_acked().IsInitialized());
+  SendDataPacket(1);
+  SendAckPacket(2, 1);
+
+  // Now ack the ack and expect an RTT update.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2),
+                           QuicTime::Delta::FromMilliseconds(5), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicPacketNumber(1), manager_.largest_packet_peer_knows_is_acked());
+
+  SendAckPacket(3, 3);
+
+  // Now ack the ack and expect only an RTT update.
+  uint64_t acked2[] = {3};
+  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicPacketNumber(3u),
+            manager_.largest_packet_peer_knows_is_acked());
+}
+
+TEST_F(QuicSentPacketManagerTest, Rtt) {
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(20);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, RttWithInvalidDelta) {
+  // Expect that the RTT is equal to the local time elapsed, since the
+  // ack_delay_time is larger than the local time elapsed
+  // and is hence invalid.
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1),
+                           QuicTime::Delta::FromMilliseconds(11), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, RttWithInfiniteDelta) {
+  // Expect that the RTT is equal to the local time elapsed, since the
+  // ack_delay_time is infinite, and is hence invalid.
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, RttWithDeltaExceedingLimit) {
+  // Initialize min and smoothed rtt to 10ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  QuicTime::Delta send_delta = QuicTime::Delta::FromMilliseconds(100);
+  QuicTime::Delta ack_delay =
+      QuicTime::Delta::FromMilliseconds(5) + manager_.peer_max_ack_delay();
+  ASSERT_GT(send_delta - rtt_stats->min_rtt(), ack_delay);
+  SendDataPacket(1);
+  clock_.AdvanceTime(send_delta);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), ack_delay, clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+
+  QuicTime::Delta expected_rtt_sample =
+      send_delta - manager_.peer_max_ack_delay();
+  EXPECT_EQ(expected_rtt_sample, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, RttZeroDelta) {
+  // Expect that the RTT is the time between send and receive since the
+  // ack_delay_time is zero.
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeout) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+
+  // Send 1 packet.
+  SendDataPacket(1);
+
+  // The first tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(2, type);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+
+  // The second tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+
+  // Ack the third and ensure the first two are still pending.
+  ExpectAck(3);
+
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+
+  // Acking two more packets will lose both of them due to nacks.
+  SendDataPacket(4);
+  SendDataPacket(5);
+  uint64_t acked[] = {4, 5};
+  uint64_t lost[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost,
+                      ABSL_ARRAYSIZE(lost));
+  // Frames in all packets are acked.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  // Notify session that stream frame in packets 1 and 2 get lost although
+  // they are not outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  EXPECT_EQ(2u, stats_.tlp_count);
+  EXPECT_EQ(0u, stats_.rto_count);
+}
+
+TEST_F(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  QuicTime rto_packet_time = clock_.Now();
+  // Advance the time.
+  clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
+
+  // The first tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(101, type);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+  clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
+
+  // The second tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(102, type);
+      })));
+  EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+
+  // Ensure the RTO is set based on the correct packet.
+  rto_packet_time = clock_.Now();
+  EXPECT_EQ(rto_packet_time + QuicTime::Delta::FromMilliseconds(500),
+            manager_.GetRetransmissionTime());
+
+  // Advance the time enough to ensure all packets are RTO'd.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(103, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(104, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(2u, stats_.tlp_count);
+  EXPECT_EQ(1u, stats_.rto_count);
+  EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
+  // There are 2 RTO retransmissions.
+  EXPECT_EQ(104 * kDefaultLength, manager_.GetBytesInFlight());
+  QuicPacketNumber largest_acked = QuicPacketNumber(103);
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(
+                  true, _, _, Pointwise(PacketNumberEq(), {largest_acked}), _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  // Although frames in packet 3 gets acked, it would be kept for another
+  // RTT.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+  // Packets [1, 102] are lost, although stream frame in packet 3 is not
+  // outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(102);
+  manager_.OnAckFrameStart(QuicPacketNumber(103), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(103), QuicPacketNumber(104));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  // All packets before 103 should be lost.
+  // Packet 104 is still in flight.
+  EXPECT_EQ(1000u, manager_.GetBytesInFlight());
+  EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
+}
+
+TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeout) {
+  // Send 2 crypto packets and 3 data packets.
+  const size_t kNumSentCryptoPackets = 2;
+  for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
+    SendCryptoPacket(i);
+  }
+  const size_t kNumSentDataPackets = 3;
+  for (size_t i = 1; i <= kNumSentDataPackets; ++i) {
+    SendDataPacket(kNumSentCryptoPackets + i);
+  }
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+  EXPECT_EQ(5 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // The first retransmits 2 packets.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(6); }))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(7); }));
+  manager_.OnRetransmissionTimeout();
+  // Expect all 4 handshake packets to be in flight and 3 data packets.
+  EXPECT_EQ(7 * kDefaultLength, manager_.GetBytesInFlight());
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // The second retransmits 2 packets.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(8); }))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(9); }));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(9 * kDefaultLength, manager_.GetBytesInFlight());
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Now ack the two crypto packets and the speculatively encrypted request,
+  // and ensure the first four crypto packets get abandoned, but not lost.
+  // Crypto packets remain in flight, so any that aren't acked will be lost.
+  uint64_t acked[] = {3, 4, 5, 8, 9};
+  uint64_t lost[] = {1, 2, 6};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost,
+                      ABSL_ARRAYSIZE(lost));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(3);
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(8), QuicPacketNumber(10));
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
+}
+
+TEST_F(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
+  // Send 1 crypto packet.
+  SendCryptoPacket(1);
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Retransmit the crypto packet as 2.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
+  manager_.OnRetransmissionTimeout();
+
+  // Retransmit the crypto packet as 3.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(3); }));
+  manager_.OnRetransmissionTimeout();
+
+  // Now ack the second crypto packet, and ensure the first gets removed, but
+  // the third does not.
+  uint64_t acked[] = {2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
+  uint64_t unacked[] = {1, 3};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+}
+
+TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutUnsentDataPacket) {
+  // Send 2 crypto packets and 1 data packet.
+  const size_t kNumSentCryptoPackets = 2;
+  for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
+    SendCryptoPacket(i);
+  }
+  SendDataPacket(3);
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Retransmit 2 crypto packets, but not the serialized packet.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(4); }))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(5); }));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       CryptoHandshakeRetransmissionThenNeuterAndAck) {
+  // Send 1 crypto packet.
+  SendCryptoPacket(1);
+
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Retransmit the crypto packet as 2.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Retransmit the crypto packet as 3.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(3); }));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Now neuter all unacked unencrypted packets, which occurs when the
+  // connection goes forward secure.
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
+  uint64_t unacked[] = {1, 2, 3};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+
+  // Ensure both packets get discarded when packet 2 is acked.
+  uint64_t acked[] = {3};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  VerifyUnackedPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmissionTimeout) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  StrictMock<MockDebugDelegate> debug_delegate;
+  manager_.SetDebugDelegate(&debug_delegate);
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+
+  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(101, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(102, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(102 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Ack a retransmission.
+  // Ensure no packets are lost.
+  QuicPacketNumber largest_acked = QuicPacketNumber(102);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(true, _, _,
+                                Pointwise(PacketNumberEq(), {largest_acked}),
+                                /*lost_packets=*/IsEmpty()));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  // RTO's use loss detection instead of immediately declaring retransmitted
+  // packets lost.
+  for (int i = 1; i <= 99; ++i) {
+    EXPECT_CALL(debug_delegate,
+                OnPacketLoss(QuicPacketNumber(i), _, LOSS_RETRANSMISSION, _));
+  }
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+  // Packets [1, 99] are considered as lost, although stream frame in packet
+  // 2 is not outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
+  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmissionTimeoutOnePacket) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  // Set the 1RTO connection option.
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(k1RTO);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(client_config);
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  StrictMock<MockDebugDelegate> debug_delegate;
+  manager_.SetDebugDelegate(&debug_delegate);
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+
+  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(1)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(101, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(101 * kDefaultLength, manager_.GetBytesInFlight());
+}
+
+TEST_F(QuicSentPacketManagerTest, NewRetransmissionTimeout) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(kNRTO);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+
+  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(101, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(102, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(102 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Ack a retransmission and expect no call to OnRetransmissionTimeout.
+  // This will include packets in the lost packet map.
+  QuicPacketNumber largest_acked = QuicPacketNumber(102);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(true, _, _,
+                                Pointwise(PacketNumberEq(), {largest_acked}),
+                                /*lost_packets=*/Not(IsEmpty())));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+  // Packets [1, 99] are considered as lost, although stream frame in packet
+  // 2 is not outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
+  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckSecond) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  // Send 1 packet.
+  SendDataPacket(1);
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(2, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Rto a second time.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(3 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Ack a retransmission and ensure OnRetransmissionTimeout is called.
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // The original packet and newest should be outstanding.
+  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
+}
+
+TEST_F(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckFirst) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  // Send 1 packet.
+  SendDataPacket(1);
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(2, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Rto a second time.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(3 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Ack a retransmission and ensure OnRetransmissionTimeout is called.
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  ExpectAck(3);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // The first two packets should still be outstanding.
+  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionTime) {
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeCryptoHandshake) {
+  QuicTime crypto_packet_send_time = clock_.Now();
+  SendCryptoPacket(1);
+
+  // Check the min.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10),
+            manager_.GetRetransmissionTime());
+
+  // Test with a standard smoothed RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
+
+  QuicTime::Delta srtt = rtt_stats->initial_rtt();
+  QuicTime expected_time = clock_.Now() + 1.5 * srtt;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(1.5 * srtt);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
+  // When session decides what to write, crypto_packet_send_time gets updated.
+  crypto_packet_send_time = clock_.Now();
+  manager_.OnRetransmissionTimeout();
+
+  // The retransmission time should now be twice as far in the future.
+  expected_time = crypto_packet_send_time + srtt * 2 * 1.5;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet for the 2nd time.
+  clock_.AdvanceTime(2 * 1.5 * srtt);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(3); }));
+  // When session decides what to write, crypto_packet_send_time gets updated.
+  crypto_packet_send_time = clock_.Now();
+  manager_.OnRetransmissionTimeout();
+
+  // Verify exponential backoff of the retransmission timeout.
+  expected_time = crypto_packet_send_time + srtt * 4 * 1.5;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       GetConservativeTransmissionTimeCryptoHandshake) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kCONH);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  // Calling SetFromConfig requires mocking out some send algorithm methods.
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+  QuicTime crypto_packet_send_time = clock_.Now();
+  SendCryptoPacket(1);
+
+  // Check the min.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(25),
+            manager_.GetRetransmissionTime());
+
+  // Test with a standard smoothed RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
+
+  QuicTime::Delta srtt = rtt_stats->initial_rtt();
+  QuicTime expected_time = clock_.Now() + 2 * srtt;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(2 * srtt);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
+  crypto_packet_send_time = clock_.Now();
+  manager_.OnRetransmissionTimeout();
+
+  // The retransmission time should now be twice as far in the future.
+  expected_time = crypto_packet_send_time + srtt * 2 * 2;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeTailLossProbe) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+  SendDataPacket(1);
+  SendDataPacket(2);
+
+  // Check the min.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10),
+            manager_.GetRetransmissionTime());
+
+  // Test with a standard smoothed RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
+  QuicTime::Delta srtt = rtt_stats->initial_rtt();
+  QuicTime::Delta expected_tlp_delay = 2 * srtt;
+  QuicTime expected_time = clock_.Now() + expected_tlp_delay;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(expected_tlp_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type);
+      })));
+  EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+
+  expected_time = clock_.Now() + expected_tlp_delay;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeSpuriousRTO) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  SendDataPacket(1);
+  SendDataPacket(2);
+  SendDataPacket(3);
+  SendDataPacket(4);
+
+  QuicTime::Delta expected_rto_delay =
+      rtt_stats->smoothed_rtt() + 4 * rtt_stats->mean_deviation();
+  QuicTime expected_time = clock_.Now() + expected_rto_delay;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(expected_rto_delay);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(5, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(6, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  // All previous packets are inflight, plus two rto retransmissions.
+  EXPECT_EQ(6 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // The delay should double the second time.
+  expected_time = clock_.Now() + expected_rto_delay + expected_rto_delay;
+  // Once we always base the timer on the right edge, leaving the older packets
+  // in flight doesn't change the timeout.
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Ack a packet before the first RTO and ensure the RTO timeout returns to the
+  // original value and OnRetransmissionTimeout is not called or reverted.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(4 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Wait 2RTTs from now for the RTO, since it's the max of the RTO time
+  // and the TLP time.  In production, there would always be two TLP's first.
+  // Since retransmission was spurious, smoothed_rtt_ is expired, and replaced
+  // by the latest RTT sample of 500ms.
+  expected_time = clock_.Now() + QuicTime::Delta::FromMilliseconds(1000);
+  // Once we always base the timer on the right edge, leaving the older packets
+  // in flight doesn't change the timeout.
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMin) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  SendDataPacket(1);
+  // Provide a 1ms RTT sample.
+  const_cast<RttStats*>(manager_.GetRttStats())
+      ->UpdateRtt(QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::Zero(),
+                  QuicTime::Zero());
+  QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(200);
+
+  // If the delay is smaller than the min, ensure it exponentially backs off
+  // from the min.
+  for (int i = 0; i < 5; ++i) {
+    EXPECT_EQ(delay,
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+    delay = delay + delay;
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
+          return RetransmitDataPacket(i + 2, type);
+        })));
+    manager_.OnRetransmissionTimeout();
+  }
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMax) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  SendDataPacket(1);
+  // Provide a 60s RTT sample.
+  const_cast<RttStats*>(manager_.GetRttStats())
+      ->UpdateRtt(QuicTime::Delta::FromSeconds(60), QuicTime::Delta::Zero(),
+                  QuicTime::Zero());
+
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayExponentialBackoff) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  SendDataPacket(1);
+  QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(500);
+
+  // Delay should back off exponentially.
+  for (int i = 0; i < 5; ++i) {
+    EXPECT_EQ(delay,
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+    delay = delay + delay;
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
+          return RetransmitDataPacket(i + 2, type);
+        })));
+    manager_.OnRetransmissionTimeout();
+  }
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmissionDelay) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  const int64_t kRttMs = 250;
+  const int64_t kDeviationMs = 5;
+
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
+                       QuicTime::Delta::Zero(), clock_.Now());
+
+  // Initial value is to set the median deviation to half of the initial rtt,
+  // the median in then multiplied by a factor of 4 and finally the smoothed rtt
+  // is added which is the initial rtt.
+  QuicTime::Delta expected_delay =
+      QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
+  EXPECT_EQ(expected_delay,
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+
+  for (int i = 0; i < 100; ++i) {
+    // Run to make sure that we converge.
+    rtt_stats->UpdateRtt(
+        QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
+        QuicTime::Delta::Zero(), clock_.Now());
+    rtt_stats->UpdateRtt(
+        QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
+        QuicTime::Delta::Zero(), clock_.Now());
+  }
+  expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
+
+  EXPECT_NEAR(kRttMs, rtt_stats->smoothed_rtt().ToMilliseconds(), 1);
+  EXPECT_NEAR(expected_delay.ToMilliseconds(),
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_)
+                  .ToMilliseconds(),
+              1);
+}
+
+TEST_F(QuicSentPacketManagerTest, GetLossDelay) {
+  auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
+  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
+
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillRepeatedly(Return(QuicTime::Zero()));
+  SendDataPacket(1);
+  SendDataPacket(2);
+
+  // Handle an ack which causes the loss algorithm to be evaluated and
+  // set the loss timeout.
+  ExpectAck(2);
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  QuicTime timeout(clock_.Now() + QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillRepeatedly(Return(timeout));
+  EXPECT_EQ(timeout, manager_.GetRetransmissionTime());
+
+  // Fire the retransmission timeout and ensure the loss detection algorithm
+  // is invoked.
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  manager_.OnRetransmissionTimeout();
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateIetfLossDetectionFromOptions) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD0);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(3, QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       NegotiateIetfLossDetectionOneFourthRttFromOptions) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       NegotiateIetfLossDetectionAdaptiveReorderingThreshold) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(3, QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       NegotiateIetfLossDetectionAdaptiveReorderingThreshold2) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD3);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       NegotiateIetfLossDetectionAdaptiveReorderingAndTimeThreshold) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD4);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateCongestionControlFromOptions) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kRENO);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kTBBR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                      ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kBYTE);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                             ->GetCongestionControlType());
+  options.clear();
+  options.push_back(kRENO);
+  options.push_back(kBYTE);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateClientCongestionControlFromOptions) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  // No change if the server receives client options.
+  const SendAlgorithmInterface* mock_sender =
+      QuicSentPacketManagerPeer::GetSendAlgorithm(manager_);
+  options.push_back(kRENO);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(mock_sender, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_));
+
+  // Change the congestion control on the client with client options.
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kTBBR);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                      ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kBYTE);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                             ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kRENO);
+  options.push_back(kBYTE);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kMAD2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(config);
+  // Set the initial RTT to 1us.
+  QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
+      QuicTime::Delta::FromMicroseconds(1));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+
+  // Send two packets, and the TLP should be 1ms.
+  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
+  SendDataPacket(1);
+  SendDataPacket(2);
+  EXPECT_EQ(expected_tlp_delay,
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kMAD2);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(client_config);
+  // Set the initial RTT to 1us.
+  QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
+      QuicTime::Delta::FromMicroseconds(1));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  // Send two packets, and the TLP should be 1ms.
+  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
+  SendDataPacket(1);
+  SendDataPacket(2);
+  EXPECT_EQ(expected_tlp_delay,
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kMAD3);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  // Provide one RTT measurement, because otherwise we use the default of 500ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
+  EXPECT_EQ(expected_rto_delay,
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
+  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
+  EXPECT_EQ(expected_tlp_delay,
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kMAD3);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  // Provide one RTT measurement, because otherwise we use the default of 500ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
+  EXPECT_EQ(expected_rto_delay,
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
+  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
+  EXPECT_EQ(expected_tlp_delay,
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kNTLP);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kNTLP);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(k1TLP);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(k1TLP);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kNRTO);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kNRTO);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, UseInitialRoundTripTimeToSend) {
+  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(325);
+  EXPECT_NE(initial_rtt, manager_.GetRttStats()->smoothed_rtt());
+
+  QuicConfig config;
+  config.SetInitialRoundTripTimeUsToSend(initial_rtt.ToMicroseconds());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.GetRttStats()->smoothed_rtt());
+  EXPECT_EQ(initial_rtt, manager_.GetRttStats()->initial_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, ResumeConnectionState) {
+  // The sent packet manager should use the RTT from CachedNetworkParameters if
+  // it is provided.
+  const QuicTime::Delta kRtt = QuicTime::Delta::FromMilliseconds(123);
+  CachedNetworkParameters cached_network_params;
+  cached_network_params.set_min_rtt_ms(kRtt.ToMilliseconds());
+
+  SendAlgorithmInterface::NetworkParams params;
+  params.bandwidth = QuicBandwidth::Zero();
+  params.allow_cwnd_to_decrease = false;
+  params.rtt = kRtt;
+  params.is_rtt_trusted = true;
+
+  EXPECT_CALL(*send_algorithm_, AdjustNetworkParameters(params));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .Times(testing::AnyNumber());
+  manager_.ResumeConnectionState(cached_network_params, false);
+  EXPECT_EQ(kRtt, manager_.GetRttStats()->initial_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, ConnectionMigrationUnspecifiedChange) {
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
+  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
+  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+
+  EXPECT_CALL(*send_algorithm_, OnConnectionMigration());
+  EXPECT_EQ(nullptr,
+            manager_.OnConnectionMigration(/*reset_send_algorithm=*/false));
+
+  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+}
+
+// Tests that ResetCongestionControlUponPeerAddressChange() resets send
+// algorithm and RTT. And unACK'ed packets are handled correctly.
+TEST_F(QuicSentPacketManagerTest,
+       ConnectionMigrationUnspecifiedChangeResetSendAlgorithm) {
+  auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
+  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
+  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
+  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+
+  RttStats old_rtt_stats;
+  old_rtt_stats.CloneFrom(*manager_.GetRttStats());
+
+  // Packet1 will be mark for retransmission upon migration.
+  EXPECT_CALL(notifier_, OnFrameLost(_));
+  std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
+      manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
+
+  EXPECT_NE(old_send_algorithm.get(), manager_.GetSendAlgorithm());
+  EXPECT_EQ(old_send_algorithm->GetCongestionControlType(),
+            manager_.GetSendAlgorithm()->GetCongestionControlType());
+  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+  // Packets sent earlier shouldn't be regarded as in flight.
+  EXPECT_EQ(0u, BytesInFlight());
+
+  // Replace the new send algorithm with the mock object.
+  manager_.SetSendAlgorithm(old_send_algorithm.release());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  // Application retransmit the data as LOSS_RETRANSMISSION.
+  RetransmitDataPacket(2, LOSS_RETRANSMISSION, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kDefaultLength, BytesInFlight());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  // Receiving an ACK for packet1 20s later shouldn't update the RTT, and
+  // shouldn't be treated as spurious retransmission.
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/false, kDefaultLength, _, _, _))
+      .WillOnce(testing::WithArg<3>(
+          Invoke([](const AckedPacketVector& acked_packets) {
+            EXPECT_EQ(1u, acked_packets.size());
+            EXPECT_EQ(QuicPacketNumber(1), acked_packets[0].packet_number);
+            // The bytes in packet1 shouldn't contribute to congestion control.
+            EXPECT_EQ(0u, acked_packets[0].bytes_acked);
+          })));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+
+  // Receiving an ACK for packet2 should update RTT and congestion control.
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _))
+      .WillOnce(testing::WithArg<3>(
+          Invoke([](const AckedPacketVector& acked_packets) {
+            EXPECT_EQ(1u, acked_packets.size());
+            EXPECT_EQ(QuicPacketNumber(2), acked_packets[0].packet_number);
+            // The bytes in packet2 should contribute to congestion control.
+            EXPECT_EQ(kDefaultLength, acked_packets[0].bytes_acked);
+          })));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+            manager_.GetRttStats()->latest_rtt());
+
+  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
+  // Trigger loss timeout and mark packet3 for retransmission.
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillOnce(Return(clock_.Now() + QuicTime::Delta::FromMilliseconds(10)));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(WithArgs<5>(Invoke([](LostPacketVector* packet_lost) {
+        packet_lost->emplace_back(QuicPacketNumber(3u), kDefaultLength);
+        return LossDetectionInterface::DetectionStats();
+      })));
+  EXPECT_CALL(notifier_, OnFrameLost(_));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(false, kDefaultLength, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(0u, BytesInFlight());
+
+  // Migrate again with unACK'ed but not in-flight packet.
+  // Packet3 shouldn't be marked for retransmission again as it is not in
+  // flight.
+  old_send_algorithm =
+      manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
+
+  EXPECT_NE(old_send_algorithm.get(), manager_.GetSendAlgorithm());
+  EXPECT_EQ(old_send_algorithm->GetCongestionControlType(),
+            manager_.GetSendAlgorithm()->GetCongestionControlType());
+  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+
+  manager_.SetSendAlgorithm(old_send_algorithm.release());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(30));
+  // Receiving an ACK for packet3 shouldn't update RTT. Though packet 3 was
+  // marked lost, this spurious retransmission shouldn't be reported to the loss
+  // algorithm.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+
+  SendDataPacket(4, ENCRYPTION_FORWARD_SECURE);
+  // Trigger loss timeout and mark packet4 for retransmission.
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillOnce(Return(clock_.Now() + QuicTime::Delta::FromMilliseconds(10)));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(WithArgs<5>(Invoke([](LostPacketVector* packet_lost) {
+        packet_lost->emplace_back(QuicPacketNumber(4u), kDefaultLength);
+        return LossDetectionInterface::DetectionStats();
+      })));
+  EXPECT_CALL(notifier_, OnFrameLost(_));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(false, kDefaultLength, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(0u, BytesInFlight());
+
+  // Application retransmit the data as LOSS_RETRANSMISSION.
+  RetransmitDataPacket(5, LOSS_RETRANSMISSION, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kDefaultLength, BytesInFlight());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(30));
+  // Receiving an ACK for packet4 should update RTT, but not bytes in flight.
+  // This spurious retransmission should be reported to the loss algorithm.
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(kDefaultLength, BytesInFlight());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(30),
+            manager_.GetRttStats()->latest_rtt());
+
+  // Migrate again with in-flight packet5 whose retransmittable frames are all
+  // ACKed. Packet5 should be marked for retransmission but nothing to
+  // retransmit.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillOnce(Return(false));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(0u);
+  old_send_algorithm =
+      manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
+  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+
+  manager_.SetSendAlgorithm(old_send_algorithm.release());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  // Receiving an ACK for packet5 shouldn't update RTT. Though packet 5 was
+  // marked for retransmission, this spurious retransmission shouldn't be
+  // reported to the loss algorithm.
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(6));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+}
+
+TEST_F(QuicSentPacketManagerTest, PathMtuIncreased) {
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, BytesInFlight(), QuicPacketNumber(1), _, _));
+  SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                          nullptr, kDefaultLength + 100, false, false);
+  manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, true);
+
+  // Ack the large packet and expect the path MTU to increase.
+  ExpectAck(1);
+  EXPECT_CALL(*network_change_visitor_,
+              OnPathMtuIncreased(kDefaultLength + 100));
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, OnAckRangeSlowPath) {
+  // Send packets 1 - 20.
+  for (size_t i = 1; i <= 20; ++i) {
+    SendDataPacket(i);
+  }
+  // Ack [5, 7), [10, 12), [15, 17).
+  uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
+  uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
+  ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1,
+                      ABSL_ARRAYSIZE(lost1));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
+  manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
+  manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
+  // Make sure empty range does not harm.
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Ack [4, 8), [9, 13), [14, 21).
+  uint64_t acked2[] = {4, 7, 9, 12, 14, 17, 18, 19, 20};
+  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(20), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(14), QuicPacketNumber(21));
+  manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, TolerateReneging) {
+  // Send packets 1 - 20.
+  for (size_t i = 1; i <= 20; ++i) {
+    SendDataPacket(i);
+  }
+  // Ack [5, 7), [10, 12), [15, 17).
+  uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
+  uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
+  ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1,
+                      ABSL_ARRAYSIZE(lost1));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
+  manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
+  manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Making sure reneged ACK does not harm. Ack [4, 8), [9, 13).
+  uint64_t acked2[] = {4, 7, 9, 12};
+  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(12), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicPacketNumber(16), manager_.GetLargestObserved());
+}
+
+TEST_F(QuicSentPacketManagerTest, MultiplePacketNumberSpaces) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  const QuicUnackedPacketMap* unacked_packets =
+      QuicSentPacketManagerPeer::GetUnackedPacketMap(&manager_);
+  EXPECT_FALSE(
+      unacked_packets
+          ->GetLargestSentRetransmittableOfPacketNumberSpace(INITIAL_DATA)
+          .IsInitialized());
+  EXPECT_FALSE(
+      manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL).IsInitialized());
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_FALSE(
+      unacked_packets
+          ->GetLargestSentRetransmittableOfPacketNumberSpace(HANDSHAKE_DATA)
+          .IsInitialized());
+  // Ack packet 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicPacketNumber(1),
+            manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL));
+  EXPECT_FALSE(
+      manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE).IsInitialized());
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_FALSE(
+      unacked_packets
+          ->GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
+          .IsInitialized());
+  // Ack packet 2.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(2),
+            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
+  EXPECT_FALSE(
+      manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized());
+  // Ack packet 3.
+  ExpectAck(3);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(3),
+            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
+  EXPECT_FALSE(
+      manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized());
+  // Send packets 4 and 5.
+  SendDataPacket(4, ENCRYPTION_ZERO_RTT);
+  SendDataPacket(5, ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_EQ(QuicPacketNumber(5),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  // Ack packet 5.
+  ExpectAck(5);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(6));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(QuicPacketNumber(3),
+            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(5),
+            manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT));
+  EXPECT_EQ(QuicPacketNumber(5),
+            manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE));
+
+  // Send packets 6 - 8.
+  SendDataPacket(6, ENCRYPTION_FORWARD_SECURE);
+  SendDataPacket(7, ENCRYPTION_FORWARD_SECURE);
+  SendDataPacket(8, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_EQ(QuicPacketNumber(8),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  // Ack all packets.
+  uint64_t acked[] = {4, 6, 7, 8};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(8), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(9));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(5),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(QuicPacketNumber(3),
+            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(8),
+            manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT));
+  EXPECT_EQ(QuicPacketNumber(8),
+            manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE));
+}
+
+TEST_F(QuicSentPacketManagerTest, PacketsGetAckedInWrongPacketNumberSpace) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+
+  // ACK packets 2 and 3 in the wrong packet number space.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, PacketsGetAckedInWrongPacketNumberSpace2) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+
+  // ACK packet 1 in the wrong packet number space.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_HANDSHAKE));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       ToleratePacketsGetAckedInWrongPacketNumberSpace) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Ack packet 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+
+  // Packet 1 gets acked in the wrong packet number space. Since packet 1 has
+  // been acked in the correct packet number space, tolerate it.
+  uint64_t acked[] = {2, 3};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_HANDSHAKE));
+}
+
+// Regression test for b/133771183.
+TEST_F(QuicSentPacketManagerTest, PacketInLimbo) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+  // Send SHLO.
+  SendCryptoPacket(1);
+  // Send data packet.
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Send Ack Packet.
+  SendAckPacket(3, 1, ENCRYPTION_FORWARD_SECURE);
+  // Retransmit SHLO.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(4); }));
+  manager_.OnRetransmissionTimeout();
+
+  // Successfully decrypt a forward secure packet.
+  manager_.SetHandshakeConfirmed();
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  // Send Ack packet.
+  SendAckPacket(5, 2, ENCRYPTION_FORWARD_SECURE);
+
+  // Retransmission alarm fires.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(6, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+
+  // Received Ack of packets 1, 3 and 4.
+  uint64_t acked[] = {1, 3, 4};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  uint64_t acked2[] = {5, 6};
+  uint64_t loss[] = {2};
+  // Verify packet 2 is detected lost.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), loss,
+                      ABSL_ARRAYSIZE(loss));
+  manager_.OnAckFrameStart(QuicPacketNumber(6), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(7));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, RtoFiresNoPacketToRetransmit) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  // Send 10 packets.
+  for (size_t i = 1; i <= 10; ++i) {
+    SendDataPacket(i);
+  }
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(11, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(12, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(1u, stats_.rto_count);
+  EXPECT_EQ(0u, manager_.pending_timer_transmission_count());
+
+  // RTO fires again, but there is no packet to be RTO retransmitted.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(2u, stats_.rto_count);
+  // Verify a credit is raised up.
+  EXPECT_EQ(1u, manager_.pending_timer_transmission_count());
+}
+
+TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
+  EnablePto(k2PTO);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  QuicTime packet1_sent_time = clock_.Now();
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set based on sent time of packet 2.
+  QuicTime deadline = clock_.Now() + expected_pto_delay;
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    // Verify PTO is set based on left edge.
+    deadline = packet1_sent_time + expected_pto_delay;
+  }
+  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(deadline - clock_.Now());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+  EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
+
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+        })));
+  } else {
+    // Verify two probe packets get sent.
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+        })))
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
+        })));
+  }
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the current value.
+  QuicTime sent_time = clock_.Now();
+  EXPECT_EQ(sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 1 and 2.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO is correctly re-armed based on sent time of packet 4.
+  EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
+  EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
+}
+
+TEST_F(QuicSentPacketManagerTest, SendOneProbePacket) {
+  EnablePto(k1PTO);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  QuicTime packet1_sent_time = clock_.Now();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+  // Verify PTO period is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  QuicTime deadline = clock_.Now() + expected_pto_delay;
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    // Verify PTO is set based on left edge.
+    deadline = packet1_sent_time + expected_pto_delay;
+  }
+  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(deadline - clock_.Now());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+
+  // Verify one probe packet gets sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+}
+
+TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeClient) {
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // Send CHLO.
+  SendCryptoPacket(1);
+  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  // Ack packet 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(0u, manager_.GetBytesInFlight());
+  // Verify retransmission timeout is not zero because handshake is not
+  // confirmed although there is no in flight packet.
+  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  // Fire PTO.
+  EXPECT_EQ(QuicSentPacketManager::PTO_MODE,
+            manager_.OnRetransmissionTimeout());
+  // Send handshake packet.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  // Ack packet 2.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_HANDSHAKE));
+  // Verify retransmission timeout is zero because server has successfully
+  // processed HANDSHAKE packet.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeServer) {
+  manager_.EnableIetfPtoAndLossDetection();
+  // Send SHLO.
+  SendCryptoPacket(1);
+  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  // Ack packet 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(0u, manager_.GetBytesInFlight());
+  // Verify retransmission timeout is not set on server side because there is
+  // nothing in flight.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, PtoTimeoutIncludesMaxAckDelay) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k1PTO);
+  // Use PTOS and PTOA.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPTOA);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set and ack delay is included.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set based on sent time of packet 2 but ack delay is
+  // not included as an immediate ACK is expected.
+  expected_pto_delay = expected_pto_delay - QuicTime::Delta::FromMilliseconds(
+                                                kDefaultDelayedAckTimeMs);
+  QuicTime deadline = clock_.Now() + expected_pto_delay;
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    deadline = packet1_sent_time + expected_pto_delay;
+  }
+  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(deadline - clock_.Now());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  // Verify 1 probe packets get sent and packet number gets skipped.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the current value. Also, ack delay is
+  // not included.
+  QuicTime sent_time = clock_.Now();
+  EXPECT_EQ(sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 1 and 2.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO is correctly re-armed based on sent time of packet 4. Because of
+  // PTOS turns out to be spurious, ACK delay is included.
+  EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 4.
+  ExpectAck(4);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  // Send more packets, such that peer will do ack decimation.
+  std::vector<uint64_t> acked2;
+  for (size_t i = 5; i <= 100; ++i) {
+    SendDataPacket(i, ENCRYPTION_FORWARD_SECURE);
+    acked2.push_back(i);
+  }
+  // Received ACK for all sent packets.
+  ExpectAcksAndLosses(true, &acked2[0], acked2.size(), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(100), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(101));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(100),
+                                   ENCRYPTION_FORWARD_SECURE));
+
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  for (size_t i = 101; i < 110; i++) {
+    SendDataPacket(i, ENCRYPTION_FORWARD_SECURE);
+    // Verify PTO timeout includes ACK delay as there are less than 10 packets
+    // outstanding.
+    EXPECT_EQ(clock_.Now() + expected_pto_delay,
+              manager_.GetRetransmissionTime());
+  }
+  expected_pto_delay = expected_pto_delay - QuicTime::Delta::FromMilliseconds(
+                                                kDefaultDelayedAckTimeMs);
+  SendDataPacket(110, ENCRYPTION_FORWARD_SECURE);
+  // Verify ACK delay is excluded.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, StartExponentialBackoffSince2ndPto) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k2PTO);
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPEB2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set based on sent time of packet 2.
+  QuicTime deadline = clock_.Now() + expected_pto_delay;
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    // Verify PTO is set based on left edge.
+    deadline = packet1_sent_time + expected_pto_delay;
+  }
+  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(deadline - clock_.Now());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  // Verify two probe packets get sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify no exponential backoff.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke 2nd PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(2u, stats_.pto_count);
+
+  // Verify two probe packets get sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(5, type, ENCRYPTION_FORWARD_SECURE);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(6, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify still no exponential backoff.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke 3rd PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(3u, stats_.pto_count);
+
+  // Verify two probe packets get sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(7, type, ENCRYPTION_FORWARD_SECURE);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(8, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify exponential backoff starts.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Invoke 4th PTO.
+  clock_.AdvanceTime(expected_pto_delay * 2);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(4u, stats_.pto_count);
+
+  // Verify two probe packets get sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(9, type, ENCRYPTION_FORWARD_SECURE);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(10, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify exponential backoff continues.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay * 4,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, PtoTimeoutRttVarMultiple) {
+  EnablePto(k1PTO);
+  // Use 2 * rttvar
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPVS1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set based on 2 times rtt var.
+  QuicTime::Delta expected_pto_delay =
+      srtt + 2 * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+// Regression test for b/143962153
+TEST_F(QuicSentPacketManagerTest, RtoNotInFlightPacket) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+  // Send SHLO.
+  QuicStreamFrame crypto_frame(1, false, 0, absl::string_view());
+  SendCryptoPacket(1);
+  // Send data packet.
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+
+  // Successfully decrypt a forward secure packet.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+  manager_.SetHandshakeConfirmed();
+
+  // 1st TLP.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+
+  // 2nd TLP.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+
+  // RTO retransmits SHLO although it is not in flight.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<0>(Invoke([&crypto_frame](const QuicFrames& frames) {
+        EXPECT_EQ(1u, frames.size());
+        EXPECT_NE(crypto_frame, frames[0].stream_frame);
+        return true;
+      })));
+  manager_.OnRetransmissionTimeout();
+}
+
+TEST_F(QuicSentPacketManagerTest, Aggressive1Pto) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k1PTO);
+  // Let the first PTO be aggressive.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPAG1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay = 2 * srtt;
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  // Verify 1 probe packets get sent and packet number gets skipped.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+
+  // Verify PTO period gets set correctly.
+  QuicTime sent_time = clock_.Now();
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, Aggressive2Ptos) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k1PTO);
+  // Let the first PTO be aggressive.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPAG2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay = 2 * srtt;
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  // Verify 1 probe packets get sent and packet number gets skipped.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+
+  // Verify PTO period gets set correctly.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke 2nd PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(2u, stats_.pto_count);
+
+  // Verify 1 probe packets get sent and packet number gets skipped.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(5, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO period gets set correctly.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay * 4,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, IW10ForUpAndDown) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kBWS5);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetInitialCongestionWindowInPackets(10));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(10u, manager_.initial_congestion_window());
+}
+
+TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EnablePto(k1PTO);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard initial key and send packet 2 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  // Verify PTO is correctly set based on sent time of packet 2.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+  EXPECT_EQ(1u, stats_.crypto_retransmit_count);
+
+  // Verify probe packet gets sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_HANDSHAKE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the current value.
+  const QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 4 in application data with 0-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(4, ENCRYPTION_ZERO_RTT);
+  const QuicTime packet4_sent_time = clock_.Now();
+  // Verify PTO timeout is still based on packet 3.
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 5 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(5, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet5_sent_time = clock_.Now();
+  // Verify PTO timeout is now based on packet 5 because packet 4 should be
+  // ignored.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 6 in 1-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(6, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is now based on packet 5.
+  EXPECT_EQ(packet5_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 7 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  const QuicTime packet7_sent_time = clock_.Now();
+  SendDataPacket(7, ENCRYPTION_HANDSHAKE);
+
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation();
+  // Verify PTO timeout is now based on packet 7.
+  EXPECT_EQ(packet7_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Neuter handshake key.
+  manager_.SetHandshakeConfirmed();
+  // Forward progress has been made, verify PTO counter gets reset. PTO timeout
+  // is armed by left edge.
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(packet4_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, ServerMultiplePacketNumberSpacePtoTimeout) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EnablePto(k1PTO);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  const QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 2 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet2_sent_time = clock_.Now();
+  // Verify PTO timeout is still based on packet 1.
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard initial keys.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+
+  // Send packet 3 in 1-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is based on packet 2.
+  const QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 4 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+  // Verify PTO timeout is based on packet 4 as application data is ignored.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard handshake keys.
+  manager_.SetHandshakeConfirmed();
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  // Verify PTO timeout is now based on packet 3 as handshake is
+  // complete/confirmed.
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge) {
+  EnablePto(k1PTO);
+  // Use PTOS and PLE1.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPLE1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  const QuicTime packet1_sent_time = clock_.Now();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is still based on packet 1.
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the current value and based on packet3.
+  QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 1 and 2.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO is correctly re-armed based on sent time of packet 4.
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) {
+  EnablePto(k1PTO);
+  // Use PTOS and PLE2.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPLE2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  const QuicTime packet1_sent_time = clock_.Now();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Sent a packet 10ms before PTO expiring.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(
+      expected_pto_delay.ToMilliseconds() - 10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO expands to packet 2 sent time + 1.5 * srtt.
+  expected_pto_delay = 1.5 * rtt_stats->smoothed_rtt();
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the expected value and based on
+  // packet3 (right edge).
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 1 and 2.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO is correctly re-armed based on sent time of packet 3 (left
+  // edge).
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutUsingStandardDeviation) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k1PTO);
+  // Use PTOS and PSDA.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPSDA);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(75),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set using standard deviation.
+  QuicTime::Delta expected_pto_delay =
+      srtt +
+      GetPtoRttvarMultiplier() * rtt_stats->GetStandardOrMeanDeviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       ComputingProbeTimeoutByLeftEdgeMultiplePacketNumberSpaces) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EnablePto(k1PTO);
+  // Use PTOS and PLE1.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPLE1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  const QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 2 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet2_sent_time = clock_.Now();
+  // Verify PTO timeout is still based on packet 1.
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard initial keys.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+
+  // Send packet 3 in 1-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is based on packet 2.
+  const QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 4 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+  // Verify PTO timeout is based on packet 4 as application data is ignored.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard handshake keys.
+  manager_.SetHandshakeConfirmed();
+  // Verify PTO timeout is now based on packet 3 as handshake is
+  // complete/confirmed.
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is still based on packet 3.
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       ComputingProbeTimeoutByLeftEdge2MultiplePacketNumberSpaces) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EnablePto(k1PTO);
+  // Use PTOS and PLE2.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPLE2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  const QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 2 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet2_sent_time = clock_.Now();
+  // Verify PTO timeout is still based on packet 1.
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard initial keys.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+
+  // Send packet 3 in 1-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is based on packet 2.
+  const QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 4 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+  // Verify PTO timeout is based on packet 4 as application data is ignored.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard handshake keys.
+  manager_.SetHandshakeConfirmed();
+  // Verify PTO timeout is now based on packet 3 as handshake is
+  // complete/confirmed.
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 5 10ms before PTO expiring.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(
+      expected_pto_delay.ToMilliseconds() - 10));
+  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout expands to packet 5 sent time + 1.5 * srtt.
+  EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->smoothed_rtt(),
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, SetHandshakeConfirmed) {
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
+      .WillOnce(
+          Invoke([](const QuicFrame& /*frame*/, QuicTime::Delta ack_delay_time,
+                    QuicTime receive_timestamp) {
+            EXPECT_TRUE(ack_delay_time.IsZero());
+            EXPECT_EQ(receive_timestamp, QuicTime::Zero());
+            return true;
+          }));
+
+  EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(2))).Times(1);
+  manager_.SetHandshakeConfirmed();
+}
+
+// Regresstion test for b/148841700.
+TEST_F(QuicSentPacketManagerTest, NeuterUnencryptedPackets) {
+  SendCryptoPacket(1);
+  SendPingPacket(2, ENCRYPTION_INITIAL);
+  // Crypto data has been discarded but ping does not.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
+      .Times(2)
+      .WillOnce(Return(false))
+      .WillOnce(Return(true));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+
+  EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(1))).Times(1);
+  manager_.NeuterUnencryptedPackets();
+}
+
+TEST_F(QuicSentPacketManagerTest, MarkInitialPacketsForRetransmission) {
+  SendCryptoPacket(1);
+  SendPingPacket(2, ENCRYPTION_HANDSHAKE);
+  // Only the INITIAL packet will be retransmitted.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  manager_.MarkInitialPacketsForRetransmission();
+}
+
+TEST_F(QuicSentPacketManagerTest, NoPacketThresholdDetectionForRuntPackets) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kRUNT);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelay) {
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+  // Before RTT sample is available.
+  // 2 TLPs + 2 RTOs.
+  QuicTime::Delta expected_delay = QuicTime::Delta::Zero();
+  for (size_t i = 0; i < 2; ++i) {
+    QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
+    expected_delay =
+        expected_delay +
+        QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
+  }
+  for (size_t i = 0; i < 2; ++i) {
+    QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
+    expected_delay =
+        expected_delay +
+        QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
+  }
+  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+
+  expected_delay = QuicTime::Delta::Zero();
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 0);
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 0);
+
+  // After RTT sample is available.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // 2 TLPs + 2 RTOs.
+  for (size_t i = 0; i < 2; ++i) {
+    QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
+    expected_delay =
+        expected_delay +
+        QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
+  }
+  for (size_t i = 0; i < 2; ++i) {
+    QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
+    expected_delay =
+        expected_delay +
+        QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
+  }
+  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayUsing2PTO) {
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(k1PTO);
+  QuicTagVector client_options;
+  client_options.push_back(kPDP2);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  client_config.SetClientConnectionOptions(client_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(manager_.pto_enabled());
+  QuicTime::Delta expected_delay = 2 * manager_.GetPtoDelay();
+  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayUsing1PTO) {
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(k1PTO);
+  QuicTagVector client_options;
+  client_options.push_back(kPDP1);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  client_config.SetClientConnectionOptions(client_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(manager_.pto_enabled());
+  QuicTime::Delta expected_delay = 1 * manager_.GetPtoDelay();
+  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+}
+
+TEST_F(QuicSentPacketManagerTest, ClientsIgnorePings) {
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  QuicConfig client_config;
+  QuicTagVector options;
+  QuicTagVector client_options;
+  client_options.push_back(kIGNP);
+  client_config.SetConnectionOptionsToSend(options);
+  client_config.SetClientConnectionOptions(client_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(client_config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  SendPingPacket(1, ENCRYPTION_INITIAL);
+  // Verify PING only packet is not considered in flight.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  SendDataPacket(2, ENCRYPTION_INITIAL);
+  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
+
+  uint64_t acked[] = {1};
+  ExpectAcksAndLosses(/*rtt_updated=*/false, acked, ABSL_ARRAYSIZE(acked),
+                      nullptr, 0);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  // Verify no RTT samples for PING only packet.
+  EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
+
+  ExpectAck(2);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats->smoothed_rtt());
+}
+
+// Regression test for b/154050235.
+TEST_F(QuicSentPacketManagerTest, ExponentialBackoffWithNoRttMeasurement) {
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kInitialRttMs),
+            rtt_stats->initial_rtt());
+  EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
+
+  SendCryptoPacket(1);
+  QuicTime::Delta expected_pto_delay =
+      QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          WithArgs<1>(Invoke([this]() { return RetransmitCryptoPacket(3); })));
+  manager_.MaybeSendProbePackets();
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    manager_.AdjustPendingTimerTransmissions();
+  }
+  // Verify exponential backoff of the PTO timeout.
+  EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, PtoDelayWithTinyInitialRtt) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  // Assume client provided a tiny initial RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMicroseconds(1));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1), rtt_stats->initial_rtt());
+  EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
+
+  SendCryptoPacket(1);
+  QuicTime::Delta expected_pto_delay = QuicTime::Delta::FromMilliseconds(10);
+  // Verify kMinHandshakeTimeoutMs is respected.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          WithArgs<1>(Invoke([this]() { return RetransmitCryptoPacket(3); })));
+  manager_.MaybeSendProbePackets();
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    manager_.AdjustPendingTimerTransmissions();
+  }
+  // Verify exponential backoff of the PTO timeout.
+  EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, HandshakeAckCausesInitialKeyDropping) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  // Send INITIAL packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  QuicTime::Delta expected_pto_delay =
+      QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+  // Send HANDSHAKE ack.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendAckPacket(2, /*largest_acked=*/1, ENCRYPTION_HANDSHAKE);
+  // Sending HANDSHAKE packet causes dropping of INITIAL key.
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+  // There is no in flight packets.
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  // Verify PTO timer gets rearmed from now because of anti-amplification.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  // Verify nothing to probe (and connection will send PING for current
+  // encryption level).
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
+  manager_.MaybeSendProbePackets();
+}
+
+// Regression test for b/156487311
+TEST_F(QuicSentPacketManagerTest, ClearLastInflightPacketsSentTime) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+  // Send INITIAL 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Send HANDSHAKE 2.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet2_sent_time = clock_.Now();
+
+  // Send half RTT 5.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+
+  // Received ACK for INITIAL 1.
+  ExpectAck(1);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  const QuicTime::Delta pto_delay =
+      rtt_stats->smoothed_rtt() +
+      GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  // Verify PTO is armed based on handshake data.
+  EXPECT_EQ(packet2_sent_time + pto_delay, manager_.GetRetransmissionTime());
+}
+
+// Regression test for b/157895910.
+TEST_F(QuicSentPacketManagerTest, EarliestSentTimeNotInitializedWhenPtoFires) {
+  if (GetQuicReloadableFlag(quic_simplify_set_retransmission_alarm)) {
+    return;
+  }
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+  // Send INITIAL 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+
+  // Send HANDSHAKE packets.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+
+  // Send half RTT packet.
+  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+
+  // Received ACK for INITIAL packet 1.
+  ExpectAck(1);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Received ACK for HANDSHAKE packets.
+  uint64_t acked[] = {2, 3, 4};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(5));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_HANDSHAKE));
+  // Verify PTO will not be armed.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, MaybeRetransmitInitialData) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  QuicTime packet1_sent_time = clock_.Now();
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  QuicTime packet2_sent_time = clock_.Now();
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+  // Verify PTO is correctly set based on packet 1.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Assume connection is going to send INITIAL ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(4, type, ENCRYPTION_INITIAL);
+      })));
+  manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
+  // Verify PTO is re-armed based on packet 2.
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Connection is going to send another INITIAL ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(5, type, ENCRYPTION_INITIAL);
+      })));
+  manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
+  // Verify PTO does not change.
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       AggressivePtoBeforeAnyRttSamplesAreAvailable) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kAPTO);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  // Send INITIAL 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Verify retransmission timeout is expected.
+  EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->initial_rtt(),
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, SendPathChallengeAndGetAck) {
+  QuicPacketNumber packet_number(1);
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, BytesInFlight(), packet_number, _, _));
+  SerializedPacket packet(packet_number, PACKET_4BYTE_PACKET_NUMBER, nullptr,
+                          kDefaultLength, false, false);
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  packet.nonretransmittable_frames.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                        NO_RETRANSMITTABLE_DATA, false);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/false, _, _,
+                                Pointwise(PacketNumberEq(), {1}), IsEmpty()));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+
+  // Get ACK for the packet.
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+}
+
+SerializedPacket MakePacketWithAckFrequencyFrame(
+    int packet_number, int ack_frequency_sequence_number,
+    QuicTime::Delta max_ack_delay) {
+  auto* ack_frequency_frame = new QuicAckFrequencyFrame();
+  ack_frequency_frame->max_ack_delay = max_ack_delay;
+  ack_frequency_frame->sequence_number = ack_frequency_sequence_number;
+  SerializedPacket packet(QuicPacketNumber(packet_number),
+                          PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                          /*has_ack=*/false,
+                          /*has_stop_waiting=*/false);
+  packet.retransmittable_frames.push_back(QuicFrame(ack_frequency_frame));
+  packet.has_ack_frequency = true;
+  packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  return packet;
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       PeerMaxAckDelayUpdatedFromAckFrequencyFrameOneAtATime) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
+      .Times(AnyNumber());
+
+  auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
+  auto one_ms = QuicTime::Delta::FromMilliseconds(1);
+  auto plus_1_ms_delay = initial_peer_max_ack_delay + one_ms;
+  auto minus_1_ms_delay = initial_peer_max_ack_delay - one_ms;
+
+  // Send and Ack frame1.
+  SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/1, /*ack_frequency_sequence_number=*/1,
+      plus_1_ms_delay);
+  // Higher on the fly max_ack_delay changes peer_max_ack_delay.
+  manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
+
+  // Send and Ack frame2.
+  SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/2, /*ack_frequency_sequence_number=*/2,
+      minus_1_ms_delay);
+  // Lower on the fly max_ack_delay does not change peer_max_ack_delay.
+  manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), minus_1_ms_delay);
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       PeerMaxAckDelayUpdatedFromInOrderAckFrequencyFrames) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
+      .Times(AnyNumber());
+
+  auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
+  auto one_ms = QuicTime::Delta::FromMilliseconds(1);
+  auto extra_1_ms = initial_peer_max_ack_delay + one_ms;
+  auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms;
+  auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms;
+  SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_1_ms);
+  SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms);
+  SerializedPacket packet3 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms);
+
+  // Send frame1, farme2, frame3.
+  manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms);
+  manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
+  manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
+
+  // Ack frame1, farme2, frame3.
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       PeerMaxAckDelayUpdatedFromOutOfOrderAckedAckFrequencyFrames) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
+      .Times(AnyNumber());
+
+  auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
+  auto one_ms = QuicTime::Delta::FromMilliseconds(1);
+  auto extra_1_ms = initial_peer_max_ack_delay + one_ms;
+  auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms;
+  auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms;
+  auto extra_4_ms = initial_peer_max_ack_delay + 4 * one_ms;
+  SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_4_ms);
+  SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms);
+  SerializedPacket packet3 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms);
+  SerializedPacket packet4 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/4, /*ack_frequency_sequence_number=*/4, extra_1_ms);
+
+  // Send frame1, farme2, frame3, frame4.
+  manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  manager_.OnPacketSent(&packet4, clock_.Now(), NOT_RETRANSMISSION,
+                        NO_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_4_ms);
+
+  // Ack frame3.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
+  // Acking frame1 do not affect peer_max_ack_delay after frame3 is acked.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
+  // Acking frame2 do not affect peer_max_ack_delay after frame3 is acked.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
+  // Acking frame4 updates peer_max_ack_delay.
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(5));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms);
+}
+
+TEST_F(QuicSentPacketManagerTest, ClearDataInMessageFrameAfterPacketSent) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+
+  QuicMessageFrame* message_frame = nullptr;
+  {
+    quiche::QuicheMemSlice slice(quiche::QuicheBuffer(&allocator_, 1024));
+    message_frame = new QuicMessageFrame(/*message_id=*/1, std::move(slice));
+    EXPECT_FALSE(message_frame->message_data.empty());
+    EXPECT_EQ(message_frame->message_length, 1024);
+
+    SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                            /*encrypted_buffer=*/nullptr, kDefaultLength,
+                            /*has_ack=*/false,
+                            /*has_stop_waiting*/ false);
+    packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
+    packet.retransmittable_frames.push_back(QuicFrame(message_frame));
+    packet.has_message = true;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  }
+
+  EXPECT_TRUE(message_frame->message_data.empty());
+  EXPECT_EQ(message_frame->message_length, 0);
+}
+
+TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrame) {
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  manager_.SetFromConfig(config);
+  manager_.SetHandshakeConfirmed();
+
+  // Set up RTTs.
+  auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80),
+                       /*ack_delay=*/QuicTime::Delta::Zero(),
+                       /*now=*/QuicTime::Zero());
+  // Make sure srtt and min_rtt are different.
+  rtt_stats->UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(160),
+      /*ack_delay=*/QuicTime::Delta::Zero(),
+      /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24));
+
+  auto frame = manager_.GetUpdatedAckFrequencyFrame();
+  EXPECT_EQ(frame.max_ack_delay,
+            std::max(rtt_stats->min_rtt() * 0.25,
+                     QuicTime::Delta::FromMilliseconds(1u)));
+  EXPECT_EQ(frame.packet_tolerance, 10u);
+}
+
+TEST_F(QuicSentPacketManagerTest, SmoothedRttIgnoreAckDelay) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kMAD0);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(config);
+
+  SendDataPacket(1);
+  // Ack 1.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1),
+                           QuicTime::Delta::FromMilliseconds(100),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  // Verify that ack_delay is ignored in the first measurement.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->smoothed_rtt());
+
+  SendDataPacket(2);
+  // Ack 2.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2),
+                           QuicTime::Delta::FromMilliseconds(100),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->smoothed_rtt());
+
+  SendDataPacket(3);
+  // Ack 3.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
+  ExpectAck(3);
+  manager_.OnAckFrameStart(QuicPacketNumber(3),
+                           QuicTime::Delta::FromMilliseconds(50), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->smoothed_rtt());
+
+  SendDataPacket(4);
+  // Ack 4.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  ExpectAck(4);
+  manager_.OnAckFrameStart(QuicPacketNumber(4),
+                           QuicTime::Delta::FromMilliseconds(300),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_INITIAL));
+  // Verify that large erroneous ack_delay does not change Smoothed RTT.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
+            manager_.GetRttStats()->latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
+            manager_.GetRttStats()->smoothed_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, IgnorePeerMaxAckDelayDuringHandshake) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // 100ms RTT.
+  const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(100);
+
+  // Server sends INITIAL 1 and HANDSHAKE 2.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+
+  // Receive client ACK for INITIAL 1 after one RTT.
+  clock_.AdvanceTime(kTestRTT);
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(kTestRTT, manager_.GetRttStats()->latest_rtt());
+
+  // Assume the cert verification on client takes 50ms, such that the HANDSHAKE
+  // packet is queued for 50ms.
+  const QuicTime::Delta queuing_delay = QuicTime::Delta::FromMilliseconds(50);
+  clock_.AdvanceTime(queuing_delay);
+  // Ack 2.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), queuing_delay, clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(kTestRTT, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrameWithSRTT) {
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  QuicTagVector quic_tag_vector;
+  quic_tag_vector.push_back(kAFF1);  // SRTT enabling tag.
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector);
+  manager_.SetFromConfig(config);
+  manager_.SetHandshakeConfirmed();
+
+  // Set up RTTs.
+  auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80),
+                       /*ack_delay=*/QuicTime::Delta::Zero(),
+                       /*now=*/QuicTime::Zero());
+  // Make sure srtt and min_rtt are different.
+  rtt_stats->UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(160),
+      /*ack_delay=*/QuicTime::Delta::Zero(),
+      /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24));
+
+  auto frame = manager_.GetUpdatedAckFrequencyFrame();
+  EXPECT_EQ(frame.max_ack_delay,
+            std::max(rtt_stats->SmoothedOrInitialRtt() * 0.25,
+                     QuicTime::Delta::FromMilliseconds(1u)));
+}
+
+TEST_F(QuicSentPacketManagerTest, SetInitialRtt) {
+  // Upper bounds.
+  manager_.SetInitialRtt(
+      QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs + 1), false);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMaxInitialRoundTripTimeUs);
+
+  manager_.SetInitialRtt(
+      QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs + 1), true);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMaxInitialRoundTripTimeUs);
+
+  EXPECT_GT(kMinUntrustedInitialRoundTripTimeUs,
+            kMinTrustedInitialRoundTripTimeUs);
+
+  // Lower bounds for untrusted rtt.
+  manager_.SetInitialRtt(QuicTime::Delta::FromMicroseconds(
+                             kMinUntrustedInitialRoundTripTimeUs - 1),
+                         false);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMinUntrustedInitialRoundTripTimeUs);
+
+  // Lower bounds for trusted rtt.
+  manager_.SetInitialRtt(QuicTime::Delta::FromMicroseconds(
+                             kMinUntrustedInitialRoundTripTimeUs - 1),
+                         true);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMinUntrustedInitialRoundTripTimeUs - 1);
+
+  manager_.SetInitialRtt(
+      QuicTime::Delta::FromMicroseconds(kMinTrustedInitialRoundTripTimeUs - 1),
+      true);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMinTrustedInitialRoundTripTimeUs);
+}
+
+TEST_F(QuicSentPacketManagerTest, GetAvailableCongestionWindow) {
+  SendDataPacket(1);
+  EXPECT_EQ(kDefaultLength, manager_.GetBytesInFlight());
+
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(kDefaultLength + 10));
+  EXPECT_EQ(10u, manager_.GetAvailableCongestionWindowInBytes());
+
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(kDefaultLength));
+  EXPECT_EQ(0u, manager_.GetAvailableCongestionWindowInBytes());
+
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(kDefaultLength - 10));
+  EXPECT_EQ(0u, manager_.GetAvailableCongestionWindowInBytes());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_server_id.cc b/quiche/quic/core/quic_server_id.cc
new file mode 100644
index 0000000..9f61072
--- /dev/null
+++ b/quiche/quic/core/quic_server_id.cc
@@ -0,0 +1,38 @@
+// 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 "quiche/quic/core/quic_server_id.h"
+
+#include <string>
+#include <tuple>
+
+namespace quic {
+
+QuicServerId::QuicServerId() : QuicServerId("", 0, false) {}
+
+QuicServerId::QuicServerId(const std::string& host, uint16_t port)
+    : QuicServerId(host, port, false) {}
+
+QuicServerId::QuicServerId(const std::string& host,
+                           uint16_t port,
+                           bool privacy_mode_enabled)
+    : host_(host), port_(port), privacy_mode_enabled_(privacy_mode_enabled) {}
+
+QuicServerId::~QuicServerId() {}
+
+bool QuicServerId::operator<(const QuicServerId& other) const {
+  return std::tie(port_, host_, privacy_mode_enabled_) <
+         std::tie(other.port_, other.host_, other.privacy_mode_enabled_);
+}
+
+bool QuicServerId::operator==(const QuicServerId& other) const {
+  return privacy_mode_enabled_ == other.privacy_mode_enabled_ &&
+         host_ == other.host_ && port_ == other.port_;
+}
+
+bool QuicServerId::operator!=(const QuicServerId& other) const {
+  return !(*this == other);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_server_id.h b/quiche/quic/core/quic_server_id.h
new file mode 100644
index 0000000..8f437d1
--- /dev/null
+++ b/quiche/quic/core/quic_server_id.h
@@ -0,0 +1,55 @@
+// 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_CORE_QUIC_SERVER_ID_H_
+#define QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/hash/hash.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// The id used to identify sessions. Includes the hostname, port, scheme and
+// privacy_mode.
+class QUIC_EXPORT_PRIVATE QuicServerId {
+ public:
+  QuicServerId();
+  QuicServerId(const std::string& host, uint16_t port);
+  QuicServerId(const std::string& host,
+               uint16_t port,
+               bool privacy_mode_enabled);
+  ~QuicServerId();
+
+  // Needed to be an element of an ordered container.
+  bool operator<(const QuicServerId& other) const;
+  bool operator==(const QuicServerId& other) const;
+
+  bool operator!=(const QuicServerId& other) const;
+
+  const std::string& host() const { return host_; }
+
+  uint16_t port() const { return port_; }
+
+  bool privacy_mode_enabled() const { return privacy_mode_enabled_; }
+
+ private:
+  std::string host_;
+  uint16_t port_;
+  bool privacy_mode_enabled_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicServerIdHash {
+ public:
+  size_t operator()(const quic::QuicServerId& server_id) const noexcept {
+    return absl::HashOf(server_id.host(), server_id.port(),
+                        server_id.privacy_mode_enabled());
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
diff --git a/quiche/quic/core/quic_server_id_test.cc b/quiche/quic/core/quic_server_id_test.cc
new file mode 100644
index 0000000..c4e5368
--- /dev/null
+++ b/quiche/quic/core/quic_server_id_test.cc
@@ -0,0 +1,124 @@
+// 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 "quiche/quic/core/quic_server_id.h"
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+namespace {
+
+class QuicServerIdTest : public QuicTest {};
+
+TEST_F(QuicServerIdTest, Constructor) {
+  QuicServerId google_server_id("google.com", 10, false);
+  EXPECT_EQ("google.com", google_server_id.host());
+  EXPECT_EQ(10, google_server_id.port());
+  EXPECT_FALSE(google_server_id.privacy_mode_enabled());
+
+  QuicServerId private_server_id("mail.google.com", 12, true);
+  EXPECT_EQ("mail.google.com", private_server_id.host());
+  EXPECT_EQ(12, private_server_id.port());
+  EXPECT_TRUE(private_server_id.privacy_mode_enabled());
+}
+
+TEST_F(QuicServerIdTest, LessThan) {
+  QuicServerId a_10_https("a.com", 10, false);
+  QuicServerId a_11_https("a.com", 11, false);
+  QuicServerId b_10_https("b.com", 10, false);
+  QuicServerId b_11_https("b.com", 11, false);
+
+  QuicServerId a_10_https_private("a.com", 10, true);
+  QuicServerId a_11_https_private("a.com", 11, true);
+  QuicServerId b_10_https_private("b.com", 10, true);
+  QuicServerId b_11_https_private("b.com", 11, true);
+
+  // Test combinations of host, port, and privacy being same on left and
+  // right side of less than.
+  EXPECT_FALSE(a_10_https < a_10_https);
+  EXPECT_TRUE(a_10_https < a_10_https_private);
+  EXPECT_FALSE(a_10_https_private < a_10_https);
+  EXPECT_FALSE(a_10_https_private < a_10_https_private);
+
+  // Test with either host, port or https being different on left and right side
+  // of less than.
+  bool left_privacy;
+  bool right_privacy;
+  for (int i = 0; i < 4; i++) {
+    left_privacy = (i / 2 == 0);
+    right_privacy = (i % 2 == 0);
+    QuicServerId a_10_https_left_private("a.com", 10, left_privacy);
+    QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
+    QuicServerId a_11_https_left_private("a.com", 11, left_privacy);
+    QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
+
+    QuicServerId b_10_https_left_private("b.com", 10, left_privacy);
+    QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
+    QuicServerId b_11_https_left_private("b.com", 11, left_privacy);
+    QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
+
+    EXPECT_TRUE(a_10_https_left_private < a_11_https_right_private);
+    EXPECT_TRUE(a_10_https_left_private < b_10_https_right_private);
+    EXPECT_TRUE(a_10_https_left_private < b_11_https_right_private);
+    EXPECT_FALSE(a_11_https_left_private < a_10_https_right_private);
+    EXPECT_FALSE(a_11_https_left_private < b_10_https_right_private);
+    EXPECT_TRUE(a_11_https_left_private < b_11_https_right_private);
+    EXPECT_FALSE(b_10_https_left_private < a_10_https_right_private);
+    EXPECT_TRUE(b_10_https_left_private < a_11_https_right_private);
+    EXPECT_TRUE(b_10_https_left_private < b_11_https_right_private);
+    EXPECT_FALSE(b_11_https_left_private < a_10_https_right_private);
+    EXPECT_FALSE(b_11_https_left_private < a_11_https_right_private);
+    EXPECT_FALSE(b_11_https_left_private < b_10_https_right_private);
+  }
+}
+
+TEST_F(QuicServerIdTest, Equals) {
+  bool left_privacy;
+  bool right_privacy;
+  for (int i = 0; i < 2; i++) {
+    left_privacy = right_privacy = (i == 0);
+    QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
+    QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
+    QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
+    QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
+
+    EXPECT_NE(a_10_https_right_private, a_11_https_right_private);
+    EXPECT_NE(a_10_https_right_private, b_10_https_right_private);
+    EXPECT_NE(a_10_https_right_private, b_11_https_right_private);
+
+    QuicServerId new_a_10_https_left_private("a.com", 10, left_privacy);
+    QuicServerId new_a_11_https_left_private("a.com", 11, left_privacy);
+    QuicServerId new_b_10_https_left_private("b.com", 10, left_privacy);
+    QuicServerId new_b_11_https_left_private("b.com", 11, left_privacy);
+
+    EXPECT_EQ(new_a_10_https_left_private, a_10_https_right_private);
+    EXPECT_EQ(new_a_11_https_left_private, a_11_https_right_private);
+    EXPECT_EQ(new_b_10_https_left_private, b_10_https_right_private);
+    EXPECT_EQ(new_b_11_https_left_private, b_11_https_right_private);
+  }
+
+  for (int i = 0; i < 2; i++) {
+    right_privacy = (i == 0);
+    QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
+    QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
+    QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
+    QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
+
+    QuicServerId new_a_10_https_left_private("a.com", 10, false);
+
+    EXPECT_NE(new_a_10_https_left_private, a_11_https_right_private);
+    EXPECT_NE(new_a_10_https_left_private, b_10_https_right_private);
+    EXPECT_NE(new_a_10_https_left_private, b_11_https_right_private);
+  }
+  QuicServerId a_10_https_private("a.com", 10, true);
+  QuicServerId new_a_10_https_no_private("a.com", 10, false);
+  EXPECT_NE(new_a_10_https_no_private, a_10_https_private);
+}
+
+}  // namespace
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_session.cc b/quiche/quic/core/quic_session.cc
new file mode 100644
index 0000000..4d89cdd
--- /dev/null
+++ b/quiche/quic/core/quic_session.cc
@@ -0,0 +1,2669 @@
+// 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 "quiche/quic/core/quic_session.h"
+
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_flow_controller.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+#include "quiche/common/quiche_text_utils.h"
+
+using spdy::SpdyPriority;
+
+namespace quic {
+
+namespace {
+
+class ClosedStreamsCleanUpDelegate : public QuicAlarm::Delegate {
+ public:
+  explicit ClosedStreamsCleanUpDelegate(QuicSession* session)
+      : session_(session) {}
+  ClosedStreamsCleanUpDelegate(const ClosedStreamsCleanUpDelegate&) = delete;
+  ClosedStreamsCleanUpDelegate& operator=(const ClosedStreamsCleanUpDelegate&) =
+      delete;
+
+  QuicConnectionContext* GetConnectionContext() override {
+    return (session_->connection() == nullptr)
+               ? nullptr
+               : session_->connection()->context();
+  }
+
+  void OnAlarm() override { session_->CleanUpClosedStreams(); }
+
+ private:
+  QuicSession* session_;
+};
+
+}  // namespace
+
+#define ENDPOINT \
+  (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+QuicSession::QuicSession(
+    QuicConnection* connection, Visitor* owner, const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicStreamCount num_expected_unidirectional_static_streams)
+    : QuicSession(connection, owner, config, supported_versions,
+                  num_expected_unidirectional_static_streams, nullptr) {}
+
+QuicSession::QuicSession(
+    QuicConnection* connection, Visitor* owner, const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicStreamCount num_expected_unidirectional_static_streams,
+    std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
+    : connection_(connection),
+      perspective_(connection->perspective()),
+      visitor_(owner),
+      write_blocked_streams_(connection->transport_version()),
+      config_(config),
+      stream_id_manager_(perspective(), connection->transport_version(),
+                         kDefaultMaxStreamsPerConnection,
+                         config_.GetMaxBidirectionalStreamsToSend()),
+      ietf_streamid_manager_(perspective(), connection->version(), this, 0,
+                             num_expected_unidirectional_static_streams,
+                             config_.GetMaxBidirectionalStreamsToSend(),
+                             config_.GetMaxUnidirectionalStreamsToSend() +
+                                 num_expected_unidirectional_static_streams),
+      num_draining_streams_(0),
+      num_outgoing_draining_streams_(0),
+      num_static_streams_(0),
+      num_zombie_streams_(0),
+      flow_controller_(
+          this, QuicUtils::GetInvalidStreamId(connection->transport_version()),
+          /*is_connection_flow_controller*/ true,
+          connection->version().AllowsLowFlowControlLimits()
+              ? 0
+              : kMinimumFlowControlSendWindow,
+          config_.GetInitialSessionFlowControlWindowToSend(),
+          kSessionReceiveWindowLimit, perspective() == Perspective::IS_SERVER,
+          nullptr),
+      currently_writing_stream_id_(0),
+      transport_goaway_sent_(false),
+      transport_goaway_received_(false),
+      control_frame_manager_(this),
+      last_message_id_(0),
+      datagram_queue_(this, std::move(datagram_observer)),
+      closed_streams_clean_up_alarm_(nullptr),
+      supported_versions_(supported_versions),
+      is_configured_(false),
+      was_zero_rtt_rejected_(false),
+      liveness_testing_in_progress_(false) {
+  closed_streams_clean_up_alarm_ =
+      absl::WrapUnique<QuicAlarm>(connection_->alarm_factory()->CreateAlarm(
+          new ClosedStreamsCleanUpDelegate(this)));
+  if (perspective() == Perspective::IS_SERVER &&
+      connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
+  }
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    config_.SetMaxUnidirectionalStreamsToSend(
+        config_.GetMaxUnidirectionalStreamsToSend() +
+        num_expected_unidirectional_static_streams);
+  }
+}
+
+void QuicSession::Initialize() {
+  connection_->set_visitor(this);
+  connection_->SetSessionNotifier(this);
+  connection_->SetDataProducer(this);
+  connection_->SetUnackedMapInitialCapacity();
+  connection_->SetFromConfig(config_);
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (config_.HasClientRequestedIndependentOption(kAFFE, perspective_) &&
+        version().HasIetfQuicFrames()) {
+      connection_->set_can_receive_ack_frequency_frame();
+      config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
+    }
+    if (config_.HasClientRequestedIndependentOption(kNBPE, perspective_)) {
+      permutes_tls_extensions_ = false;
+    }
+  }
+
+  connection_->CreateConnectionIdManager();
+
+  // On the server side, version negotiation has been done by the dispatcher,
+  // and the server session is created with the right version.
+  if (perspective() == Perspective::IS_SERVER) {
+    connection_->OnSuccessfulVersionNegotiation();
+  }
+
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    return;
+  }
+
+  QUICHE_DCHECK_EQ(QuicUtils::GetCryptoStreamId(transport_version()),
+                   GetMutableCryptoStream()->id());
+}
+
+QuicSession::~QuicSession() {
+  if (closed_streams_clean_up_alarm_ != nullptr) {
+    closed_streams_clean_up_alarm_->PermanentCancel();
+  }
+}
+
+PendingStream* QuicSession::PendingStreamOnStreamFrame(
+    const QuicStreamFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QuicStreamId stream_id = frame.stream_id;
+
+  PendingStream* pending = GetOrCreatePendingStream(stream_id);
+
+  if (!pending) {
+    if (frame.fin) {
+      QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
+      OnFinalByteOffsetReceived(stream_id, final_byte_offset);
+    }
+    return nullptr;
+  }
+
+  pending->OnStreamFrame(frame);
+  if (!connection()->connected()) {
+    return nullptr;
+  }
+  return pending;
+}
+
+void QuicSession::MaybeProcessPendingStream(PendingStream* pending) {
+  QUICHE_DCHECK(pending != nullptr);
+  QuicStreamId stream_id = pending->id();
+  absl::optional<QuicResetStreamError> stop_sending_error_code =
+      pending->GetStopSendingErrorCode();
+  QuicStream* stream = ProcessPendingStream(pending);
+  if (stream != nullptr) {
+    // The pending stream should now be in the scope of normal streams.
+    QUICHE_DCHECK(IsClosedStream(stream_id) || IsOpenStream(stream_id))
+        << "Stream " << stream_id << " not created";
+    pending_stream_map_.erase(stream_id);
+    if (stop_sending_error_code) {
+      stream->OnStopSending(*stop_sending_error_code);
+      if (!connection()->connected()) {
+        return;
+      }
+    }
+    stream->OnStreamCreatedFromPendingStream();
+    return;
+  }
+  // At this point, none of the bytes has been successfully consumed by the
+  // application layer. We should close the pending stream even if it is
+  // bidirectionl as no application will be able to write in a bidirectional
+  // stream with zero byte as input.
+  if (pending->sequencer()->IsClosed()) {
+    ClosePendingStream(stream_id);
+  }
+}
+
+void QuicSession::PendingStreamOnWindowUpdateFrame(
+    const QuicWindowUpdateFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
+  if (pending) {
+    pending->OnWindowUpdateFrame(frame);
+  }
+}
+
+void QuicSession::PendingStreamOnStopSendingFrame(
+    const QuicStopSendingFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
+  if (pending) {
+    pending->OnStopSending(frame.error());
+  }
+}
+
+void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
+  QuicStreamId stream_id = frame.stream_id;
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (ShouldProcessFrameByPendingStream(STREAM_FRAME, stream_id)) {
+    PendingStream* pending = PendingStreamOnStreamFrame(frame);
+    if (pending != nullptr && ShouldProcessPendingStreamImmediately()) {
+      MaybeProcessPendingStream(pending);
+    }
+    return;
+  }
+
+  QuicStream* stream = GetOrCreateStream(stream_id);
+
+  if (!stream) {
+    // The stream no longer exists, but we may still be interested in the
+    // final stream byte offset sent by the peer. A frame with a FIN can give
+    // us this offset.
+    if (frame.fin) {
+      QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
+      OnFinalByteOffsetReceived(stream_id, final_byte_offset);
+    }
+    return;
+  }
+  stream->OnStreamFrame(frame);
+}
+
+void QuicSession::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  GetMutableCryptoStream()->OnCryptoFrame(frame);
+}
+
+void QuicSession::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
+  // STOP_SENDING is in IETF QUIC only.
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
+
+  QuicStreamId stream_id = frame.stream_id;
+  // If Stream ID is invalid then close the connection.
+  // TODO(ianswett): This check is redundant to checks for IsClosedStream,
+  // but removing it requires removing multiple QUICHE_DCHECKs.
+  // TODO(ianswett): Multiple QUIC_DVLOGs could be QUIC_PEER_BUGs.
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received STOP_SENDING with invalid stream_id: "
+                  << stream_id << " Closing connection";
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for an invalid stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  // If stream_id is READ_UNIDIRECTIONAL, close the connection.
+  if (QuicUtils::GetStreamType(stream_id, perspective(),
+                               IsIncomingStream(stream_id),
+                               version()) == READ_UNIDIRECTIONAL) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received STOP_SENDING for a read-only stream_id: "
+                  << stream_id << ".";
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for a read-only stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (visitor_) {
+    visitor_->OnStopSendingReceived(frame);
+  }
+  if (ShouldProcessFrameByPendingStream(STOP_SENDING_FRAME, stream_id)) {
+    PendingStreamOnStopSendingFrame(frame);
+    return;
+  }
+
+  QuicStream* stream = GetOrCreateStream(stream_id);
+  if (!stream) {
+    // Errors are handled by GetOrCreateStream.
+    return;
+  }
+
+  stream->OnStopSending(frame.error());
+}
+
+void QuicSession::OnPacketDecrypted(EncryptionLevel level) {
+  GetMutableCryptoStream()->OnPacketDecrypted(level);
+  if (liveness_testing_in_progress_) {
+    liveness_testing_in_progress_ = false;
+    OnCanCreateNewOutgoingStream(/*unidirectional=*/false);
+  }
+}
+
+void QuicSession::OnOneRttPacketAcknowledged() {
+  GetMutableCryptoStream()->OnOneRttPacketAcknowledged();
+}
+
+void QuicSession::OnHandshakePacketSent() {
+  GetMutableCryptoStream()->OnHandshakePacketSent();
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicSession::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return GetMutableCryptoStream()->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter> QuicSession::CreateCurrentOneRttEncrypter() {
+  return GetMutableCryptoStream()->CreateCurrentOneRttEncrypter();
+}
+
+void QuicSession::PendingStreamOnRstStream(const QuicRstStreamFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QuicStreamId stream_id = frame.stream_id;
+
+  PendingStream* pending = GetOrCreatePendingStream(stream_id);
+
+  if (!pending) {
+    HandleRstOnValidNonexistentStream(frame);
+    return;
+  }
+
+  pending->OnRstStreamFrame(frame);
+  // At this point, none of the bytes has been consumed by the application
+  // layer. It is safe to close the pending stream even if it is bidirectionl as
+  // no application will be able to write in a bidirectional stream with zero
+  // byte as input.
+  ClosePendingStream(stream_id);
+}
+
+void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
+  QuicStreamId stream_id = frame.stream_id;
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version()) &&
+      QuicUtils::GetStreamType(stream_id, perspective(),
+                               IsIncomingStream(stream_id),
+                               version()) == WRITE_UNIDIRECTIONAL) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received RESET_STREAM for a write-only stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (visitor_) {
+    visitor_->OnRstStreamReceived(frame);
+  }
+
+  if (ShouldProcessFrameByPendingStream(RST_STREAM_FRAME, stream_id)) {
+    PendingStreamOnRstStream(frame);
+    return;
+  }
+
+  QuicStream* stream = GetOrCreateStream(stream_id);
+
+  if (!stream) {
+    HandleRstOnValidNonexistentStream(frame);
+    return;  // Errors are handled by GetOrCreateStream.
+  }
+  stream->OnStreamReset(frame);
+}
+
+void QuicSession::OnGoAway(const QuicGoAwayFrame& /*frame*/) {
+  QUIC_BUG_IF(quic_bug_12435_1, version().UsesHttp3())
+      << "gQUIC GOAWAY received on version " << version();
+
+  transport_goaway_received_ = true;
+}
+
+void QuicSession::OnMessageReceived(absl::string_view message) {
+  QUIC_DVLOG(1) << ENDPOINT << "Received message of length "
+                << message.length();
+  QUIC_DVLOG(2) << ENDPOINT << "Contents of message of length "
+                << message.length() << ":" << std::endl
+                << quiche::QuicheTextUtils::HexDump(message);
+}
+
+void QuicSession::OnHandshakeDoneReceived() {
+  QUIC_DVLOG(1) << ENDPOINT << "OnHandshakeDoneReceived";
+  GetMutableCryptoStream()->OnHandshakeDoneReceived();
+}
+
+void QuicSession::OnNewTokenReceived(absl::string_view token) {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  GetMutableCryptoStream()->OnNewTokenReceived(token);
+}
+
+// static
+void QuicSession::RecordConnectionCloseAtServer(QuicErrorCode error,
+                                                ConnectionCloseSource source) {
+  if (error != QUIC_NO_ERROR) {
+    if (source == ConnectionCloseSource::FROM_SELF) {
+      QUIC_SERVER_HISTOGRAM_ENUM(
+          "quic_server_connection_close_errors", error, QUIC_LAST_ERROR,
+          "QuicErrorCode for server-closed connections.");
+    } else {
+      QUIC_SERVER_HISTOGRAM_ENUM(
+          "quic_client_connection_close_errors", error, QUIC_LAST_ERROR,
+          "QuicErrorCode for client-closed connections.");
+    }
+  }
+}
+
+void QuicSession::OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                                     ConnectionCloseSource source) {
+  QUICHE_DCHECK(!connection_->connected());
+  if (perspective() == Perspective::IS_SERVER) {
+    RecordConnectionCloseAtServer(frame.quic_error_code, source);
+  }
+
+  if (on_closed_frame_.quic_error_code == QUIC_NO_ERROR) {
+    // Save all of the connection close information
+    on_closed_frame_ = frame;
+  }
+
+  GetMutableCryptoStream()->OnConnectionClosed(frame.quic_error_code, source);
+
+  PerformActionOnActiveStreams([this, frame, source](QuicStream* stream) {
+    QuicStreamId id = stream->id();
+    stream->OnConnectionClosed(frame.quic_error_code, source);
+    auto it = stream_map_.find(id);
+    if (it != stream_map_.end()) {
+      QUIC_BUG_IF(quic_bug_12435_2, !it->second->IsZombie())
+          << ENDPOINT << "Non-zombie stream " << id
+          << " failed to close under OnConnectionClosed";
+    }
+    return true;
+  });
+
+  closed_streams_clean_up_alarm_->Cancel();
+
+  if (visitor_) {
+    visitor_->OnConnectionClosed(connection_->GetOneActiveServerConnectionId(),
+                                 frame.quic_error_code, frame.error_details,
+                                 source);
+  }
+}
+
+void QuicSession::OnWriteBlocked() {
+  if (!connection_->connected()) {
+    return;
+  }
+  if (visitor_) {
+    visitor_->OnWriteBlocked(connection_);
+  }
+}
+
+void QuicSession::OnSuccessfulVersionNegotiation(
+    const ParsedQuicVersion& /*version*/) {}
+
+void QuicSession::OnPacketReceived(const QuicSocketAddress& /*self_address*/,
+                                   const QuicSocketAddress& peer_address,
+                                   bool is_connectivity_probe) {
+  if (is_connectivity_probe && perspective() == Perspective::IS_SERVER) {
+    // Server only sends back a connectivity probe after received a
+    // connectivity probe from a new peer address.
+      connection_->SendConnectivityProbingPacket(nullptr, peer_address);
+  }
+}
+
+void QuicSession::OnPathDegrading() {}
+
+void QuicSession::OnForwardProgressMadeAfterPathDegrading() {}
+
+bool QuicSession::AllowSelfAddressChange() const { return false; }
+
+void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
+  // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't
+  // assume that it still exists.
+  QuicStreamId stream_id = frame.stream_id;
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    // This is a window update that applies to the connection, rather than an
+    // individual stream.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received connection level flow control window "
+                     "update with max data: "
+                  << frame.max_data;
+    flow_controller_.UpdateSendWindowOffset(frame.max_data);
+    return;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version()) &&
+      QuicUtils::GetStreamType(stream_id, perspective(),
+                               IsIncomingStream(stream_id),
+                               version()) == READ_UNIDIRECTIONAL) {
+    connection()->CloseConnection(
+        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
+        "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (ShouldProcessFrameByPendingStream(WINDOW_UPDATE_FRAME, stream_id)) {
+    PendingStreamOnWindowUpdateFrame(frame);
+    return;
+  }
+
+  QuicStream* stream = GetOrCreateStream(stream_id);
+  if (stream != nullptr) {
+    stream->OnWindowUpdateFrame(frame);
+  }
+}
+
+void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) {
+  // TODO(rjshade): Compare our flow control receive windows for specified
+  //                streams: if we have a large window then maybe something
+  //                had gone wrong with the flow control accounting.
+  QUIC_DLOG(INFO) << ENDPOINT << "Received BLOCKED frame with stream id: "
+                  << frame.stream_id;
+}
+
+bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream,
+                                            uint64_t previous_bytes_written,
+                                            bool previous_fin_sent) {
+  if (  // Stream should not be closed.
+      !stream->write_side_closed() &&
+      // Not connection flow control blocked.
+      !flow_controller_.IsBlocked() &&
+      // Detect lack of forward progress.
+      previous_bytes_written == stream->stream_bytes_written() &&
+      previous_fin_sent == stream->fin_sent()) {
+    stream->set_busy_counter(stream->busy_counter() + 1);
+    QUIC_DVLOG(1) << ENDPOINT << "Suspected busy loop on stream id "
+                  << stream->id() << " stream_bytes_written "
+                  << stream->stream_bytes_written() << " fin "
+                  << stream->fin_sent() << " count " << stream->busy_counter();
+    // Wait a few iterations before firing, the exact count is
+    // arbitrary, more than a few to cover a few test-only false
+    // positives.
+    if (stream->busy_counter() > 20) {
+      QUIC_LOG(ERROR) << ENDPOINT << "Detected busy loop on stream id "
+                      << stream->id() << " stream_bytes_written "
+                      << stream->stream_bytes_written() << " fin "
+                      << stream->fin_sent();
+      return false;
+    }
+  } else {
+    stream->set_busy_counter(0);
+  }
+  return true;
+}
+
+bool QuicSession::CheckStreamWriteBlocked(QuicStream* stream) const {
+  if (!stream->write_side_closed() && stream->HasBufferedData() &&
+      !stream->IsFlowControlBlocked() &&
+      !write_blocked_streams_.IsStreamBlocked(stream->id())) {
+    QUIC_DLOG(ERROR) << ENDPOINT << "stream " << stream->id()
+                     << " has buffered " << stream->BufferedDataBytes()
+                     << " bytes, and is not flow control blocked, "
+                        "but it is not in the write block list.";
+    return false;
+  }
+  return true;
+}
+
+void QuicSession::OnCanWrite() {
+  if (connection_->framer().is_processing_packet()) {
+    // Do not write data in the middle of packet processing because rest
+    // frames in the packet may change the data to write. For example, lost
+    // data could be acknowledged. Also, connection is going to emit
+    // OnCanWrite signal post packet processing.
+    QUIC_BUG(session_write_mid_packet_processing)
+        << ENDPOINT << "Try to write mid packet processing.";
+    return;
+  }
+  if (!RetransmitLostData()) {
+    // Cannot finish retransmitting lost data, connection is write blocked.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Cannot finish retransmitting lost data, connection is "
+                     "write blocked.";
+    return;
+  }
+  // We limit the number of writes to the number of pending streams. If more
+  // streams become pending, WillingAndAbleToWrite will be true, which will
+  // cause the connection to request resumption before yielding to other
+  // connections.
+  // If we are connection level flow control blocked, then only allow the
+  // crypto and headers streams to try writing as all other streams will be
+  // blocked.
+  size_t num_writes = flow_controller_.IsBlocked()
+                          ? write_blocked_streams_.NumBlockedSpecialStreams()
+                          : write_blocked_streams_.NumBlockedStreams();
+  if (num_writes == 0 && !control_frame_manager_.WillingToWrite() &&
+      datagram_queue_.empty() &&
+      (!QuicVersionUsesCryptoFrames(transport_version()) ||
+       !GetCryptoStream()->HasBufferedCryptoFrames())) {
+    return;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(connection_);
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
+    if (crypto_stream->HasBufferedCryptoFrames()) {
+      crypto_stream->WriteBufferedCryptoFrames();
+    }
+    if (crypto_stream->HasBufferedCryptoFrames()) {
+      // Cannot finish writing buffered crypto frames, connection is write
+      // blocked.
+      return;
+    }
+  }
+  if (control_frame_manager_.WillingToWrite()) {
+    control_frame_manager_.OnCanWrite();
+  }
+  // TODO(b/147146815): this makes all datagrams go before stream data.  We
+  // should have a better priority scheme for this.
+  if (!datagram_queue_.empty()) {
+    size_t written = datagram_queue_.SendDatagrams();
+    QUIC_DVLOG(1) << ENDPOINT << "Sent " << written << " datagrams";
+    if (!datagram_queue_.empty()) {
+      return;
+    }
+  }
+  std::vector<QuicStreamId> last_writing_stream_ids;
+  for (size_t i = 0; i < num_writes; ++i) {
+    if (!(write_blocked_streams_.HasWriteBlockedSpecialStream() ||
+          write_blocked_streams_.HasWriteBlockedDataStreams())) {
+      // Writing one stream removed another!? Something's broken.
+      QUIC_BUG(quic_bug_10866_1)
+          << "WriteBlockedStream is missing, num_writes: " << num_writes
+          << ", finished_writes: " << i
+          << ", connected: " << connection_->connected()
+          << ", connection level flow control blocked: "
+          << flow_controller_.IsBlocked();
+      for (QuicStreamId id : last_writing_stream_ids) {
+        QUIC_LOG(WARNING) << "last_writing_stream_id: " << id;
+      }
+      connection_->CloseConnection(QUIC_INTERNAL_ERROR,
+                                   "WriteBlockedStream is missing",
+                                   ConnectionCloseBehavior::SILENT_CLOSE);
+      return;
+    }
+    if (!CanWriteStreamData()) {
+      return;
+    }
+    currently_writing_stream_id_ = write_blocked_streams_.PopFront();
+    last_writing_stream_ids.push_back(currently_writing_stream_id_);
+    QUIC_DVLOG(1) << ENDPOINT << "Removing stream "
+                  << currently_writing_stream_id_ << " from write-blocked list";
+    QuicStream* stream = GetOrCreateStream(currently_writing_stream_id_);
+    if (stream != nullptr && !stream->IsFlowControlBlocked()) {
+      // If the stream can't write all bytes it'll re-add itself to the blocked
+      // list.
+      uint64_t previous_bytes_written = stream->stream_bytes_written();
+      bool previous_fin_sent = stream->fin_sent();
+      QUIC_DVLOG(1) << ENDPOINT << "stream " << stream->id()
+                    << " bytes_written " << previous_bytes_written << " fin "
+                    << previous_fin_sent;
+      stream->OnCanWrite();
+      QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
+      QUICHE_DCHECK(CheckStreamNotBusyLooping(stream, previous_bytes_written,
+                                              previous_fin_sent));
+    }
+    currently_writing_stream_id_ = 0;
+  }
+}
+
+bool QuicSession::SendProbingData() {
+  if (connection()->sent_packet_manager().MaybeRetransmitOldestPacket(
+          PROBING_RETRANSMISSION)) {
+    return true;
+  }
+  return false;
+}
+
+bool QuicSession::WillingAndAbleToWrite() const {
+  // Schedule a write when:
+  // 1) control frame manager has pending or new control frames, or
+  // 2) any stream has pending retransmissions, or
+  // 3) If the crypto or headers streams are blocked, or
+  // 4) connection is not flow control blocked and there are write blocked
+  // streams.
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    if (HasPendingHandshake()) {
+      return true;
+    }
+    if (!IsEncryptionEstablished()) {
+      return false;
+    }
+  }
+  if (control_frame_manager_.WillingToWrite() ||
+      !streams_with_pending_retransmission_.empty()) {
+    return true;
+  }
+  if (flow_controller_.IsBlocked()) {
+    if (VersionUsesHttp3(transport_version())) {
+      return false;
+    }
+    // Crypto and headers streams are not blocked by connection level flow
+    // control.
+    return write_blocked_streams_.HasWriteBlockedSpecialStream();
+  }
+  return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
+         write_blocked_streams_.HasWriteBlockedDataStreams();
+}
+
+std::string QuicSession::GetStreamsInfoForLogging() const {
+  std::string info = absl::StrCat(
+      "num_active_streams: ", GetNumActiveStreams(),
+      ", num_pending_streams: ", pending_streams_size(),
+      ", num_outgoing_draining_streams: ", num_outgoing_draining_streams(),
+      " ");
+  // Log info for up to 5 streams.
+  size_t i = 5;
+  for (const auto& it : stream_map_) {
+    if (it.second->is_static()) {
+      continue;
+    }
+    // Calculate the stream creation delay.
+    const QuicTime::Delta delay =
+        connection_->clock()->ApproximateNow() - it.second->creation_time();
+    absl::StrAppend(
+        &info, "{", it.second->id(), ":", delay.ToDebuggingValue(), ";",
+        it.second->stream_bytes_written(), ",", it.second->fin_sent(), ",",
+        it.second->HasBufferedData(), ",", it.second->fin_buffered(), ";",
+        it.second->stream_bytes_read(), ",", it.second->fin_received(), "}");
+    --i;
+    if (i == 0) {
+      break;
+    }
+  }
+  return info;
+}
+
+bool QuicSession::HasPendingHandshake() const {
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    return GetCryptoStream()->HasPendingCryptoRetransmission() ||
+           GetCryptoStream()->HasBufferedCryptoFrames();
+  }
+  return streams_with_pending_retransmission_.contains(
+             QuicUtils::GetCryptoStreamId(transport_version())) ||
+         write_blocked_streams_.IsStreamBlocked(
+             QuicUtils::GetCryptoStreamId(transport_version()));
+}
+
+void QuicSession::ProcessUdpPacket(const QuicSocketAddress& self_address,
+                                   const QuicSocketAddress& peer_address,
+                                   const QuicReceivedPacket& packet) {
+  QuicConnectionContextSwitcher cs(connection_->context());
+  connection_->ProcessUdpPacket(self_address, peer_address, packet);
+}
+
+QuicConsumedData QuicSession::WritevData(QuicStreamId id, size_t write_length,
+                                         QuicStreamOffset offset,
+                                         StreamSendingState state,
+                                         TransmissionType type,
+                                         EncryptionLevel level) {
+  QUICHE_DCHECK(connection_->connected())
+      << ENDPOINT << "Try to write stream data when connection is closed.";
+  if (!IsEncryptionEstablished() &&
+      !QuicUtils::IsCryptoStreamId(transport_version(), id)) {
+    // Do not let streams write without encryption. The calling stream will end
+    // up write blocked until OnCanWrite is next called.
+    if (was_zero_rtt_rejected_ && !OneRttKeysAvailable()) {
+      QUICHE_DCHECK(version().UsesTls() &&
+                    perspective() == Perspective::IS_CLIENT);
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "Suppress the write while 0-RTT gets rejected and "
+                         "1-RTT keys are not available. Version: "
+                      << ParsedQuicVersionToString(version());
+    } else if (version().UsesTls() || perspective() == Perspective::IS_SERVER) {
+      QUIC_BUG(quic_bug_10866_2)
+          << ENDPOINT << "Try to send data of stream " << id
+          << " before encryption is established. Version: "
+          << ParsedQuicVersionToString(version());
+    } else {
+      // In QUIC crypto, this could happen when the client sends full CHLO and
+      // 0-RTT request, then receives an inchoate REJ and sends an inchoate
+      // CHLO. The client then gets the ACK of the inchoate CHLO or the client
+      // gets the full REJ and needs to verify the proof (before it sends the
+      // full CHLO), such that there is no outstanding crypto data.
+      // Retransmission alarm fires in TLP mode which tries to retransmit the
+      // 0-RTT request (without encryption).
+      QUIC_DLOG(INFO) << ENDPOINT << "Try to send data of stream " << id
+                      << " before encryption is established.";
+    }
+    return QuicConsumedData(0, false);
+  }
+
+  SetTransmissionType(type);
+  QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
+
+  QuicConsumedData data =
+      connection_->SendStreamData(id, write_length, offset, state);
+  if (type == NOT_RETRANSMISSION) {
+    // This is new stream data.
+    write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed);
+  }
+
+  return data;
+}
+
+size_t QuicSession::SendCryptoData(EncryptionLevel level, size_t write_length,
+                                   QuicStreamOffset offset,
+                                   TransmissionType type) {
+  QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
+  if (!connection()->framer().HasEncrypterOfEncryptionLevel(level)) {
+    const std::string error_details = absl::StrCat(
+        "Try to send crypto data with missing keys of encryption level: ",
+        EncryptionLevelToString(level));
+    QUIC_BUG(quic_bug_10866_3) << ENDPOINT << error_details;
+    connection()->CloseConnection(
+        QUIC_MISSING_WRITE_KEYS, error_details,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return 0;
+  }
+  SetTransmissionType(type);
+  QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
+  const auto bytes_consumed =
+      connection_->SendCryptoData(level, write_length, offset);
+  return bytes_consumed;
+}
+
+void QuicSession::OnControlFrameManagerError(QuicErrorCode error_code,
+                                             std::string error_details) {
+  connection_->CloseConnection(
+      error_code, error_details,
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+bool QuicSession::WriteControlFrame(const QuicFrame& frame,
+                                    TransmissionType type) {
+  QUICHE_DCHECK(connection()->connected())
+      << ENDPOINT << "Try to write control frames when connection is closed.";
+  if (!IsEncryptionEstablished()) {
+    // Suppress the write before encryption gets established.
+    return false;
+  }
+  SetTransmissionType(type);
+  QuicConnection::ScopedEncryptionLevelContext context(
+      connection(), GetEncryptionLevelToSendApplicationData());
+  return connection_->SendControlFrame(frame);
+}
+
+void QuicSession::ResetStream(QuicStreamId id, QuicRstStreamErrorCode error) {
+  QuicStream* stream = GetStream(id);
+  if (stream != nullptr && stream->is_static()) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Try to reset a static stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (stream != nullptr) {
+    stream->Reset(error);
+    return;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(connection());
+  MaybeSendStopSendingFrame(id, QuicResetStreamError::FromInternal(error));
+  MaybeSendRstStreamFrame(id, QuicResetStreamError::FromInternal(error), 0);
+}
+
+void QuicSession::MaybeSendRstStreamFrame(QuicStreamId id,
+                                          QuicResetStreamError error,
+                                          QuicStreamOffset bytes_written) {
+  if (!connection()->connected()) {
+    return;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version()) ||
+      QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
+                               version()) != READ_UNIDIRECTIONAL) {
+    control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
+  }
+
+  connection_->OnStreamReset(id, error.internal_code());
+}
+
+void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id,
+                                            QuicResetStreamError error) {
+  if (!connection()->connected()) {
+    return;
+  }
+  if (VersionHasIetfQuicFrames(transport_version()) &&
+      QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
+                               version()) != WRITE_UNIDIRECTIONAL) {
+    control_frame_manager_.WriteOrBufferStopSending(error, id);
+  }
+}
+
+void QuicSession::SendGoAway(QuicErrorCode error_code,
+                             const std::string& reason) {
+  // GOAWAY frame is not supported in IETF QUIC.
+  QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
+  if (!IsEncryptionEstablished()) {
+    QUIC_CODE_COUNT(quic_goaway_before_encryption_established);
+    connection_->CloseConnection(
+        error_code, reason,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (transport_goaway_sent_) {
+    return;
+  }
+  transport_goaway_sent_ = true;
+
+  QUICHE_DCHECK_EQ(perspective(), Perspective::IS_SERVER);
+  control_frame_manager_.WriteOrBufferGoAway(
+      error_code,
+      QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
+          transport_version()),
+      reason);
+}
+
+void QuicSession::SendBlocked(QuicStreamId id) {
+  control_frame_manager_.WriteOrBufferBlocked(id);
+}
+
+void QuicSession::SendWindowUpdate(QuicStreamId id,
+                                   QuicStreamOffset byte_offset) {
+  control_frame_manager_.WriteOrBufferWindowUpdate(id, byte_offset);
+}
+
+void QuicSession::OnStreamError(QuicErrorCode error_code,
+                                std::string error_details) {
+  connection_->CloseConnection(
+      error_code, error_details,
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicSession::OnStreamError(QuicErrorCode error_code,
+                                QuicIetfTransportErrorCodes ietf_error,
+                                std::string error_details) {
+  connection_->CloseConnection(
+      error_code, ietf_error, error_details,
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicSession::SendMaxStreams(QuicStreamCount stream_count,
+                                 bool unidirectional) {
+  if (!is_configured_) {
+    QUIC_BUG(quic_bug_10866_5)
+        << "Try to send max streams before config negotiated.";
+    return;
+  }
+  control_frame_manager_.WriteOrBufferMaxStreams(stream_count, unidirectional);
+}
+
+void QuicSession::InsertLocallyClosedStreamsHighestOffset(
+    const QuicStreamId id, QuicStreamOffset offset) {
+  locally_closed_streams_highest_offset_[id] = offset;
+}
+
+void QuicSession::OnStreamClosed(QuicStreamId stream_id) {
+  QUIC_DVLOG(1) << ENDPOINT << "Closing stream: " << stream_id;
+  StreamMap::iterator it = stream_map_.find(stream_id);
+  if (it == stream_map_.end()) {
+    QUIC_BUG(quic_bug_10866_6)
+        << ENDPOINT << "Stream is already closed: " << stream_id;
+    return;
+  }
+  QuicStream* stream = it->second.get();
+  StreamType type = stream->type();
+
+  const bool stream_waiting_for_acks = stream->IsWaitingForAcks();
+  if (stream_waiting_for_acks) {
+    // The stream needs to be kept alive because it's waiting for acks.
+    ++num_zombie_streams_;
+  } else {
+    closed_streams_.push_back(std::move(it->second));
+    stream_map_.erase(it);
+    // Do not retransmit data of a closed stream.
+    streams_with_pending_retransmission_.erase(stream_id);
+    if (!closed_streams_clean_up_alarm_->IsSet()) {
+      closed_streams_clean_up_alarm_->Set(
+          connection_->clock()->ApproximateNow());
+    }
+    QUIC_BUG_IF(
+        364846171_1,
+        connection_->packet_creator().HasPendingStreamFramesOfStream(stream_id))
+        << "Stream " << stream_id
+        << " gets closed while there are pending frames.";
+  }
+
+  if (!stream->HasReceivedFinalOffset()) {
+    // If we haven't received a FIN or RST for this stream, we need to keep
+    // track of the how many bytes the stream's flow controller believes it has
+    // received, for accurate connection level flow control accounting.
+    // If this is an outgoing stream, it is technically open from peer's
+    // perspective. Do not inform stream Id manager yet.
+    QUICHE_DCHECK(!stream->was_draining());
+    InsertLocallyClosedStreamsHighestOffset(
+        stream_id, stream->highest_received_byte_offset());
+    return;
+  }
+
+  const bool stream_was_draining = stream->was_draining();
+  QUIC_DVLOG_IF(1, stream_was_draining)
+      << ENDPOINT << "Stream " << stream_id << " was draining";
+  if (stream_was_draining) {
+    QUIC_BUG_IF(quic_bug_12435_4, num_draining_streams_ == 0);
+    --num_draining_streams_;
+    if (!IsIncomingStream(stream_id)) {
+      QUIC_BUG_IF(quic_bug_12435_5, num_outgoing_draining_streams_ == 0);
+      --num_outgoing_draining_streams_;
+    }
+    // Stream Id manager has been informed with draining streams.
+    return;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    stream_id_manager_.OnStreamClosed(
+        /*is_incoming=*/IsIncomingStream(stream_id));
+  }
+  if (!connection_->connected()) {
+    return;
+  }
+  if (IsIncomingStream(stream_id)) {
+    // Stream Id manager is only interested in peer initiated stream IDs.
+    if (VersionHasIetfQuicFrames(transport_version())) {
+      ietf_streamid_manager_.OnStreamClosed(stream_id);
+    }
+    return;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    OnCanCreateNewOutgoingStream(type != BIDIRECTIONAL);
+  }
+}
+
+void QuicSession::ClosePendingStream(QuicStreamId stream_id) {
+  QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  pending_stream_map_.erase(stream_id);
+  if (connection_->connected()) {
+    ietf_streamid_manager_.OnStreamClosed(stream_id);
+  }
+}
+
+bool QuicSession::ShouldProcessFrameByPendingStream(QuicFrameType type,
+                                                    QuicStreamId id) const {
+  return UsesPendingStreamForFrame(type, id) &&
+         stream_map_.find(id) == stream_map_.end();
+}
+
+void QuicSession::OnFinalByteOffsetReceived(
+    QuicStreamId stream_id, QuicStreamOffset final_byte_offset) {
+  auto it = locally_closed_streams_highest_offset_.find(stream_id);
+  if (it == locally_closed_streams_highest_offset_.end()) {
+    return;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Received final byte offset "
+                << final_byte_offset << " for stream " << stream_id;
+  QuicByteCount offset_diff = final_byte_offset - it->second;
+  if (flow_controller_.UpdateHighestReceivedOffset(
+          flow_controller_.highest_received_byte_offset() + offset_diff)) {
+    // If the final offset violates flow control, close the connection now.
+    if (flow_controller_.FlowControlViolation()) {
+      connection_->CloseConnection(
+          QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+          "Connection level flow control violation",
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+  }
+
+  flow_controller_.AddBytesConsumed(offset_diff);
+  locally_closed_streams_highest_offset_.erase(it);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    stream_id_manager_.OnStreamClosed(
+        /*is_incoming=*/IsIncomingStream(stream_id));
+  }
+  if (IsIncomingStream(stream_id)) {
+    if (VersionHasIetfQuicFrames(transport_version())) {
+      ietf_streamid_manager_.OnStreamClosed(stream_id);
+    }
+  } else if (!VersionHasIetfQuicFrames(transport_version())) {
+    OnCanCreateNewOutgoingStream(false);
+  }
+}
+
+bool QuicSession::IsEncryptionEstablished() const {
+  if (GetCryptoStream() == nullptr) {
+    return false;
+  }
+  return GetCryptoStream()->encryption_established();
+}
+
+bool QuicSession::OneRttKeysAvailable() const {
+  if (GetCryptoStream() == nullptr) {
+    return false;
+  }
+  return GetCryptoStream()->one_rtt_keys_available();
+}
+
+void QuicSession::OnConfigNegotiated() {
+  // In versions with TLS, the configs will be set twice if 0-RTT is available.
+  // In the second config setting, 1-RTT keys are guaranteed to be available.
+  if (version().UsesTls() && is_configured_ &&
+      connection_->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
+    QUIC_BUG(quic_bug_12435_6)
+        << ENDPOINT
+        << "1-RTT keys missing when config is negotiated for the second time.";
+    connection_->CloseConnection(
+        QUIC_INTERNAL_ERROR,
+        "1-RTT keys missing when config is negotiated for the second time.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "OnConfigNegotiated";
+  connection_->SetFromConfig(config_);
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    uint32_t max_streams = 0;
+    if (config_.HasReceivedMaxBidirectionalStreams()) {
+      max_streams = config_.ReceivedMaxBidirectionalStreams();
+    }
+    if (was_zero_rtt_rejected_ &&
+        max_streams <
+            ietf_streamid_manager_.outgoing_bidirectional_stream_count()) {
+      connection_->CloseConnection(
+          QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+          absl::StrCat(
+              "Server rejected 0-RTT, aborting because new bidirectional "
+              "initial stream limit ",
+              max_streams, " is less than current open streams: ",
+              ietf_streamid_manager_.outgoing_bidirectional_stream_count()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Setting Bidirectional outgoing_max_streams_ to "
+                  << max_streams;
+    if (perspective_ == Perspective::IS_CLIENT &&
+        max_streams <
+            ietf_streamid_manager_.max_outgoing_bidirectional_streams()) {
+      connection_->CloseConnection(
+          was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+                                 : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+          absl::StrCat(
+              was_zero_rtt_rejected_
+                  ? "Server rejected 0-RTT, aborting because "
+                  : "",
+              "new bidirectional limit ", max_streams,
+              " decreases the current limit: ",
+              ietf_streamid_manager_.max_outgoing_bidirectional_streams()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+    if (ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
+            max_streams)) {
+      OnCanCreateNewOutgoingStream(/*unidirectional = */ false);
+    }
+
+    max_streams = 0;
+    if (config_.HasReceivedMaxUnidirectionalStreams()) {
+      max_streams = config_.ReceivedMaxUnidirectionalStreams();
+    }
+
+    if (was_zero_rtt_rejected_ &&
+        max_streams <
+            ietf_streamid_manager_.outgoing_unidirectional_stream_count()) {
+      connection_->CloseConnection(
+          QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+          absl::StrCat(
+              "Server rejected 0-RTT, aborting because new unidirectional "
+              "initial stream limit ",
+              max_streams, " is less than current open streams: ",
+              ietf_streamid_manager_.outgoing_unidirectional_stream_count()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+
+    if (max_streams <
+        ietf_streamid_manager_.max_outgoing_unidirectional_streams()) {
+      connection_->CloseConnection(
+          was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+                                 : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+          absl::StrCat(
+              was_zero_rtt_rejected_
+                  ? "Server rejected 0-RTT, aborting because "
+                  : "",
+              "new unidirectional limit ", max_streams,
+              " decreases the current limit: ",
+              ietf_streamid_manager_.max_outgoing_unidirectional_streams()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Setting Unidirectional outgoing_max_streams_ to "
+                  << max_streams;
+    if (ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
+            max_streams)) {
+      OnCanCreateNewOutgoingStream(/*unidirectional = */ true);
+    }
+  } else {
+    uint32_t max_streams = 0;
+    if (config_.HasReceivedMaxBidirectionalStreams()) {
+      max_streams = config_.ReceivedMaxBidirectionalStreams();
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Setting max_open_outgoing_streams_ to "
+                  << max_streams;
+    if (was_zero_rtt_rejected_ &&
+        max_streams < stream_id_manager_.num_open_outgoing_streams()) {
+      connection_->CloseConnection(
+          QUIC_INTERNAL_ERROR,
+          absl::StrCat(
+              "Server rejected 0-RTT, aborting because new stream limit ",
+              max_streams, " is less than current open streams: ",
+              stream_id_manager_.num_open_outgoing_streams()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+    stream_id_manager_.set_max_open_outgoing_streams(max_streams);
+  }
+
+  if (perspective() == Perspective::IS_SERVER) {
+    if (config_.HasReceivedConnectionOptions()) {
+      // The following variations change the initial receive flow control
+      // window sizes.
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW6)) {
+        AdjustInitialFlowControlWindows(64 * 1024);
+      }
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW7)) {
+        AdjustInitialFlowControlWindows(128 * 1024);
+      }
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW8)) {
+        AdjustInitialFlowControlWindows(256 * 1024);
+      }
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW9)) {
+        AdjustInitialFlowControlWindows(512 * 1024);
+      }
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFWA)) {
+        AdjustInitialFlowControlWindows(1024 * 1024);
+      }
+    }
+
+    config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
+        config_.GetMaxBidirectionalStreamsToSend());
+    ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
+        config_.GetMaxUnidirectionalStreamsToSend());
+  } else {
+    // A small number of additional incoming streams beyond the limit should be
+    // allowed. This helps avoid early connection termination when FIN/RSTs for
+    // old streams are lost or arrive out of order.
+    // Use a minimum number of additional streams, or a percentage increase,
+    // whichever is larger.
+    uint32_t max_incoming_streams_to_send =
+        config_.GetMaxBidirectionalStreamsToSend();
+    uint32_t max_incoming_streams =
+        std::max(max_incoming_streams_to_send + kMaxStreamsMinimumIncrement,
+                 static_cast<uint32_t>(max_incoming_streams_to_send *
+                                       kMaxStreamsMultiplier));
+    stream_id_manager_.set_max_open_incoming_streams(max_incoming_streams);
+  }
+
+  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    // When using IETF-style TLS transport parameters, inform existing streams
+    // of new flow-control limits.
+    if (config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) {
+      OnNewStreamOutgoingBidirectionalFlowControlWindow(
+          config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+    }
+    if (config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) {
+      OnNewStreamIncomingBidirectionalFlowControlWindow(
+          config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+    }
+    if (config_.HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
+      OnNewStreamUnidirectionalFlowControlWindow(
+          config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
+    }
+  } else {  // The version uses Google QUIC Crypto.
+    if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) {
+      // Streams which were created before the SHLO was received (0-RTT
+      // requests) are now informed of the peer's initial flow control window.
+      OnNewStreamFlowControlWindow(
+          config_.ReceivedInitialStreamFlowControlWindowBytes());
+    }
+  }
+
+  if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) {
+    OnNewSessionFlowControlWindow(
+        config_.ReceivedInitialSessionFlowControlWindowBytes());
+  }
+
+  is_configured_ = true;
+  connection()->OnConfigNegotiated();
+
+  // Ask flow controllers to try again since the config could have unblocked us.
+  // Or if this session is configured on TLS enabled QUIC versions,
+  // attempt to retransmit 0-RTT data if there's any.
+  // TODO(fayang): consider removing this OnCanWrite call.
+  if (!connection_->framer().is_processing_packet() &&
+      (connection_->version().AllowsLowFlowControlLimits() ||
+       version().UsesTls())) {
+    QUIC_CODE_COUNT(quic_session_on_can_write_on_config_negotiated);
+    OnCanWrite();
+  }
+}
+
+absl::optional<std::string> QuicSession::OnAlpsData(
+    const uint8_t* /*alps_data*/, size_t /*alps_length*/) {
+  return absl::nullopt;
+}
+
+void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) {
+  const float session_window_multiplier =
+      config_.GetInitialStreamFlowControlWindowToSend()
+          ? static_cast<float>(
+                config_.GetInitialSessionFlowControlWindowToSend()) /
+                config_.GetInitialStreamFlowControlWindowToSend()
+          : 1.5;
+
+  QUIC_DVLOG(1) << ENDPOINT << "Set stream receive window to " << stream_window;
+  config_.SetInitialStreamFlowControlWindowToSend(stream_window);
+
+  size_t session_window = session_window_multiplier * stream_window;
+  QUIC_DVLOG(1) << ENDPOINT << "Set session receive window to "
+                << session_window;
+  config_.SetInitialSessionFlowControlWindowToSend(session_window);
+  flow_controller_.UpdateReceiveWindowSize(session_window);
+  // Inform all existing streams about the new window.
+  for (auto const& kv : stream_map_) {
+    kv.second->UpdateReceiveWindowSize(stream_window);
+  }
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    GetMutableCryptoStream()->UpdateReceiveWindowSize(stream_window);
+  }
+}
+
+void QuicSession::HandleFrameOnNonexistentOutgoingStream(
+    QuicStreamId stream_id) {
+  QUICHE_DCHECK(!IsClosedStream(stream_id));
+  // Received a frame for a locally-created stream that is not currently
+  // active. This is an error.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    connection()->CloseConnection(
+        QUIC_HTTP_STREAM_WRONG_DIRECTION, "Data for nonexistent stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  connection()->CloseConnection(
+      QUIC_INVALID_STREAM_ID, "Data for nonexistent stream",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicSession::HandleRstOnValidNonexistentStream(
+    const QuicRstStreamFrame& frame) {
+  // If the stream is neither originally in active streams nor created in
+  // GetOrCreateStream(), it could be a closed stream in which case its
+  // final received byte offset need to be updated.
+  if (IsClosedStream(frame.stream_id)) {
+    // The RST frame contains the final byte offset for the stream: we can now
+    // update the connection level flow controller if needed.
+    OnFinalByteOffsetReceived(frame.stream_id, frame.byte_offset);
+  }
+}
+
+void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) {
+  QUICHE_DCHECK(version().UsesQuicCrypto());
+  QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamFlowControlWindow " << new_window;
+  if (new_window < kMinimumFlowControlSendWindow) {
+    QUIC_LOG_FIRST_N(ERROR, 1)
+        << "Peer sent us an invalid stream flow control send window: "
+        << new_window << ", below minimum: " << kMinimumFlowControlSendWindow;
+    connection_->CloseConnection(
+        QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  // Inform all existing streams about the new window.
+  for (auto const& kv : stream_map_) {
+    QUIC_DVLOG(1) << ENDPOINT << "Informing stream " << kv.first
+                  << " of new stream flow control window " << new_window;
+    if (!kv.second->MaybeConfigSendWindowOffset(
+            new_window, /* was_zero_rtt_rejected = */ false)) {
+      return;
+    }
+  }
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    QUIC_DVLOG(1)
+        << ENDPOINT
+        << "Informing crypto stream of new stream flow control window "
+        << new_window;
+    GetMutableCryptoStream()->MaybeConfigSendWindowOffset(
+        new_window, /* was_zero_rtt_rejected = */ false);
+  }
+}
+
+void QuicSession::OnNewStreamUnidirectionalFlowControlWindow(
+    QuicStreamOffset new_window) {
+  QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
+  QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamUnidirectionalFlowControlWindow "
+                << new_window;
+  // Inform all existing outgoing unidirectional streams about the new window.
+  for (auto const& kv : stream_map_) {
+    const QuicStreamId id = kv.first;
+    if (!version().HasIetfQuicFrames()) {
+      if (kv.second->type() == BIDIRECTIONAL) {
+        continue;
+      }
+    } else {
+      if (QuicUtils::IsBidirectionalStreamId(id, version())) {
+        continue;
+      }
+    }
+    if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
+                                       perspective())) {
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Informing unidirectional stream " << id
+                  << " of new stream flow control window " << new_window;
+    if (!kv.second->MaybeConfigSendWindowOffset(new_window,
+                                                was_zero_rtt_rejected_)) {
+      return;
+    }
+  }
+}
+
+void QuicSession::OnNewStreamOutgoingBidirectionalFlowControlWindow(
+    QuicStreamOffset new_window) {
+  QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
+  QUIC_DVLOG(1) << ENDPOINT
+                << "OnNewStreamOutgoingBidirectionalFlowControlWindow "
+                << new_window;
+  // Inform all existing outgoing bidirectional streams about the new window.
+  for (auto const& kv : stream_map_) {
+    const QuicStreamId id = kv.first;
+    if (!version().HasIetfQuicFrames()) {
+      if (kv.second->type() != BIDIRECTIONAL) {
+        continue;
+      }
+    } else {
+      if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
+        continue;
+      }
+    }
+    if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
+                                       perspective())) {
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Informing outgoing bidirectional stream "
+                  << id << " of new stream flow control window " << new_window;
+    if (!kv.second->MaybeConfigSendWindowOffset(new_window,
+                                                was_zero_rtt_rejected_)) {
+      return;
+    }
+  }
+}
+
+void QuicSession::OnNewStreamIncomingBidirectionalFlowControlWindow(
+    QuicStreamOffset new_window) {
+  QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
+  QUIC_DVLOG(1) << ENDPOINT
+                << "OnNewStreamIncomingBidirectionalFlowControlWindow "
+                << new_window;
+  // Inform all existing incoming bidirectional streams about the new window.
+  for (auto const& kv : stream_map_) {
+    const QuicStreamId id = kv.first;
+    if (!version().HasIetfQuicFrames()) {
+      if (kv.second->type() != BIDIRECTIONAL) {
+        continue;
+      }
+    } else {
+      if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
+        continue;
+      }
+    }
+    if (QuicUtils::IsOutgoingStreamId(connection_->version(), id,
+                                      perspective())) {
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Informing incoming bidirectional stream "
+                  << id << " of new stream flow control window " << new_window;
+    if (!kv.second->MaybeConfigSendWindowOffset(new_window,
+                                                was_zero_rtt_rejected_)) {
+      return;
+    }
+  }
+}
+
+void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) {
+  QUIC_DVLOG(1) << ENDPOINT << "OnNewSessionFlowControlWindow " << new_window;
+
+  if (was_zero_rtt_rejected_ && new_window < flow_controller_.bytes_sent()) {
+    std::string error_details = absl::StrCat(
+        "Server rejected 0-RTT. Aborting because the client received session "
+        "flow control send window: ",
+        new_window,
+        ", which is below currently used: ", flow_controller_.bytes_sent());
+    QUIC_LOG(ERROR) << error_details;
+    connection_->CloseConnection(
+        QUIC_ZERO_RTT_UNRETRANSMITTABLE, error_details,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (!connection_->version().AllowsLowFlowControlLimits() &&
+      new_window < kMinimumFlowControlSendWindow) {
+    std::string error_details = absl::StrCat(
+        "Peer sent us an invalid session flow control send window: ",
+        new_window, ", below minimum: ", kMinimumFlowControlSendWindow);
+    QUIC_LOG_FIRST_N(ERROR, 1) << error_details;
+    connection_->CloseConnection(
+        QUIC_FLOW_CONTROL_INVALID_WINDOW, error_details,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (perspective_ == Perspective::IS_CLIENT &&
+      new_window < flow_controller_.send_window_offset()) {
+    // The client receives a lower limit than remembered, violating
+    // https://tools.ietf.org/html/draft-ietf-quic-transport-27#section-7.3.1
+    std::string error_details = absl::StrCat(
+        was_zero_rtt_rejected_ ? "Server rejected 0-RTT, aborting because "
+                               : "",
+        "new session max data ", new_window,
+        " decreases current limit: ", flow_controller_.send_window_offset());
+    QUIC_LOG(ERROR) << error_details;
+    connection_->CloseConnection(
+        was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+                               : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+        error_details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  flow_controller_.UpdateSendWindowOffset(new_window);
+}
+
+bool QuicSession::OnNewDecryptionKeyAvailable(
+    EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
+    bool set_alternative_decrypter, bool latch_once_used) {
+  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3 &&
+      !connection()->framer().HasEncrypterOfEncryptionLevel(
+          QuicUtils::GetEncryptionLevel(
+              QuicUtils::GetPacketNumberSpace(level)))) {
+    // This should never happen because connection should never decrypt a packet
+    // while an ACK for it cannot be encrypted.
+    return false;
+  }
+  if (connection()->version().KnowsWhichDecrypterToUse()) {
+    connection()->InstallDecrypter(level, std::move(decrypter));
+    return true;
+  }
+  if (set_alternative_decrypter) {
+    connection()->SetAlternativeDecrypter(level, std::move(decrypter),
+                                          latch_once_used);
+    return true;
+  }
+  connection()->SetDecrypter(level, std::move(decrypter));
+  return true;
+}
+
+void QuicSession::OnNewEncryptionKeyAvailable(
+    EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
+  connection()->SetEncrypter(level, std::move(encrypter));
+  if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
+    return;
+  }
+
+  bool reset_encryption_level = false;
+  if (IsEncryptionEstablished() && level == ENCRYPTION_HANDSHAKE) {
+    // ENCRYPTION_HANDSHAKE keys are only used for the handshake. If
+    // ENCRYPTION_ZERO_RTT keys exist, it is possible for a client to send
+    // stream data, which must not be sent at the ENCRYPTION_HANDSHAKE level.
+    // Therefore, we avoid setting the default encryption level to
+    // ENCRYPTION_HANDSHAKE.
+    reset_encryption_level = true;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
+  connection()->SetDefaultEncryptionLevel(level);
+  if (reset_encryption_level) {
+    connection()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  }
+  QUIC_BUG_IF(quic_bug_12435_7,
+              IsEncryptionEstablished() &&
+                  (connection()->encryption_level() == ENCRYPTION_INITIAL ||
+                   connection()->encryption_level() == ENCRYPTION_HANDSHAKE))
+      << "Encryption is established, but the encryption level " << level
+      << " does not support sending stream data";
+}
+
+void QuicSession::SetDefaultEncryptionLevel(EncryptionLevel level) {
+  QUICHE_DCHECK_EQ(PROTOCOL_QUIC_CRYPTO,
+                   connection_->version().handshake_protocol);
+  QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
+  connection()->SetDefaultEncryptionLevel(level);
+
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      break;
+    case ENCRYPTION_ZERO_RTT:
+      if (perspective() == Perspective::IS_CLIENT) {
+        // Retransmit old 0-RTT data (if any) with the new 0-RTT keys, since
+        // they can't be decrypted by the server.
+        connection_->MarkZeroRttPacketsForRetransmission(0);
+        if (!connection_->framer().is_processing_packet()) {
+          // TODO(fayang): consider removing this OnCanWrite call.
+          // Given any streams blocked by encryption a chance to write.
+          QUIC_CODE_COUNT(
+              quic_session_on_can_write_set_default_encryption_level);
+          OnCanWrite();
+        }
+      }
+      break;
+    case ENCRYPTION_HANDSHAKE:
+      break;
+    case ENCRYPTION_FORWARD_SECURE:
+      QUIC_BUG_IF(quic_bug_12435_8, !config_.negotiated())
+          << ENDPOINT << "Handshake confirmed without parameter negotiation.";
+      connection()->mutable_stats().handshake_completion_time =
+          connection()->clock()->ApproximateNow();
+      break;
+    default:
+      QUIC_BUG(quic_bug_10866_7) << "Unknown encryption level: " << level;
+  }
+}
+
+void QuicSession::OnTlsHandshakeComplete() {
+  QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3, connection_->version().handshake_protocol);
+  QUIC_BUG_IF(quic_bug_12435_9,
+              !GetCryptoStream()->crypto_negotiated_params().cipher_suite)
+      << ENDPOINT << "Handshake completes without cipher suite negotiation.";
+  QUIC_BUG_IF(quic_bug_12435_10, !config_.negotiated())
+      << ENDPOINT << "Handshake completes without parameter negotiation.";
+  connection()->mutable_stats().handshake_completion_time =
+      connection()->clock()->ApproximateNow();
+  if (connection()->version().UsesTls() &&
+      perspective_ == Perspective::IS_SERVER) {
+    // Server sends HANDSHAKE_DONE to signal confirmation of the handshake
+    // to the client.
+    control_frame_manager_.WriteOrBufferHandshakeDone();
+    if (connection()->version().HasIetfQuicFrames()) {
+      MaybeSendAddressToken();
+    }
+  }
+}
+
+bool QuicSession::MaybeSendAddressToken() {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER &&
+                connection()->version().HasIetfQuicFrames());
+  absl::optional<CachedNetworkParameters> cached_network_params =
+      GenerateCachedNetworkParameters();
+
+  std::string address_token = GetCryptoStream()->GetAddressToken(
+      cached_network_params.has_value() ? &cached_network_params.value()
+                                        : nullptr);
+  if (address_token.empty()) {
+    return false;
+  }
+  const size_t buf_len = address_token.length() + 1;
+  auto buffer = std::make_unique<char[]>(buf_len);
+  QuicDataWriter writer(buf_len, buffer.get());
+  // Add |kAddressTokenPrefix| for token sent in NEW_TOKEN frame.
+  writer.WriteUInt8(kAddressTokenPrefix);
+  writer.WriteBytes(address_token.data(), address_token.length());
+  control_frame_manager_.WriteOrBufferNewToken(
+      absl::string_view(buffer.get(), buf_len));
+  if (cached_network_params.has_value()) {
+    connection()->OnSendConnectionState(*cached_network_params);
+  }
+  return true;
+}
+
+void QuicSession::DiscardOldDecryptionKey(EncryptionLevel level) {
+  if (!connection()->version().KnowsWhichDecrypterToUse()) {
+    return;
+  }
+  connection()->RemoveDecrypter(level);
+}
+
+void QuicSession::DiscardOldEncryptionKey(EncryptionLevel level) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Discarding " << level << " keys";
+  if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    connection()->RemoveEncrypter(level);
+  }
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      NeuterUnencryptedData();
+      break;
+    case ENCRYPTION_HANDSHAKE:
+      NeuterHandshakeData();
+      break;
+    case ENCRYPTION_ZERO_RTT:
+      break;
+    case ENCRYPTION_FORWARD_SECURE:
+      QUIC_BUG(quic_bug_10866_8)
+          << ENDPOINT << "Discarding 1-RTT keys is not allowed";
+      break;
+    default:
+      QUIC_BUG(quic_bug_10866_9)
+          << ENDPOINT
+          << "Cannot discard keys for unknown encryption level: " << level;
+  }
+}
+
+void QuicSession::NeuterHandshakeData() {
+  GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(
+      ENCRYPTION_HANDSHAKE);
+  connection()->OnHandshakeComplete();
+}
+
+void QuicSession::OnZeroRttRejected(int reason) {
+  was_zero_rtt_rejected_ = true;
+  connection_->MarkZeroRttPacketsForRetransmission(reason);
+  if (connection_->encryption_level() == ENCRYPTION_FORWARD_SECURE) {
+    QUIC_BUG(quic_bug_10866_10)
+        << "1-RTT keys already available when 0-RTT is rejected.";
+    connection_->CloseConnection(
+        QUIC_INTERNAL_ERROR,
+        "1-RTT keys already available when 0-RTT is rejected.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }
+}
+
+bool QuicSession::FillTransportParameters(TransportParameters* params) {
+  if (version().UsesTls()) {
+    if (perspective() == Perspective::IS_SERVER) {
+      config_.SetOriginalConnectionIdToSend(
+          connection_->GetOriginalDestinationConnectionId());
+      config_.SetInitialSourceConnectionIdToSend(connection_->connection_id());
+    } else {
+      config_.SetInitialSourceConnectionIdToSend(
+          connection_->client_connection_id());
+    }
+  }
+  return config_.FillTransportParameters(params);
+}
+
+QuicErrorCode QuicSession::ProcessTransportParameters(
+    const TransportParameters& params, bool is_resumption,
+    std::string* error_details) {
+  return config_.ProcessTransportParameters(params, is_resumption,
+                                            error_details);
+}
+
+void QuicSession::OnHandshakeCallbackDone() {
+  if (!connection_->connected()) {
+    return;
+  }
+
+  if (!connection()->is_processing_packet()) {
+    connection()->MaybeProcessUndecryptablePackets();
+  }
+}
+
+bool QuicSession::PacketFlusherAttached() const {
+  QUICHE_DCHECK(connection_->connected());
+  return connection()->packet_creator().PacketFlusherAttached();
+}
+
+void QuicSession::OnCryptoHandshakeMessageSent(
+    const CryptoHandshakeMessage& /*message*/) {}
+
+void QuicSession::OnCryptoHandshakeMessageReceived(
+    const CryptoHandshakeMessage& /*message*/) {}
+
+void QuicSession::RegisterStreamPriority(
+    QuicStreamId id, bool is_static,
+    const spdy::SpdyStreamPrecedence& precedence) {
+  write_blocked_streams()->RegisterStream(id, is_static, precedence);
+}
+
+void QuicSession::UnregisterStreamPriority(QuicStreamId id, bool is_static) {
+  write_blocked_streams()->UnregisterStream(id, is_static);
+}
+
+void QuicSession::UpdateStreamPriority(
+    QuicStreamId id, const spdy::SpdyStreamPrecedence& new_precedence) {
+  write_blocked_streams()->UpdateStreamPriority(id, new_precedence);
+}
+
+QuicConfig* QuicSession::config() { return &config_; }
+
+void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) {
+  QuicStreamId stream_id = stream->id();
+  bool is_static = stream->is_static();
+  QUIC_DVLOG(1) << ENDPOINT << "num_streams: " << stream_map_.size()
+                << ". activating stream " << stream_id;
+  QUICHE_DCHECK(!stream_map_.contains(stream_id));
+  stream_map_[stream_id] = std::move(stream);
+  if (is_static) {
+    ++num_static_streams_;
+    return;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Do not inform stream ID manager of static streams.
+    stream_id_manager_.ActivateStream(
+        /*is_incoming=*/IsIncomingStream(stream_id));
+  }
+}
+
+QuicStreamId QuicSession::GetNextOutgoingBidirectionalStreamId() {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetNextOutgoingBidirectionalStreamId();
+  }
+  return stream_id_manager_.GetNextOutgoingStreamId();
+}
+
+QuicStreamId QuicSession::GetNextOutgoingUnidirectionalStreamId() {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetNextOutgoingUnidirectionalStreamId();
+  }
+  return stream_id_manager_.GetNextOutgoingStreamId();
+}
+
+bool QuicSession::CanOpenNextOutgoingBidirectionalStream() {
+  if (liveness_testing_in_progress_) {
+    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective());
+    return false;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    if (!stream_id_manager_.CanOpenNextOutgoingStream()) {
+      return false;
+    }
+  } else {
+    if (!ietf_streamid_manager_.CanOpenNextOutgoingBidirectionalStream()) {
+      if (is_configured_) {
+        // Send STREAM_BLOCKED after config negotiated.
+        control_frame_manager_.WriteOrBufferStreamsBlocked(
+            ietf_streamid_manager_.max_outgoing_bidirectional_streams(),
+            /*unidirectional=*/false);
+      }
+      return false;
+    }
+  }
+  if (perspective() == Perspective::IS_CLIENT &&
+      connection_->MaybeTestLiveness()) {
+    // Now is relatively close to the idle timeout having the risk that requests
+    // could be discarded at the server.
+    liveness_testing_in_progress_ = true;
+    return false;
+  }
+  return true;
+}
+
+bool QuicSession::CanOpenNextOutgoingUnidirectionalStream() {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return stream_id_manager_.CanOpenNextOutgoingStream();
+  }
+  if (ietf_streamid_manager_.CanOpenNextOutgoingUnidirectionalStream()) {
+    return true;
+  }
+  if (is_configured_) {
+    // Send STREAM_BLOCKED after config negotiated.
+    control_frame_manager_.WriteOrBufferStreamsBlocked(
+        ietf_streamid_manager_.max_outgoing_unidirectional_streams(),
+        /*unidirectional=*/true);
+  }
+  return false;
+}
+
+QuicStreamCount QuicSession::GetAdvertisedMaxIncomingBidirectionalStreams()
+    const {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  return ietf_streamid_manager_.advertised_max_incoming_bidirectional_streams();
+}
+
+QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) {
+  QUICHE_DCHECK(!pending_stream_map_.contains(stream_id));
+  if (QuicUtils::IsCryptoStreamId(transport_version(), stream_id)) {
+    return GetMutableCryptoStream();
+  }
+
+  StreamMap::iterator it = stream_map_.find(stream_id);
+  if (it != stream_map_.end()) {
+    return it->second->IsZombie() ? nullptr : it->second.get();
+  }
+
+  if (IsClosedStream(stream_id)) {
+    return nullptr;
+  }
+
+  if (!IsIncomingStream(stream_id)) {
+    HandleFrameOnNonexistentOutgoingStream(stream_id);
+    return nullptr;
+  }
+
+  // TODO(fkastenholz): If we are creating a new stream and we have sent a
+  // goaway, we should ignore the stream creation. Need to add code to A) test
+  // if goaway was sent ("if (transport_goaway_sent_)") and B) reject stream
+  // creation ("return nullptr")
+
+  if (!MaybeIncreaseLargestPeerStreamId(stream_id)) {
+    return nullptr;
+  }
+
+  if (!VersionHasIetfQuicFrames(transport_version()) &&
+      !stream_id_manager_.CanOpenIncomingStream()) {
+    // Refuse to open the stream.
+    ResetStream(stream_id, QUIC_REFUSED_STREAM);
+    return nullptr;
+  }
+
+  return CreateIncomingStream(stream_id);
+}
+
+void QuicSession::StreamDraining(QuicStreamId stream_id, bool unidirectional) {
+  QUICHE_DCHECK(stream_map_.contains(stream_id));
+  QUIC_DVLOG(1) << ENDPOINT << "Stream " << stream_id << " is draining";
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    ietf_streamid_manager_.OnStreamClosed(stream_id);
+  } else {
+    stream_id_manager_.OnStreamClosed(
+        /*is_incoming=*/IsIncomingStream(stream_id));
+  }
+  ++num_draining_streams_;
+  if (!IsIncomingStream(stream_id)) {
+    ++num_outgoing_draining_streams_;
+    if (!VersionHasIetfQuicFrames(transport_version())) {
+      OnCanCreateNewOutgoingStream(unidirectional);
+    }
+  }
+}
+
+bool QuicSession::MaybeIncreaseLargestPeerStreamId(
+    const QuicStreamId stream_id) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    std::string error_details;
+    if (ietf_streamid_manager_.MaybeIncreaseLargestPeerStreamId(
+            stream_id, &error_details)) {
+      return true;
+    }
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, error_details,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  if (!stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id)) {
+    connection()->CloseConnection(
+        QUIC_TOO_MANY_AVAILABLE_STREAMS,
+        absl::StrCat(stream_id, " exceeds available streams ",
+                     stream_id_manager_.MaxAvailableStreams()),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  return true;
+}
+
+bool QuicSession::ShouldYield(QuicStreamId stream_id) {
+  if (stream_id == currently_writing_stream_id_) {
+    return false;
+  }
+  return write_blocked_streams()->ShouldYield(stream_id);
+}
+
+PendingStream* QuicSession::GetOrCreatePendingStream(QuicStreamId stream_id) {
+  auto it = pending_stream_map_.find(stream_id);
+  if (it != pending_stream_map_.end()) {
+    return it->second.get();
+  }
+
+  if (IsClosedStream(stream_id) ||
+      !MaybeIncreaseLargestPeerStreamId(stream_id)) {
+    return nullptr;
+  }
+
+  auto pending = std::make_unique<PendingStream>(stream_id, this);
+  PendingStream* unowned_pending = pending.get();
+  pending_stream_map_[stream_id] = std::move(pending);
+  return unowned_pending;
+}
+
+void QuicSession::set_largest_peer_created_stream_id(
+    QuicStreamId largest_peer_created_stream_id) {
+  QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
+  stream_id_manager_.set_largest_peer_created_stream_id(
+      largest_peer_created_stream_id);
+}
+
+QuicStreamId QuicSession::GetLargestPeerCreatedStreamId(
+    bool unidirectional) const {
+  // This method is only used in IETF QUIC.
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  return ietf_streamid_manager_.GetLargestPeerCreatedStreamId(unidirectional);
+}
+
+void QuicSession::DeleteConnection() {
+  if (connection_) {
+    delete connection_;
+    connection_ = nullptr;
+  }
+}
+
+bool QuicSession::MaybeSetStreamPriority(
+    QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
+  auto active_stream = stream_map_.find(stream_id);
+  if (active_stream != stream_map_.end()) {
+    active_stream->second->SetPriority(precedence);
+    return true;
+  }
+
+  return false;
+}
+
+bool QuicSession::IsClosedStream(QuicStreamId id) {
+  QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
+  if (IsOpenStream(id)) {
+    // Stream is active
+    return false;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return !ietf_streamid_manager_.IsAvailableStream(id);
+  }
+
+  return !stream_id_manager_.IsAvailableStream(id);
+}
+
+bool QuicSession::IsOpenStream(QuicStreamId id) {
+  QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
+  const StreamMap::iterator it = stream_map_.find(id);
+  if (it != stream_map_.end()) {
+    return !it->second->IsZombie();
+  }
+  if (pending_stream_map_.contains(id) ||
+      QuicUtils::IsCryptoStreamId(transport_version(), id)) {
+    // Stream is active
+    return true;
+  }
+  return false;
+}
+
+bool QuicSession::IsStaticStream(QuicStreamId id) const {
+  auto it = stream_map_.find(id);
+  if (it == stream_map_.end()) {
+    return false;
+  }
+  return it->second->is_static();
+}
+
+size_t QuicSession::GetNumActiveStreams() const {
+  QUICHE_DCHECK_GE(
+      static_cast<QuicStreamCount>(stream_map_.size()),
+      num_static_streams_ + num_draining_streams_ + num_zombie_streams_);
+  return stream_map_.size() - num_draining_streams_ - num_static_streams_ -
+         num_zombie_streams_;
+}
+
+void QuicSession::MarkConnectionLevelWriteBlocked(QuicStreamId id) {
+  if (GetOrCreateStream(id) == nullptr) {
+    QUIC_BUG(quic_bug_10866_11)
+        << "Marking unknown stream " << id << " blocked.";
+    QUIC_LOG_FIRST_N(ERROR, 2) << QuicStackTrace();
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Adding stream " << id
+                << " to write-blocked list";
+
+  write_blocked_streams_.AddStream(id);
+}
+
+bool QuicSession::HasDataToWrite() const {
+  return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
+         write_blocked_streams_.HasWriteBlockedDataStreams() ||
+         connection_->HasQueuedData() ||
+         !streams_with_pending_retransmission_.empty() ||
+         control_frame_manager_.WillingToWrite();
+}
+
+void QuicSession::OnAckNeedsRetransmittableFrame() {
+  flow_controller_.SendWindowUpdate();
+}
+
+void QuicSession::SendAckFrequency(const QuicAckFrequencyFrame& frame) {
+  control_frame_manager_.WriteOrBufferAckFrequency(frame);
+}
+
+void QuicSession::SendNewConnectionId(const QuicNewConnectionIdFrame& frame) {
+  // Count NEW_CONNECTION_ID frames sent to client.
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 1, 6);
+  control_frame_manager_.WriteOrBufferNewConnectionId(
+      frame.connection_id, frame.sequence_number, frame.retire_prior_to,
+      frame.stateless_reset_token);
+}
+
+void QuicSession::SendRetireConnectionId(uint64_t sequence_number) {
+  // Count RETIRE_CONNECTION_ID frames sent to client.
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 2, 6);
+  control_frame_manager_.WriteOrBufferRetireConnectionId(sequence_number);
+}
+
+void QuicSession::OnServerConnectionIdIssued(
+    const QuicConnectionId& server_connection_id) {
+  if (visitor_) {
+    visitor_->OnNewConnectionIdSent(
+        connection_->GetOneActiveServerConnectionId(), server_connection_id);
+  }
+}
+
+void QuicSession::OnServerConnectionIdRetired(
+    const QuicConnectionId& server_connection_id) {
+  if (visitor_) {
+    visitor_->OnConnectionIdRetired(server_connection_id);
+  }
+}
+
+bool QuicSession::IsConnectionFlowControlBlocked() const {
+  return flow_controller_.IsBlocked();
+}
+
+bool QuicSession::IsStreamFlowControlBlocked() {
+  for (auto const& kv : stream_map_) {
+    if (kv.second->IsFlowControlBlocked()) {
+      return true;
+    }
+  }
+  if (!QuicVersionUsesCryptoFrames(transport_version()) &&
+      GetMutableCryptoStream()->IsFlowControlBlocked()) {
+    return true;
+  }
+  return false;
+}
+
+size_t QuicSession::MaxAvailableBidirectionalStreams() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
+  }
+  return stream_id_manager_.MaxAvailableStreams();
+}
+
+size_t QuicSession::MaxAvailableUnidirectionalStreams() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
+  }
+  return stream_id_manager_.MaxAvailableStreams();
+}
+
+bool QuicSession::IsIncomingStream(QuicStreamId id) const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return !QuicUtils::IsOutgoingStreamId(version(), id, perspective_);
+  }
+  return stream_id_manager_.IsIncomingStream(id);
+}
+
+void QuicSession::MaybeCloseZombieStream(QuicStreamId id) {
+  auto it = stream_map_.find(id);
+  if (it == stream_map_.end()) {
+    return;
+  }
+  --num_zombie_streams_;
+  closed_streams_.push_back(std::move(it->second));
+  stream_map_.erase(it);
+
+  if (!closed_streams_clean_up_alarm_->IsSet()) {
+    closed_streams_clean_up_alarm_->Set(connection_->clock()->ApproximateNow());
+  }
+  // Do not retransmit data of a closed stream.
+  streams_with_pending_retransmission_.erase(id);
+  QUIC_BUG_IF(364846171_2,
+              connection_->packet_creator().HasPendingStreamFramesOfStream(id))
+      << "Stream " << id << " gets closed while there are pending frames.";
+}
+
+QuicStream* QuicSession::GetStream(QuicStreamId id) const {
+  auto active_stream = stream_map_.find(id);
+  if (active_stream != stream_map_.end()) {
+    return active_stream->second.get();
+  }
+
+  if (QuicUtils::IsCryptoStreamId(transport_version(), id)) {
+    return const_cast<QuicCryptoStream*>(GetCryptoStream());
+  }
+
+  return nullptr;
+}
+
+QuicStream* QuicSession::GetActiveStream(QuicStreamId id) const {
+  auto stream = stream_map_.find(id);
+  if (stream != stream_map_.end() && !stream->second->is_static()) {
+    return stream->second.get();
+  }
+  return nullptr;
+}
+
+bool QuicSession::OnFrameAcked(const QuicFrame& frame,
+                               QuicTime::Delta ack_delay_time,
+                               QuicTime receive_timestamp) {
+  if (frame.type == MESSAGE_FRAME) {
+    OnMessageAcked(frame.message_frame->message_id, receive_timestamp);
+    return true;
+  }
+  if (frame.type == CRYPTO_FRAME) {
+    return GetMutableCryptoStream()->OnCryptoFrameAcked(*frame.crypto_frame,
+                                                        ack_delay_time);
+  }
+  if (frame.type != STREAM_FRAME) {
+    return control_frame_manager_.OnControlFrameAcked(frame);
+  }
+  bool new_stream_data_acked = false;
+  QuicStream* stream = GetStream(frame.stream_frame.stream_id);
+  // Stream can already be reset when sent frame gets acked.
+  if (stream != nullptr) {
+    QuicByteCount newly_acked_length = 0;
+    new_stream_data_acked = stream->OnStreamFrameAcked(
+        frame.stream_frame.offset, frame.stream_frame.data_length,
+        frame.stream_frame.fin, ack_delay_time, receive_timestamp,
+        &newly_acked_length);
+    if (!stream->HasPendingRetransmission()) {
+      streams_with_pending_retransmission_.erase(stream->id());
+    }
+  }
+  return new_stream_data_acked;
+}
+
+void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) {
+  QuicStream* stream = GetStream(frame.stream_id);
+  if (stream == nullptr) {
+    QUIC_BUG(quic_bug_10866_12)
+        << "Stream: " << frame.stream_id << " is closed when " << frame
+        << " is retransmitted.";
+    connection()->CloseConnection(
+        QUIC_INTERNAL_ERROR, "Attempt to retransmit frame of a closed stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  stream->OnStreamFrameRetransmitted(frame.offset, frame.data_length,
+                                     frame.fin);
+}
+
+void QuicSession::OnFrameLost(const QuicFrame& frame) {
+  if (frame.type == MESSAGE_FRAME) {
+    OnMessageLost(frame.message_frame->message_id);
+    return;
+  }
+  if (frame.type == CRYPTO_FRAME) {
+    GetMutableCryptoStream()->OnCryptoFrameLost(frame.crypto_frame);
+    return;
+  }
+  if (frame.type != STREAM_FRAME) {
+    control_frame_manager_.OnControlFrameLost(frame);
+    return;
+  }
+  QuicStream* stream = GetStream(frame.stream_frame.stream_id);
+  if (stream == nullptr) {
+    return;
+  }
+  stream->OnStreamFrameLost(frame.stream_frame.offset,
+                            frame.stream_frame.data_length,
+                            frame.stream_frame.fin);
+  if (stream->HasPendingRetransmission() &&
+      !streams_with_pending_retransmission_.contains(
+          frame.stream_frame.stream_id)) {
+    streams_with_pending_retransmission_.insert(
+        std::make_pair(frame.stream_frame.stream_id, true));
+  }
+}
+
+bool QuicSession::RetransmitFrames(const QuicFrames& frames,
+                                   TransmissionType type) {
+  QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
+  for (const QuicFrame& frame : frames) {
+    if (frame.type == MESSAGE_FRAME) {
+      // Do not retransmit MESSAGE frames.
+      continue;
+    }
+    if (frame.type == CRYPTO_FRAME) {
+      const bool data_retransmitted =
+          GetMutableCryptoStream()->RetransmitData(frame.crypto_frame, type);
+      if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted) &&
+          !data_retransmitted) {
+        return false;
+      }
+      continue;
+    }
+    if (frame.type != STREAM_FRAME) {
+      if (!control_frame_manager_.RetransmitControlFrame(frame, type)) {
+        return false;
+      }
+      continue;
+    }
+    QuicStream* stream = GetStream(frame.stream_frame.stream_id);
+    if (stream != nullptr &&
+        !stream->RetransmitStreamData(frame.stream_frame.offset,
+                                      frame.stream_frame.data_length,
+                                      frame.stream_frame.fin, type)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicSession::IsFrameOutstanding(const QuicFrame& frame) const {
+  if (frame.type == MESSAGE_FRAME) {
+    return false;
+  }
+  if (frame.type == CRYPTO_FRAME) {
+    return GetCryptoStream()->IsFrameOutstanding(
+        frame.crypto_frame->level, frame.crypto_frame->offset,
+        frame.crypto_frame->data_length);
+  }
+  if (frame.type != STREAM_FRAME) {
+    return control_frame_manager_.IsControlFrameOutstanding(frame);
+  }
+  QuicStream* stream = GetStream(frame.stream_frame.stream_id);
+  return stream != nullptr &&
+         stream->IsStreamFrameOutstanding(frame.stream_frame.offset,
+                                          frame.stream_frame.data_length,
+                                          frame.stream_frame.fin);
+}
+
+bool QuicSession::HasUnackedCryptoData() const {
+  const QuicCryptoStream* crypto_stream = GetCryptoStream();
+  return crypto_stream->IsWaitingForAcks() || crypto_stream->HasBufferedData();
+}
+
+bool QuicSession::HasUnackedStreamData() const {
+  for (const auto& it : stream_map_) {
+    if (it.second->IsWaitingForAcks()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+HandshakeState QuicSession::GetHandshakeState() const {
+  return GetCryptoStream()->GetHandshakeState();
+}
+
+WriteStreamDataResult QuicSession::WriteStreamData(QuicStreamId id,
+                                                   QuicStreamOffset offset,
+                                                   QuicByteCount data_length,
+                                                   QuicDataWriter* writer) {
+  QuicStream* stream = GetStream(id);
+  if (stream == nullptr) {
+    // This causes the connection to be closed because of failed to serialize
+    // packet.
+    QUIC_BUG(quic_bug_10866_13)
+        << "Stream " << id << " does not exist when trying to write data."
+        << " version:" << transport_version();
+    return STREAM_MISSING;
+  }
+  if (stream->WriteStreamData(offset, data_length, writer)) {
+    return WRITE_SUCCESS;
+  }
+  return WRITE_FAILED;
+}
+
+bool QuicSession::WriteCryptoData(EncryptionLevel level,
+                                  QuicStreamOffset offset,
+                                  QuicByteCount data_length,
+                                  QuicDataWriter* writer) {
+  return GetMutableCryptoStream()->WriteCryptoFrame(level, offset, data_length,
+                                                    writer);
+}
+
+StatelessResetToken QuicSession::GetStatelessResetToken() const {
+  return QuicUtils::GenerateStatelessResetToken(connection_->connection_id());
+}
+
+bool QuicSession::CanWriteStreamData() const {
+  // Don't write stream data if there are queued data packets.
+  if (connection_->HasQueuedPackets()) {
+    return false;
+  }
+  // Immediately write handshake data.
+  if (HasPendingHandshake()) {
+    return true;
+  }
+  return connection_->CanWrite(HAS_RETRANSMITTABLE_DATA);
+}
+
+bool QuicSession::RetransmitLostData() {
+  QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
+  // Retransmit crypto data first.
+  bool uses_crypto_frames = QuicVersionUsesCryptoFrames(transport_version());
+  QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
+  if (uses_crypto_frames && crypto_stream->HasPendingCryptoRetransmission()) {
+    crypto_stream->WritePendingCryptoRetransmission();
+  }
+  // Retransmit crypto data in stream 1 frames (version < 47).
+  if (!uses_crypto_frames &&
+      streams_with_pending_retransmission_.contains(
+          QuicUtils::GetCryptoStreamId(transport_version()))) {
+    // Retransmit crypto data first.
+    QuicStream* crypto_stream =
+        GetStream(QuicUtils::GetCryptoStreamId(transport_version()));
+    crypto_stream->OnCanWrite();
+    QUICHE_DCHECK(CheckStreamWriteBlocked(crypto_stream));
+    if (crypto_stream->HasPendingRetransmission()) {
+      // Connection is write blocked.
+      return false;
+    } else {
+      streams_with_pending_retransmission_.erase(
+          QuicUtils::GetCryptoStreamId(transport_version()));
+    }
+  }
+  if (control_frame_manager_.HasPendingRetransmission()) {
+    control_frame_manager_.OnCanWrite();
+    if (control_frame_manager_.HasPendingRetransmission()) {
+      return false;
+    }
+  }
+  while (!streams_with_pending_retransmission_.empty()) {
+    if (!CanWriteStreamData()) {
+      break;
+    }
+    // Retransmit lost data on headers and data streams.
+    const QuicStreamId id = streams_with_pending_retransmission_.begin()->first;
+    QuicStream* stream = GetStream(id);
+    if (stream != nullptr) {
+      stream->OnCanWrite();
+      QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
+      if (stream->HasPendingRetransmission()) {
+        // Connection is write blocked.
+        break;
+      } else if (!streams_with_pending_retransmission_.empty() &&
+                 streams_with_pending_retransmission_.begin()->first == id) {
+        // Retransmit lost data may cause connection close. If this stream
+        // has not yet sent fin, a RST_STREAM will be sent and it will be
+        // removed from streams_with_pending_retransmission_.
+        streams_with_pending_retransmission_.pop_front();
+      }
+    } else {
+      QUIC_BUG(quic_bug_10866_14)
+          << "Try to retransmit data of a closed stream";
+      streams_with_pending_retransmission_.pop_front();
+    }
+  }
+
+  return streams_with_pending_retransmission_.empty();
+}
+
+void QuicSession::NeuterUnencryptedData() {
+  QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
+  crypto_stream->NeuterUnencryptedStreamData();
+  if (!crypto_stream->HasPendingRetransmission() &&
+      !QuicVersionUsesCryptoFrames(transport_version())) {
+    streams_with_pending_retransmission_.erase(
+        QuicUtils::GetCryptoStreamId(transport_version()));
+  }
+  connection_->NeuterUnencryptedPackets();
+}
+
+void QuicSession::SetTransmissionType(TransmissionType type) {
+  connection_->SetTransmissionType(type);
+}
+
+MessageResult QuicSession::SendMessage(
+    absl::Span<quiche::QuicheMemSlice> message) {
+  return SendMessage(message, /*flush=*/false);
+}
+
+MessageResult QuicSession::SendMessage(quiche::QuicheMemSlice message) {
+  return SendMessage(absl::MakeSpan(&message, 1), /*flush=*/false);
+}
+
+MessageResult QuicSession::SendMessage(
+    absl::Span<quiche::QuicheMemSlice> message, bool flush) {
+  QUICHE_DCHECK(connection_->connected())
+      << ENDPOINT << "Try to write messages when connection is closed.";
+  if (!IsEncryptionEstablished()) {
+    return {MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0};
+  }
+  QuicConnection::ScopedEncryptionLevelContext context(
+      connection(), GetEncryptionLevelToSendApplicationData());
+  MessageStatus result =
+      connection_->SendMessage(last_message_id_ + 1, message, flush);
+  if (result == MESSAGE_STATUS_SUCCESS) {
+    return {result, ++last_message_id_};
+  }
+  return {result, 0};
+}
+
+void QuicSession::OnMessageAcked(QuicMessageId message_id,
+                                 QuicTime /*receive_timestamp*/) {
+  QUIC_DVLOG(1) << ENDPOINT << "message " << message_id << " gets acked.";
+}
+
+void QuicSession::OnMessageLost(QuicMessageId message_id) {
+  QUIC_DVLOG(1) << ENDPOINT << "message " << message_id
+                << " is considered lost";
+}
+
+void QuicSession::CleanUpClosedStreams() { closed_streams_.clear(); }
+
+QuicPacketLength QuicSession::GetCurrentLargestMessagePayload() const {
+  return connection_->GetCurrentLargestMessagePayload();
+}
+
+QuicPacketLength QuicSession::GetGuaranteedLargestMessagePayload() const {
+  return connection_->GetGuaranteedLargestMessagePayload();
+}
+
+QuicStreamId QuicSession::next_outgoing_bidirectional_stream_id() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.next_outgoing_bidirectional_stream_id();
+  }
+  return stream_id_manager_.next_outgoing_stream_id();
+}
+
+QuicStreamId QuicSession::next_outgoing_unidirectional_stream_id() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.next_outgoing_unidirectional_stream_id();
+  }
+  return stream_id_manager_.next_outgoing_stream_id();
+}
+
+bool QuicSession::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
+  const bool allow_new_streams =
+      frame.unidirectional
+          ? ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
+                frame.stream_count)
+          : ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
+                frame.stream_count);
+  if (allow_new_streams) {
+    OnCanCreateNewOutgoingStream(frame.unidirectional);
+  }
+
+  return true;
+}
+
+bool QuicSession::OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) {
+  std::string error_details;
+  if (ietf_streamid_manager_.OnStreamsBlockedFrame(frame, &error_details)) {
+    return true;
+  }
+  connection_->CloseConnection(
+      QUIC_STREAMS_BLOCKED_ERROR, error_details,
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  return false;
+}
+
+size_t QuicSession::max_open_incoming_bidirectional_streams() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
+  }
+  return stream_id_manager_.max_open_incoming_streams();
+}
+
+size_t QuicSession::max_open_incoming_unidirectional_streams() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
+  }
+  return stream_id_manager_.max_open_incoming_streams();
+}
+
+std::vector<absl::string_view>::const_iterator QuicSession::SelectAlpn(
+    const std::vector<absl::string_view>& alpns) const {
+  const std::string alpn = AlpnForVersion(connection()->version());
+  return std::find(alpns.cbegin(), alpns.cend(), alpn);
+}
+
+void QuicSession::OnAlpnSelected(absl::string_view alpn) {
+  QUIC_DLOG(INFO) << (perspective() == Perspective::IS_SERVER ? "Server: "
+                                                              : "Client: ")
+                  << "ALPN selected: " << alpn;
+}
+
+void QuicSession::NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level) {
+  GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(level);
+}
+
+void QuicSession::PerformActionOnActiveStreams(
+    std::function<bool(QuicStream*)> action) {
+  std::vector<QuicStream*> active_streams;
+  for (const auto& it : stream_map_) {
+    if (!it.second->is_static() && !it.second->IsZombie()) {
+      active_streams.push_back(it.second.get());
+    }
+  }
+
+  for (QuicStream* stream : active_streams) {
+    if (!action(stream)) {
+      return;
+    }
+  }
+}
+
+void QuicSession::PerformActionOnActiveStreams(
+    std::function<bool(QuicStream*)> action) const {
+  for (const auto& it : stream_map_) {
+    if (!it.second->is_static() && !it.second->IsZombie() &&
+        !action(it.second.get())) {
+      return;
+    }
+  }
+}
+
+EncryptionLevel QuicSession::GetEncryptionLevelToSendApplicationData() const {
+  return connection_->framer().GetEncryptionLevelToSendApplicationData();
+}
+
+void QuicSession::ProcessAllPendingStreams() {
+  std::vector<PendingStream*> pending_streams;
+  pending_streams.reserve(pending_stream_map_.size());
+  for (auto it = pending_stream_map_.cbegin(); it != pending_stream_map_.cend();
+       ++it) {
+    pending_streams.push_back(it->second.get());
+  }
+  for (auto* pending_stream : pending_streams) {
+    MaybeProcessPendingStream(pending_stream);
+    if (!connection()->connected()) {
+      return;
+    }
+  }
+}
+
+void QuicSession::ValidatePath(
+    std::unique_ptr<QuicPathValidationContext> context,
+    std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
+  connection_->ValidatePath(std::move(context), std::move(result_delegate));
+}
+
+bool QuicSession::HasPendingPathValidation() const {
+  return connection_->HasPendingPathValidation();
+}
+
+bool QuicSession::MigratePath(const QuicSocketAddress& self_address,
+                              const QuicSocketAddress& peer_address,
+                              QuicPacketWriter* writer, bool owns_writer) {
+  return connection_->MigratePath(self_address, peer_address, writer,
+                                  owns_writer);
+}
+
+bool QuicSession::ValidateToken(absl::string_view token) {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_SERVER);
+  if (GetQuicFlag(FLAGS_quic_reject_retry_token_in_initial_packet)) {
+    return false;
+  }
+  if (token.empty() || token[0] != kAddressTokenPrefix) {
+    // Validate the prefix for token received in NEW_TOKEN frame.
+    return false;
+  }
+  const bool valid = GetCryptoStream()->ValidateAddressToken(
+      absl::string_view(token.data() + 1, token.length() - 1));
+  if (valid) {
+    const CachedNetworkParameters* cached_network_params =
+        GetCryptoStream()->PreviousCachedNetworkParams();
+    if (cached_network_params != nullptr &&
+        cached_network_params->timestamp() > 0) {
+      connection()->OnReceiveConnectionState(*cached_network_params);
+    }
+  }
+  return valid;
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_session.h b/quiche/quic/core/quic_session.h
new file mode 100644
index 0000000..a5aae44
--- /dev/null
+++ b/quiche/quic/core/quic_session.h
@@ -0,0 +1,1020 @@
+// 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.
+
+// A QuicSession, which demuxes a single connection to individual streams.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_SESSION_H_
+#define QUICHE_QUIC_CORE_QUIC_SESSION_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/crypto/tls_connection.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_stop_sending_frame.h"
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+#include "quiche/quic/core/handshaker_delegate_interface.h"
+#include "quiche/quic/core/legacy_quic_stream_id_manager.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_control_frame_manager.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_datagram_queue.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/quic/core/session_notifier_interface.h"
+#include "quiche/quic/core/stream_delegate_interface.h"
+#include "quiche/quic/core/uber_quic_stream_id_manager.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+class QuicCryptoStream;
+class QuicFlowController;
+class QuicStream;
+class QuicStreamIdManager;
+
+namespace test {
+class QuicSessionPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE QuicSession
+    : public QuicConnectionVisitorInterface,
+      public SessionNotifierInterface,
+      public QuicStreamFrameDataProducer,
+      public QuicStreamIdManager::DelegateInterface,
+      public HandshakerDelegateInterface,
+      public StreamDelegateInterface,
+      public QuicControlFrameManager::DelegateInterface {
+ public:
+  // An interface from the session to the entity owning the session.
+  // This lets the session notify its owner (the Dispatcher) when the connection
+  // is closed, blocked, or added/removed from the time-wait list.
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() {}
+
+    // Called when the connection is closed after the streams have been closed.
+    virtual void OnConnectionClosed(QuicConnectionId server_connection_id,
+                                    QuicErrorCode error,
+                                    const std::string& error_details,
+                                    ConnectionCloseSource source) = 0;
+
+    // Called when the session has become write blocked.
+    virtual void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) = 0;
+
+    // Called when the session receives reset on a stream from the peer.
+    virtual void OnRstStreamReceived(const QuicRstStreamFrame& frame) = 0;
+
+    // Called when the session receives a STOP_SENDING for a stream from the
+    // peer.
+    virtual void OnStopSendingReceived(const QuicStopSendingFrame& frame) = 0;
+
+    // Called when a NewConnectionId frame has been sent.
+    virtual void OnNewConnectionIdSent(
+        const QuicConnectionId& server_connection_id,
+        const QuicConnectionId& new_connection_id) = 0;
+
+    // Called when a ConnectionId has been retired.
+    virtual void OnConnectionIdRetired(
+        const QuicConnectionId& server_connection_id) = 0;
+  };
+
+  // Does not take ownership of |connection| or |visitor|.
+  QuicSession(QuicConnection* connection, Visitor* owner,
+              const QuicConfig& config,
+              const ParsedQuicVersionVector& supported_versions,
+              QuicStreamCount num_expected_unidirectional_static_streams);
+  QuicSession(QuicConnection* connection, Visitor* owner,
+              const QuicConfig& config,
+              const ParsedQuicVersionVector& supported_versions,
+              QuicStreamCount num_expected_unidirectional_static_streams,
+              std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer);
+  QuicSession(const QuicSession&) = delete;
+  QuicSession& operator=(const QuicSession&) = delete;
+
+  ~QuicSession() override;
+
+  virtual void Initialize();
+
+  // Return the reserved crypto stream as a constant pointer.
+  virtual const QuicCryptoStream* GetCryptoStream() const = 0;
+
+  // QuicConnectionVisitorInterface methods:
+  void OnStreamFrame(const QuicStreamFrame& frame) override;
+  void OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  void OnRstStream(const QuicRstStreamFrame& frame) override;
+  void OnGoAway(const QuicGoAwayFrame& frame) override;
+  void OnMessageReceived(absl::string_view message) override;
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
+  void OnBlockedFrame(const QuicBlockedFrame& frame) override;
+  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                          ConnectionCloseSource source) override;
+  void OnWriteBlocked() override;
+  void OnSuccessfulVersionNegotiation(
+      const ParsedQuicVersion& version) override;
+  void OnPacketReceived(const QuicSocketAddress& self_address,
+                        const QuicSocketAddress& peer_address,
+                        bool is_connectivity_probe) override;
+  void OnCanWrite() override;
+  bool SendProbingData() override;
+  bool ValidateStatelessReset(
+      const quic::QuicSocketAddress& /*self_address*/,
+      const quic::QuicSocketAddress& /*peer_address*/) override {
+    return true;
+  }
+  void OnCongestionWindowChange(QuicTime /*now*/) override {}
+  void OnConnectionMigration(AddressChangeType /*type*/) override {}
+  // Adds a connection level WINDOW_UPDATE frame.
+  void OnAckNeedsRetransmittableFrame() override;
+  void SendAckFrequency(const QuicAckFrequencyFrame& frame) override;
+  void SendNewConnectionId(const QuicNewConnectionIdFrame& frame) override;
+  void SendRetireConnectionId(uint64_t sequence_number) override;
+  void OnServerConnectionIdIssued(
+      const QuicConnectionId& server_connection_id) override;
+  void OnServerConnectionIdRetired(
+      const QuicConnectionId& server_connection_id) override;
+  bool WillingAndAbleToWrite() const override;
+  std::string GetStreamsInfoForLogging() const override;
+  void OnPathDegrading() override;
+  void OnForwardProgressMadeAfterPathDegrading() override;
+  bool AllowSelfAddressChange() const override;
+  HandshakeState GetHandshakeState() const override;
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
+  void OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
+  void OnPacketDecrypted(EncryptionLevel level) override;
+  void OnOneRttPacketAcknowledged() override;
+  void OnHandshakePacketSent() override;
+  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  void BeforeConnectionCloseSent() override {}
+  bool ValidateToken(absl::string_view token) override;
+  bool MaybeSendAddressToken() override;
+  bool IsKnownServerAddress(
+      const QuicSocketAddress& /*address*/) const override {
+    return false;
+  }
+
+  // QuicStreamFrameDataProducer
+  WriteStreamDataResult WriteStreamData(QuicStreamId id,
+                                        QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        QuicDataWriter* writer) override;
+  bool WriteCryptoData(EncryptionLevel level, QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer) override;
+
+  // SessionNotifierInterface methods:
+  bool OnFrameAcked(const QuicFrame& frame, QuicTime::Delta ack_delay_time,
+                    QuicTime receive_timestamp) override;
+  void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) override;
+  void OnFrameLost(const QuicFrame& frame) override;
+  bool RetransmitFrames(const QuicFrames& frames,
+                        TransmissionType type) override;
+  bool IsFrameOutstanding(const QuicFrame& frame) const override;
+  bool HasUnackedCryptoData() const override;
+  bool HasUnackedStreamData() const override;
+
+  void SendMaxStreams(QuicStreamCount stream_count,
+                      bool unidirectional) override;
+  // The default implementation does nothing. Subclasses should override if
+  // for example they queue up stream requests.
+  virtual void OnCanCreateNewOutgoingStream(bool /*unidirectional*/) {}
+
+  // Called on every incoming packet. Passes |packet| through to |connection_|.
+  virtual void ProcessUdpPacket(const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address,
+                                const QuicReceivedPacket& packet);
+
+  // Sends |message| as a QUIC DATAGRAM frame (QUIC MESSAGE frame in gQUIC).
+  // See <https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram> for
+  // more details.
+  //
+  // Returns a MessageResult struct which includes the status of the write
+  // operation and a message ID.  The message ID (not sent on the wire) can be
+  // used to track the message; OnMessageAcked and OnMessageLost are called when
+  // a specific message gets acked or lost.
+  //
+  // If the write operation is successful, all of the slices in |message| are
+  // consumed, leaving them empty.  If MESSAGE_STATUS_INTERNAL_ERROR is
+  // returned, the slices in question may or may not be consumed; it is no
+  // longer safe to access those.  For all other status codes, |message| is kept
+  // intact.
+  //
+  // Note that SendMessage will fail with status = MESSAGE_STATUS_BLOCKED
+  // if the connection is congestion control blocked or the underlying socket is
+  // write blocked. In this case the caller can retry sending message again when
+  // connection becomes available, for example after getting OnCanWrite()
+  // callback.
+  //
+  // SendMessage flushes the current packet even it is not full; if the
+  // application needs to bundle other data in the same packet, consider using
+  // QuicConnection::ScopedPacketFlusher around the relevant write operations.
+  MessageResult SendMessage(absl::Span<quiche::QuicheMemSlice> message);
+
+  // Same as above SendMessage, except caller can specify if the given |message|
+  // should be flushed even if the underlying connection is deemed unwritable.
+  MessageResult SendMessage(absl::Span<quiche::QuicheMemSlice> message,
+                            bool flush);
+
+  // Single-slice version of SendMessage().  Unlike the version above, this
+  // version always takes ownership of the slice.
+  MessageResult SendMessage(quiche::QuicheMemSlice message);
+
+  // Called when message with |message_id| gets acked.
+  virtual void OnMessageAcked(QuicMessageId message_id,
+                              QuicTime receive_timestamp);
+
+  // Called when message with |message_id| is considered as lost.
+  virtual void OnMessageLost(QuicMessageId message_id);
+
+  // QuicControlFrameManager::DelegateInterface
+  // Close the connection on error.
+  void OnControlFrameManagerError(QuicErrorCode error_code,
+                                  std::string error_details) override;
+  // Called by control frame manager when it wants to write control frames to
+  // the peer. Returns true if |frame| is consumed, false otherwise. The frame
+  // will be sent in specified transmission |type|.
+  bool WriteControlFrame(const QuicFrame& frame,
+                         TransmissionType type) override;
+
+  // Called to send RST_STREAM (and STOP_SENDING) and close stream. If stream
+  // |id| does not exist, just send RST_STREAM (and STOP_SENDING).
+  virtual void ResetStream(QuicStreamId id, QuicRstStreamErrorCode error);
+
+  // Called when the session wants to go away and not accept any new streams.
+  virtual void SendGoAway(QuicErrorCode error_code, const std::string& reason);
+
+  // Sends a BLOCKED frame.
+  virtual void SendBlocked(QuicStreamId id);
+
+  // Sends a WINDOW_UPDATE frame.
+  virtual void SendWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
+
+  // Called by stream |stream_id| when it gets closed.
+  virtual void OnStreamClosed(QuicStreamId stream_id);
+
+  // Returns true if outgoing packets will be encrypted, even if the server
+  // hasn't confirmed the handshake yet.
+  virtual bool IsEncryptionEstablished() const;
+
+  // Returns true if 1RTT keys are available.
+  bool OneRttKeysAvailable() const;
+
+  // Called by the QuicCryptoStream when a new QuicConfig has been negotiated.
+  virtual void OnConfigNegotiated();
+
+  // Called by the TLS handshaker when ALPS data is received.
+  // Returns an error message if an error has occurred, or nullopt otherwise.
+  virtual absl::optional<std::string> OnAlpsData(const uint8_t* alps_data,
+                                                 size_t alps_length);
+
+  // From HandshakerDelegateInterface
+  bool OnNewDecryptionKeyAvailable(EncryptionLevel level,
+                                   std::unique_ptr<QuicDecrypter> decrypter,
+                                   bool set_alternative_decrypter,
+                                   bool latch_once_used) override;
+  void OnNewEncryptionKeyAvailable(
+      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override;
+  void SetDefaultEncryptionLevel(EncryptionLevel level) override;
+  void OnTlsHandshakeComplete() override;
+  void DiscardOldDecryptionKey(EncryptionLevel level) override;
+  void DiscardOldEncryptionKey(EncryptionLevel level) override;
+  void NeuterUnencryptedData() override;
+  void NeuterHandshakeData() override;
+  void OnZeroRttRejected(int reason) override;
+  bool FillTransportParameters(TransportParameters* params) override;
+  QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
+                                           bool is_resumption,
+                                           std::string* error_details) override;
+  void OnHandshakeCallbackDone() override;
+  bool PacketFlusherAttached() const override;
+  ParsedQuicVersion parsed_version() const override { return version(); }
+
+  // Implement StreamDelegateInterface.
+  void OnStreamError(QuicErrorCode error_code,
+                     std::string error_details) override;
+  void OnStreamError(QuicErrorCode error_code,
+                     QuicIetfTransportErrorCodes ietf_error,
+                     std::string error_details) override;
+  // Sets priority in the write blocked list.
+  void RegisterStreamPriority(
+      QuicStreamId id, bool is_static,
+      const spdy::SpdyStreamPrecedence& precedence) override;
+  // Clears priority from the write blocked list.
+  void UnregisterStreamPriority(QuicStreamId id, bool is_static) override;
+  // Updates priority on the write blocked list.
+  void UpdateStreamPriority(
+      QuicStreamId id,
+      const spdy::SpdyStreamPrecedence& new_precedence) override;
+
+  // Called by streams when they want to write data to the peer.
+  // Returns a pair with the number of bytes consumed from data, and a boolean
+  // indicating if the fin bit was consumed.  This does not indicate the data
+  // has been sent on the wire: it may have been turned into a packet and queued
+  // if the socket was unexpectedly blocked.
+  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
+                              QuicStreamOffset offset, StreamSendingState state,
+                              TransmissionType type,
+                              EncryptionLevel level) override;
+
+  size_t SendCryptoData(EncryptionLevel level, size_t write_length,
+                        QuicStreamOffset offset,
+                        TransmissionType type) override;
+
+  // Called by the QuicCryptoStream when a handshake message is sent.
+  virtual void OnCryptoHandshakeMessageSent(
+      const CryptoHandshakeMessage& message);
+
+  // Called by the QuicCryptoStream when a handshake message is received.
+  virtual void OnCryptoHandshakeMessageReceived(
+      const CryptoHandshakeMessage& message);
+
+  // Returns mutable config for this session. Returned config is owned
+  // by QuicSession.
+  QuicConfig* config();
+
+  // Returns true if the stream existed previously and has been closed.
+  // Returns false if the stream is still active or if the stream has
+  // not yet been created.
+  bool IsClosedStream(QuicStreamId id);
+
+  QuicConnection* connection() { return connection_; }
+  const QuicConnection* connection() const { return connection_; }
+  const QuicSocketAddress& peer_address() const {
+    return connection_->peer_address();
+  }
+  const QuicSocketAddress& self_address() const {
+    return connection_->self_address();
+  }
+  QuicConnectionId connection_id() const {
+    return connection_->connection_id();
+  }
+
+  // Returns the number of currently open streams, excluding static streams, and
+  // never counting unfinished streams.
+  size_t GetNumActiveStreams() const;
+
+  // Add the stream to the session's write-blocked list because it is blocked by
+  // connection-level flow control but not by its own stream-level flow control.
+  // The stream will be given a chance to write when a connection-level
+  // WINDOW_UPDATE arrives.
+  virtual void MarkConnectionLevelWriteBlocked(QuicStreamId id);
+
+  // Called to close zombie stream |id|.
+  void MaybeCloseZombieStream(QuicStreamId id);
+
+  // Returns true if there is pending handshake data in the crypto stream.
+  // TODO(ianswett): Make this private or remove.
+  bool HasPendingHandshake() const;
+
+  // Returns true if the session has data to be sent, either queued in the
+  // connection, or in a write-blocked stream.
+  bool HasDataToWrite() const;
+
+  // Initiates a path validation on the path described in the given context,
+  // asynchronously calls |result_delegate| upon success or failure.
+  // The initiator should extend QuicPathValidationContext to provide the writer
+  // and ResultDelegate to react upon the validation result.
+  // Example implementations of these for path validation for connection
+  // migration could be:
+  //  class QUIC_EXPORT_PRIVATE PathMigrationContext
+  //      : public QuicPathValidationContext {
+  //   public:
+  //    PathMigrationContext(std::unique_ptr<QuicPacketWriter> writer,
+  //                         const QuicSocketAddress& self_address,
+  //                         const QuicSocketAddress& peer_address)
+  //        : QuicPathValidationContext(self_address, peer_address),
+  //          alternative_writer_(std::move(writer)) {}
+  //
+  //    QuicPacketWriter* WriterToUse() override {
+  //         return alternative_writer_.get();
+  //    }
+  //
+  //    QuicPacketWriter* ReleaseWriter() {
+  //         return alternative_writer_.release();
+  //    }
+  //
+  //   private:
+  //    std::unique_ptr<QuicPacketWriter> alternative_writer_;
+  //  };
+  //
+  //  class PathMigrationValidationResultDelegate
+  //      : public QuicPathValidator::ResultDelegate {
+  //   public:
+  //    PathMigrationValidationResultDelegate(QuicConnection* connection)
+  //        : QuicPathValidator::ResultDelegate(), connection_(connection) {}
+  //
+  //    void OnPathValidationSuccess(
+  //        std::unique_ptr<QuicPathValidationContext> context) override {
+  //    // Do some work to prepare for migration.
+  //    // ...
+  //
+  //    // Actually migrate to the validated path.
+  //    auto migration_context = std::unique_ptr<PathMigrationContext>(
+  //        static_cast<PathMigrationContext*>(context.release()));
+  //    connection_->MigratePath(migration_context->self_address(),
+  //                          migration_context->peer_address(),
+  //                          migration_context->ReleaseWriter(),
+  //                          /*owns_writer=*/true);
+  //
+  //    // Post-migration actions
+  //    // ...
+  //  }
+  //
+  //    void OnPathValidationFailure(
+  //        std::unique_ptr<QuicPathValidationContext> /*context*/) override {
+  //    // Handle validation failure.
+  //  }
+  //
+  //   private:
+  //    QuicConnection* connection_;
+  //  };
+  void ValidatePath(
+      std::unique_ptr<QuicPathValidationContext> context,
+      std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
+
+  // Return true if there is a path being validated.
+  bool HasPendingPathValidation() const;
+
+  // Switch to the path described in |context| without validating the path.
+  bool MigratePath(const QuicSocketAddress& self_address,
+                   const QuicSocketAddress& peer_address,
+                   QuicPacketWriter* writer, bool owns_writer);
+
+  // Returns the largest payload that will fit into a single MESSAGE frame.
+  // Because overhead can vary during a connection, this method should be
+  // checked for every message.
+  QuicPacketLength GetCurrentLargestMessagePayload() const;
+
+  // Returns the largest payload that will fit into a single MESSAGE frame at
+  // any point during the connection.  This assumes the version and
+  // connection ID lengths do not change.
+  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
+
+  bool transport_goaway_sent() const { return transport_goaway_sent_; }
+
+  bool transport_goaway_received() const { return transport_goaway_received_; }
+
+  // Returns the Google QUIC error code
+  QuicErrorCode error() const { return on_closed_frame_.quic_error_code; }
+  const std::string& error_details() const {
+    return on_closed_frame_.error_details;
+  }
+  uint64_t transport_close_frame_type() const {
+    return on_closed_frame_.transport_close_frame_type;
+  }
+  QuicConnectionCloseType close_type() const {
+    return on_closed_frame_.close_type;
+  }
+
+  Perspective perspective() const { return perspective_; }
+
+  QuicFlowController* flow_controller() { return &flow_controller_; }
+
+  // Returns true if connection is flow controller blocked.
+  bool IsConnectionFlowControlBlocked() const;
+
+  // Returns true if any stream is flow controller blocked.
+  bool IsStreamFlowControlBlocked();
+
+  size_t max_open_incoming_bidirectional_streams() const;
+  size_t max_open_incoming_unidirectional_streams() const;
+
+  size_t MaxAvailableBidirectionalStreams() const;
+  size_t MaxAvailableUnidirectionalStreams() const;
+
+  // Returns existing stream with id = |stream_id|. If no
+  // such stream exists, and |stream_id| is a peer-created stream id,
+  // then a new stream is created and returned. In all other cases, nullptr is
+  // returned.
+  // Caller does not own the returned stream.
+  QuicStream* GetOrCreateStream(const QuicStreamId stream_id);
+
+  // Mark a stream as draining.
+  void StreamDraining(QuicStreamId id, bool unidirectional);
+
+  // Returns true if this stream should yield writes to another blocked stream.
+  virtual bool ShouldYield(QuicStreamId stream_id);
+
+  // Clean up closed_streams_.
+  void CleanUpClosedStreams();
+
+  const ParsedQuicVersionVector& supported_versions() const {
+    return supported_versions_;
+  }
+
+  QuicStreamId next_outgoing_bidirectional_stream_id() const;
+  QuicStreamId next_outgoing_unidirectional_stream_id() const;
+
+  // Return true if given stream is peer initiated.
+  bool IsIncomingStream(QuicStreamId id) const;
+
+  // Record errors when a connection is closed at the server side, should only
+  // be called from server's perspective.
+  // Noop if |error| is QUIC_NO_ERROR.
+  static void RecordConnectionCloseAtServer(QuicErrorCode error,
+                                            ConnectionCloseSource source);
+
+  QuicTransportVersion transport_version() const {
+    return connection_->transport_version();
+  }
+
+  ParsedQuicVersion version() const { return connection_->version(); }
+
+  bool is_configured() const { return is_configured_; }
+
+  // Called to neuter crypto data of encryption |level|.
+  void NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level);
+
+  // Returns the ALPN values to negotiate on this session.
+  virtual std::vector<std::string> GetAlpnsToOffer() const {
+    // TODO(vasilvv): this currently sets HTTP/3 by default.  Switch all
+    // non-HTTP applications to appropriate ALPNs.
+    return std::vector<std::string>({AlpnForVersion(connection()->version())});
+  }
+
+  // Provided a list of ALPNs offered by the client, selects an ALPN from the
+  // list, or alpns.end() if none of the ALPNs are acceptable.
+  virtual std::vector<absl::string_view>::const_iterator SelectAlpn(
+      const std::vector<absl::string_view>& alpns) const;
+
+  // Called when the ALPN of the connection is established for a connection that
+  // uses TLS handshake.
+  virtual void OnAlpnSelected(absl::string_view alpn);
+
+  // Called on clients by the crypto handshaker to provide application state
+  // necessary for sending application data in 0-RTT. The state provided here is
+  // the same state that was provided to the crypto handshaker in
+  // QuicCryptoStream::SetServerApplicationStateForResumption on a previous
+  // connection. Application protocols that require state to be carried over
+  // from the previous connection to support 0-RTT data must implement this
+  // method to ingest this state. For example, an HTTP/3 QuicSession would
+  // implement this function to process the remembered server SETTINGS and apply
+  // those SETTINGS to 0-RTT data. This function returns true if the application
+  // state has been successfully processed, and false if there was an error
+  // processing the cached state and the connection should be closed.
+  virtual bool ResumeApplicationState(ApplicationState* /*cached_state*/) {
+    return true;
+  }
+
+  // Does actual work of sending RESET_STREAM, if the stream type allows.
+  // Also informs the connection so that pending stream frames can be flushed.
+  virtual void MaybeSendRstStreamFrame(QuicStreamId id,
+                                       QuicResetStreamError error,
+                                       QuicStreamOffset bytes_written);
+
+  // Sends a STOP_SENDING frame if the stream type allows.
+  virtual void MaybeSendStopSendingFrame(QuicStreamId id,
+                                         QuicResetStreamError error);
+
+  // Returns the encryption level to send application data.
+  EncryptionLevel GetEncryptionLevelToSendApplicationData() const;
+
+  const absl::optional<std::string> user_agent_id() const {
+    return user_agent_id_;
+  }
+
+  // TODO(wub): remove saving user-agent to QuicSession.
+  void SetUserAgentId(std::string user_agent_id) {
+    user_agent_id_ = std::move(user_agent_id);
+    connection()->OnUserAgentIdKnown(user_agent_id_.value());
+  }
+
+  void SetSourceAddressTokenToSend(absl::string_view token) {
+    connection()->SetSourceAddressTokenToSend(token);
+  }
+
+  const QuicClock* GetClock() const {
+    return connection()->helper()->GetClock();
+  }
+
+  bool liveness_testing_in_progress() const {
+    return liveness_testing_in_progress_;
+  }
+
+  bool permutes_tls_extensions() const { return permutes_tls_extensions_; }
+
+  virtual QuicSSLConfig GetSSLConfig() const { return QuicSSLConfig(); }
+
+  // Latched value of flag --quic_tls_server_support_client_cert.
+  bool support_client_cert() const { return support_client_cert_; }
+
+  // Try converting all pending streams to normal streams.
+  void ProcessAllPendingStreams();
+
+  const ParsedQuicVersionVector& client_original_supported_versions() const {
+    QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+    return client_original_supported_versions_;
+  }
+  void set_client_original_supported_versions(
+      const ParsedQuicVersionVector& client_original_supported_versions) {
+    QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+    client_original_supported_versions_ = client_original_supported_versions;
+  }
+
+ protected:
+  using StreamMap =
+      absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>;
+
+  using PendingStreamMap =
+      absl::flat_hash_map<QuicStreamId, std::unique_ptr<PendingStream>>;
+
+  using ClosedStreams = std::vector<std::unique_ptr<QuicStream>>;
+
+  using ZombieStreamMap =
+      absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>;
+
+  // Creates a new stream to handle a peer-initiated stream.
+  // Caller does not own the returned stream.
+  // Returns nullptr and does error handling if the stream can not be created.
+  virtual QuicStream* CreateIncomingStream(QuicStreamId id) = 0;
+  virtual QuicStream* CreateIncomingStream(PendingStream* pending) = 0;
+
+  // Return the reserved crypto stream.
+  virtual QuicCryptoStream* GetMutableCryptoStream() = 0;
+
+  // Adds |stream| to the stream map.
+  virtual void ActivateStream(std::unique_ptr<QuicStream> stream);
+
+  // Set transmission type of next sending packets.
+  void SetTransmissionType(TransmissionType type);
+
+  // Returns the stream ID for a new outgoing bidirectional/unidirectional
+  // stream, and increments the underlying counter.
+  QuicStreamId GetNextOutgoingBidirectionalStreamId();
+  QuicStreamId GetNextOutgoingUnidirectionalStreamId();
+
+  // Indicates whether the next outgoing bidirectional/unidirectional stream ID
+  // can be allocated or not. The test for version-99/IETF QUIC is whether it
+  // will exceed the maximum-stream-id or not. For non-version-99 (Google) QUIC
+  // it checks whether the next stream would exceed the limit on the number of
+  // open streams.
+  bool CanOpenNextOutgoingBidirectionalStream();
+  bool CanOpenNextOutgoingUnidirectionalStream();
+
+  // Returns the maximum bidirectional streams parameter sent with the handshake
+  // as a transport parameter, or in the most recent MAX_STREAMS frame.
+  QuicStreamCount GetAdvertisedMaxIncomingBidirectionalStreams() const;
+
+  // When a stream is closed locally, it may not yet know how many bytes the
+  // peer sent on that stream.
+  // When this data arrives (via stream frame w. FIN, trailing headers, or RST)
+  // this method is called, and correctly updates the connection level flow
+  // controller.
+  virtual void OnFinalByteOffsetReceived(QuicStreamId id,
+                                         QuicStreamOffset final_byte_offset);
+
+  // Returns true if a frame with the given type and id can be prcoessed by a
+  // PendingStream. However, the frame will always be processed by a QuicStream
+  // if one exists with the given stream_id.
+  virtual bool UsesPendingStreamForFrame(QuicFrameType /*type*/,
+                                         QuicStreamId /*stream_id*/) const {
+    return false;
+  }
+
+  // Returns true if a pending stream should be converted to a real stream after
+  // a corresponding STREAM_FRAME is received.
+  virtual bool ShouldProcessPendingStreamImmediately() const { return true; }
+
+  spdy::SpdyPriority GetSpdyPriorityofStream(QuicStreamId stream_id) const {
+    return write_blocked_streams_.GetSpdyPriorityofStream(stream_id);
+  }
+
+  size_t pending_streams_size() const { return pending_stream_map_.size(); }
+
+  ClosedStreams* closed_streams() { return &closed_streams_; }
+
+  void set_largest_peer_created_stream_id(
+      QuicStreamId largest_peer_created_stream_id);
+
+  QuicWriteBlockedList* write_blocked_streams() {
+    return &write_blocked_streams_;
+  }
+
+  // Returns true if the stream is still active.
+  bool IsOpenStream(QuicStreamId id);
+
+  // Returns true if the stream is a static stream.
+  bool IsStaticStream(QuicStreamId id) const;
+
+  // Close connection when receive a frame for a locally-created nonexistent
+  // stream.
+  // Prerequisite: IsClosedStream(stream_id) == false
+  // Server session might need to override this method to allow server push
+  // stream to be promised before creating an active stream.
+  virtual void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id);
+
+  virtual bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id);
+
+  void InsertLocallyClosedStreamsHighestOffset(const QuicStreamId id,
+                                               QuicStreamOffset offset);
+  // If stream is a locally closed stream, this RST will update FIN offset.
+  // Otherwise stream is a preserved stream and the behavior of it depends on
+  // derived class's own implementation.
+  virtual void HandleRstOnValidNonexistentStream(
+      const QuicRstStreamFrame& frame);
+
+  // Returns a stateless reset token which will be included in the public reset
+  // packet.
+  virtual StatelessResetToken GetStatelessResetToken() const;
+
+  QuicControlFrameManager& control_frame_manager() {
+    return control_frame_manager_;
+  }
+
+  const LegacyQuicStreamIdManager& stream_id_manager() const {
+    return stream_id_manager_;
+  }
+
+  QuicDatagramQueue* datagram_queue() { return &datagram_queue_; }
+
+  size_t num_static_streams() const { return num_static_streams_; }
+
+  size_t num_zombie_streams() const { return num_zombie_streams_; }
+
+  bool was_zero_rtt_rejected() const { return was_zero_rtt_rejected_; }
+
+  size_t num_outgoing_draining_streams() const {
+    return num_outgoing_draining_streams_;
+  }
+
+  size_t num_draining_streams() const { return num_draining_streams_; }
+
+  // Processes the stream type information of |pending| depending on
+  // different kinds of sessions' own rules. If the pending stream has been
+  // converted to a normal stream, returns a pointer to the new stream;
+  // otherwise, returns nullptr.
+  virtual QuicStream* ProcessPendingStream(PendingStream* /*pending*/) {
+    return nullptr;
+  }
+
+  // Called by applications to perform |action| on active streams.
+  // Stream iteration will be stopped if action returns false.
+  void PerformActionOnActiveStreams(std::function<bool(QuicStream*)> action);
+  void PerformActionOnActiveStreams(
+      std::function<bool(QuicStream*)> action) const;
+
+  // Return the largest peer created stream id depending on directionality
+  // indicated by |unidirectional|.
+  QuicStreamId GetLargestPeerCreatedStreamId(bool unidirectional) const;
+
+  // Deletes the connection and sets it to nullptr, so calling it mulitiple
+  // times is safe.
+  void DeleteConnection();
+
+  // Call SetPriority() on stream id |id| and return true if stream is active.
+  bool MaybeSetStreamPriority(QuicStreamId stream_id,
+                              const spdy::SpdyStreamPrecedence& precedence);
+
+  void SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface> tuner) {
+    connection()->SetLossDetectionTuner(std::move(tuner));
+  }
+
+  // Find stream with |id|, returns nullptr if the stream does not exist or
+  // closed. static streams and zombie streams are not considered active
+  // streams.
+  QuicStream* GetActiveStream(QuicStreamId id) const;
+
+  const UberQuicStreamIdManager& ietf_streamid_manager() const {
+    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+    return ietf_streamid_manager_;
+  }
+
+  // Only called at a server session. Generate a CachedNetworkParameters that
+  // can be sent to the client as part of the address token, based on the latest
+  // bandwidth/rtt information. If return absl::nullopt, address token will not
+  // contain the CachedNetworkParameters.
+  virtual absl::optional<CachedNetworkParameters>
+  GenerateCachedNetworkParameters() const {
+    return absl::nullopt;
+  }
+
+ private:
+  friend class test::QuicSessionPeer;
+
+  // Called in OnConfigNegotiated when we receive a new stream level flow
+  // control window in a negotiated config. Closes the connection if invalid.
+  void OnNewStreamFlowControlWindow(QuicStreamOffset new_window);
+
+  // Called in OnConfigNegotiated when we receive a new unidirectional stream
+  // flow control window in a negotiated config.
+  void OnNewStreamUnidirectionalFlowControlWindow(QuicStreamOffset new_window);
+
+  // Called in OnConfigNegotiated when we receive a new outgoing bidirectional
+  // stream flow control window in a negotiated config.
+  void OnNewStreamOutgoingBidirectionalFlowControlWindow(
+      QuicStreamOffset new_window);
+
+  // Called in OnConfigNegotiated when we receive a new incoming bidirectional
+  // stream flow control window in a negotiated config.
+  void OnNewStreamIncomingBidirectionalFlowControlWindow(
+      QuicStreamOffset new_window);
+
+  // Called in OnConfigNegotiated when we receive a new connection level flow
+  // control window in a negotiated config. Closes the connection if invalid.
+  void OnNewSessionFlowControlWindow(QuicStreamOffset new_window);
+
+  // Debug helper for |OnCanWrite()|, check that OnStreamWrite() makes
+  // forward progress.  Returns false if busy loop detected.
+  bool CheckStreamNotBusyLooping(QuicStream* stream,
+                                 uint64_t previous_bytes_written,
+                                 bool previous_fin_sent);
+
+  // Debug helper for OnCanWrite. Check that after QuicStream::OnCanWrite(),
+  // if stream has buffered data and is not stream level flow control blocked,
+  // it has to be in the write blocked list.
+  bool CheckStreamWriteBlocked(QuicStream* stream) const;
+
+  // Called in OnConfigNegotiated for Finch trials to measure performance of
+  // starting with larger flow control receive windows.
+  void AdjustInitialFlowControlWindows(size_t stream_window);
+
+  // Find stream with |id|, returns nullptr if the stream does not exist or
+  // closed.
+  QuicStream* GetStream(QuicStreamId id) const;
+
+  // Can return NULL, e.g., if the stream has been closed before.
+  PendingStream* GetOrCreatePendingStream(QuicStreamId stream_id);
+
+  // Let streams and control frame managers retransmit lost data, returns true
+  // if all lost data is retransmitted. Returns false otherwise.
+  bool RetransmitLostData();
+
+  // Returns true if stream data should be written.
+  bool CanWriteStreamData() const;
+
+  // Closes the pending stream |stream_id| before it has been created.
+  void ClosePendingStream(QuicStreamId stream_id);
+
+  // Whether the frame with given type and id should be feed to a pending
+  // stream.
+  bool ShouldProcessFrameByPendingStream(QuicFrameType type,
+                                         QuicStreamId id) const;
+
+  // Process the pending stream if possible.
+  void MaybeProcessPendingStream(PendingStream* pending);
+
+  // Creates or gets pending stream, feeds it with |frame|, and returns the
+  // pending stream. Can return NULL, e.g., if the stream ID is invalid.
+  PendingStream* PendingStreamOnStreamFrame(const QuicStreamFrame& frame);
+
+  // Creates or gets pending strea, feed it with |frame|, and closes the pending
+  // stream.
+  void PendingStreamOnRstStream(const QuicRstStreamFrame& frame);
+
+  // Creates or gets pending stream, feeds it with |frame|, and records the
+  // max_data in the pending stream.
+  void PendingStreamOnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
+
+  // Creates or gets pending stream, feeds it with |frame|, and records the
+  // ietf_error_code in the pending stream.
+  void PendingStreamOnStopSendingFrame(const QuicStopSendingFrame& frame);
+
+  // Keep track of highest received byte offset of locally closed streams, while
+  // waiting for a definitive final highest offset from the peer.
+  absl::flat_hash_map<QuicStreamId, QuicStreamOffset>
+      locally_closed_streams_highest_offset_;
+
+  QuicConnection* connection_;
+
+  // Store perspective on QuicSession during the constructor as it may be needed
+  // during our destructor when connection_ may have already been destroyed.
+  Perspective perspective_;
+
+  // May be null.
+  Visitor* visitor_;
+
+  // A list of streams which need to write more data.  Stream register
+  // themselves in their constructor, and unregisterm themselves in their
+  // destructors, so the write blocked list must outlive all streams.
+  QuicWriteBlockedList write_blocked_streams_;
+
+  ClosedStreams closed_streams_;
+
+  QuicConfig config_;
+
+  // Map from StreamId to pointers to streams. Owns the streams.
+  StreamMap stream_map_;
+
+  // Map from StreamId to PendingStreams for peer-created unidirectional streams
+  // which are waiting for the first byte of payload to arrive.
+  PendingStreamMap pending_stream_map_;
+
+  // TODO(fayang): Consider moving LegacyQuicStreamIdManager into
+  // UberQuicStreamIdManager.
+  // Manages stream IDs for Google QUIC.
+  LegacyQuicStreamIdManager stream_id_manager_;
+
+  // Manages stream IDs for version99/IETF QUIC
+  UberQuicStreamIdManager ietf_streamid_manager_;
+
+  // A counter for streams which have sent and received FIN but waiting for
+  // application to consume data.
+  size_t num_draining_streams_;
+
+  // A counter for self initiated streams which have sent and received FIN but
+  // waiting for application to consume data.
+  size_t num_outgoing_draining_streams_;
+
+  // A counter for static streams which are in stream_map_.
+  size_t num_static_streams_;
+
+  // A counter for streams which have done reading and writing, but are waiting
+  // for acks.
+  size_t num_zombie_streams_;
+
+  // Received information for a connection close.
+  QuicConnectionCloseFrame on_closed_frame_;
+
+  // Used for connection-level flow control.
+  QuicFlowController flow_controller_;
+
+  // The stream id which was last popped in OnCanWrite, or 0, if not under the
+  // call stack of OnCanWrite.
+  QuicStreamId currently_writing_stream_id_;
+
+  // Whether a transport layer GOAWAY frame has been sent.
+  // Such a frame only exists in Google QUIC, therefore |transport_goaway_sent_|
+  // is always false when using IETF QUIC.
+  bool transport_goaway_sent_;
+
+  // Whether a transport layer GOAWAY frame has been received.
+  // Such a frame only exists in Google QUIC, therefore
+  // |transport_goaway_received_| is always false when using IETF QUIC.
+  bool transport_goaway_received_;
+
+  QuicControlFrameManager control_frame_manager_;
+
+  // Id of latest successfully sent message.
+  QuicMessageId last_message_id_;
+
+  // The buffer used to queue the DATAGRAM frames.
+  QuicDatagramQueue datagram_queue_;
+
+  // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
+  // is not used here.
+  // List of streams with pending retransmissions.
+  quiche::QuicheLinkedHashMap<QuicStreamId, bool>
+      streams_with_pending_retransmission_;
+
+  // Clean up closed_streams_ when this alarm fires.
+  std::unique_ptr<QuicAlarm> closed_streams_clean_up_alarm_;
+
+  // Supported version list used by the crypto handshake only. Please note, this
+  // list may be a superset of the connection framer's supported versions.
+  ParsedQuicVersionVector supported_versions_;
+
+  // Only non-empty on the client after receiving a version negotiation packet,
+  // contains the configured versions from the original session before version
+  // negotiation was received.
+  ParsedQuicVersionVector client_original_supported_versions_;
+
+  absl::optional<std::string> user_agent_id_;
+
+  // Initialized to false. Set to true when the session has been properly
+  // configured and is ready for general operation.
+  bool is_configured_;
+
+  // Whether the session has received a 0-RTT rejection (QUIC+TLS only).
+  bool was_zero_rtt_rejected_;
+
+  // This indicates a liveness testing is in progress, and push back the
+  // creation of new outgoing bidirectional streams.
+  bool liveness_testing_in_progress_;
+
+  // Whether BoringSSL randomizes the order of TLS extensions.
+  bool permutes_tls_extensions_ = true;
+
+  const bool support_client_cert_ =
+      GetQuicRestartFlag(quic_tls_server_support_client_cert);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SESSION_H_
diff --git a/quiche/quic/core/quic_session_test.cc b/quiche/quic/core/quic_session_test.cc
new file mode 100644
index 0000000..d97200e
--- /dev/null
+++ b/quiche/quic/core/quic_session_test.cc
@@ -0,0 +1,3093 @@
+// 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 "quiche/quic/core/quic_session.h"
+
+#include <cstdint>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/frames/quic_max_streams_frame.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_mem_slice_storage.h"
+
+using spdy::kV3HighestPriority;
+using spdy::SpdyPriority;
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::AtLeast;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::NiceMock;
+using ::testing::Return;
+using ::testing::StrictMock;
+using ::testing::WithArg;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
+ public:
+  explicit TestCryptoStream(QuicSession* session)
+      : QuicCryptoStream(session),
+        QuicCryptoHandshaker(this, session),
+        encryption_established_(false),
+        one_rtt_keys_available_(false),
+        params_(new QuicCryptoNegotiatedParameters) {
+    // Simulate a negotiated cipher_suite with a fake value.
+    params_->cipher_suite = 1;
+  }
+
+  void EstablishZeroRttEncryption() {
+    encryption_established_ = true;
+    session()->connection()->SetEncrypter(
+        ENCRYPTION_ZERO_RTT,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+  }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
+    encryption_established_ = true;
+    one_rtt_keys_available_ = true;
+    QuicErrorCode error;
+    std::string error_details;
+    session()->config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session()->config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    if (session()->version().UsesTls()) {
+      if (session()->perspective() == Perspective::IS_CLIENT) {
+        session()->config()->SetOriginalConnectionIdToSend(
+            session()->connection()->connection_id());
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->connection_id());
+      } else {
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->client_connection_id());
+      }
+      TransportParameters transport_parameters;
+      EXPECT_TRUE(
+          session()->config()->FillTransportParameters(&transport_parameters));
+      error = session()->config()->ProcessTransportParameters(
+          transport_parameters, /* is_resumption = */ false, &error_details);
+    } else {
+      CryptoHandshakeMessage msg;
+      session()->config()->ToHandshakeMessage(&msg, transport_version());
+      error =
+          session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
+    }
+    EXPECT_THAT(error, IsQuicNoError());
+    session()->OnNewEncryptionKeyAvailable(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+    session()->OnConfigNegotiated();
+    if (session()->connection()->version().handshake_protocol ==
+        PROTOCOL_TLS1_3) {
+      session()->OnTlsHandshakeComplete();
+    } else {
+      session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  }
+
+  // QuicCryptoStream implementation
+  ssl_early_data_reason_t EarlyDataReason() const override {
+    return ssl_early_data_unknown;
+  }
+  bool encryption_established() const override {
+    return encryption_established_;
+  }
+  bool one_rtt_keys_available() const override {
+    return one_rtt_keys_available_;
+  }
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override {
+    return *params_;
+  }
+  CryptoMessageParser* crypto_message_parser() override {
+    return QuicCryptoHandshaker::crypto_message_parser();
+  }
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_parameters*/)
+      const override {
+    return "";
+  }
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    return true;
+  }
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    return nullptr;
+  }
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {}
+  HandshakeState GetHandshakeState() const override {
+    return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+  }
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {}
+  MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter,
+              (),
+              (override));
+  MOCK_METHOD(std::unique_ptr<QuicEncrypter>,
+              CreateCurrentOneRttEncrypter,
+              (),
+              (override));
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  bool HasPendingCryptoRetransmission() const override { return false; }
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override {}
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    return false;
+  }
+
+  SSL* GetSsl() const override { return nullptr; }
+
+ private:
+  using QuicCryptoStream::session;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+};
+
+class TestStream : public QuicStream {
+ public:
+  TestStream(QuicStreamId id, QuicSession* session, StreamType type)
+      : TestStream(id, session, /*is_static=*/false, type) {}
+
+  TestStream(QuicStreamId id,
+             QuicSession* session,
+             bool is_static,
+             StreamType type)
+      : QuicStream(id, session, is_static, type) {}
+
+  TestStream(PendingStream* pending, QuicSession* session)
+      : QuicStream(pending, session, /*is_static=*/false) {}
+
+  using QuicStream::CloseWriteSide;
+  using QuicStream::WriteMemSlices;
+
+  void OnDataAvailable() override {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  MOCK_METHOD(bool,
+              RetransmitStreamData,
+              (QuicStreamOffset, QuicByteCount, bool, TransmissionType),
+              (override));
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+};
+
+class TestSession : public QuicSession {
+ public:
+  explicit TestSession(QuicConnection* connection,
+                       MockQuicSessionVisitor* session_visitor)
+      : QuicSession(connection,
+                    session_visitor,
+                    DefaultQuicConfig(),
+                    CurrentSupportedVersions(),
+                    /*num_expected_unidirectional_static_streams = */ 0),
+        crypto_stream_(this),
+        writev_consumes_all_data_(false),
+        uses_pending_streams_(false),
+        num_incoming_streams_created_(0) {
+    Initialize();
+    this->connection()->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection->perspective()));
+    if (this->connection()->version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(this->connection());
+    }
+  }
+
+  ~TestSession() override { DeleteConnection(); }
+
+  TestCryptoStream* GetMutableCryptoStream() override {
+    return &crypto_stream_;
+  }
+
+  const TestCryptoStream* GetCryptoStream() const override {
+    return &crypto_stream_;
+  }
+
+  TestStream* CreateOutgoingBidirectionalStream() {
+    QuicStreamId id = GetNextOutgoingBidirectionalStreamId();
+    if (id ==
+        QuicUtils::GetInvalidStreamId(connection()->transport_version())) {
+      return nullptr;
+    }
+    TestStream* stream = new TestStream(id, this, BIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateOutgoingUnidirectionalStream() {
+    TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
+                                        this, WRITE_UNIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateIncomingStream(QuicStreamId id) override {
+    // Enforce the limit on the number of open streams.
+    if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
+        stream_id_manager().num_open_incoming_streams() + 1 >
+            max_open_incoming_bidirectional_streams()) {
+      // No need to do this test for version 99; it's done by
+      // QuicSession::GetOrCreateStream.
+      connection()->CloseConnection(
+          QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return nullptr;
+    }
+
+    TestStream* stream = new TestStream(
+        id, this,
+        DetermineStreamType(id, connection()->version(), perspective(),
+                            /*is_incoming=*/true, BIDIRECTIONAL));
+    ActivateStream(absl::WrapUnique(stream));
+    ++num_incoming_streams_created_;
+    return stream;
+  }
+
+  TestStream* CreateIncomingStream(PendingStream* pending) override {
+    TestStream* stream = new TestStream(pending, this);
+    ActivateStream(absl::WrapUnique(stream));
+    ++num_incoming_streams_created_;
+    return stream;
+  }
+
+  // QuicSession doesn't do anything in this method. So it's overridden here to
+  // test that the session handles pending streams correctly in terms of
+  // receiving stream frames.
+  QuicStream* ProcessPendingStream(PendingStream* pending) override {
+    if (pending->is_bidirectional()) {
+      return CreateIncomingStream(pending);
+    }
+    struct iovec iov;
+    if (pending->sequencer()->GetReadableRegion(&iov)) {
+      // Create TestStream once the first byte is received.
+      return CreateIncomingStream(pending);
+    }
+    return nullptr;
+  }
+
+  bool IsClosedStream(QuicStreamId id) {
+    return QuicSession::IsClosedStream(id);
+  }
+
+  QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
+    return QuicSession::GetOrCreateStream(stream_id);
+  }
+
+  bool ShouldKeepConnectionAlive() const override {
+    return GetNumActiveStreams() > 0;
+  }
+
+  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
+                              QuicStreamOffset offset, StreamSendingState state,
+                              TransmissionType type,
+                              EncryptionLevel level) override {
+    bool fin = state != NO_FIN;
+    QuicConsumedData consumed(write_length, fin);
+    if (!writev_consumes_all_data_) {
+      consumed =
+          QuicSession::WritevData(id, write_length, offset, state, type, level);
+    }
+    QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
+        id, consumed.bytes_consumed);
+    return consumed;
+  }
+
+  MOCK_METHOD(void,
+              OnCanCreateNewOutgoingStream,
+              (bool unidirectional),
+              (override));
+
+  void set_writev_consumes_all_data(bool val) {
+    writev_consumes_all_data_ = val;
+  }
+
+  QuicConsumedData SendStreamData(QuicStream* stream) {
+    if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
+                                     stream->id()) &&
+        this->connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
+      this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    QuicStreamPeer::SendBuffer(stream).SaveStreamData("not empty");
+    QuicConsumedData consumed =
+        WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION,
+                   GetEncryptionLevelToSendApplicationData());
+    QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
+        consumed.bytes_consumed);
+    return consumed;
+  }
+
+  const QuicFrame& save_frame() { return save_frame_; }
+
+  bool SaveFrame(const QuicFrame& frame) {
+    save_frame_ = frame;
+    DeleteFrame(&const_cast<QuicFrame&>(frame));
+    return true;
+  }
+
+  QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
+    QUICHE_DCHECK(writev_consumes_all_data_);
+    return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
+                      GetEncryptionLevelToSendApplicationData());
+  }
+
+  bool UsesPendingStreamForFrame(QuicFrameType type,
+                                 QuicStreamId stream_id) const override {
+    if (!uses_pending_streams_) {
+      return false;
+    }
+    // Uses pending stream for STREAM/RST_STREAM frames with unidirectional read
+    // stream and uses pending stream for
+    // STREAM/RST_STREAM/STOP_SENDING/WINDOW_UPDATE frames with bidirectional
+    // stream.
+    bool is_incoming_stream = IsIncomingStream(stream_id);
+    StreamType stream_type = QuicUtils::GetStreamType(
+        stream_id, perspective(), is_incoming_stream, version());
+    switch (type) {
+      case STREAM_FRAME:
+        ABSL_FALLTHROUGH_INTENDED;
+      case RST_STREAM_FRAME:
+        return is_incoming_stream;
+      case STOP_SENDING_FRAME:
+        ABSL_FALLTHROUGH_INTENDED;
+      case WINDOW_UPDATE_FRAME:
+        return stream_type == BIDIRECTIONAL;
+      default:
+        return false;
+    }
+  }
+
+  bool ShouldProcessPendingStreamImmediately() const override {
+    return process_pending_stream_immediately_;
+  }
+
+  void set_uses_pending_streams(bool uses_pending_streams) {
+    uses_pending_streams_ = uses_pending_streams;
+  }
+
+  void set_process_pending_stream_immediately(
+      bool process_pending_stream_immediately) {
+    process_pending_stream_immediately_ = process_pending_stream_immediately;
+  }
+
+  int num_incoming_streams_created() const {
+    return num_incoming_streams_created_;
+  }
+
+  using QuicSession::ActivateStream;
+  using QuicSession::CanOpenNextOutgoingBidirectionalStream;
+  using QuicSession::CanOpenNextOutgoingUnidirectionalStream;
+  using QuicSession::closed_streams;
+  using QuicSession::GetNextOutgoingBidirectionalStreamId;
+  using QuicSession::GetNextOutgoingUnidirectionalStreamId;
+
+ private:
+  StrictMock<TestCryptoStream> crypto_stream_;
+
+  bool writev_consumes_all_data_;
+  bool uses_pending_streams_;
+  bool process_pending_stream_immediately_ = true;
+  QuicFrame save_frame_;
+  int num_incoming_streams_created_;
+};
+
+class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicSessionTestBase(Perspective perspective, bool configure_session)
+      : connection_(
+            new StrictMock<MockQuicConnection>(&helper_,
+                                               &alarm_factory_,
+                                               perspective,
+                                               SupportedVersions(GetParam()))),
+        session_(connection_, &session_visitor_),
+        configure_session_(configure_session) {
+    session_.config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session_.config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+
+    if (configure_session) {
+      if (VersionHasIetfQuicFrames(transport_version())) {
+        EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
+        EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(true)).Times(1);
+      }
+      QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
+          session_.config(), kDefaultMaxStreamsPerConnection);
+      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
+          session_.config(), kDefaultMaxStreamsPerConnection);
+      QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+          session_.config(), kMinimumFlowControlSendWindow);
+      QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+          session_.config(), kMinimumFlowControlSendWindow);
+      QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+          session_.config(), kMinimumFlowControlSendWindow);
+      QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+          session_.config(), kMinimumFlowControlSendWindow);
+      connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+      session_.OnConfigNegotiated();
+    }
+    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .Times(testing::AnyNumber());
+    testing::Mock::VerifyAndClearExpectations(&session_);
+  }
+
+  ~QuicSessionTestBase() {
+    if (configure_session_) {
+      EXPECT_TRUE(session_.is_configured());
+    }
+  }
+
+  void CheckClosedStreams() {
+    QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        connection_->transport_version(), Perspective::IS_CLIENT);
+    if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+      first_stream_id =
+          QuicUtils::GetCryptoStreamId(connection_->transport_version());
+    }
+    for (QuicStreamId i = first_stream_id; i < 100; i++) {
+      if (closed_streams_.find(i) == closed_streams_.end()) {
+        EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
+      } else {
+        EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
+      }
+    }
+  }
+
+  void CloseStream(QuicStreamId id) {
+    if (VersionHasIetfQuicFrames(transport_version())) {
+      if (QuicUtils::GetStreamType(
+              id, session_.perspective(), session_.IsIncomingStream(id),
+              connection_->version()) == READ_UNIDIRECTIONAL) {
+        // Verify STOP_SENDING but no RESET_STREAM is sent for
+        // READ_UNIDIRECTIONAL streams.
+        EXPECT_CALL(*connection_, SendControlFrame(_))
+            .Times(1)
+            .WillOnce(Invoke(&ClearControlFrame));
+        EXPECT_CALL(*connection_, OnStreamReset(id, _)).Times(1);
+      } else if (QuicUtils::GetStreamType(
+                     id, session_.perspective(), session_.IsIncomingStream(id),
+                     connection_->version()) == WRITE_UNIDIRECTIONAL) {
+        // Verify RESET_STREAM but not STOP_SENDING is sent for write-only
+        // stream.
+        EXPECT_CALL(*connection_, SendControlFrame(_))
+            .Times(1)
+            .WillOnce(Invoke(&ClearControlFrame));
+        EXPECT_CALL(*connection_, OnStreamReset(id, _));
+      } else {
+        // Verify RESET_STREAM and STOP_SENDING are sent for BIDIRECTIONAL
+        // streams.
+        EXPECT_CALL(*connection_, SendControlFrame(_))
+            .Times(2)
+            .WillRepeatedly(Invoke(&ClearControlFrame));
+        EXPECT_CALL(*connection_, OnStreamReset(id, _));
+      }
+    } else {
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+      EXPECT_CALL(*connection_, OnStreamReset(id, _));
+    }
+    session_.ResetStream(id, QUIC_STREAM_CANCELLED);
+    closed_streams_.insert(id);
+  }
+
+  void CompleteHandshake() {
+    CryptoHandshakeMessage msg;
+    if (connection_->version().UsesTls() &&
+        connection_->perspective() == Perspective::IS_SERVER) {
+      // HANDSHAKE_DONE frame.
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+    }
+    session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+  }
+
+  QuicTransportVersion transport_version() const {
+    return connection_->transport_version();
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return QuicUtils::GetFirstBidirectionalStreamId(
+               connection_->transport_version(), Perspective::IS_CLIENT) +
+           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
+  }
+
+  QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
+    return QuicUtils::GetFirstUnidirectionalStreamId(
+               connection_->transport_version(), Perspective::IS_CLIENT) +
+           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return QuicUtils::GetFirstBidirectionalStreamId(
+               connection_->transport_version(), Perspective::IS_SERVER) +
+           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
+  }
+
+  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
+    return QuicUtils::GetFirstUnidirectionalStreamId(
+               connection_->transport_version(), Perspective::IS_SERVER) +
+           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
+  }
+
+  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
+                               Perspective perspective,
+                               bool bidirectional) {
+    // Calculate and build up stream ID rather than use
+    // GetFirst... because tests that rely on this method
+    // needs to do the stream count where #1 is 0/1/2/3, and not
+    // take into account that stream 0 is special.
+    QuicStreamId id =
+        ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
+    if (!bidirectional) {
+      id |= 0x2;
+    }
+    if (perspective == Perspective::IS_SERVER) {
+      id |= 0x1;
+    }
+    return id;
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  NiceMock<MockQuicSessionVisitor> session_visitor_;
+  StrictMock<MockQuicConnection>* connection_;
+  TestSession session_;
+  std::set<QuicStreamId> closed_streams_;
+  bool configure_session_;
+};
+
+class QuicSessionTestServer : public QuicSessionTestBase {
+ public:
+  // CheckMultiPathResponse validates that a written packet
+  // contains both expected path responses.
+  WriteResult CheckMultiPathResponse(const char* buffer,
+                                     size_t buf_len,
+                                     const QuicIpAddress& /*self_address*/,
+                                     const QuicSocketAddress& /*peer_address*/,
+                                     PerPacketOptions* /*options*/) {
+    QuicEncryptedPacket packet(buffer, buf_len);
+    {
+      InSequence s;
+      EXPECT_CALL(framer_visitor_, OnPacket());
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+      EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+      EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+      EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
+          .WillOnce(
+              WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
+                EXPECT_EQ(path_frame_buffer1_, frame.data_buffer);
+                return true;
+              })));
+      EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
+          .WillOnce(
+              WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
+                EXPECT_EQ(path_frame_buffer2_, frame.data_buffer);
+                return true;
+              })));
+      EXPECT_CALL(framer_visitor_, OnPacketComplete());
+    }
+    client_framer_.ProcessPacket(packet);
+    return WriteResult(WRITE_STATUS_OK, 0);
+  }
+
+ protected:
+  QuicSessionTestServer()
+      : QuicSessionTestBase(Perspective::IS_SERVER, /*configure_session=*/true),
+        path_frame_buffer1_({0, 1, 2, 3, 4, 5, 6, 7}),
+        path_frame_buffer2_({8, 9, 10, 11, 12, 13, 14, 15}),
+        client_framer_(SupportedVersions(GetParam()),
+                       QuicTime::Zero(),
+                       Perspective::IS_CLIENT,
+                       kQuicDefaultConnectionIdLength) {
+    client_framer_.set_visitor(&framer_visitor_);
+    client_framer_.SetInitialObfuscators(TestConnectionId());
+    if (client_framer_.version().KnowsWhichDecrypterToUse()) {
+      client_framer_.InstallDecrypter(
+          ENCRYPTION_FORWARD_SECURE,
+          std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    }
+  }
+
+  QuicPathFrameBuffer path_frame_buffer1_;
+  QuicPathFrameBuffer path_frame_buffer2_;
+  StrictMock<MockFramerVisitor> framer_visitor_;
+  // Framer used to process packets sent by server.
+  QuicFramer client_framer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSessionTestServer,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSessionTestServer, PeerAddress) {
+  EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
+            session_.peer_address());
+}
+
+TEST_P(QuicSessionTestServer, SelfAddress) {
+  EXPECT_TRUE(session_.self_address().IsInitialized());
+}
+
+TEST_P(QuicSessionTestServer, DontCallOnWriteBlockedForDisconnectedConnection) {
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  connection_->CloseConnection(QUIC_NO_ERROR, "Everything is fine.",
+                               ConnectionCloseBehavior::SILENT_CLOSE);
+  ASSERT_FALSE(connection_->connected());
+
+  EXPECT_CALL(session_visitor_, OnWriteBlocked(_)).Times(0);
+  session_.OnWriteBlocked();
+}
+
+TEST_P(QuicSessionTestServer, OneRttKeysAvailable) {
+  EXPECT_FALSE(session_.OneRttKeysAvailable());
+  CompleteHandshake();
+  EXPECT_TRUE(session_.OneRttKeysAvailable());
+}
+
+TEST_P(QuicSessionTestServer, IsClosedStreamDefault) {
+  // Ensure that no streams are initially closed.
+  QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      connection_->transport_version(), Perspective::IS_CLIENT);
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    first_stream_id =
+        QuicUtils::GetCryptoStreamId(connection_->transport_version());
+  }
+  for (QuicStreamId i = first_stream_id; i < 100; i++) {
+    EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
+  }
+}
+
+TEST_P(QuicSessionTestServer, AvailableBidirectionalStreams) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(3)) != nullptr);
+  // Smaller bidirectional streams should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(1)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(2)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(2)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(1)) != nullptr);
+}
+
+TEST_P(QuicSessionTestServer, AvailableUnidirectionalStreams) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedUnidirectionalId(3)) != nullptr);
+  // Smaller unidirectional streams should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedUnidirectionalId(1)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedUnidirectionalId(2)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedUnidirectionalId(2)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedUnidirectionalId(1)) != nullptr);
+}
+
+TEST_P(QuicSessionTestServer, MaxAvailableBidirectionalStreams) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_EQ(session_.max_open_incoming_bidirectional_streams(),
+              session_.MaxAvailableBidirectionalStreams());
+  } else {
+    // The protocol specification requires that there can be at least 10 times
+    // as many available streams as the connection's maximum open streams.
+    EXPECT_EQ(session_.max_open_incoming_bidirectional_streams() *
+                  kMaxAvailableStreamsMultiplier,
+              session_.MaxAvailableBidirectionalStreams());
+  }
+}
+
+TEST_P(QuicSessionTestServer, MaxAvailableUnidirectionalStreams) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_EQ(session_.max_open_incoming_unidirectional_streams(),
+              session_.MaxAvailableUnidirectionalStreams());
+  } else {
+    // The protocol specification requires that there can be at least 10 times
+    // as many available streams as the connection's maximum open streams.
+    EXPECT_EQ(session_.max_open_incoming_unidirectional_streams() *
+                  kMaxAvailableStreamsMultiplier,
+              session_.MaxAvailableUnidirectionalStreams());
+  }
+}
+
+TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamLocallyCreated) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
+
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(0));
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(1));
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamLocallyCreated) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingUnidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(0), stream2->id());
+  TestStream* stream4 = session_.CreateOutgoingUnidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(1), stream4->id());
+
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedUnidirectionalId(0));
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedUnidirectionalId(1));
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamPeerCreated) {
+  CompleteHandshake();
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
+  session_.GetOrCreateStream(stream_id1);
+  session_.GetOrCreateStream(stream_id2);
+
+  CheckClosedStreams();
+  CloseStream(stream_id1);
+  CheckClosedStreams();
+  CloseStream(stream_id2);
+  // Create a stream, and make another available.
+  QuicStream* stream3 = session_.GetOrCreateStream(
+      stream_id2 +
+      2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
+  CheckClosedStreams();
+  // Close one, but make sure the other is still not closed
+  CloseStream(stream3->id());
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamPeerCreated) {
+  CompleteHandshake();
+  QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
+  QuicStreamId stream_id2 = GetNthClientInitiatedUnidirectionalId(1);
+  session_.GetOrCreateStream(stream_id1);
+  session_.GetOrCreateStream(stream_id2);
+
+  CheckClosedStreams();
+  CloseStream(stream_id1);
+  CheckClosedStreams();
+  CloseStream(stream_id2);
+  // Create a stream, and make another available.
+  QuicStream* stream3 = session_.GetOrCreateStream(
+      stream_id2 +
+      2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
+  CheckClosedStreams();
+  // Close one, but make sure the other is still not closed
+  CloseStream(stream3->id());
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, MaximumAvailableOpenedBidirectionalStreams) {
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  session_.GetOrCreateStream(stream_id);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_NE(nullptr,
+            session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(
+                session_.max_open_incoming_bidirectional_streams() - 1)));
+}
+
+TEST_P(QuicSessionTestServer, MaximumAvailableOpenedUnidirectionalStreams) {
+  QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
+  session_.GetOrCreateStream(stream_id);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_NE(nullptr,
+            session_.GetOrCreateStream(GetNthClientInitiatedUnidirectionalId(
+                session_.max_open_incoming_unidirectional_streams() - 1)));
+}
+
+TEST_P(QuicSessionTestServer, TooManyAvailableBidirectionalStreams) {
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2;
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
+  // A stream ID which is too large to create.
+  stream_id2 = GetNthClientInitiatedBidirectionalId(
+      session_.MaxAvailableBidirectionalStreams() + 2);
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // IETF QUIC terminates the connection with invalid stream id
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  } else {
+    // other versions terminate the connection with
+    // QUIC_TOO_MANY_AVAILABLE_STREAMS.
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  }
+  EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
+}
+
+TEST_P(QuicSessionTestServer, TooManyAvailableUnidirectionalStreams) {
+  QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
+  QuicStreamId stream_id2;
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
+  // A stream ID which is too large to create.
+  stream_id2 = GetNthClientInitiatedUnidirectionalId(
+      session_.MaxAvailableUnidirectionalStreams() + 2);
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // IETF QUIC terminates the connection with invalid stream id
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  } else {
+    // other versions terminate the connection with
+    // QUIC_TOO_MANY_AVAILABLE_STREAMS.
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  }
+  EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
+}
+
+TEST_P(QuicSessionTestServer, ManyAvailableBidirectionalStreams) {
+  // When max_open_streams_ is 200, should be able to create 200 streams
+  // out-of-order, that is, creating the one with the largest stream ID first.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 200);
+    // Smaller limit on unidirectional streams to help detect crossed wires.
+    QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 50);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
+  }
+  // Create a stream at the start of the range.
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+
+  // Create the largest stream ID of a threatened total of 200 streams.
+  // GetNth... starts at 0, so for 200 streams, get the 199th.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                         GetNthClientInitiatedBidirectionalId(199)));
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // If IETF QUIC, check to make sure that creating bidirectional
+    // streams does not mess up the unidirectional streams.
+    stream_id = GetNthClientInitiatedUnidirectionalId(0);
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+    // Now try to get the last possible unidirectional stream.
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                           GetNthClientInitiatedUnidirectionalId(49)));
+    // and this should fail because it exceeds the unidirectional limit
+    // (but not the bi-)
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INVALID_STREAM_ID,
+                        "Stream id 798 would exceed stream count limit 50",
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+        .Times(1);
+    EXPECT_EQ(nullptr, session_.GetOrCreateStream(
+                           GetNthClientInitiatedUnidirectionalId(199)));
+  }
+}
+
+TEST_P(QuicSessionTestServer, ManyAvailableUnidirectionalStreams) {
+  // When max_open_streams_ is 200, should be able to create 200 streams
+  // out-of-order, that is, creating the one with the largest stream ID first.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 200);
+    // Smaller limit on unidirectional streams to help detect crossed wires.
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 50);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
+  }
+  // Create one stream.
+  QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+
+  // Create the largest stream ID of a threatened total of 200 streams.
+  // GetNth... starts at 0, so for 200 streams, get the 199th.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                         GetNthClientInitiatedUnidirectionalId(199)));
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // If IETF QUIC, check to make sure that creating unidirectional
+    // streams does not mess up the bidirectional streams.
+    stream_id = GetNthClientInitiatedBidirectionalId(0);
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+    // Now try to get the last possible bidirectional stream.
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                           GetNthClientInitiatedBidirectionalId(49)));
+    // and this should fail because it exceeds the bnidirectional limit
+    // (but not the uni-)
+    std::string error_detail;
+    if (QuicVersionUsesCryptoFrames(transport_version())) {
+      error_detail = "Stream id 796 would exceed stream count limit 50";
+    } else {
+      error_detail = "Stream id 800 would exceed stream count limit 50";
+    }
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INVALID_STREAM_ID, error_detail,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+        .Times(1);
+    EXPECT_EQ(nullptr, session_.GetOrCreateStream(
+                           GetNthClientInitiatedBidirectionalId(199)));
+  }
+}
+
+TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId closed_stream_id = stream2->id();
+  // Close the stream.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
+  stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+  std::string msg =
+      absl::StrCat("Marking unknown stream ", closed_stream_id, " blocked.");
+  EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
+                  msg);
+}
+
+TEST_P(QuicSessionTestServer, OnCanWrite) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  InSequence s;
+
+  // Reregister, to test the loop limit.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  // 2 will get called a second time as it didn't finish its block
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  // 4 will not get called, as we exceeded the loop limit.
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, TestBatchedWrites) {
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.set_writev_consumes_all_data(true);
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // With two sessions blocked, we should get two write calls.  They should both
+  // go to the first stream as it will only write 6k and mark itself blocked
+  // again.
+  InSequence s;
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+
+  // We should get one more call for stream2, at which point it has used its
+  // write quota and we move over to stream 4.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  session_.OnCanWrite();
+
+  // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
+  // priority stream 6.  4 should be preempted.  6 will write but *not* block so
+  // will cede back to 4.
+  stream6->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_CALL(*stream4, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendLargeFakeData(stream4, 6000);
+        session_.MarkConnectionLevelWriteBlocked(stream4->id());
+        session_.MarkConnectionLevelWriteBlocked(stream6->id());
+      }));
+  EXPECT_CALL(*stream6, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendStreamData(stream6);
+        session_.SendLargeFakeData(stream4, 6000);
+      }));
+  session_.OnCanWrite();
+
+  // Stream4 alread did 6k worth of writes, so after doing another 12k it should
+  // cede and 2 should resume.
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 12000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
+  // Encryption needs to be established before data can be sent.
+  CompleteHandshake();
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm, GetCongestionWindow())
+      .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
+  EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+
+  // Expect that we only send one packet, the writes from different streams
+  // should be bundled together.
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*send_algorithm, GetCongestionWindow()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  // stream4->OnCanWrite is not called.
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Still congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // stream4->OnCanWrite is called once the connection stops being
+  // congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) {
+  CompleteHandshake();
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Drive packet writer manually.
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, SendStreamsBlocked) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
+    ASSERT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
+    session_.GetNextOutgoingBidirectionalStreamId();
+  }
+  // Next checking causes STREAMS_BLOCKED to be sent.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke([](const QuicFrame& frame) {
+        EXPECT_FALSE(frame.streams_blocked_frame.unidirectional);
+        EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+                  frame.streams_blocked_frame.stream_count);
+        ClearControlFrame(frame);
+        return true;
+      }));
+  EXPECT_FALSE(session_.CanOpenNextOutgoingBidirectionalStream());
+
+  for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
+    ASSERT_TRUE(session_.CanOpenNextOutgoingUnidirectionalStream());
+    session_.GetNextOutgoingUnidirectionalStreamId();
+  }
+  // Next checking causes STREAM_BLOCKED to be sent.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke([](const QuicFrame& frame) {
+        EXPECT_TRUE(frame.streams_blocked_frame.unidirectional);
+        EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+                  frame.streams_blocked_frame.stream_count);
+        ClearControlFrame(frame);
+        return true;
+      }));
+  EXPECT_FALSE(session_.CanOpenNextOutgoingUnidirectionalStream());
+}
+
+TEST_P(QuicSessionTestServer, BufferedHandshake) {
+  // This test is testing behavior of crypto stream flow control, but when
+  // CRYPTO frames are used, there is no flow control for the crypto handshake.
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  session_.set_writev_consumes_all_data(true);
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Default value.
+
+  // Test that blocking other streams does not change our status.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream3->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  // Blocking (due to buffering of) the Crypto stream is detected.
+  session_.MarkConnectionLevelWriteBlocked(
+      QuicUtils::GetCryptoStreamId(connection_->transport_version()));
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  InSequence s;
+  // Force most streams to re-register, which is common scenario when we block
+  // the Crypto stream, and only the crypto stream can "really" write.
+
+  // Due to prioritization, we *should* be asked to write the crypto stream
+  // first.
+  // Don't re-register the crypto stream (which signals complete writing).
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_CALL(*crypto_stream, OnCanWrite());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
+    session_.SendStreamData(stream3);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Crypto stream wrote.
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  CloseStream(stream6->id());
+
+  InSequence s;
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Ensure connection level flow control blockage.
+  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
+  EXPECT_TRUE(session_.flow_controller()->IsBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+
+  // Mark the crypto and headers streams as write blocked, we expect them to be
+  // allowed to write later.
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    session_.MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()));
+  }
+
+  // Create a data stream, and although it is write blocked we never expect it
+  // to be allowed to write as we are connection level flow control blocked.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream->id());
+  EXPECT_CALL(*stream, OnCanWrite()).Times(0);
+
+  // The crypto and headers streams should be called even though we are
+  // connection flow control blocked.
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, OnCanWrite());
+  }
+
+  // After the crypto and header streams perform a write, the connection will be
+  // blocked by the flow control, hence it should become application-limited.
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, SendGoAway) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // In IETF QUIC, GOAWAY lives up in the HTTP layer.
+    return;
+  }
+  CompleteHandshake();
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.transport_goaway_sent());
+
+  const QuicStreamId kTestStreamId = 5u;
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  EXPECT_CALL(*connection_,
+              OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
+      .Times(0);
+  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
+}
+
+TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) {
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // In IETF QUIC, GOAWAY lives up in the HTTP layer.
+    return;
+  }
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.transport_goaway_sent());
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+}
+
+TEST_P(QuicSessionTestServer, InvalidGoAway) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // In IETF QUIC, GOAWAY lives up in the HTTP layer.
+    return;
+  }
+  QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
+                          session_.next_outgoing_bidirectional_stream_id(), "");
+  session_.OnGoAway(go_away);
+}
+
+// Test that server session will send a connectivity probe in response to a
+// connectivity probe on the same path.
+TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbe) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicSocketAddress old_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+
+  QuicSocketAddress new_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
+
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+    EXPECT_CALL(*connection_, SendConnectivityProbingPacket(_, _))
+        .WillOnce(
+            Invoke(connection_,
+                   &MockQuicConnection::ReallySendConnectivityProbingPacket));
+  session_.OnPacketReceived(session_.self_address(), new_peer_address,
+                            /*is_connectivity_probe=*/true);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+}
+
+TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
+  EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+  CompleteHandshake();
+  EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+}
+
+TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
+  if (VersionUsesHttp3(connection_->transport_version())) {
+    // The test relies on headers stream, which no longer exists in IETF QUIC.
+    return;
+  }
+  QuicStreamId headers_stream_id =
+      QuicUtils::GetHeadersStreamId(connection_->transport_version());
+  std::unique_ptr<TestStream> fake_headers_stream =
+      std::make_unique<TestStream>(headers_stream_id, &session_,
+                                   /*is_static*/ true, BIDIRECTIONAL);
+  QuicSessionPeer::ActivateStream(&session_, std::move(fake_headers_stream));
+  // Send two bytes of payload.
+  QuicStreamFrame data1(headers_stream_id, true, 0, absl::string_view("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicStreamFrame data1(
+      QuicUtils::GetInvalidStreamId(connection_->transport_version()), true, 0,
+      absl::string_view("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSessionTestServer, OnRstStreamInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicRstStreamFrame rst1(
+      kInvalidControlFrameId,
+      QuicUtils::GetInvalidStreamId(connection_->transport_version()),
+      QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
+  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test requires Google QUIC crypto because it assumes streams start
+    // off unblocked.
+    return;
+  }
+  // Test that if a stream is flow control blocked, then on receipt of the SHLO
+  // containing a suitable send window offset, the stream becomes unblocked.
+
+  // Ensure that Writev consumes all the data it is given (simulate no socket
+  // blocking).
+  session_.set_writev_consumes_all_data(true);
+  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
+
+  // Create a stream, and send enough data to make it flow control blocked.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  std::string body(kMinimumFlowControlSendWindow, '.');
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
+  stream2->WriteOrBufferData(body, false, nullptr);
+  EXPECT_TRUE(stream2->IsFlowControlBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Now complete the crypto handshake, resulting in an increased flow control
+  // send window.
+  CompleteHandshake();
+  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
+  // Stream is now unblocked.
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
+  CompleteHandshake();
+  // Test that when we receive an out of order stream RST we correctly adjust
+  // our connection level flow control receive window.
+  // On close, the stream should mark as consumed all bytes between the highest
+  // byte consumed so far and the final byte offset from the RST frame.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  const QuicStreamOffset kByteOffset =
+      1 + kInitialSessionFlowControlWindowForTest / 2;
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kByteOffset);
+  session_.OnRstStream(rst_frame);
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // The test requires the stream to be fully closed in both directions. For
+    // IETF QUIC, the RST_STREAM only closes one side.
+    QuicStopSendingFrame frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED);
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    session_.OnStopSendingFrame(frame);
+  }
+  EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
+  CompleteHandshake();
+  // Test the situation where we receive a FIN on a stream, and before we fully
+  // consume all the data from the sequencer buffer we locally RST the stream.
+  // The bytes between highest consumed byte, and the final byte offset that we
+  // determined when the FIN arrived, should be marked as consumed at the
+  // connection level flow controller when the stream is reset.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  const QuicStreamOffset kByteOffset =
+      kInitialSessionFlowControlWindowForTest / 2 - 1;
+  QuicStreamFrame frame(stream->id(), true, kByteOffset, ".");
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(connection_->connected());
+
+  EXPECT_EQ(0u, session_.flow_controller()->bytes_consumed());
+  EXPECT_EQ(kByteOffset + frame.data_length,
+            stream->highest_received_byte_offset());
+
+  // Reset stream locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(kByteOffset + frame.data_length,
+            session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
+  CompleteHandshake();
+  // Test that when we RST the stream (and tear down stream state), and then
+  // receive a FIN from the peer, we correctly adjust our connection level flow
+  // control receive window.
+
+  // Connection starts with some non-zero highest received byte offset,
+  // due to other active streams.
+  const uint64_t kInitialConnectionBytesConsumed = 567;
+  const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
+  EXPECT_LT(kInitialConnectionBytesConsumed,
+            kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->UpdateHighestReceivedOffset(
+      kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
+
+  // Reset our stream: this results in the stream being closed locally.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+
+  // Now receive a response from the peer with a FIN. We should handle this by
+  // adjusting the connection level flow control receive window to take into
+  // account the total number of bytes sent by the peer.
+  const QuicStreamOffset kByteOffset = 5678;
+  std::string body = "hello";
+  QuicStreamFrame frame(stream->id(), true, kByteOffset,
+                        absl::string_view(body));
+  session_.OnStreamFrame(frame);
+
+  QuicStreamOffset total_stream_bytes_sent_by_peer =
+      kByteOffset + body.length();
+  EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer,
+            session_.flow_controller()->bytes_consumed());
+  EXPECT_EQ(
+      kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer,
+      session_.flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
+  CompleteHandshake();
+  // Test that when we RST the stream (and tear down stream state), and then
+  // receive a RST from the peer, we correctly adjust our connection level flow
+  // control receive window.
+
+  // Connection starts with some non-zero highest received byte offset,
+  // due to other active streams.
+  const uint64_t kInitialConnectionBytesConsumed = 567;
+  const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
+  EXPECT_LT(kInitialConnectionBytesConsumed,
+            kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->UpdateHighestReceivedOffset(
+      kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
+
+  // Reset our stream: this results in the stream being closed locally.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+  // Now receive a RST from the peer. We should handle this by adjusting the
+  // connection level flow control receive window to take into account the total
+  // number of bytes sent by the peer.
+  const QuicStreamOffset kByteOffset = 5678;
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kByteOffset);
+  session_.OnRstStream(rst_frame);
+
+  EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset,
+            session_.flow_controller()->bytes_consumed());
+  EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset,
+            session_.flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
+  // Test that receipt of an invalid (< default) stream flow control window from
+  // the peer results in the connection being torn down.
+  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
+                                                            kInvalidWindow);
+
+  if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
+  } else {
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+// Test negotiation of custom server initial flow control window.
+TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
+  QuicTagVector copt;
+  copt.push_back(kIFW7);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+  EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
+                             session_.flow_controller()));
+}
+
+TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
+  CompleteHandshake();
+  // Test that if we receive a stream RST with a highest byte offset that
+  // violates flow control, that we close the connection.
+  const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
+      .Times(2);
+
+  // Check that stream frame + FIN results in connection close.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  QuicStreamFrame frame(stream->id(), true, kLargeOffset, absl::string_view());
+  session_.OnStreamFrame(frame);
+
+  // Check that RST results in connection close.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kLargeOffset);
+  session_.OnRstStream(rst_frame);
+}
+
+TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
+  CompleteHandshake();
+  // If a buggy/malicious peer creates too many streams that are not ended
+  // with a FIN or RST then we send an RST to refuse streams. For IETF QUIC the
+  // connection is closed.
+  const QuicStreamId kMaxStreams = 5;
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
+                                                            kMaxStreams);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+  }
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(kMaxStreams);
+  // Create kMaxStreams data streams, and close them all without receiving a
+  // FIN or a RST_STREAM from the client.
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
+       i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
+    QuicStreamFrame data1(i, false, 0, absl::string_view("HT"));
+    session_.OnStreamFrame(data1);
+    CloseStream(i);
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INVALID_STREAM_ID,
+                        "Stream id 20 would exceed stream count limit 5", _));
+  } else {
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+    EXPECT_CALL(*connection_,
+                OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
+        .Times(1);
+  }
+  // Create one more data streams to exceed limit of open stream.
+  QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpenedOutgoing) {
+  // Verify that a draining stream (which has received a FIN but not consumed
+  // it) does not count against the open quota (because it is closed from the
+  // protocol point of view).
+  CompleteHandshake();
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+  QuicStreamFrame data1(stream_id, true, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
+  }
+  session_.StreamDraining(stream_id, /*unidirectional=*/false);
+}
+
+TEST_P(QuicSessionTestServer, NoPendingStreams) {
+  session_.set_uses_pending_streams(false);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+}
+
+TEST_P(QuicSessionTestServer, PendingStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(true);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+}
+
+TEST_P(QuicSessionTestServer, BufferAllIncomingStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(false);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  // Read unidirectional stream is still buffered when the first byte arrives.
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  // Bidirectional stream is buffered.
+  QuicStreamId bidirectional_stream_id =
+      QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                               Perspective::IS_CLIENT);
+  QuicStreamFrame data3(bidirectional_stream_id, false, 0,
+                        absl::string_view("HT"));
+  session_.OnStreamFrame(data3);
+  EXPECT_TRUE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  session_.ProcessAllPendingStreams();
+  // Both bidirectional and read-unidirectional streams are unbuffered.
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_FALSE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(2, session_.num_incoming_streams_created());
+}
+
+TEST_P(QuicSessionTestServer, RstPendingStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(false);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  QuicRstStreamFrame rst1(kInvalidControlFrameId, stream_id,
+                          QUIC_ERROR_PROCESSING_STREAM, 12);
+  session_.OnRstStream(rst1);
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  session_.ProcessAllPendingStreams();
+  // Bidirectional stream is buffered.
+  QuicStreamId bidirectional_stream_id =
+      QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                               Perspective::IS_CLIENT);
+  QuicStreamFrame data3(bidirectional_stream_id, false, 0,
+                        absl::string_view("HT"));
+  session_.OnStreamFrame(data3);
+  EXPECT_TRUE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  // Bidirectional pending stream is removed after RST_STREAM is received.
+  QuicRstStreamFrame rst2(kInvalidControlFrameId, bidirectional_stream_id,
+                          QUIC_ERROR_PROCESSING_STREAM, 12);
+  session_.OnRstStream(rst2);
+  EXPECT_FALSE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+}
+
+TEST_P(QuicSessionTestServer, OnFinPendingStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(true);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data(stream_id, true, 0, "");
+  session_.OnStreamFrame(data);
+
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  session_.set_process_pending_stream_immediately(false);
+  // Bidirectional pending stream remains after Fin is received.
+  // Bidirectional stream is buffered.
+  QuicStreamId bidirectional_stream_id =
+      QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                               Perspective::IS_CLIENT);
+  QuicStreamFrame data2(bidirectional_stream_id, true, 0,
+                        absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_TRUE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  session_.ProcessAllPendingStreams();
+  EXPECT_FALSE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+  QuicStream* bidirectional_stream =
+      QuicSessionPeer::GetStream(&session_, bidirectional_stream_id);
+  EXPECT_TRUE(bidirectional_stream->fin_received());
+}
+
+TEST_P(QuicSessionTestServer, UnidirectionalPendingStreamOnWindowUpdate) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.set_uses_pending_streams(true);
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
+                                            0);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
+          "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.", _));
+  session_.OnWindowUpdateFrame(window_update_frame);
+}
+
+TEST_P(QuicSessionTestServer, BidirectionalPendingStreamOnWindowUpdate) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(false);
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data);
+  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
+                                            kDefaultFlowControlSendWindow * 2);
+  session_.OnWindowUpdateFrame(window_update_frame);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  session_.ProcessAllPendingStreams();
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+  QuicStream* bidirectional_stream =
+      QuicSessionPeer::GetStream(&session_, stream_id);
+  QuicByteCount send_window =
+      QuicStreamPeer::SendWindowSize(bidirectional_stream);
+  EXPECT_EQ(send_window, kDefaultFlowControlSendWindow * 2);
+}
+
+TEST_P(QuicSessionTestServer, UnidirectionalPendingStreamOnStopSending) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.set_uses_pending_streams(true);
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  QuicStopSendingFrame stop_sending_frame(kInvalidControlFrameId, stream_id,
+                                          QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Received STOP_SENDING for a read-only stream", _));
+  session_.OnStopSendingFrame(stop_sending_frame);
+}
+
+TEST_P(QuicSessionTestServer, BidirectionalPendingStreamOnStopSending) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(false);
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data(stream_id, true, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data);
+  QuicStopSendingFrame stop_sending_frame(kInvalidControlFrameId, stream_id,
+                                          QUIC_STREAM_CANCELLED);
+  session_.OnStopSendingFrame(stop_sending_frame);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  EXPECT_CALL(*connection_, OnStreamReset(stream_id, _));
+  session_.ProcessAllPendingStreams();
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+  QuicStream* bidirectional_stream =
+      QuicSessionPeer::GetStream(&session_, stream_id);
+  EXPECT_TRUE(bidirectional_stream->write_side_closed());
+}
+
+TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
+  // Verify that a draining stream (which has received a FIN but not consumed
+  // it) does not count against the open quota (because it is closed from the
+  // protocol point of view).
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // On IETF QUIC, we will expect to see a MAX_STREAMS go out when there are
+    // not enough streams to create the next one.
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  }
+  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
+  const QuicStreamId kMaxStreams = 5;
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
+                                                            kMaxStreams);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+  }
+
+  // Create kMaxStreams + 1 data streams, and mark them draining.
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(2 * kMaxStreams + 1);
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
+       i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
+    QuicStreamFrame data1(i, true, 0, absl::string_view("HT"));
+    session_.OnStreamFrame(data1);
+    EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+    session_.StreamDraining(i, /*unidirectional=*/false);
+    EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  }
+}
+
+class QuicSessionTestClient : public QuicSessionTestBase {
+ protected:
+  QuicSessionTestClient()
+      : QuicSessionTestBase(Perspective::IS_CLIENT,
+                            /*configure_session=*/true) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSessionTestClient,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSessionTestClient, AvailableBidirectionalStreamsClient) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(2)) != nullptr);
+  // Smaller bidirectional streams should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(0)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(1)) != nullptr);
+  // And 5 should be not available.
+  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(1)));
+}
+
+TEST_P(QuicSessionTestClient, InvalidSessionFlowControlWindowInHandshake) {
+  // Test that receipt of an invalid (< default for gQUIC, < current for TLS)
+  // session flow control window from the peer results in the connection being
+  // torn down.
+  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
+                                                             kInvalidWindow);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(connection_->version().AllowsLowFlowControlLimits()
+                          ? QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED
+                          : QUIC_FLOW_CONTROL_INVALID_WINDOW,
+                      _, _));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSessionTestClient, InvalidBidiStreamLimitInHandshake) {
+  // IETF QUIC only feature.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
+      session_.config(), kDefaultMaxStreamsPerConnection - 1);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSessionTestClient, InvalidUniStreamLimitInHandshake) {
+  // IETF QUIC only feature.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
+      session_.config(), kDefaultMaxStreamsPerConnection - 1);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSessionTestClient, InvalidStreamFlowControlWindowInHandshake) {
+  // IETF QUIC only feature.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  session_.CreateOutgoingBidirectionalStream();
+  session_.CreateOutgoingBidirectionalStream();
+  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+      session_.config(), kMinimumFlowControlSendWindow - 1);
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSessionTestClient, OnMaxStreamFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  QuicMaxStreamsFrame frame;
+  frame.unidirectional = false;
+  frame.stream_count = 120;
+  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
+  session_.OnMaxStreamsFrame(frame);
+
+  QuicMaxStreamsFrame frame2;
+  frame2.unidirectional = false;
+  frame2.stream_count = 110;
+  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
+  session_.OnMaxStreamsFrame(frame2);
+}
+
+TEST_P(QuicSessionTestClient, AvailableUnidirectionalStreamsClient) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedUnidirectionalId(2)) != nullptr);
+  // Smaller unidirectional streams should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedUnidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedUnidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedUnidirectionalId(0)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedUnidirectionalId(1)) != nullptr);
+  // And 5 should be not available.
+  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedUnidirectionalId(1)));
+}
+
+TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
+  CompleteHandshake();
+  // Verify that an incoming FIN is recorded in a stream object even if the read
+  // side has been closed.  This prevents an entry from being made in
+  // locally_closed_streams_highest_offset_ (which will never be deleted).
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+
+  // Close the read side manually.
+  QuicStreamPeer::CloseReadSide(stream);
+
+  // Receive a stream data frame with FIN.
+  QuicStreamFrame frame(stream_id, true, 0, absl::string_view());
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(stream->fin_received());
+
+  // Reset stream locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+  EXPECT_TRUE(connection_->connected());
+  EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
+  EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
+
+  // The stream is not waiting for the arrival of the peer's final offset as it
+  // was received with the FIN earlier.
+  EXPECT_EQ(
+      0u,
+      QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
+}
+
+TEST_P(QuicSessionTestClient, IncomingStreamWithClientInitiatedStreamId) {
+  const QuicErrorCode expected_error =
+      VersionHasIetfQuicFrames(transport_version())
+          ? QUIC_HTTP_STREAM_WRONG_DIRECTION
+          : QUIC_INVALID_STREAM_ID;
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(expected_error, "Data for nonexistent stream",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(1),
+                        /* fin = */ false, /* offset = */ 0,
+                        absl::string_view("foo"));
+  session_.OnStreamFrame(frame);
+}
+
+TEST_P(QuicSessionTestClient, MinAckDelaySetOnTheClientQuicConfig) {
+  if (!session_.version().HasIetfQuicFrames()) {
+    return;
+  }
+  session_.config()->SetClientConnectionOptions({kAFFE});
+  session_.Initialize();
+  ASSERT_EQ(session_.config()->GetMinAckDelayToSendMs(),
+            kDefaultMinAckDelayTimeMs);
+  ASSERT_TRUE(session_.connection()->can_receive_ack_frequency_frame());
+}
+
+TEST_P(QuicSessionTestClient, FailedToCreateStreamIfTooCloseToIdleTimeout) {
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
+  QuicTime deadline = QuicConnectionPeer::GetIdleNetworkDeadline(connection_);
+  ASSERT_TRUE(deadline.IsInitialized());
+  QuicTime::Delta timeout = deadline - helper_.GetClock()->ApproximateNow();
+  // Advance time to very close idle timeout.
+  connection_->AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(1));
+  // Verify creation of new stream gets pushed back and connectivity probing
+  // packet gets sent.
+  EXPECT_CALL(*connection_, SendConnectivityProbingPacket(_, _)).Times(1);
+  EXPECT_FALSE(session_.CanOpenNextOutgoingBidirectionalStream());
+
+  // New packet gets received, idle deadline gets extended.
+  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false));
+  QuicConnectionPeer::GetIdleNetworkDetector(connection_)
+      .OnPacketReceived(helper_.GetClock()->ApproximateNow());
+  session_.OnPacketDecrypted(ENCRYPTION_FORWARD_SECURE);
+
+  EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
+}
+
+TEST_P(QuicSessionTestServer, ZombieStreams) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamPeer::SetStreamBytesWritten(3, stream2);
+  EXPECT_TRUE(stream2->IsWaitingForAcks());
+
+  CloseStream(stream2->id());
+  ASSERT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
+  session_.MaybeCloseZombieStream(stream2->id());
+  EXPECT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
+}
+
+TEST_P(QuicSessionTestServer, RstStreamReceivedAfterRstStreamSent) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamPeer::SetStreamBytesWritten(3, stream2);
+  EXPECT_TRUE(stream2->IsWaitingForAcks());
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
+  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
+  stream2->Reset(quic::QUIC_STREAM_CANCELLED);
+
+  QuicRstStreamFrame rst1(kInvalidControlFrameId, stream2->id(),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
+  }
+  session_.OnRstStream(rst1);
+}
+
+// Regression test of b/71548958.
+TEST_P(QuicSessionTestServer, TestZombieStreams) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  std::string body(100, '.');
+  stream2->WriteOrBufferData(body, false, nullptr);
+  EXPECT_TRUE(stream2->IsWaitingForAcks());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream2).size());
+
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream2->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  // Just for the RST_STREAM
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(*connection_,
+                OnStreamReset(stream2->id(), QUIC_STREAM_CANCELLED));
+  } else {
+    EXPECT_CALL(*connection_,
+                OnStreamReset(stream2->id(), QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  stream2->OnStreamReset(rst_frame);
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // The test requires the stream to be fully closed in both directions. For
+    // IETF QUIC, the RST_STREAM only closes one side.
+    QuicStopSendingFrame frame(kInvalidControlFrameId, stream2->id(),
+                               QUIC_STREAM_CANCELLED);
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    session_.OnStopSendingFrame(frame);
+  }
+  ASSERT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
+
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Once for the RST_STREAM, once for the STOP_SENDING
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .Times(2)
+        .WillRepeatedly(Invoke(&ClearControlFrame));
+  } else {
+    // Just for the RST_STREAM
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  }
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream4->id(), QUIC_STREAM_CANCELLED));
+  stream4->WriteOrBufferData(body, false, nullptr);
+  // Note well: Reset() actually closes the stream in both directions. For
+  // GOOGLE QUIC it sends a RST_STREAM (which does a 2-way close), for IETF
+  // QUIC it sends both a RST_STREAM and a STOP_SENDING (each of which
+  // closes in only one direction).
+  stream4->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(2u, session_.closed_streams()->size());
+}
+
+TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
+  CompleteHandshake();
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame1;
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    frame1 = QuicStreamFrame(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
+        0, 1300);
+  }
+  QuicStreamFrame frame2(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream4->id(), false, 0, 9);
+
+  // Lost data on cryption stream, streams 2 and 4.
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(true));
+  }
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    session_.OnFrameLost(QuicFrame(frame1));
+  } else {
+    QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
+    session_.OnFrameLost(QuicFrame(&crypto_frame));
+  }
+  session_.OnFrameLost(QuicFrame(frame2));
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Mark streams 2 and 4 write blocked.
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // Lost data is retransmitted before new data, and retransmissions for crypto
+  // stream go first.
+  // Do not check congestion window when crypto stream has lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    EXPECT_CALL(*crypto_stream, OnCanWrite());
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(false));
+  }
+  // Check congestion window for non crypto streams.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
+  // Connection is blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Unblock connection.
+  // Stream 2 retransmits lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  // Stream 2 sends new data.
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
+  CompleteHandshake();
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  session_.OnFrameLost(QuicFrame(frame2));
+  session_.OnFrameLost(QuicFrame(frame1));
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+  // Reset stream 4 locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
+  stream4->Reset(QUIC_STREAM_CANCELLED);
+
+  // Verify stream 4 is removed from streams with lost data list.
+  EXPECT_CALL(*stream6, OnCanWrite());
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream6, OnCanWrite());
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, RetransmitFrames) {
+  CompleteHandshake();
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  session_.SendWindowUpdate(stream2->id(), 9);
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+  QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1));
+  frames.push_back(QuicFrame(window_update));
+  frames.push_back(QuicFrame(frame2));
+  frames.push_back(QuicFrame(frame3));
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+
+  EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
+}
+
+// Regression test of b/110082001.
+TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) {
+  CompleteHandshake();
+  // This test mimics the scenario when a dynamic stream retransmits lost data
+  // and causes connection close.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamFrame frame(stream->id(), false, 0, 9);
+
+  EXPECT_CALL(*stream, HasPendingRetransmission())
+      .Times(2)
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  session_.OnFrameLost(QuicFrame(frame));
+  // Retransmit stream data causes connection close. Stream has not sent fin
+  // yet, so an RST is sent.
+  EXPECT_CALL(*stream, OnCanWrite()).WillOnce(Invoke([this, stream]() {
+    session_.ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
+  }));
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Once for the RST_STREAM, once for the STOP_SENDING
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .Times(2)
+        .WillRepeatedly(Invoke(&session_, &TestSession::SaveFrame));
+  } else {
+    // Just for the RST_STREAM
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(&session_, &TestSession::SaveFrame));
+  }
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, SendMessage) {
+  // Cannot send message when encryption is not established.
+  EXPECT_FALSE(session_.OneRttKeysAvailable());
+  EXPECT_EQ(MessageResult(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0),
+            session_.SendMessage(MemSliceFromString("")));
+
+  CompleteHandshake();
+  EXPECT_TRUE(session_.OneRttKeysAvailable());
+
+  EXPECT_CALL(*connection_, SendMessage(1, _, false))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
+            session_.SendMessage(MemSliceFromString("")));
+  // Verify message_id increases.
+  EXPECT_CALL(*connection_, SendMessage(2, _, false))
+      .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
+  EXPECT_EQ(MessageResult(MESSAGE_STATUS_TOO_LARGE, 0),
+            session_.SendMessage(MemSliceFromString("")));
+  // Verify unsent message does not consume a message_id.
+  EXPECT_CALL(*connection_, SendMessage(2, _, false))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 2),
+            session_.SendMessage(MemSliceFromString("")));
+
+  QuicMessageFrame frame(1);
+  QuicMessageFrame frame2(2);
+  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
+  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
+
+  // Lost message 2.
+  session_.OnMessageLost(2);
+  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
+
+  // message 1 gets acked.
+  session_.OnMessageAcked(1, QuicTime::Zero());
+  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
+}
+
+// Regression test of b/115323618.
+TEST_P(QuicSessionTestServer, LocallyResetZombieStreams) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  std::string body(100, '.');
+  QuicStreamPeer::CloseReadSide(stream2);
+  stream2->WriteOrBufferData(body, true, nullptr);
+  EXPECT_TRUE(stream2->IsWaitingForAcks());
+  // Verify stream2 is a zombie streams.
+  auto& stream_map = QuicSessionPeer::stream_map(&session_);
+  ASSERT_TRUE(stream_map.contains(stream2->id()));
+  auto* stream = stream_map.find(stream2->id())->second.get();
+  EXPECT_TRUE(stream->IsZombie());
+
+  QuicStreamFrame frame(stream2->id(), true, 0, 100);
+  EXPECT_CALL(*stream2, HasPendingRetransmission())
+      .WillRepeatedly(Return(true));
+  session_.OnFrameLost(QuicFrame(frame));
+
+  // Reset stream2 locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
+  stream2->Reset(QUIC_STREAM_CANCELLED);
+
+  // Verify stream 2 gets closed.
+  EXPECT_TRUE(session_.IsClosedStream(stream2->id()));
+  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, CleanUpClosedStreamsAlarm) {
+  CompleteHandshake();
+  EXPECT_FALSE(
+      QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
+
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_FALSE(stream2->IsWaitingForAcks());
+
+  CloseStream(stream2->id());
+  EXPECT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_TRUE(
+      QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
+
+  alarm_factory_.FireAlarm(
+      QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_));
+  EXPECT_TRUE(session_.closed_streams()->empty());
+}
+
+TEST_P(QuicSessionTestServer, WriteUnidirectionalStream) {
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
+                                       &session_, WRITE_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+  std::string body(100, '.');
+  stream4->WriteOrBufferData(body, false, nullptr);
+  stream4->WriteOrBufferData(body, true, nullptr);
+  auto& stream_map = QuicSessionPeer::stream_map(&session_);
+  ASSERT_TRUE(stream_map.contains(stream4->id()));
+  auto* stream = stream_map.find(stream4->id())->second.get();
+  EXPECT_TRUE(stream->IsZombie());
+}
+
+TEST_P(QuicSessionTestServer, ReceivedDataOnWriteUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
+                                       &session_, WRITE_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _))
+      .Times(1);
+  QuicStreamFrame stream_frame(GetNthServerInitiatedUnidirectionalId(1), false,
+                               0, 2);
+  session_.OnStreamFrame(stream_frame);
+}
+
+TEST_P(QuicSessionTestServer, ReadUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
+                                       &session_, READ_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+  EXPECT_FALSE(stream4->IsWaitingForAcks());
+  // Discard all incoming data.
+  stream4->StopReading();
+
+  std::string data(100, '.');
+  QuicStreamFrame stream_frame(GetNthClientInitiatedUnidirectionalId(1), false,
+                               0, data);
+  stream4->OnStreamFrame(stream_frame);
+  EXPECT_TRUE(session_.closed_streams()->empty());
+
+  QuicStreamFrame stream_frame2(GetNthClientInitiatedUnidirectionalId(1), true,
+                                100, data);
+  stream4->OnStreamFrame(stream_frame2);
+  EXPECT_EQ(1u, session_.closed_streams()->size());
+}
+
+TEST_P(QuicSessionTestServer, WriteOrBufferDataOnReadUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
+                                       &session_, READ_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
+      .Times(1);
+  std::string body(100, '.');
+  stream4->WriteOrBufferData(body, false, nullptr);
+}
+
+TEST_P(QuicSessionTestServer, WritevDataOnReadUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
+                                       &session_, READ_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
+      .Times(1);
+  std::string body(100, '.');
+  struct iovec iov = {const_cast<char*>(body.data()), body.length()};
+  quiche::QuicheMemSliceStorage storage(
+      &iov, 1, session_.connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  stream4->WriteMemSlices(storage.ToSpan(), false);
+}
+
+TEST_P(QuicSessionTestServer, WriteMemSlicesOnReadUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
+                                       &session_, READ_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
+      .Times(1);
+  std::string data(1024, 'a');
+  std::vector<quiche::QuicheMemSlice> buffers;
+  buffers.push_back(MemSliceFromString(data));
+  buffers.push_back(MemSliceFromString(data));
+  stream4->WriteMemSlices(absl::MakeSpan(buffers), false);
+}
+
+// Test code that tests that an incoming stream frame with a new (not previously
+// seen) stream id is acceptable. The ID must not be larger than has been
+// advertised. It may be equal to what has been advertised.  These tests
+// invoke QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId by calling
+// QuicSession::OnStreamFrame in order to check that all the steps are connected
+// properly and that nothing in the call path interferes with the check.
+// First test make sure that streams with ids below the limit are accepted.
+TEST_P(QuicSessionTestServer, NewStreamIdBelowLimit) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Applicable only to IETF QUIC
+    return;
+  }
+  QuicStreamId bidirectional_stream_id = StreamCountToId(
+      QuicSessionPeer::ietf_streamid_manager(&session_)
+              ->advertised_max_incoming_bidirectional_streams() -
+          1,
+      Perspective::IS_CLIENT,
+      /*bidirectional=*/true);
+
+  QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
+                                             "Random String");
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStreamFrame(bidirectional_stream_frame);
+
+  QuicStreamId unidirectional_stream_id = StreamCountToId(
+      QuicSessionPeer::ietf_streamid_manager(&session_)
+              ->advertised_max_incoming_unidirectional_streams() -
+          1,
+      Perspective::IS_CLIENT,
+      /*bidirectional=*/false);
+  QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
+                                              0, "Random String");
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStreamFrame(unidirectional_stream_frame);
+}
+
+// Accept a stream with an ID that equals the limit.
+TEST_P(QuicSessionTestServer, NewStreamIdAtLimit) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Applicable only to IETF QUIC
+    return;
+  }
+  QuicStreamId bidirectional_stream_id =
+      StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                          ->advertised_max_incoming_bidirectional_streams(),
+                      Perspective::IS_CLIENT, /*bidirectional=*/true);
+  QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
+                                             "Random String");
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStreamFrame(bidirectional_stream_frame);
+
+  QuicStreamId unidirectional_stream_id =
+      StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                          ->advertised_max_incoming_unidirectional_streams(),
+                      Perspective::IS_CLIENT, /*bidirectional=*/false);
+  QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
+                                              0, "Random String");
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStreamFrame(unidirectional_stream_frame);
+}
+
+// Close the connection if the id exceeds the limit.
+TEST_P(QuicSessionTestServer, NewStreamIdAboveLimit) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Applicable only to IETF QUIC
+    return;
+  }
+
+  QuicStreamId bidirectional_stream_id = StreamCountToId(
+      QuicSessionPeer::ietf_streamid_manager(&session_)
+              ->advertised_max_incoming_bidirectional_streams() +
+          1,
+      Perspective::IS_CLIENT, /*bidirectional=*/true);
+  QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
+                                             "Random String");
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Stream id 400 would exceed stream count limit 100", _));
+  session_.OnStreamFrame(bidirectional_stream_frame);
+
+  QuicStreamId unidirectional_stream_id = StreamCountToId(
+      QuicSessionPeer::ietf_streamid_manager(&session_)
+              ->advertised_max_incoming_unidirectional_streams() +
+          1,
+      Perspective::IS_CLIENT, /*bidirectional=*/false);
+  QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
+                                              0, "Random String");
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Stream id 402 would exceed stream count limit 100", _));
+  session_.OnStreamFrame(unidirectional_stream_frame);
+}
+
+// Checks that invalid stream ids are handled.
+TEST_P(QuicSessionTestServer, OnStopSendingInvalidStreamId) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  // Check that "invalid" stream ids are rejected.
+  QuicStopSendingFrame frame(1, -1, QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Received STOP_SENDING for an invalid stream", _));
+  session_.OnStopSendingFrame(frame);
+}
+
+TEST_P(QuicSessionTestServer, OnStopSendingReadUnidirectional) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  // It's illegal to send STOP_SENDING with a stream ID that is read-only.
+  QuicStopSendingFrame frame(1, GetNthClientInitiatedUnidirectionalId(1),
+                             QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Received STOP_SENDING for a read-only stream", _));
+  session_.OnStopSendingFrame(frame);
+}
+
+// Static streams ignore STOP_SENDING.
+TEST_P(QuicSessionTestServer, OnStopSendingStaticStreams) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  QuicStreamId stream_id = 0;
+  std::unique_ptr<TestStream> fake_static_stream = std::make_unique<TestStream>(
+      stream_id, &session_, /*is_static*/ true, BIDIRECTIONAL);
+  QuicSessionPeer::ActivateStream(&session_, std::move(fake_static_stream));
+  // Check that a stream id in the static stream map is ignored.
+  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_STREAM_ID,
+                              "Received STOP_SENDING for a static stream", _));
+  session_.OnStopSendingFrame(frame);
+}
+
+// If stream is write closed, do not send a RESET_STREAM frame.
+TEST_P(QuicSessionTestServer, OnStopSendingForWriteClosedStream) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+  QuicStreamPeer::SetFinSent(stream);
+  stream->CloseWriteSide();
+  EXPECT_TRUE(stream->write_side_closed());
+  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStopSendingFrame(frame);
+}
+
+// If stream is closed, return true and do not close the connection.
+TEST_P(QuicSessionTestServer, OnStopSendingClosedStream) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+  CloseStream(stream_id);
+  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStopSendingFrame(frame);
+}
+
+// If stream id is a nonexistent local stream, return false and close the
+// connection.
+TEST_P(QuicSessionTestServer, OnStopSendingInputNonExistentLocalStream) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+
+  QuicStopSendingFrame frame(1, GetNthServerInitiatedBidirectionalId(123456),
+                             QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_STREAM_WRONG_DIRECTION,
+                                            "Data for nonexistent stream", _))
+      .Times(1);
+  session_.OnStopSendingFrame(frame);
+}
+
+// If a STOP_SENDING is received for a peer initiated stream, the new stream
+// will be created.
+TEST_P(QuicSessionTestServer, OnStopSendingNewStream) {
+  CompleteHandshake();
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  QuicStopSendingFrame frame(1, GetNthClientInitiatedBidirectionalId(1),
+                             QUIC_STREAM_CANCELLED);
+
+  // A Rst will be sent as a response for STOP_SENDING.
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
+  session_.OnStopSendingFrame(frame);
+
+  QuicStream* stream =
+      session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(1));
+  EXPECT_TRUE(stream);
+  EXPECT_TRUE(stream->write_side_closed());
+}
+
+// For a valid stream, ensure that all works
+TEST_P(QuicSessionTestServer, OnStopSendingInputValidStream) {
+  CompleteHandshake();
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Applicable only to IETF QUIC
+    return;
+  }
+
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  // Ensure that the stream starts out open in both directions.
+  EXPECT_FALSE(stream->write_side_closed());
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
+
+  QuicStreamId stream_id = stream->id();
+  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
+  // Expect a reset to come back out.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_STREAM_CANCELLED));
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStopSendingFrame(frame);
+
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
+  EXPECT_TRUE(stream->write_side_closed());
+}
+
+TEST_P(QuicSessionTestServer, WriteBufferedCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  std::string data(1350, 'a');
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  // Only consumed 1000 bytes.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Return(1000));
+  crypto_stream->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  EXPECT_TRUE(session_.HasPendingHandshake());
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  connection_->SetEncrypter(
+      ENCRYPTION_ZERO_RTT,
+      std::make_unique<NullEncrypter>(connection_->perspective()));
+  crypto_stream->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
+      .WillOnce(Return(350));
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Return(1350));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.HasPendingHandshake());
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+// Regression test for
+// https://bugs.chromium.org/p/chromium/issues/detail?id=1002119
+TEST_P(QuicSessionTestServer, StreamFrameReceivedAfterFin) {
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamFrame frame(stream->id(), true, 0, ",");
+  session_.OnStreamFrame(frame);
+
+  QuicStreamFrame frame1(stream->id(), false, 1, ",");
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET, _, _));
+  session_.OnStreamFrame(frame1);
+}
+
+TEST_P(QuicSessionTestServer, ResetForIETFStreamTypes) {
+  CompleteHandshake();
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+
+  QuicStreamId read_only = GetNthClientInitiatedUnidirectionalId(0);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(1)
+      .WillOnce(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(read_only, _));
+  session_.ResetStream(read_only, QUIC_STREAM_CANCELLED);
+
+  QuicStreamId write_only = GetNthServerInitiatedUnidirectionalId(0);
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(1)
+      .WillOnce(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(write_only, _));
+  session_.ResetStream(write_only, QUIC_STREAM_CANCELLED);
+
+  QuicStreamId bidirectional = GetNthClientInitiatedBidirectionalId(0);
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(bidirectional, _));
+  session_.ResetStream(bidirectional, QUIC_STREAM_CANCELLED);
+}
+
+TEST_P(QuicSessionTestServer, DecryptionKeyAvailableBeforeEncryptionKey) {
+  if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
+    return;
+  }
+  ASSERT_FALSE(connection_->framer().HasEncrypterOfEncryptionLevel(
+      ENCRYPTION_HANDSHAKE));
+  EXPECT_FALSE(session_.OnNewDecryptionKeyAvailable(
+      ENCRYPTION_HANDSHAKE, /*decrypter=*/nullptr,
+      /*set_alternative_decrypter=*/false, /*latch_once_used=*/false));
+}
+
+TEST_P(QuicSessionTestServer, IncomingStreamWithServerInitiatedStreamId) {
+  const QuicErrorCode expected_error =
+      VersionHasIetfQuicFrames(transport_version())
+          ? QUIC_HTTP_STREAM_WRONG_DIRECTION
+          : QUIC_INVALID_STREAM_ID;
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(expected_error, "Data for nonexistent stream",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  QuicStreamFrame frame(GetNthServerInitiatedBidirectionalId(1),
+                        /* fin = */ false, /* offset = */ 0,
+                        absl::string_view("foo"));
+  session_.OnStreamFrame(frame);
+}
+
+// A client test class that can be used when the automatic configuration is not
+// desired.
+class QuicSessionTestClientUnconfigured : public QuicSessionTestBase {
+ protected:
+  QuicSessionTestClientUnconfigured()
+      : QuicSessionTestBase(Perspective::IS_CLIENT,
+                            /*configure_session=*/false) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSessionTestClientUnconfigured,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSessionTestClientUnconfigured, StreamInitiallyBlockedThenUnblocked) {
+  if (!connection_->version().AllowsLowFlowControlLimits()) {
+    return;
+  }
+  // Create a stream before negotiating the config and verify it starts off
+  // blocked.
+  QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams(&session_, 10);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_TRUE(stream2->IsFlowControlBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Negotiate the config with higher received limits.
+  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+      session_.config(), kMinimumFlowControlSendWindow);
+  QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+      session_.config(), kMinimumFlowControlSendWindow);
+  session_.OnConfigNegotiated();
+
+  // Stream is now unblocked.
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_socket_address_coder.cc b/quiche/quic/core/quic_socket_address_coder.cc
new file mode 100644
index 0000000..9bf85b2
--- /dev/null
+++ b/quiche/quic/core/quic_socket_address_coder.cc
@@ -0,0 +1,92 @@
+// 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 "quiche/quic/core/quic_socket_address_coder.h"
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+
+namespace quic {
+
+namespace {
+
+// For convenience, the values of these constants match the values of AF_INET
+// and AF_INET6 on Linux.
+const uint16_t kIPv4 = 2;
+const uint16_t kIPv6 = 10;
+
+}  // namespace
+
+QuicSocketAddressCoder::QuicSocketAddressCoder() {}
+
+QuicSocketAddressCoder::QuicSocketAddressCoder(const QuicSocketAddress& address)
+    : address_(address) {}
+
+QuicSocketAddressCoder::~QuicSocketAddressCoder() {}
+
+std::string QuicSocketAddressCoder::Encode() const {
+  std::string serialized;
+  uint16_t address_family;
+  switch (address_.host().address_family()) {
+    case IpAddressFamily::IP_V4:
+      address_family = kIPv4;
+      break;
+    case IpAddressFamily::IP_V6:
+      address_family = kIPv6;
+      break;
+    default:
+      return serialized;
+  }
+  serialized.append(reinterpret_cast<const char*>(&address_family),
+                    sizeof(address_family));
+  serialized.append(address_.host().ToPackedString());
+  uint16_t port = address_.port();
+  serialized.append(reinterpret_cast<const char*>(&port), sizeof(port));
+  return serialized;
+}
+
+bool QuicSocketAddressCoder::Decode(const char* data, size_t length) {
+  uint16_t address_family;
+  if (length < sizeof(address_family)) {
+    return false;
+  }
+  memcpy(&address_family, data, sizeof(address_family));
+  data += sizeof(address_family);
+  length -= sizeof(address_family);
+
+  size_t ip_length;
+  switch (address_family) {
+    case kIPv4:
+      ip_length = QuicIpAddress::kIPv4AddressSize;
+      break;
+    case kIPv6:
+      ip_length = QuicIpAddress::kIPv6AddressSize;
+      break;
+    default:
+      return false;
+  }
+  if (length < ip_length) {
+    return false;
+  }
+  std::vector<uint8_t> ip(ip_length);
+  memcpy(&ip[0], data, ip_length);
+  data += ip_length;
+  length -= ip_length;
+
+  uint16_t port;
+  if (length != sizeof(port)) {
+    return false;
+  }
+  memcpy(&port, data, length);
+
+  QuicIpAddress ip_address;
+  ip_address.FromPackedString(reinterpret_cast<const char*>(&ip[0]), ip_length);
+  address_ = QuicSocketAddress(ip_address, port);
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_socket_address_coder.h b/quiche/quic/core/quic_socket_address_coder.h
new file mode 100644
index 0000000..b56ee6a
--- /dev/null
+++ b/quiche/quic/core/quic_socket_address_coder.h
@@ -0,0 +1,42 @@
+// 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_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
+#define QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
+
+#include <cstdint>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// Serializes and parses a socket address (IP address and port), to be used in
+// the kCADR tag in the ServerHello handshake message and the Public Reset
+// packet.
+class QUIC_EXPORT_PRIVATE QuicSocketAddressCoder {
+ public:
+  QuicSocketAddressCoder();
+  explicit QuicSocketAddressCoder(const QuicSocketAddress& address);
+  QuicSocketAddressCoder(const QuicSocketAddressCoder&) = delete;
+  QuicSocketAddressCoder& operator=(const QuicSocketAddressCoder&) = delete;
+  ~QuicSocketAddressCoder();
+
+  std::string Encode() const;
+
+  bool Decode(const char* data, size_t length);
+
+  QuicIpAddress ip() const { return address_.host(); }
+
+  uint16_t port() const { return address_.port(); }
+
+ private:
+  QuicSocketAddress address_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
diff --git a/quiche/quic/core/quic_socket_address_coder_test.cc b/quiche/quic/core/quic_socket_address_coder_test.cc
new file mode 100644
index 0000000..32f3570
--- /dev/null
+++ b/quiche/quic/core/quic_socket_address_coder_test.cc
@@ -0,0 +1,130 @@
+// 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 "quiche/quic/core/quic_socket_address_coder.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QuicSocketAddressCoderTest : public QuicTest {};
+
+TEST_F(QuicSocketAddressCoderTest, EncodeIPv4) {
+  QuicIpAddress ip;
+  ip.FromString("4.31.198.44");
+  QuicSocketAddressCoder coder(QuicSocketAddress(ip, 0x1234));
+  std::string serialized = coder.Encode();
+  std::string expected("\x02\x00\x04\x1f\xc6\x2c\x34\x12", 8);
+  EXPECT_EQ(expected, serialized);
+}
+
+TEST_F(QuicSocketAddressCoderTest, EncodeIPv6) {
+  QuicIpAddress ip;
+  ip.FromString("2001:700:300:1800::f");
+  QuicSocketAddressCoder coder(QuicSocketAddress(ip, 0x5678));
+  std::string serialized = coder.Encode();
+  std::string expected(
+      "\x0a\x00"
+      "\x20\x01\x07\x00\x03\x00\x18\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x0f"
+      "\x78\x56",
+      20);
+  EXPECT_EQ(expected, serialized);
+}
+
+TEST_F(QuicSocketAddressCoderTest, DecodeIPv4) {
+  std::string serialized("\x02\x00\x04\x1f\xc6\x2c\x34\x12", 8);
+  QuicSocketAddressCoder coder;
+  ASSERT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+  EXPECT_EQ(IpAddressFamily::IP_V4, coder.ip().address_family());
+  std::string expected_addr("\x04\x1f\xc6\x2c");
+  EXPECT_EQ(expected_addr, coder.ip().ToPackedString());
+  EXPECT_EQ(0x1234, coder.port());
+}
+
+TEST_F(QuicSocketAddressCoderTest, DecodeIPv6) {
+  std::string serialized(
+      "\x0a\x00"
+      "\x20\x01\x07\x00\x03\x00\x18\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x0f"
+      "\x78\x56",
+      20);
+  QuicSocketAddressCoder coder;
+  ASSERT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+  EXPECT_EQ(IpAddressFamily::IP_V6, coder.ip().address_family());
+  std::string expected_addr(
+      "\x20\x01\x07\x00\x03\x00\x18\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x0f",
+      16);
+  EXPECT_EQ(expected_addr, coder.ip().ToPackedString());
+  EXPECT_EQ(0x5678, coder.port());
+}
+
+TEST_F(QuicSocketAddressCoderTest, DecodeBad) {
+  std::string serialized(
+      "\x0a\x00"
+      "\x20\x01\x07\x00\x03\x00\x18\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x0f"
+      "\x78\x56",
+      20);
+  QuicSocketAddressCoder coder;
+  EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+  // Append junk.
+  serialized.push_back('\0');
+  EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
+  // Undo.
+  serialized.resize(20);
+  EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+
+  // Set an unknown address family.
+  serialized[0] = '\x03';
+  EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
+  // Undo.
+  serialized[0] = '\x0a';
+  EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+
+  // Truncate.
+  size_t len = serialized.length();
+  for (size_t i = 0; i < len; i++) {
+    ASSERT_FALSE(serialized.empty());
+    serialized.erase(serialized.length() - 1);
+    EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
+  }
+  EXPECT_TRUE(serialized.empty());
+}
+
+TEST_F(QuicSocketAddressCoderTest, EncodeAndDecode) {
+  struct {
+    const char* ip_literal;
+    uint16_t port;
+  } test_case[] = {
+      {"93.184.216.119", 0x1234},
+      {"199.204.44.194", 80},
+      {"149.20.4.69", 443},
+      {"127.0.0.1", 8080},
+      {"2001:700:300:1800::", 0x5678},
+      {"::1", 65534},
+  };
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_case); i++) {
+    QuicIpAddress ip;
+    ASSERT_TRUE(ip.FromString(test_case[i].ip_literal));
+    QuicSocketAddressCoder encoder(QuicSocketAddress(ip, test_case[i].port));
+    std::string serialized = encoder.Encode();
+
+    QuicSocketAddressCoder decoder;
+    ASSERT_TRUE(decoder.Decode(serialized.data(), serialized.length()));
+    EXPECT_EQ(encoder.ip(), decoder.ip());
+    EXPECT_EQ(encoder.port(), decoder.port());
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream.cc b/quiche/quic/core/quic_stream.cc
new file mode 100644
index 0000000..7d1a9dd
--- /dev/null
+++ b/quiche/quic/core/quic_stream.cc
@@ -0,0 +1,1459 @@
+// 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 "quiche/quic/core/quic_stream.h"
+
+#include <limits>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_flow_controller.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+using spdy::SpdyPriority;
+
+namespace quic {
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+namespace {
+
+QuicByteCount DefaultFlowControlWindow(ParsedQuicVersion version) {
+  if (!version.AllowsLowFlowControlLimits()) {
+    return kDefaultFlowControlSendWindow;
+  }
+  return 0;
+}
+
+QuicByteCount GetInitialStreamFlowControlWindowToSend(QuicSession* session,
+                                                      QuicStreamId stream_id) {
+  ParsedQuicVersion version = session->connection()->version();
+  if (version.handshake_protocol != PROTOCOL_TLS1_3) {
+    return session->config()->GetInitialStreamFlowControlWindowToSend();
+  }
+
+  // Unidirectional streams (v99 only).
+  if (VersionHasIetfQuicFrames(version.transport_version) &&
+      !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
+    return session->config()
+        ->GetInitialMaxStreamDataBytesUnidirectionalToSend();
+  }
+
+  if (QuicUtils::IsOutgoingStreamId(version, stream_id,
+                                    session->perspective())) {
+    return session->config()
+        ->GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend();
+  }
+
+  return session->config()
+      ->GetInitialMaxStreamDataBytesIncomingBidirectionalToSend();
+}
+
+QuicByteCount GetReceivedFlowControlWindow(QuicSession* session,
+                                           QuicStreamId stream_id) {
+  ParsedQuicVersion version = session->connection()->version();
+  if (version.handshake_protocol != PROTOCOL_TLS1_3) {
+    if (session->config()->HasReceivedInitialStreamFlowControlWindowBytes()) {
+      return session->config()->ReceivedInitialStreamFlowControlWindowBytes();
+    }
+
+    return DefaultFlowControlWindow(version);
+  }
+
+  // Unidirectional streams (v99 only).
+  if (VersionHasIetfQuicFrames(version.transport_version) &&
+      !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
+    if (session->config()
+            ->HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
+      return session->config()
+          ->ReceivedInitialMaxStreamDataBytesUnidirectional();
+    }
+
+    return DefaultFlowControlWindow(version);
+  }
+
+  if (QuicUtils::IsOutgoingStreamId(version, stream_id,
+                                    session->perspective())) {
+    if (session->config()
+            ->HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) {
+      return session->config()
+          ->ReceivedInitialMaxStreamDataBytesOutgoingBidirectional();
+    }
+
+    return DefaultFlowControlWindow(version);
+  }
+
+  if (session->config()
+          ->HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) {
+    return session->config()
+        ->ReceivedInitialMaxStreamDataBytesIncomingBidirectional();
+  }
+
+  return DefaultFlowControlWindow(version);
+}
+
+}  // namespace
+
+// static
+const SpdyPriority QuicStream::kDefaultPriority;
+
+// static
+const int QuicStream::kDefaultUrgency;
+
+PendingStream::PendingStream(QuicStreamId id, QuicSession* session)
+    : id_(id),
+      version_(session->version()),
+      stream_delegate_(session),
+      stream_bytes_read_(0),
+      fin_received_(false),
+      is_bidirectional_(QuicUtils::GetStreamType(id, session->perspective(),
+                                                 /*peer_initiated = */ true,
+                                                 session->version()) ==
+                        BIDIRECTIONAL),
+      connection_flow_controller_(session->flow_controller()),
+      flow_controller_(session, id,
+                       /*is_connection_flow_controller*/ false,
+                       GetReceivedFlowControlWindow(session, id),
+                       GetInitialStreamFlowControlWindowToSend(session, id),
+                       kStreamReceiveWindowLimit,
+                       session->flow_controller()->auto_tune_receive_window(),
+                       session->flow_controller()),
+      sequencer_(this) {}
+
+void PendingStream::OnDataAvailable() {
+  // Data should be kept in the sequencer so that
+  // QuicSession::ProcessPendingStream() can read it.
+}
+
+void PendingStream::OnFinRead() { QUICHE_DCHECK(sequencer_.IsClosed()); }
+
+void PendingStream::AddBytesConsumed(QuicByteCount bytes) {
+  // It will be called when the metadata of the stream is consumed.
+  flow_controller_.AddBytesConsumed(bytes);
+  connection_flow_controller_->AddBytesConsumed(bytes);
+}
+
+void PendingStream::ResetWithError(QuicResetStreamError /*error*/) {
+  // Currently PendingStream is only read-unidirectional. It shouldn't send
+  // Reset.
+  QUIC_NOTREACHED();
+}
+
+void PendingStream::OnUnrecoverableError(QuicErrorCode error,
+                                         const std::string& details) {
+  stream_delegate_->OnStreamError(error, details);
+}
+
+void PendingStream::OnUnrecoverableError(QuicErrorCode error,
+                                         QuicIetfTransportErrorCodes ietf_error,
+                                         const std::string& details) {
+  stream_delegate_->OnStreamError(error, ietf_error, details);
+}
+
+QuicStreamId PendingStream::id() const { return id_; }
+
+ParsedQuicVersion PendingStream::version() const { return version_; }
+
+void PendingStream::OnStreamFrame(const QuicStreamFrame& frame) {
+  QUICHE_DCHECK_EQ(frame.stream_id, id_);
+
+  bool is_stream_too_long =
+      (frame.offset > kMaxStreamLength) ||
+      (kMaxStreamLength - frame.offset < frame.data_length);
+  if (is_stream_too_long) {
+    // Close connection if stream becomes too long.
+    QUIC_PEER_BUG(quic_peer_bug_12570_1)
+        << "Receive stream frame reaches max stream length. frame offset "
+        << frame.offset << " length " << frame.data_length;
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Peer sends more data than allowed on this stream.");
+    return;
+  }
+
+  if (frame.offset + frame.data_length > sequencer_.close_offset()) {
+    OnUnrecoverableError(
+        QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
+        absl::StrCat(
+            "Stream ", id_,
+            " received data with offset: ", frame.offset + frame.data_length,
+            ", which is beyond close offset: ", sequencer()->close_offset()));
+    return;
+  }
+
+  if (frame.fin) {
+    fin_received_ = true;
+  }
+
+  // This count includes duplicate data received.
+  QuicByteCount frame_payload_size = frame.data_length;
+  stream_bytes_read_ += frame_payload_size;
+
+  // Flow control is interested in tracking highest received offset.
+  // Only interested in received frames that carry data.
+  if (frame_payload_size > 0 &&
+      MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
+    // As the highest received offset has changed, check to see if this is a
+    // violation of flow control.
+    if (flow_controller_.FlowControlViolation() ||
+        connection_flow_controller_->FlowControlViolation()) {
+      OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                           "Flow control violation after increasing offset");
+      return;
+    }
+  }
+
+  sequencer_.OnStreamFrame(frame);
+}
+
+void PendingStream::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
+  QUICHE_DCHECK_EQ(frame.stream_id, id_);
+
+  if (frame.byte_offset > kMaxStreamLength) {
+    // Peer are not suppose to write bytes more than maxium allowed.
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Reset frame stream offset overflow.");
+    return;
+  }
+
+  const QuicStreamOffset kMaxOffset =
+      std::numeric_limits<QuicStreamOffset>::max();
+  if (sequencer()->close_offset() != kMaxOffset &&
+      frame.byte_offset != sequencer()->close_offset()) {
+    OnUnrecoverableError(
+        QUIC_STREAM_MULTIPLE_OFFSET,
+        absl::StrCat("Stream ", id_,
+                     " received new final offset: ", frame.byte_offset,
+                     ", which is different from close offset: ",
+                     sequencer()->close_offset()));
+    return;
+  }
+
+  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
+  if (flow_controller_.FlowControlViolation() ||
+      connection_flow_controller_->FlowControlViolation()) {
+    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                         "Flow control violation after increasing offset");
+    return;
+  }
+}
+
+void PendingStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
+  QUICHE_DCHECK(is_bidirectional_);
+  flow_controller_.UpdateSendWindowOffset(frame.max_data);
+}
+
+bool PendingStream::MaybeIncreaseHighestReceivedOffset(
+    QuicStreamOffset new_offset) {
+  uint64_t increment =
+      new_offset - flow_controller_.highest_received_byte_offset();
+  if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) {
+    return false;
+  }
+
+  // If |new_offset| increased the stream flow controller's highest received
+  // offset, increase the connection flow controller's value by the incremental
+  // difference.
+  connection_flow_controller_->UpdateHighestReceivedOffset(
+      connection_flow_controller_->highest_received_byte_offset() + increment);
+  return true;
+}
+
+void PendingStream::OnStopSending(
+    QuicResetStreamError stop_sending_error_code) {
+  if (!stop_sending_error_code_) {
+    stop_sending_error_code_ = stop_sending_error_code;
+  }
+}
+
+void PendingStream::MarkConsumed(QuicByteCount num_bytes) {
+  sequencer_.MarkConsumed(num_bytes);
+}
+
+void PendingStream::StopReading() {
+  QUIC_DVLOG(1) << "Stop reading from pending stream " << id();
+  sequencer_.StopReading();
+}
+
+QuicStream::QuicStream(PendingStream* pending, QuicSession* session,
+                       bool is_static)
+    : QuicStream(pending->id_, session, std::move(pending->sequencer_),
+                 is_static,
+                 QuicUtils::GetStreamType(pending->id_, session->perspective(),
+                                          /*peer_initiated = */ true,
+                                          session->version()),
+                 pending->stream_bytes_read_, pending->fin_received_,
+                 std::move(pending->flow_controller_),
+                 pending->connection_flow_controller_) {
+  QUICHE_DCHECK(session->version().HasIetfQuicFrames());
+  sequencer_.set_stream(this);
+}
+
+namespace {
+
+absl::optional<QuicFlowController> FlowController(QuicStreamId id,
+                                                  QuicSession* session,
+                                                  StreamType type) {
+  if (type == CRYPTO) {
+    // The only QuicStream with a StreamType of CRYPTO is QuicCryptoStream, when
+    // it is using crypto frames instead of stream frames. The QuicCryptoStream
+    // doesn't have any flow control in that case, so we don't create a
+    // QuicFlowController for it.
+    return absl::nullopt;
+  }
+  return QuicFlowController(
+      session, id,
+      /*is_connection_flow_controller*/ false,
+      GetReceivedFlowControlWindow(session, id),
+      GetInitialStreamFlowControlWindowToSend(session, id),
+      kStreamReceiveWindowLimit,
+      session->flow_controller()->auto_tune_receive_window(),
+      session->flow_controller());
+}
+
+}  // namespace
+
+QuicStream::QuicStream(QuicStreamId id, QuicSession* session, bool is_static,
+                       StreamType type)
+    : QuicStream(id, session, QuicStreamSequencer(this), is_static, type, 0,
+                 false, FlowController(id, session, type),
+                 session->flow_controller()) {}
+
+QuicStream::QuicStream(QuicStreamId id, QuicSession* session,
+                       QuicStreamSequencer sequencer, bool is_static,
+                       StreamType type, uint64_t stream_bytes_read,
+                       bool fin_received,
+                       absl::optional<QuicFlowController> flow_controller,
+                       QuicFlowController* connection_flow_controller)
+    : sequencer_(std::move(sequencer)),
+      id_(id),
+      session_(session),
+      stream_delegate_(session),
+      precedence_(CalculateDefaultPriority(session)),
+      stream_bytes_read_(stream_bytes_read),
+      stream_error_(QuicResetStreamError::NoError()),
+      connection_error_(QUIC_NO_ERROR),
+      read_side_closed_(false),
+      write_side_closed_(false),
+      write_side_data_recvd_state_notified_(false),
+      fin_buffered_(false),
+      fin_sent_(false),
+      fin_outstanding_(false),
+      fin_lost_(false),
+      fin_received_(fin_received),
+      rst_sent_(false),
+      rst_received_(false),
+      stop_sending_sent_(false),
+      flow_controller_(std::move(flow_controller)),
+      connection_flow_controller_(connection_flow_controller),
+      stream_contributes_to_connection_flow_control_(true),
+      busy_counter_(0),
+      add_random_padding_after_fin_(false),
+      send_buffer_(
+          session->connection()->helper()->GetStreamSendBufferAllocator()),
+      buffered_data_threshold_(GetQuicFlag(FLAGS_quic_buffered_data_threshold)),
+      is_static_(is_static),
+      deadline_(QuicTime::Zero()),
+      was_draining_(false),
+      type_(VersionHasIetfQuicFrames(session->transport_version()) &&
+                    type != CRYPTO
+                ? QuicUtils::GetStreamType(id_, session->perspective(),
+                                           session->IsIncomingStream(id_),
+                                           session->version())
+                : type),
+      creation_time_(session->connection()->clock()->ApproximateNow()),
+      perspective_(session->perspective()) {
+  if (type_ == WRITE_UNIDIRECTIONAL) {
+    fin_received_ = true;
+    CloseReadSide();
+  } else if (type_ == READ_UNIDIRECTIONAL) {
+    fin_sent_ = true;
+    CloseWriteSide();
+  }
+  if (type_ != CRYPTO) {
+    stream_delegate_->RegisterStreamPriority(id, is_static_, precedence_);
+  }
+}
+
+QuicStream::~QuicStream() {
+  if (session_ != nullptr && IsWaitingForAcks()) {
+    QUIC_DVLOG(1)
+        << ENDPOINT << "Stream " << id_
+        << " gets destroyed while waiting for acks. stream_bytes_outstanding = "
+        << send_buffer_.stream_bytes_outstanding()
+        << ", fin_outstanding: " << fin_outstanding_;
+  }
+  if (stream_delegate_ != nullptr && type_ != CRYPTO) {
+    stream_delegate_->UnregisterStreamPriority(id(), is_static_);
+  }
+}
+
+void QuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
+  QUICHE_DCHECK_EQ(frame.stream_id, id_);
+
+  QUICHE_DCHECK(!(read_side_closed_ && write_side_closed_));
+
+  if (frame.fin && is_static_) {
+    OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
+                         "Attempt to close a static stream");
+    return;
+  }
+
+  if (type_ == WRITE_UNIDIRECTIONAL) {
+    OnUnrecoverableError(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM,
+                         "Data received on write unidirectional stream");
+    return;
+  }
+
+  bool is_stream_too_long =
+      (frame.offset > kMaxStreamLength) ||
+      (kMaxStreamLength - frame.offset < frame.data_length);
+  if (is_stream_too_long) {
+    // Close connection if stream becomes too long.
+    QUIC_PEER_BUG(quic_peer_bug_10586_1)
+        << "Receive stream frame on stream " << id_
+        << " reaches max stream length. frame offset " << frame.offset
+        << " length " << frame.data_length << ". " << sequencer_.DebugString();
+    OnUnrecoverableError(
+        QUIC_STREAM_LENGTH_OVERFLOW,
+        absl::StrCat("Peer sends more data than allowed on stream ", id_,
+                     ". frame: offset = ", frame.offset, ", length = ",
+                     frame.data_length, ". ", sequencer_.DebugString()));
+    return;
+  }
+
+  if (frame.offset + frame.data_length > sequencer_.close_offset()) {
+    OnUnrecoverableError(
+        QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
+        absl::StrCat(
+            "Stream ", id_,
+            " received data with offset: ", frame.offset + frame.data_length,
+            ", which is beyond close offset: ", sequencer_.close_offset()));
+    return;
+  }
+
+  if (frame.fin && !fin_received_) {
+    fin_received_ = true;
+    if (fin_sent_) {
+      QUICHE_DCHECK(!was_draining_);
+      session_->StreamDraining(id_,
+                               /*unidirectional=*/type_ != BIDIRECTIONAL);
+      was_draining_ = true;
+    }
+  }
+
+  if (read_side_closed_) {
+    QUIC_DLOG(INFO)
+        << ENDPOINT << "Stream " << frame.stream_id
+        << " is closed for reading. Ignoring newly received stream data.";
+    // The subclass does not want to read data:  blackhole the data.
+    return;
+  }
+
+  // This count includes duplicate data received.
+  QuicByteCount frame_payload_size = frame.data_length;
+  stream_bytes_read_ += frame_payload_size;
+
+  // Flow control is interested in tracking highest received offset.
+  // Only interested in received frames that carry data.
+  if (frame_payload_size > 0 &&
+      MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
+    // As the highest received offset has changed, check to see if this is a
+    // violation of flow control.
+    QUIC_BUG_IF(quic_bug_12570_2, !flow_controller_.has_value())
+        << ENDPOINT << "OnStreamFrame called on stream without flow control";
+    if ((flow_controller_.has_value() &&
+         flow_controller_->FlowControlViolation()) ||
+        connection_flow_controller_->FlowControlViolation()) {
+      OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                           "Flow control violation after increasing offset");
+      return;
+    }
+  }
+
+  sequencer_.OnStreamFrame(frame);
+}
+
+bool QuicStream::OnStopSending(QuicResetStreamError error) {
+  // Do not reset the stream if all data has been sent and acknowledged.
+  if (write_side_closed() && !IsWaitingForAcks()) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Ignoring STOP_SENDING for a write closed stream, id: "
+                  << id_;
+    return false;
+  }
+
+  if (is_static_) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received STOP_SENDING for a static stream, id: " << id_
+                  << " Closing connection";
+    OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
+                         "Received STOP_SENDING for a static stream");
+    return false;
+  }
+
+  stream_error_ = error;
+  MaybeSendRstStream(error);
+  return true;
+}
+
+int QuicStream::num_frames_received() const {
+  return sequencer_.num_frames_received();
+}
+
+int QuicStream::num_duplicate_frames_received() const {
+  return sequencer_.num_duplicate_frames_received();
+}
+
+void QuicStream::OnStreamReset(const QuicRstStreamFrame& frame) {
+  rst_received_ = true;
+  if (frame.byte_offset > kMaxStreamLength) {
+    // Peer are not suppose to write bytes more than maxium allowed.
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Reset frame stream offset overflow.");
+    return;
+  }
+
+  const QuicStreamOffset kMaxOffset =
+      std::numeric_limits<QuicStreamOffset>::max();
+  if (sequencer()->close_offset() != kMaxOffset &&
+      frame.byte_offset != sequencer()->close_offset()) {
+    OnUnrecoverableError(
+        QUIC_STREAM_MULTIPLE_OFFSET,
+        absl::StrCat("Stream ", id_,
+                     " received new final offset: ", frame.byte_offset,
+                     ", which is different from close offset: ",
+                     sequencer_.close_offset()));
+    return;
+  }
+
+  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
+  QUIC_BUG_IF(quic_bug_12570_3, !flow_controller_.has_value())
+      << ENDPOINT << "OnStreamReset called on stream without flow control";
+  if ((flow_controller_.has_value() &&
+       flow_controller_->FlowControlViolation()) ||
+      connection_flow_controller_->FlowControlViolation()) {
+    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                         "Flow control violation after increasing offset");
+    return;
+  }
+
+  stream_error_ = frame.error();
+  // Google QUIC closes both sides of the stream in response to a
+  // RESET_STREAM, IETF QUIC closes only the read side.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    CloseWriteSide();
+  }
+  CloseReadSide();
+}
+
+void QuicStream::OnConnectionClosed(QuicErrorCode error,
+                                    ConnectionCloseSource /*source*/) {
+  if (read_side_closed_ && write_side_closed_) {
+    return;
+  }
+  if (error != QUIC_NO_ERROR) {
+    stream_error_ =
+        QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECTION_ERROR);
+    connection_error_ = error;
+  }
+
+  CloseWriteSide();
+  CloseReadSide();
+}
+
+void QuicStream::OnFinRead() {
+  QUICHE_DCHECK(sequencer_.IsClosed());
+  // OnFinRead can be called due to a FIN flag in a headers block, so there may
+  // have been no OnStreamFrame call with a FIN in the frame.
+  fin_received_ = true;
+  // If fin_sent_ is true, then CloseWriteSide has already been called, and the
+  // stream will be destroyed by CloseReadSide, so don't need to call
+  // StreamDraining.
+  CloseReadSide();
+}
+
+void QuicStream::SetFinSent() {
+  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
+  fin_sent_ = true;
+}
+
+void QuicStream::Reset(QuicRstStreamErrorCode error) {
+  ResetWithError(QuicResetStreamError::FromInternal(error));
+}
+
+void QuicStream::ResetWithError(QuicResetStreamError error) {
+  stream_error_ = error;
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  MaybeSendStopSending(error);
+  MaybeSendRstStream(error);
+
+  if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
+    session()->MaybeCloseZombieStream(id_);
+  }
+}
+
+void QuicStream::ResetWriteSide(QuicResetStreamError error) {
+  stream_error_ = error;
+  MaybeSendRstStream(error);
+
+  if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
+    session()->MaybeCloseZombieStream(id_);
+  }
+}
+
+void QuicStream::SendStopSending(QuicResetStreamError error) {
+  stream_error_ = error;
+  MaybeSendStopSending(error);
+
+  if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
+    session()->MaybeCloseZombieStream(id_);
+  }
+}
+
+void QuicStream::OnUnrecoverableError(QuicErrorCode error,
+                                      const std::string& details) {
+  stream_delegate_->OnStreamError(error, details);
+}
+
+void QuicStream::OnUnrecoverableError(QuicErrorCode error,
+                                      QuicIetfTransportErrorCodes ietf_error,
+                                      const std::string& details) {
+  stream_delegate_->OnStreamError(error, ietf_error, details);
+}
+
+const spdy::SpdyStreamPrecedence& QuicStream::precedence() const {
+  return precedence_;
+}
+
+void QuicStream::SetPriority(const spdy::SpdyStreamPrecedence& precedence) {
+  precedence_ = precedence;
+
+  MaybeSendPriorityUpdateFrame();
+
+  stream_delegate_->UpdateStreamPriority(id(), precedence);
+}
+
+void QuicStream::WriteOrBufferData(
+    absl::string_view data, bool fin,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  QUIC_BUG_IF(quic_bug_12570_4,
+              QuicUtils::IsCryptoStreamId(transport_version(), id_))
+      << ENDPOINT
+      << "WriteOrBufferData is used to send application data, use "
+         "WriteOrBufferDataAtLevel to send crypto data.";
+  return WriteOrBufferDataAtLevel(
+      data, fin, session()->GetEncryptionLevelToSendApplicationData(),
+      ack_listener);
+}
+
+void QuicStream::WriteOrBufferDataAtLevel(
+    absl::string_view data, bool fin, EncryptionLevel level,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  if (data.empty() && !fin) {
+    QUIC_BUG(quic_bug_10586_2) << "data.empty() && !fin";
+    return;
+  }
+
+  if (fin_buffered_) {
+    QUIC_BUG(quic_bug_10586_3) << "Fin already buffered";
+    return;
+  }
+  if (write_side_closed_) {
+    QUIC_DLOG(ERROR) << ENDPOINT
+                     << "Attempt to write when the write side is closed";
+    if (type_ == READ_UNIDIRECTIONAL) {
+      OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
+                           "Try to send data on read unidirectional stream");
+    }
+    return;
+  }
+
+  fin_buffered_ = fin;
+
+  bool had_buffered_data = HasBufferedData();
+  // Do not respect buffered data upper limit as WriteOrBufferData guarantees
+  // all data to be consumed.
+  if (data.length() > 0) {
+    QuicStreamOffset offset = send_buffer_.stream_offset();
+    if (kMaxStreamLength - offset < data.length()) {
+      QUIC_BUG(quic_bug_10586_4) << "Write too many data via stream " << id_;
+      OnUnrecoverableError(
+          QUIC_STREAM_LENGTH_OVERFLOW,
+          absl::StrCat("Write too many data via stream ", id_));
+      return;
+    }
+    send_buffer_.SaveStreamData(data);
+    OnDataBuffered(offset, data.length(), ack_listener);
+  }
+  if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) {
+    // Write data if there is no buffered data before.
+    WriteBufferedData(level);
+  }
+}
+
+void QuicStream::OnCanWrite() {
+  if (HasDeadlinePassed()) {
+    OnDeadlinePassed();
+    return;
+  }
+  if (HasPendingRetransmission()) {
+    WritePendingRetransmission();
+    // Exit early to allow other streams to write pending retransmissions if
+    // any.
+    return;
+  }
+
+  if (write_side_closed_) {
+    QUIC_DLOG(ERROR)
+        << ENDPOINT << "Stream " << id()
+        << " attempting to write new data when the write side is closed";
+    return;
+  }
+  if (HasBufferedData() || (fin_buffered_ && !fin_sent_)) {
+    WriteBufferedData(session()->GetEncryptionLevelToSendApplicationData());
+  }
+  if (!fin_buffered_ && !fin_sent_ && CanWriteNewData()) {
+    // Notify upper layer to write new data when buffered data size is below
+    // low water mark.
+    OnCanWriteNewData();
+  }
+}
+
+void QuicStream::MaybeSendBlocked() {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_5)
+        << ENDPOINT << "MaybeSendBlocked called on stream without flow control";
+    return;
+  }
+  if (flow_controller_->ShouldSendBlocked()) {
+    session_->SendBlocked(id_);
+  }
+  if (!stream_contributes_to_connection_flow_control_) {
+    return;
+  }
+  if (connection_flow_controller_->ShouldSendBlocked()) {
+    session_->SendBlocked(QuicUtils::GetInvalidStreamId(transport_version()));
+  }
+  // If the stream is blocked by connection-level flow control but not by
+  // stream-level flow control, add the stream to the write blocked list so that
+  // the stream will be given a chance to write when a connection-level
+  // WINDOW_UPDATE arrives.
+  if (connection_flow_controller_->IsBlocked() &&
+      !flow_controller_->IsBlocked()) {
+    session_->MarkConnectionLevelWriteBlocked(id());
+  }
+}
+
+QuicConsumedData QuicStream::WriteMemSlice(quiche::QuicheMemSlice span,
+                                           bool fin) {
+  return WriteMemSlices(absl::MakeSpan(&span, 1), fin);
+}
+
+QuicConsumedData QuicStream::WriteMemSlices(
+    absl::Span<quiche::QuicheMemSlice> span, bool fin) {
+  QuicConsumedData consumed_data(0, false);
+  if (span.empty() && !fin) {
+    QUIC_BUG(quic_bug_10586_6) << "span.empty() && !fin";
+    return consumed_data;
+  }
+
+  if (fin_buffered_) {
+    QUIC_BUG(quic_bug_10586_7) << "Fin already buffered";
+    return consumed_data;
+  }
+
+  if (write_side_closed_) {
+    QUIC_DLOG(ERROR) << ENDPOINT << "Stream " << id()
+                     << " attempting to write when the write side is closed";
+    if (type_ == READ_UNIDIRECTIONAL) {
+      OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
+                           "Try to send data on read unidirectional stream");
+    }
+    return consumed_data;
+  }
+
+  bool had_buffered_data = HasBufferedData();
+  if (CanWriteNewData() || span.empty()) {
+    consumed_data.fin_consumed = fin;
+    if (!span.empty()) {
+      // Buffer all data if buffered data size is below limit.
+      QuicStreamOffset offset = send_buffer_.stream_offset();
+      consumed_data.bytes_consumed = send_buffer_.SaveMemSliceSpan(span);
+      if (offset > send_buffer_.stream_offset() ||
+          kMaxStreamLength < send_buffer_.stream_offset()) {
+        QUIC_BUG(quic_bug_10586_8) << "Write too many data via stream " << id_;
+        OnUnrecoverableError(
+            QUIC_STREAM_LENGTH_OVERFLOW,
+            absl::StrCat("Write too many data via stream ", id_));
+        return consumed_data;
+      }
+      OnDataBuffered(offset, consumed_data.bytes_consumed, nullptr);
+    }
+  }
+  fin_buffered_ = consumed_data.fin_consumed;
+
+  if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) {
+    // Write data if there is no buffered data before.
+    WriteBufferedData(session()->GetEncryptionLevelToSendApplicationData());
+  }
+
+  return consumed_data;
+}
+
+bool QuicStream::HasPendingRetransmission() const {
+  return send_buffer_.HasPendingRetransmission() || fin_lost_;
+}
+
+bool QuicStream::IsStreamFrameOutstanding(QuicStreamOffset offset,
+                                          QuicByteCount data_length,
+                                          bool fin) const {
+  return send_buffer_.IsStreamDataOutstanding(offset, data_length) ||
+         (fin && fin_outstanding_);
+}
+
+void QuicStream::CloseReadSide() {
+  if (read_side_closed_) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Done reading from stream " << id();
+
+  read_side_closed_ = true;
+  sequencer_.ReleaseBuffer();
+
+  if (write_side_closed_) {
+    QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
+    session_->OnStreamClosed(id());
+    OnClose();
+  }
+}
+
+void QuicStream::CloseWriteSide() {
+  if (write_side_closed_) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Done writing to stream " << id();
+
+  write_side_closed_ = true;
+  if (read_side_closed_) {
+    QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
+    session_->OnStreamClosed(id());
+    OnClose();
+  }
+}
+
+void QuicStream::MaybeSendStopSending(QuicResetStreamError error) {
+  if (stop_sending_sent_) {
+    return;
+  }
+
+  if (!session()->version().UsesHttp3() && !error.ok()) {
+    // In gQUIC, RST with error closes both read and write side.
+    return;
+  }
+
+  if (session()->version().UsesHttp3()) {
+    session()->MaybeSendStopSendingFrame(id(), error);
+  } else {
+    QUICHE_DCHECK_EQ(QUIC_STREAM_NO_ERROR, error.internal_code());
+    session()->MaybeSendRstStreamFrame(id(), QuicResetStreamError::NoError(),
+                                       stream_bytes_written());
+  }
+  stop_sending_sent_ = true;
+  CloseReadSide();
+}
+
+void QuicStream::MaybeSendRstStream(QuicResetStreamError error) {
+  if (rst_sent_) {
+    return;
+  }
+
+  if (!session()->version().UsesHttp3()) {
+    QUIC_BUG_IF(quic_bug_12570_5, error.ok());
+    stop_sending_sent_ = true;
+    CloseReadSide();
+  }
+  session()->MaybeSendRstStreamFrame(id(), error, stream_bytes_written());
+  rst_sent_ = true;
+  CloseWriteSide();
+}
+
+bool QuicStream::HasBufferedData() const {
+  QUICHE_DCHECK_GE(send_buffer_.stream_offset(), stream_bytes_written());
+  return send_buffer_.stream_offset() > stream_bytes_written();
+}
+
+ParsedQuicVersion QuicStream::version() const { return session_->version(); }
+
+QuicTransportVersion QuicStream::transport_version() const {
+  return session_->transport_version();
+}
+
+HandshakeProtocol QuicStream::handshake_protocol() const {
+  return session_->connection()->version().handshake_protocol;
+}
+
+void QuicStream::StopReading() {
+  QUIC_DVLOG(1) << ENDPOINT << "Stop reading from stream " << id();
+  sequencer_.StopReading();
+}
+
+void QuicStream::OnClose() {
+  QUICHE_DCHECK(read_side_closed_ && write_side_closed_);
+
+  if (!fin_sent_ && !rst_sent_) {
+    QUIC_BUG_IF(quic_bug_12570_6, session()->connection()->connected() &&
+                                      session()->version().UsesHttp3())
+        << "The stream should've already sent RST in response to "
+           "STOP_SENDING";
+    // For flow control accounting, tell the peer how many bytes have been
+    // written on this stream before termination. Done here if needed, using a
+    // RST_STREAM frame.
+    MaybeSendRstStream(QUIC_RST_ACKNOWLEDGEMENT);
+    session_->MaybeCloseZombieStream(id_);
+  }
+
+  if (!flow_controller_.has_value() ||
+      flow_controller_->FlowControlViolation() ||
+      connection_flow_controller_->FlowControlViolation()) {
+    return;
+  }
+  // The stream is being closed and will not process any further incoming bytes.
+  // As there may be more bytes in flight, to ensure that both endpoints have
+  // the same connection level flow control state, mark all unreceived or
+  // buffered bytes as consumed.
+  QuicByteCount bytes_to_consume =
+      flow_controller_->highest_received_byte_offset() -
+      flow_controller_->bytes_consumed();
+  AddBytesConsumed(bytes_to_consume);
+}
+
+void QuicStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
+  if (type_ == READ_UNIDIRECTIONAL) {
+    OnUnrecoverableError(
+        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
+        "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.");
+    return;
+  }
+
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_9)
+        << ENDPOINT
+        << "OnWindowUpdateFrame called on stream without flow control";
+    return;
+  }
+
+  if (flow_controller_->UpdateSendWindowOffset(frame.max_data)) {
+    // Let session unblock this stream.
+    session_->MarkConnectionLevelWriteBlocked(id_);
+  }
+}
+
+bool QuicStream::MaybeIncreaseHighestReceivedOffset(
+    QuicStreamOffset new_offset) {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_10)
+        << ENDPOINT
+        << "MaybeIncreaseHighestReceivedOffset called on stream without "
+           "flow control";
+    return false;
+  }
+  uint64_t increment =
+      new_offset - flow_controller_->highest_received_byte_offset();
+  if (!flow_controller_->UpdateHighestReceivedOffset(new_offset)) {
+    return false;
+  }
+
+  // If |new_offset| increased the stream flow controller's highest received
+  // offset, increase the connection flow controller's value by the incremental
+  // difference.
+  if (stream_contributes_to_connection_flow_control_) {
+    connection_flow_controller_->UpdateHighestReceivedOffset(
+        connection_flow_controller_->highest_received_byte_offset() +
+        increment);
+  }
+  return true;
+}
+
+void QuicStream::AddBytesSent(QuicByteCount bytes) {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_11)
+        << ENDPOINT << "AddBytesSent called on stream without flow control";
+    return;
+  }
+  flow_controller_->AddBytesSent(bytes);
+  if (stream_contributes_to_connection_flow_control_) {
+    connection_flow_controller_->AddBytesSent(bytes);
+  }
+}
+
+void QuicStream::AddBytesConsumed(QuicByteCount bytes) {
+  if (type_ == CRYPTO) {
+    // A stream with type CRYPTO has no flow control, so there's nothing this
+    // function needs to do. This function still gets called by the
+    // QuicStreamSequencers used by QuicCryptoStream.
+    return;
+  }
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_12570_7)
+        << ENDPOINT
+        << "AddBytesConsumed called on non-crypto stream without flow control";
+    return;
+  }
+  // Only adjust stream level flow controller if still reading.
+  if (!read_side_closed_) {
+    flow_controller_->AddBytesConsumed(bytes);
+  }
+
+  if (stream_contributes_to_connection_flow_control_) {
+    connection_flow_controller_->AddBytesConsumed(bytes);
+  }
+}
+
+bool QuicStream::MaybeConfigSendWindowOffset(QuicStreamOffset new_offset,
+                                             bool was_zero_rtt_rejected) {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_12)
+        << ENDPOINT
+        << "ConfigSendWindowOffset called on stream without flow control";
+    return false;
+  }
+
+  // The validation code below is for QUIC with TLS only.
+  if (new_offset < flow_controller_->send_window_offset()) {
+    QUICHE_DCHECK(session()->version().UsesTls());
+    if (was_zero_rtt_rejected && new_offset < flow_controller_->bytes_sent()) {
+      // The client is given flow control window lower than what's written in
+      // 0-RTT. This QUIC implementation is unable to retransmit them.
+      QUIC_BUG_IF(quic_bug_12570_8, perspective_ == Perspective::IS_SERVER)
+          << "Server streams' flow control should never be configured twice.";
+      OnUnrecoverableError(
+          QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+          absl::StrCat(
+              "Server rejected 0-RTT, aborting because new stream max data ",
+              new_offset, " for stream ", id_, " is less than currently used: ",
+              flow_controller_->bytes_sent()));
+      return false;
+    } else if (session()->version().AllowsLowFlowControlLimits()) {
+      // In IETF QUIC, if the client receives flow control limit lower than what
+      // was resumed from 0-RTT, depending on 0-RTT status, it's either the
+      // peer's fault or our implementation's fault.
+      QUIC_BUG_IF(quic_bug_12570_9, perspective_ == Perspective::IS_SERVER)
+          << "Server streams' flow control should never be configured twice.";
+      OnUnrecoverableError(
+          was_zero_rtt_rejected ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+                                : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+          absl::StrCat(
+              was_zero_rtt_rejected ? "Server rejected 0-RTT, aborting because "
+                                    : "",
+              "new stream max data ", new_offset, " decreases current limit: ",
+              flow_controller_->send_window_offset()));
+      return false;
+    }
+  }
+
+  if (flow_controller_->UpdateSendWindowOffset(new_offset)) {
+    // Let session unblock this stream.
+    session_->MarkConnectionLevelWriteBlocked(id_);
+  }
+  return true;
+}
+
+void QuicStream::AddRandomPaddingAfterFin() {
+  add_random_padding_after_fin_ = true;
+}
+
+bool QuicStream::OnStreamFrameAcked(QuicStreamOffset offset,
+                                    QuicByteCount data_length, bool fin_acked,
+                                    QuicTime::Delta /*ack_delay_time*/,
+                                    QuicTime /*receive_timestamp*/,
+                                    QuicByteCount* newly_acked_length) {
+  QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " Acking "
+                << "[" << offset << ", " << offset + data_length << "]"
+                << " fin = " << fin_acked;
+  *newly_acked_length = 0;
+  if (!send_buffer_.OnStreamDataAcked(offset, data_length,
+                                      newly_acked_length)) {
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent data.");
+    return false;
+  }
+  if (!fin_sent_ && fin_acked) {
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent fin.");
+    return false;
+  }
+  // Indicates whether ack listener's OnPacketAcked should be called.
+  const bool new_data_acked =
+      *newly_acked_length > 0 || (fin_acked && fin_outstanding_);
+  if (fin_acked) {
+    fin_outstanding_ = false;
+    fin_lost_ = false;
+  }
+  if (!IsWaitingForAcks() && write_side_closed_ &&
+      !write_side_data_recvd_state_notified_) {
+    OnWriteSideInDataRecvdState();
+    write_side_data_recvd_state_notified_ = true;
+  }
+  if (!IsWaitingForAcks() && read_side_closed_ && write_side_closed_) {
+    session_->MaybeCloseZombieStream(id_);
+  }
+  return new_data_acked;
+}
+
+void QuicStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                            QuicByteCount data_length,
+                                            bool fin_retransmitted) {
+  send_buffer_.OnStreamDataRetransmitted(offset, data_length);
+  if (fin_retransmitted) {
+    fin_lost_ = false;
+  }
+}
+
+void QuicStream::OnStreamFrameLost(QuicStreamOffset offset,
+                                   QuicByteCount data_length, bool fin_lost) {
+  QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " Losting "
+                << "[" << offset << ", " << offset + data_length << "]"
+                << " fin = " << fin_lost;
+  if (data_length > 0) {
+    send_buffer_.OnStreamDataLost(offset, data_length);
+  }
+  if (fin_lost && fin_outstanding_) {
+    fin_lost_ = true;
+  }
+}
+
+bool QuicStream::RetransmitStreamData(QuicStreamOffset offset,
+                                      QuicByteCount data_length, bool fin,
+                                      TransmissionType type) {
+  QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
+                type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
+  if (HasDeadlinePassed()) {
+    OnDeadlinePassed();
+    return true;
+  }
+  QuicIntervalSet<QuicStreamOffset> retransmission(offset,
+                                                   offset + data_length);
+  retransmission.Difference(bytes_acked());
+  bool retransmit_fin = fin && fin_outstanding_;
+  if (retransmission.Empty() && !retransmit_fin) {
+    return true;
+  }
+  QuicConsumedData consumed(0, false);
+  for (const auto& interval : retransmission) {
+    QuicStreamOffset retransmission_offset = interval.min();
+    QuicByteCount retransmission_length = interval.max() - interval.min();
+    const bool can_bundle_fin =
+        retransmit_fin && (retransmission_offset + retransmission_length ==
+                           stream_bytes_written());
+    consumed = stream_delegate_->WritevData(
+        id_, retransmission_length, retransmission_offset,
+        can_bundle_fin ? FIN : NO_FIN, type,
+        session()->GetEncryptionLevelToSendApplicationData());
+    QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+                  << " is forced to retransmit stream data ["
+                  << retransmission_offset << ", "
+                  << retransmission_offset + retransmission_length
+                  << ") and fin: " << can_bundle_fin
+                  << ", consumed: " << consumed;
+    OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
+                               consumed.fin_consumed);
+    if (can_bundle_fin) {
+      retransmit_fin = !consumed.fin_consumed;
+    }
+    if (consumed.bytes_consumed < retransmission_length ||
+        (can_bundle_fin && !consumed.fin_consumed)) {
+      // Connection is write blocked.
+      return false;
+    }
+  }
+  if (retransmit_fin) {
+    QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+                  << " retransmits fin only frame.";
+    consumed = stream_delegate_->WritevData(
+        id_, 0, stream_bytes_written(), FIN, type,
+        session()->GetEncryptionLevelToSendApplicationData());
+    if (!consumed.fin_consumed) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicStream::IsWaitingForAcks() const {
+  return (!rst_sent_ || stream_error_.ok()) &&
+         (send_buffer_.stream_bytes_outstanding() || fin_outstanding_);
+}
+
+QuicByteCount QuicStream::ReadableBytes() const {
+  return sequencer_.ReadableBytes();
+}
+
+bool QuicStream::WriteStreamData(QuicStreamOffset offset,
+                                 QuicByteCount data_length,
+                                 QuicDataWriter* writer) {
+  QUICHE_DCHECK_LT(0u, data_length);
+  QUIC_DVLOG(2) << ENDPOINT << "Write stream " << id_ << " data from offset "
+                << offset << " length " << data_length;
+  return send_buffer_.WriteStreamData(offset, data_length, writer);
+}
+
+void QuicStream::WriteBufferedData(EncryptionLevel level) {
+  QUICHE_DCHECK(!write_side_closed_ && (HasBufferedData() || fin_buffered_));
+
+  if (session_->ShouldYield(id())) {
+    session_->MarkConnectionLevelWriteBlocked(id());
+    return;
+  }
+
+  // Size of buffered data.
+  QuicByteCount write_length = BufferedDataBytes();
+
+  // A FIN with zero data payload should not be flow control blocked.
+  bool fin_with_zero_data = (fin_buffered_ && write_length == 0);
+
+  bool fin = fin_buffered_;
+
+  // How much data flow control permits to be written.
+  QuicByteCount send_window;
+  if (flow_controller_.has_value()) {
+    send_window = flow_controller_->SendWindowSize();
+  } else {
+    send_window = std::numeric_limits<QuicByteCount>::max();
+    QUIC_BUG(quic_bug_10586_13)
+        << ENDPOINT
+        << "WriteBufferedData called on stream without flow control";
+  }
+  if (stream_contributes_to_connection_flow_control_) {
+    send_window =
+        std::min(send_window, connection_flow_controller_->SendWindowSize());
+  }
+
+  if (send_window == 0 && !fin_with_zero_data) {
+    // Quick return if nothing can be sent.
+    MaybeSendBlocked();
+    return;
+  }
+
+  if (write_length > send_window) {
+    // Don't send the FIN unless all the data will be sent.
+    fin = false;
+
+    // Writing more data would be a violation of flow control.
+    write_length = send_window;
+    QUIC_DVLOG(1) << "stream " << id() << " shortens write length to "
+                  << write_length << " due to flow control";
+  }
+
+  StreamSendingState state = fin ? FIN : NO_FIN;
+  if (fin && add_random_padding_after_fin_) {
+    state = FIN_AND_PADDING;
+  }
+  QuicConsumedData consumed_data =
+      stream_delegate_->WritevData(id(), write_length, stream_bytes_written(),
+                                   state, NOT_RETRANSMISSION, level);
+
+  OnStreamDataConsumed(consumed_data.bytes_consumed);
+
+  AddBytesSent(consumed_data.bytes_consumed);
+  QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " sends "
+                << stream_bytes_written() << " bytes "
+                << " and has buffered data " << BufferedDataBytes() << " bytes."
+                << " fin is sent: " << consumed_data.fin_consumed
+                << " fin is buffered: " << fin_buffered_;
+
+  // The write may have generated a write error causing this stream to be
+  // closed. If so, simply return without marking the stream write blocked.
+  if (write_side_closed_) {
+    return;
+  }
+
+  if (consumed_data.bytes_consumed == write_length) {
+    if (!fin_with_zero_data) {
+      MaybeSendBlocked();
+    }
+    if (fin && consumed_data.fin_consumed) {
+      QUICHE_DCHECK(!fin_sent_);
+      fin_sent_ = true;
+      fin_outstanding_ = true;
+      if (fin_received_) {
+        QUICHE_DCHECK(!was_draining_);
+        session_->StreamDraining(id_,
+                                 /*unidirectional=*/type_ != BIDIRECTIONAL);
+        was_draining_ = true;
+      }
+      CloseWriteSide();
+    } else if (fin && !consumed_data.fin_consumed) {
+      session_->MarkConnectionLevelWriteBlocked(id());
+    }
+  } else {
+    session_->MarkConnectionLevelWriteBlocked(id());
+  }
+  if (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed) {
+    busy_counter_ = 0;
+  }
+}
+
+uint64_t QuicStream::BufferedDataBytes() const {
+  QUICHE_DCHECK_GE(send_buffer_.stream_offset(), stream_bytes_written());
+  return send_buffer_.stream_offset() - stream_bytes_written();
+}
+
+bool QuicStream::CanWriteNewData() const {
+  return BufferedDataBytes() < buffered_data_threshold_;
+}
+
+bool QuicStream::CanWriteNewDataAfterData(QuicByteCount length) const {
+  return (BufferedDataBytes() + length) < buffered_data_threshold_;
+}
+
+uint64_t QuicStream::stream_bytes_written() const {
+  return send_buffer_.stream_bytes_written();
+}
+
+const QuicIntervalSet<QuicStreamOffset>& QuicStream::bytes_acked() const {
+  return send_buffer_.bytes_acked();
+}
+
+void QuicStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
+  send_buffer_.OnStreamDataConsumed(bytes_consumed);
+}
+
+void QuicStream::WritePendingRetransmission() {
+  while (HasPendingRetransmission()) {
+    QuicConsumedData consumed(0, false);
+    if (!send_buffer_.HasPendingRetransmission()) {
+      QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+                    << " retransmits fin only frame.";
+      consumed = stream_delegate_->WritevData(
+          id_, 0, stream_bytes_written(), FIN, LOSS_RETRANSMISSION,
+          session()->GetEncryptionLevelToSendApplicationData());
+      fin_lost_ = !consumed.fin_consumed;
+      if (fin_lost_) {
+        // Connection is write blocked.
+        return;
+      }
+    } else {
+      StreamPendingRetransmission pending =
+          send_buffer_.NextPendingRetransmission();
+      // Determine whether the lost fin can be bundled with the data.
+      const bool can_bundle_fin =
+          fin_lost_ &&
+          (pending.offset + pending.length == stream_bytes_written());
+      consumed = stream_delegate_->WritevData(
+          id_, pending.length, pending.offset, can_bundle_fin ? FIN : NO_FIN,
+          LOSS_RETRANSMISSION,
+          session()->GetEncryptionLevelToSendApplicationData());
+      QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+                    << " tries to retransmit stream data [" << pending.offset
+                    << ", " << pending.offset + pending.length
+                    << ") and fin: " << can_bundle_fin
+                    << ", consumed: " << consumed;
+      OnStreamFrameRetransmitted(pending.offset, consumed.bytes_consumed,
+                                 consumed.fin_consumed);
+      if (consumed.bytes_consumed < pending.length ||
+          (can_bundle_fin && !consumed.fin_consumed)) {
+        // Connection is write blocked.
+        return;
+      }
+    }
+  }
+}
+
+bool QuicStream::MaybeSetTtl(QuicTime::Delta ttl) {
+  if (is_static_) {
+    QUIC_BUG(quic_bug_10586_14) << "Cannot set TTL of a static stream.";
+    return false;
+  }
+  if (deadline_.IsInitialized()) {
+    QUIC_DLOG(WARNING) << "Deadline has already been set.";
+    return false;
+  }
+  QuicTime now = session()->connection()->clock()->ApproximateNow();
+  deadline_ = now + ttl;
+  return true;
+}
+
+bool QuicStream::HasDeadlinePassed() const {
+  if (!deadline_.IsInitialized()) {
+    // No deadline has been set.
+    return false;
+  }
+  QuicTime now = session()->connection()->clock()->ApproximateNow();
+  if (now < deadline_) {
+    return false;
+  }
+  // TTL expired.
+  QUIC_DVLOG(1) << "stream " << id() << " deadline has passed";
+  return true;
+}
+
+void QuicStream::OnDeadlinePassed() { Reset(QUIC_STREAM_TTL_EXPIRED); }
+
+bool QuicStream::IsFlowControlBlocked() const {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_15)
+        << "Trying to access non-existent flow controller.";
+    return false;
+  }
+  return flow_controller_->IsBlocked();
+}
+
+QuicStreamOffset QuicStream::highest_received_byte_offset() const {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_16)
+        << "Trying to access non-existent flow controller.";
+    return 0;
+  }
+  return flow_controller_->highest_received_byte_offset();
+}
+
+void QuicStream::UpdateReceiveWindowSize(QuicStreamOffset size) {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_17)
+        << "Trying to access non-existent flow controller.";
+    return;
+  }
+  flow_controller_->UpdateReceiveWindowSize(size);
+}
+
+// static
+spdy::SpdyStreamPrecedence QuicStream::CalculateDefaultPriority(
+    const QuicSession* session) {
+  return spdy::SpdyStreamPrecedence(
+      VersionUsesHttp3(session->transport_version())
+          ? kDefaultUrgency
+          : QuicStream::kDefaultPriority);
+}
+
+absl::optional<QuicByteCount> QuicStream::GetSendWindow() const {
+  return flow_controller_.has_value()
+             ? absl::optional<QuicByteCount>(flow_controller_->SendWindowSize())
+             : absl::nullopt;
+}
+
+absl::optional<QuicByteCount> QuicStream::GetReceiveWindow() const {
+  return flow_controller_.has_value()
+             ? absl::optional<QuicByteCount>(
+                   flow_controller_->receive_window_size())
+             : absl::nullopt;
+}
+
+void QuicStream::OnStreamCreatedFromPendingStream() {
+  sequencer()->SetUnblocked();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream.h b/quiche/quic/core/quic_stream.h
new file mode 100644
index 0000000..b2a6502
--- /dev/null
+++ b/quiche/quic/core/quic_stream.h
@@ -0,0 +1,626 @@
+// 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 <string>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_flow_controller.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_send_buffer.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/session_notifier_interface.h"
+#include "quiche/quic/core/stream_delegate_interface.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+#include "quiche/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 ResetWithError(QuicResetStreamError error) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& details) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            QuicIetfTransportErrorCodes ietf_error,
+                            const std::string& details) override;
+  QuicStreamId id() const override;
+  ParsedQuicVersion version() 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);
+
+  bool is_bidirectional() const { return is_bidirectional_; }
+
+  // Stores the final byte offset from |frame|.
+  // If the final offset violates flow control, the connection will be closed.
+  void OnRstStreamFrame(const QuicRstStreamFrame& frame);
+
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
+
+  void OnStopSending(QuicResetStreamError stop_sending_error_code);
+
+  // The error code received from QuicStopSendingFrame (if any).
+  const absl::optional<QuicResetStreamError>& GetStopSendingErrorCode() const {
+    return stop_sending_error_code_;
+  }
+
+  // Returns the number of bytes read on this stream.
+  uint64_t stream_bytes_read() { return stream_bytes_read_; }
+
+  const QuicStreamSequencer* sequencer() const { return &sequencer_; }
+
+  void MarkConsumed(QuicByteCount num_bytes);
+
+  // Tells the sequencer to ignore all incoming data itself and not call
+  // OnDataAvailable().
+  void StopReading();
+
+ private:
+  friend class QuicStream;
+
+  bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
+
+  // ID of this stream.
+  QuicStreamId id_;
+
+  // QUIC version being used by this stream.
+  ParsedQuicVersion version_;
+
+  // |stream_delegate_| must outlive this stream.
+  StreamDelegateInterface* stream_delegate_;
+
+  // 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_;
+
+  // True if this pending stream is backing a bidirectional stream.
+  bool is_bidirectional_;
+
+  // 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_;
+  // The error code received from QuicStopSendingFrame (if any).
+  absl::optional<QuicResetStreamError> stop_sending_error_code_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicStream
+    : public QuicStreamSequencer::StreamInterface {
+ public:
+  // Default priority for Google QUIC.
+  // 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 in case of Google QUIC.
+  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, QuicSession* session, bool is_static);
+  QuicStream(const QuicStream&) = delete;
+  QuicStream& operator=(const QuicStream&) = delete;
+
+  virtual ~QuicStream();
+
+  // Default priority for IETF QUIC, defined by the priority extension at
+  // https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html#urgency.
+  static const int kDefaultUrgency = 3;
+
+  // QuicStreamSequencer::StreamInterface implementation.
+  QuicStreamId id() const override { return id_; }
+  ParsedQuicVersion version() const override;
+  // 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 ResetWithError(QuicResetStreamError error) override;
+  // Convenience wrapper for the method above.
+  // TODO(b/200606367): switch all calls to using QuicResetStreamError
+  // interface.
+  void Reset(QuicRstStreamErrorCode error);
+
+  // Reset() sends both RESET_STREAM and STOP_SENDING; the two methods below
+  // allow to send only one of those.
+  void ResetWriteSide(QuicResetStreamError error);
+  void SendStopSending(QuicResetStreamError error);
+
+  // Called by the subclass or the sequencer to close the entire connection from
+  // this end.
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& details) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            QuicIetfTransportErrorCodes ietf_error,
+                            const std::string& details) 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 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);
+
+  const spdy::SpdyStreamPrecedence& precedence() const;
+
+  // Send PRIORITY_UPDATE frame if application protocol supports it.
+  virtual void MaybeSendPriorityUpdateFrame() {}
+
+  // Sets |priority_| to priority.  This should only be called before bytes are
+  // written to the server.  For a server stream, this is called when a
+  // PRIORITY_UPDATE frame is received.  This calls
+  // MaybeSendPriorityUpdateFrame(), which for a client stream might send a
+  // PRIORITY_UPDATE frame.
+  void SetPriority(const spdy::SpdyStreamPrecedence& precedence);
+
+  // 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.
+  QuicByteCount ReadableBytes() const;
+
+  QuicRstStreamErrorCode stream_error() const {
+    return stream_error_.internal_code();
+  }
+  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 read_side_closed() const { return read_side_closed_; }
+
+  bool IsZombie() const {
+    return read_side_closed_ && write_side_closed_ && IsWaitingForAcks();
+  }
+
+  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; }
+
+  // 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;
+
+  // Flow controller related methods.
+  bool IsFlowControlBlocked() const;
+  QuicStreamOffset highest_received_byte_offset() const;
+  void UpdateReceiveWindowSize(QuicStreamOffset size);
+
+  // 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);
+
+  // Set the flow controller's send window offset from session config.
+  // |was_zero_rtt_rejected| is true if this config is from a rejected IETF QUIC
+  // 0-RTT attempt. Closes the connection and returns false if |new_offset| is
+  // not valid.
+  bool MaybeConfigSendWindowOffset(QuicStreamOffset new_offset,
+                                   bool was_zero_rtt_rejected);
+
+  // 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 HasReceivedFinalOffset() 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 on the application encryption
+  // level as the connection will consume, and then buffers any remaining data
+  // in the send buffer. 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(
+      absl::string_view data, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Sends |data| to connection with specified |level|.
+  void WriteOrBufferDataAtLevel(
+      absl::string_view data, bool fin, EncryptionLevel level,
+      quiche::QuicheReferenceCountedPointer<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,
+                                  QuicTime receive_timestamp,
+                                  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| with Transmission |type|.
+  // Returns true if all data gets retransmitted.
+  virtual bool RetransmitStreamData(QuicStreamOffset offset,
+                                    QuicByteCount data_length, bool fin,
+                                    TransmissionType type);
+
+  // Sets deadline of this stream to be now + |ttl|, returns true if the setting
+  // succeeds.
+  bool MaybeSetTtl(QuicTime::Delta ttl);
+
+  // Commits data into the stream write buffer, and potentially sends it over
+  // the wire.  This method has all-or-nothing semantics: if the write buffer is
+  // not full, all of the memslices in |span| are moved into it; otherwise,
+  // nothing happens.
+  QuicConsumedData WriteMemSlices(absl::Span<quiche::QuicheMemSlice> span,
+                                  bool fin);
+  QuicConsumedData WriteMemSlice(quiche::QuicheMemSlice 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_; }
+
+  // Handle received StopSending frame. Returns true if the processing finishes
+  // gracefully.
+  virtual bool OnStopSending(QuicResetStreamError error);
+
+  // Returns true if the stream is static.
+  bool is_static() const { return is_static_; }
+
+  bool was_draining() const { return was_draining_; }
+
+  static spdy::SpdyStreamPrecedence CalculateDefaultPriority(
+      const QuicSession* session);
+
+  QuicTime creation_time() const { return creation_time_; }
+
+  bool fin_buffered() const { return fin_buffered_; }
+
+  // True if buffered data in send buffer is below buffered_data_threshold_.
+  bool CanWriteNewData() const;
+
+  // Called immediately after the stream is created from a pending stream,
+  // indicating it can start processing data.
+  void OnStreamCreatedFromPendingStream();
+
+ protected:
+  // Called when data of [offset, offset + data_length] is buffered in send
+  // buffer.
+  virtual void OnDataBuffered(
+      QuicStreamOffset /*offset*/, QuicByteCount /*data_length*/,
+      const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
+      /*ack_listener*/) {}
+
+  // Called 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();
+
+  // 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(QuicByteCount bytes_consumed);
+
+  // 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;
+
+  // 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();
+
+  // Called to set fin_sent_. This is only used by Google QUIC while body is
+  // empty.
+  void SetFinSent();
+
+  // Send STOP_SENDING if it hasn't been sent yet.
+  void MaybeSendStopSending(QuicResetStreamError error);
+
+  // Send RESET_STREAM if it hasn't been sent yet.
+  void MaybeSendRstStream(QuicResetStreamError error);
+
+  // Convenience warppers for two methods above.
+  void MaybeSendRstStream(QuicRstStreamErrorCode error) {
+    MaybeSendRstStream(QuicResetStreamError::FromInternal(error));
+  }
+  void MaybeSendStopSending(QuicRstStreamErrorCode error) {
+    MaybeSendStopSending(QuicResetStreamError::FromInternal(error));
+  }
+
+  // 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();
+
+  void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
+  void set_stream_error(QuicResetStreamError error) { stream_error_ = error; }
+
+  StreamDelegateInterface* stream_delegate() { return stream_delegate_; }
+
+  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_; }
+
+  // Called when the write side of the stream is closed, and all of the outgoing
+  // data has been acknowledged.  This corresponds to the "Data Recvd" state of
+  // RFC 9000.
+  virtual void OnWriteSideInDataRecvdState() {}
+
+  // Return the current flow control send window in bytes.
+  absl::optional<QuicByteCount> GetSendWindow() const;
+  absl::optional<QuicByteCount> GetReceiveWindow() const;
+
+ 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,
+             absl::optional<QuicFlowController> flow_controller,
+             QuicFlowController* connection_flow_controller);
+
+  // 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) at |level|.
+  void WriteBufferedData(EncryptionLevel level);
+
+  // Close the read side of the stream.  May cause the stream to be closed.
+  void CloseReadSide();
+
+  // Called when bytes are sent to the peer.
+  void AddBytesSent(QuicByteCount bytes);
+
+  // Returns true if deadline_ has passed.
+  bool HasDeadlinePassed() const;
+
+  QuicStreamSequencer sequencer_;
+  QuicStreamId id_;
+  // Pointer to the owning QuicSession object.
+  // TODO(b/136274541): Remove session pointer from streams.
+  QuicSession* session_;
+  StreamDelegateInterface* stream_delegate_;
+  // The precedence of the stream, once parsed.
+  spdy::SpdyStreamPrecedence precedence_;
+  // 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.
+  QuicResetStreamError 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 OnWriteSideInDataRecvdState() has already been called.
+  bool write_side_data_recvd_state_notified_;
+
+  // 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_;
+
+  // True if the stream has sent STOP_SENDING to the session.
+  bool stop_sending_sent_;
+
+  absl::optional<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 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_;
+
+  // True if this stream has entered draining state.
+  bool was_draining_;
+
+  // Indicates whether this stream is bidirectional, read unidirectional or
+  // write unidirectional.
+  const StreamType type_;
+
+  // Creation time of this stream, as reported by the QuicClock.
+  const QuicTime creation_time_;
+
+  Perspective perspective_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_H_
diff --git a/quiche/quic/core/quic_stream_frame_data_producer.h b/quiche/quic/core/quic_stream_frame_data_producer.h
new file mode 100644
index 0000000..886c875
--- /dev/null
+++ b/quiche/quic/core/quic_stream_frame_data_producer.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2017 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_STREAM_FRAME_DATA_PRODUCER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
+
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+class QuicDataWriter;
+
+// Pure virtual class to retrieve stream data.
+class QUIC_EXPORT_PRIVATE QuicStreamFrameDataProducer {
+ public:
+  virtual ~QuicStreamFrameDataProducer() {}
+
+  // Let |writer| write |data_length| data with |offset| of stream |id|. The
+  // write fails when either stream is closed or corresponding data is failed to
+  // be retrieved. This method allows writing a single stream frame from data
+  // that spans multiple buffers.
+  virtual WriteStreamDataResult WriteStreamData(QuicStreamId id,
+                                                QuicStreamOffset offset,
+                                                QuicByteCount data_length,
+                                                QuicDataWriter* writer) = 0;
+
+  // Writes the data for a CRYPTO frame to |writer| for a frame at encryption
+  // level |level| starting at offset |offset| for |data_length| bytes. Returns
+  // whether writing the data was successful.
+  virtual bool WriteCryptoData(EncryptionLevel level,
+                               QuicStreamOffset offset,
+                               QuicByteCount data_length,
+                               QuicDataWriter* writer) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
diff --git a/quiche/quic/core/quic_stream_id_manager.cc b/quiche/quic/core/quic_stream_id_manager.cc
new file mode 100644
index 0000000..04d93bb
--- /dev/null
+++ b/quiche/quic/core/quic_stream_id_manager.cc
@@ -0,0 +1,243 @@
+// Copyright (c) 2018 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 "quiche/quic/core/quic_stream_id_manager.h"
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? " Server: " : " Client: ")
+
+QuicStreamIdManager::QuicStreamIdManager(
+    DelegateInterface* delegate,
+    bool unidirectional,
+    Perspective perspective,
+    ParsedQuicVersion version,
+    QuicStreamCount max_allowed_outgoing_streams,
+    QuicStreamCount max_allowed_incoming_streams)
+    : delegate_(delegate),
+      unidirectional_(unidirectional),
+      perspective_(perspective),
+      version_(version),
+      outgoing_max_streams_(max_allowed_outgoing_streams),
+      next_outgoing_stream_id_(GetFirstOutgoingStreamId()),
+      outgoing_stream_count_(0),
+      incoming_actual_max_streams_(max_allowed_incoming_streams),
+      incoming_advertised_max_streams_(max_allowed_incoming_streams),
+      incoming_initial_max_open_streams_(max_allowed_incoming_streams),
+      incoming_stream_count_(0),
+      largest_peer_created_stream_id_(
+          QuicUtils::GetInvalidStreamId(version.transport_version)) {}
+
+QuicStreamIdManager::~QuicStreamIdManager() {}
+
+bool QuicStreamIdManager::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& frame,
+    std::string* error_details) {
+  QUICHE_DCHECK_EQ(frame.unidirectional, unidirectional_);
+  if (frame.stream_count > incoming_advertised_max_streams_) {
+    // Peer thinks it can send more streams that we've told it.
+    *error_details = absl::StrCat(
+        "StreamsBlockedFrame's stream count ", frame.stream_count,
+        " exceeds incoming max stream ", incoming_advertised_max_streams_);
+    return false;
+  }
+  QUICHE_DCHECK_LE(incoming_advertised_max_streams_,
+                   incoming_actual_max_streams_);
+  if (incoming_advertised_max_streams_ == incoming_actual_max_streams_) {
+    // We have told peer about current max.
+    return true;
+  }
+  if (frame.stream_count < incoming_actual_max_streams_) {
+    // Peer thinks it's blocked on a stream count that is less than our current
+    // max. Inform the peer of the correct stream count.
+    SendMaxStreamsFrame();
+  }
+  return true;
+}
+
+bool QuicStreamIdManager::MaybeAllowNewOutgoingStreams(
+    QuicStreamCount max_open_streams) {
+  if (max_open_streams <= outgoing_max_streams_) {
+    // Only update the stream count if it would increase the limit.
+    return false;
+  }
+
+  // This implementation only supports 32 bit Stream IDs, so limit max streams
+  // if it would exceed the max 32 bits can express.
+  outgoing_max_streams_ =
+      std::min(max_open_streams, QuicUtils::GetMaxStreamCount());
+
+  return true;
+}
+
+void QuicStreamIdManager::SetMaxOpenIncomingStreams(
+    QuicStreamCount max_open_streams) {
+  QUIC_BUG_IF(quic_bug_12413_1, incoming_stream_count_ > 0)
+      << "non-zero incoming stream count " << incoming_stream_count_
+      << " when setting max incoming stream to " << max_open_streams;
+  QUIC_DLOG_IF(WARNING, incoming_initial_max_open_streams_ != max_open_streams)
+      << absl::StrCat(unidirectional_ ? "unidirectional " : "bidirectional: ",
+                      "incoming stream limit changed from ",
+                      incoming_initial_max_open_streams_, " to ",
+                      max_open_streams);
+  incoming_actual_max_streams_ = max_open_streams;
+  incoming_advertised_max_streams_ = max_open_streams;
+  incoming_initial_max_open_streams_ = max_open_streams;
+}
+
+void QuicStreamIdManager::MaybeSendMaxStreamsFrame() {
+  int divisor = GetQuicFlag(FLAGS_quic_max_streams_window_divisor);
+
+  if (divisor > 0) {
+    if ((incoming_advertised_max_streams_ - incoming_stream_count_) >
+        (incoming_initial_max_open_streams_ / divisor)) {
+      // window too large, no advertisement
+      return;
+    }
+  }
+  SendMaxStreamsFrame();
+}
+
+void QuicStreamIdManager::SendMaxStreamsFrame() {
+  QUIC_BUG_IF(quic_bug_12413_2,
+              incoming_advertised_max_streams_ >= incoming_actual_max_streams_);
+  incoming_advertised_max_streams_ = incoming_actual_max_streams_;
+  delegate_->SendMaxStreams(incoming_advertised_max_streams_, unidirectional_);
+}
+
+void QuicStreamIdManager::OnStreamClosed(QuicStreamId stream_id) {
+  QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
+                   unidirectional_);
+  if (QuicUtils::IsOutgoingStreamId(version_, stream_id, perspective_)) {
+    // Nothing to do for outgoing streams.
+    return;
+  }
+  // If the stream is inbound, we can increase the actual stream limit and maybe
+  // advertise the new limit to the peer.
+  if (incoming_actual_max_streams_ == QuicUtils::GetMaxStreamCount()) {
+    // Reached the maximum stream id value that the implementation
+    // supports. Nothing can be done here.
+    return;
+  }
+  // One stream closed, and another one can be opened.
+  incoming_actual_max_streams_++;
+  MaybeSendMaxStreamsFrame();
+}
+
+QuicStreamId QuicStreamIdManager::GetNextOutgoingStreamId() {
+  QUIC_BUG_IF(quic_bug_12413_3, outgoing_stream_count_ >= outgoing_max_streams_)
+      << "Attempt to allocate a new outgoing stream that would exceed the "
+         "limit ("
+      << outgoing_max_streams_ << ")";
+  QuicStreamId id = next_outgoing_stream_id_;
+  next_outgoing_stream_id_ +=
+      QuicUtils::StreamIdDelta(version_.transport_version);
+  outgoing_stream_count_++;
+  return id;
+}
+
+bool QuicStreamIdManager::CanOpenNextOutgoingStream() const {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
+  return outgoing_stream_count_ < outgoing_max_streams_;
+}
+
+bool QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
+    const QuicStreamId stream_id,
+    std::string* error_details) {
+  // |stream_id| must be an incoming stream of the right directionality.
+  QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
+                   unidirectional_);
+  QUICHE_DCHECK_NE(QuicUtils::IsServerInitiatedStreamId(
+                       version_.transport_version, stream_id),
+                   perspective_ == Perspective::IS_SERVER);
+  if (available_streams_.erase(stream_id) == 1) {
+    // stream_id is available.
+    return true;
+  }
+
+  if (largest_peer_created_stream_id_ !=
+      QuicUtils::GetInvalidStreamId(version_.transport_version)) {
+    QUICHE_DCHECK_GT(stream_id, largest_peer_created_stream_id_);
+  }
+
+  // Calculate increment of incoming_stream_count_ by creating stream_id.
+  const QuicStreamCount delta =
+      QuicUtils::StreamIdDelta(version_.transport_version);
+  const QuicStreamId least_new_stream_id =
+      largest_peer_created_stream_id_ ==
+              QuicUtils::GetInvalidStreamId(version_.transport_version)
+          ? GetFirstIncomingStreamId()
+          : largest_peer_created_stream_id_ + delta;
+  const QuicStreamCount stream_count_increment =
+      (stream_id - least_new_stream_id) / delta + 1;
+
+  if (incoming_stream_count_ + stream_count_increment >
+      incoming_advertised_max_streams_) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Failed to create a new incoming stream with id:"
+                    << stream_id << ", reaching MAX_STREAMS limit: "
+                    << incoming_advertised_max_streams_ << ".";
+    *error_details = absl::StrCat("Stream id ", stream_id,
+                                  " would exceed stream count limit ",
+                                  incoming_advertised_max_streams_);
+    return false;
+  }
+
+  for (QuicStreamId id = least_new_stream_id; id < stream_id; id += delta) {
+    available_streams_.insert(id);
+  }
+  incoming_stream_count_ += stream_count_increment;
+  largest_peer_created_stream_id_ = stream_id;
+  return true;
+}
+
+bool QuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
+  QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(id, version_),
+                   unidirectional_);
+  if (QuicUtils::IsOutgoingStreamId(version_, id, perspective_)) {
+    // Stream IDs under next_ougoing_stream_id_ are either open or previously
+    // open but now closed.
+    return id >= next_outgoing_stream_id_;
+  }
+  // For peer created streams, we also need to consider available streams.
+  return largest_peer_created_stream_id_ ==
+             QuicUtils::GetInvalidStreamId(version_.transport_version) ||
+         id > largest_peer_created_stream_id_ ||
+         available_streams_.contains(id);
+}
+
+QuicStreamId QuicStreamIdManager::GetFirstOutgoingStreamId() const {
+  return (unidirectional_) ? QuicUtils::GetFirstUnidirectionalStreamId(
+                                 version_.transport_version, perspective_)
+                           : QuicUtils::GetFirstBidirectionalStreamId(
+                                 version_.transport_version, perspective_);
+}
+
+QuicStreamId QuicStreamIdManager::GetFirstIncomingStreamId() const {
+  return (unidirectional_) ? QuicUtils::GetFirstUnidirectionalStreamId(
+                                 version_.transport_version,
+                                 QuicUtils::InvertPerspective(perspective_))
+                           : QuicUtils::GetFirstBidirectionalStreamId(
+                                 version_.transport_version,
+                                 QuicUtils::InvertPerspective(perspective_));
+}
+
+QuicStreamCount QuicStreamIdManager::available_incoming_streams() const {
+  return incoming_advertised_max_streams_ - incoming_stream_count_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_id_manager.h b/quiche/quic/core/quic_stream_id_manager.h
new file mode 100644
index 0000000..33d7566
--- /dev/null
+++ b/quiche/quic/core/quic_stream_id_manager.h
@@ -0,0 +1,186 @@
+// Copyright (c) 2018 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_STREAM_ID_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
+
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace test {
+class QuicSessionPeer;
+class QuicStreamIdManagerPeer;
+}  // namespace test
+
+// This class manages the stream ids for IETF QUIC.
+class QUIC_EXPORT_PRIVATE QuicStreamIdManager {
+ public:
+  class QUIC_EXPORT_PRIVATE DelegateInterface {
+   public:
+    virtual ~DelegateInterface() = default;
+
+    // Send a MAX_STREAMS frame.
+    virtual void SendMaxStreams(QuicStreamCount stream_count,
+                                bool unidirectional) = 0;
+  };
+
+  QuicStreamIdManager(DelegateInterface* delegate,
+                      bool unidirectional,
+                      Perspective perspective,
+                      ParsedQuicVersion version,
+                      QuicStreamCount max_allowed_outgoing_streams,
+                      QuicStreamCount max_allowed_incoming_streams);
+
+  ~QuicStreamIdManager();
+
+  // Generate a string suitable for sending to the log/etc to show current state
+  // of the stream ID manager.
+  std::string DebugString() const {
+    return absl::StrCat(
+        " { unidirectional_: ", unidirectional_,
+        ", perspective: ", perspective_,
+        ", outgoing_max_streams_: ", outgoing_max_streams_,
+        ", next_outgoing_stream_id_: ", next_outgoing_stream_id_,
+        ", outgoing_stream_count_: ", outgoing_stream_count_,
+        ", incoming_actual_max_streams_: ", incoming_actual_max_streams_,
+        ", incoming_advertised_max_streams_: ",
+        incoming_advertised_max_streams_,
+        ", incoming_stream_count_: ", incoming_stream_count_,
+        ", available_streams_.size(): ", available_streams_.size(),
+        ", largest_peer_created_stream_id_: ", largest_peer_created_stream_id_,
+        " }");
+  }
+
+  // Processes the STREAMS_BLOCKED frame. If error is encountered, populates
+  // |error_details| and returns false.
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
+                             std::string* error_details);
+
+  // Returns whether the next outgoing stream ID can be allocated or not.
+  bool CanOpenNextOutgoingStream() const;
+
+  // Generate and send a MAX_STREAMS frame.
+  void SendMaxStreamsFrame();
+
+  // Invoked to deal with releasing a stream. Does nothing if the stream is
+  // outgoing. If the stream is incoming, the number of streams that the peer
+  // can open will be updated and a MAX_STREAMS frame, informing the peer of
+  // the additional streams, may be sent.
+  void OnStreamClosed(QuicStreamId stream_id);
+
+  // Returns the next outgoing stream id. Applications must call
+  // CanOpenNextOutgoingStream() first.
+  QuicStreamId GetNextOutgoingStreamId();
+
+  void SetMaxOpenIncomingStreams(QuicStreamCount max_open_streams);
+
+  // Called on |max_open_streams| outgoing streams can be created because of 1)
+  // config negotiated or 2) MAX_STREAMS received. Returns true if new
+  // streams can be created.
+  bool MaybeAllowNewOutgoingStreams(QuicStreamCount max_open_streams);
+
+  // Checks if the incoming stream ID exceeds the MAX_STREAMS limit.  If the
+  // limit is exceeded, populates |error_detials| and returns false.
+  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id,
+                                        std::string* error_details);
+
+  // Returns true if |id| is still available.
+  bool IsAvailableStream(QuicStreamId id) const;
+
+  QuicStreamCount incoming_initial_max_open_streams() const {
+    return incoming_initial_max_open_streams_;
+  }
+
+  QuicStreamId next_outgoing_stream_id() const {
+    return next_outgoing_stream_id_;
+  }
+
+  // Number of streams that the peer believes that it can still create.
+  QuicStreamCount available_incoming_streams() const;
+
+  QuicStreamId largest_peer_created_stream_id() const {
+    return largest_peer_created_stream_id_;
+  }
+
+  QuicStreamCount outgoing_max_streams() const { return outgoing_max_streams_; }
+  QuicStreamCount incoming_actual_max_streams() const {
+    return incoming_actual_max_streams_;
+  }
+  QuicStreamCount incoming_advertised_max_streams() const {
+    return incoming_advertised_max_streams_;
+  }
+  QuicStreamCount outgoing_stream_count() const {
+    return outgoing_stream_count_;
+  }
+
+ private:
+  friend class test::QuicSessionPeer;
+  friend class test::QuicStreamIdManagerPeer;
+
+  // Check whether the MAX_STREAMS window has opened up enough and, if so,
+  // generate and send a MAX_STREAMS frame.
+  void MaybeSendMaxStreamsFrame();
+
+  // Get what should be the first incoming/outgoing stream ID that
+  // this stream id manager will manage, taking into account directionality and
+  // client/server perspective.
+  QuicStreamId GetFirstOutgoingStreamId() const;
+  QuicStreamId GetFirstIncomingStreamId() const;
+
+  // Back reference to the session containing this Stream ID Manager.
+  DelegateInterface* delegate_;
+
+  // Whether this stream id manager is for unidrectional (true) or bidirectional
+  // (false) streams.
+  const bool unidirectional_;
+
+  // Is this manager a client or a server.
+  const Perspective perspective_;
+
+  // QUIC version used for this manager.
+  const ParsedQuicVersion version_;
+
+  // The number of streams that this node can initiate.
+  // This limit is first set when config is negotiated, but may be updated upon
+  // receiving MAX_STREAMS frame.
+  QuicStreamCount outgoing_max_streams_;
+
+  // The ID to use for the next outgoing stream.
+  QuicStreamId next_outgoing_stream_id_;
+
+  // The number of outgoing streams that have ever been opened, including those
+  // that have been closed. This number must never be larger than
+  // outgoing_max_streams_.
+  QuicStreamCount outgoing_stream_count_;
+
+  // FOR INCOMING STREAMS
+
+  // The actual maximum number of streams that can be opened by the peer.
+  QuicStreamCount incoming_actual_max_streams_;
+  // Max incoming stream number that has been advertised to the peer and is <=
+  // incoming_actual_max_streams_. It is set to incoming_actual_max_streams_
+  // when a MAX_STREAMS is sent.
+  QuicStreamCount incoming_advertised_max_streams_;
+
+  // Initial maximum on the number of open streams allowed.
+  QuicStreamCount incoming_initial_max_open_streams_;
+
+  // The number of streams that have been created, including open ones and
+  // closed ones.
+  QuicStreamCount incoming_stream_count_;
+
+  // Set of stream ids that are less than the largest stream id that has been
+  // received, but are nonetheless available to be created.
+  absl::flat_hash_set<QuicStreamId> available_streams_;
+
+  QuicStreamId largest_peer_created_stream_id_;
+};
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
diff --git a/quiche/quic/core/quic_stream_id_manager_test.cc b/quiche/quic/core/quic_stream_id_manager_test.cc
new file mode 100644
index 0000000..a9b3e6f
--- /dev/null
+++ b/quiche/quic/core/quic_stream_id_manager_test.cc
@@ -0,0 +1,479 @@
+// Copyright (c) 2018 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 "quiche/quic/core/quic_stream_id_manager.h"
+
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockDelegate : public QuicStreamIdManager::DelegateInterface {
+ public:
+  MOCK_METHOD(void,
+              SendMaxStreams,
+              (QuicStreamCount stream_count, bool unidirectional),
+              (override));
+};
+
+struct TestParams {
+  TestParams(ParsedQuicVersion version,
+             Perspective perspective,
+             bool is_unidirectional)
+      : version(version),
+        perspective(perspective),
+        is_unidirectional(is_unidirectional) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+  bool is_unidirectional;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version), "_",
+      (p.perspective == Perspective::IS_CLIENT ? "Client" : "Server"),
+      (p.is_unidirectional ? "Unidirectional" : "Bidirectional"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (!version.HasIetfQuicFrames()) {
+      continue;
+    }
+    for (Perspective perspective :
+         {Perspective::IS_CLIENT, Perspective::IS_SERVER}) {
+      for (bool is_unidirectional : {true, false}) {
+        params.push_back(TestParams(version, perspective, is_unidirectional));
+      }
+    }
+  }
+  return params;
+}
+
+class QuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
+ protected:
+  QuicStreamIdManagerTest()
+      : stream_id_manager_(&delegate_,
+                           IsUnidirectional(),
+                           perspective(),
+                           GetParam().version,
+                           0,
+                           kDefaultMaxStreamsPerConnection) {
+    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  }
+
+  QuicTransportVersion transport_version() const {
+    return GetParam().version.transport_version;
+  }
+
+  // Returns the stream ID for the Nth incoming stream (created by the peer)
+  // of the corresponding directionality of this manager.
+  QuicStreamId GetNthIncomingStreamId(int n) {
+    return QuicUtils::StreamIdDelta(transport_version()) * n +
+           (IsUnidirectional()
+                ? QuicUtils::GetFirstUnidirectionalStreamId(
+                      transport_version(),
+                      QuicUtils::InvertPerspective(perspective()))
+                : QuicUtils::GetFirstBidirectionalStreamId(
+                      transport_version(),
+                      QuicUtils::InvertPerspective(perspective())));
+  }
+
+  bool IsUnidirectional() { return GetParam().is_unidirectional; }
+  Perspective perspective() { return GetParam().perspective; }
+
+  StrictMock<MockDelegate> delegate_;
+  QuicStreamIdManager stream_id_manager_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicStreamIdManagerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicStreamIdManagerTest, Initialization) {
+  EXPECT_EQ(0u, stream_id_manager_.outgoing_max_streams());
+
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            stream_id_manager_.incoming_actual_max_streams());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            stream_id_manager_.incoming_advertised_max_streams());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            stream_id_manager_.incoming_initial_max_open_streams());
+}
+
+// This test checks that the stream advertisement window is set to 1
+// if the number of stream ids is 1. This is a special case in the code.
+TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsWindowForSingleStream) {
+  stream_id_manager_.SetMaxOpenIncomingStreams(1);
+  EXPECT_EQ(1u, stream_id_manager_.incoming_initial_max_open_streams());
+  EXPECT_EQ(1u, stream_id_manager_.incoming_actual_max_streams());
+}
+
+TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsBadValuesOverMaxFailsOutgoing) {
+  QuicStreamCount implementation_max = QuicUtils::GetMaxStreamCount();
+  // Ensure that the limit is less than the implementation maximum.
+  EXPECT_LT(stream_id_manager_.outgoing_max_streams(), implementation_max);
+
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeAllowNewOutgoingStreams(implementation_max + 1));
+  // Should be pegged at the max.
+  EXPECT_EQ(implementation_max, stream_id_manager_.outgoing_max_streams());
+}
+
+// Check the case of the stream count in a STREAMS_BLOCKED frame is less than
+// the count most recently advertised in a MAX_STREAMS frame.
+TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedOk) {
+  QuicStreamCount stream_count =
+      stream_id_manager_.incoming_initial_max_open_streams();
+  QuicStreamsBlockedFrame frame(0, stream_count - 1, IsUnidirectional());
+  // We have notified peer about current max.
+  EXPECT_CALL(delegate_, SendMaxStreams(stream_count, IsUnidirectional()))
+      .Times(0);
+  std::string error_details;
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+}
+
+// Check the case of the stream count in a STREAMS_BLOCKED frame is equal to the
+// count most recently advertised in a MAX_STREAMS frame. No MAX_STREAMS
+// should be generated.
+TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedNoOp) {
+  QuicStreamCount stream_count =
+      stream_id_manager_.incoming_initial_max_open_streams();
+  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
+  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
+}
+
+// Check the case of the stream count in a STREAMS_BLOCKED frame is greater than
+// the count most recently advertised in a MAX_STREAMS frame. Expect a
+// connection close with an error.
+TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedTooBig) {
+  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
+  QuicStreamCount stream_count =
+      stream_id_manager_.incoming_initial_max_open_streams() + 1;
+  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
+  std::string error_details;
+  EXPECT_FALSE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+  EXPECT_EQ(
+      error_details,
+      "StreamsBlockedFrame's stream count 101 exceeds incoming max stream 100");
+}
+
+// Same basic tests as above, but calls
+// QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId directly, avoiding the
+// call chain. The intent is that if there is a problem, the following tests
+// will point to either the stream ID manager or the call chain. They also
+// provide specific, small scale, tests of a public QuicStreamIdManager method.
+// First test make sure that streams with ids below the limit are accepted.
+TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdValidBelowLimit) {
+  QuicStreamId stream_id = GetNthIncomingStreamId(
+      stream_id_manager_.incoming_actual_max_streams() - 2);
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
+}
+
+// Accept a stream with an ID that equals the limit.
+TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdValidAtLimit) {
+  QuicStreamId stream_id = GetNthIncomingStreamId(
+      stream_id_manager_.incoming_actual_max_streams() - 1);
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
+}
+
+// Close the connection if the id exceeds the limit.
+TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdInValidAboveLimit) {
+  QuicStreamId stream_id =
+      GetNthIncomingStreamId(stream_id_manager_.incoming_actual_max_streams());
+  std::string error_details;
+  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      stream_id, &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat("Stream id ", stream_id,
+                         " would exceed stream count limit 100"));
+}
+
+TEST_P(QuicStreamIdManagerTest, OnStreamsBlockedFrame) {
+  // Get the current maximum allowed incoming stream count.
+  QuicStreamCount advertised_stream_count =
+      stream_id_manager_.incoming_advertised_max_streams();
+
+  QuicStreamsBlockedFrame frame;
+
+  frame.unidirectional = IsUnidirectional();
+
+  // If the peer is saying it's blocked on the stream count that
+  // we've advertised, it's a noop since the peer has the correct information.
+  frame.stream_count = advertised_stream_count;
+  std::string error_details;
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+
+  // If the peer is saying it's blocked on a stream count that is larger
+  // than what we've advertised, the connection should get closed.
+  frame.stream_count = advertised_stream_count + 1;
+  EXPECT_FALSE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+  EXPECT_EQ(
+      error_details,
+      "StreamsBlockedFrame's stream count 101 exceeds incoming max stream 100");
+
+  // If the peer is saying it's blocked on a count that is less than
+  // our actual count, we send a MAX_STREAMS frame and update
+  // the advertised value.
+  // First, need to bump up the actual max so there is room for the MAX
+  // STREAMS frame to send a larger ID.
+  QuicStreamCount actual_stream_count =
+      stream_id_manager_.incoming_actual_max_streams();
+
+  // Closing a stream will result in the ability to initiate one more
+  // stream
+  stream_id_manager_.OnStreamClosed(
+      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_));
+  EXPECT_EQ(actual_stream_count + 1u,
+            stream_id_manager_.incoming_actual_max_streams());
+  EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
+            stream_id_manager_.incoming_advertised_max_streams() + 1u);
+
+  // Now simulate receiving a STREAMS_BLOCKED frame...
+  // Changing the actual maximum, above, forces a MAX_STREAMS frame to be
+  // sent, so the logic for that (SendMaxStreamsFrame(), etc) is tested.
+
+  // The STREAMS_BLOCKED frame contains the previous advertised count,
+  // not the one that the peer would have received as a result of the
+  // MAX_STREAMS sent earler.
+  frame.stream_count = advertised_stream_count;
+
+  EXPECT_CALL(delegate_,
+              SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
+                             IsUnidirectional()));
+
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+  // Check that the saved frame is correct.
+  EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
+            stream_id_manager_.incoming_advertised_max_streams());
+}
+
+TEST_P(QuicStreamIdManagerTest, GetNextOutgoingStream) {
+  // Number of streams we can open and the first one we should get when
+  // opening...
+  size_t number_of_streams = kDefaultMaxStreamsPerConnection;
+
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeAllowNewOutgoingStreams(number_of_streams));
+
+  QuicStreamId stream_id = IsUnidirectional()
+                               ? QuicUtils::GetFirstUnidirectionalStreamId(
+                                     transport_version(), perspective())
+                               : QuicUtils::GetFirstBidirectionalStreamId(
+                                     transport_version(), perspective());
+
+  EXPECT_EQ(number_of_streams, stream_id_manager_.outgoing_max_streams());
+  while (number_of_streams) {
+    EXPECT_TRUE(stream_id_manager_.CanOpenNextOutgoingStream());
+    EXPECT_EQ(stream_id, stream_id_manager_.GetNextOutgoingStreamId());
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+    number_of_streams--;
+  }
+
+  // If we try to check that the next outgoing stream id is available it should
+  // fail.
+  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
+
+  // If we try to get the next id (above the limit), it should cause a quic-bug.
+  EXPECT_QUIC_BUG(
+      stream_id_manager_.GetNextOutgoingStreamId(),
+      "Attempt to allocate a new outgoing stream that would exceed the limit");
+}
+
+TEST_P(QuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
+  QuicStreamId max_stream_id = GetNthIncomingStreamId(
+      stream_id_manager_.incoming_actual_max_streams() - 1);
+  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(max_stream_id,
+                                                                  nullptr));
+
+  QuicStreamId first_stream_id = GetNthIncomingStreamId(0);
+  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      first_stream_id, nullptr));
+  // A bad stream ID results in a closed connection.
+  std::string error_details;
+  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      max_stream_id + QuicUtils::StreamIdDelta(transport_version()),
+      &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat(
+                "Stream id ",
+                max_stream_id + QuicUtils::StreamIdDelta(transport_version()),
+                " would exceed stream count limit 100"));
+}
+
+TEST_P(QuicStreamIdManagerTest, MaxStreamsWindow) {
+  // Open and then close a number of streams to get close to the threshold of
+  // sending a MAX_STREAM_FRAME.
+  int stream_count = stream_id_manager_.incoming_initial_max_open_streams() /
+                         GetQuicFlag(FLAGS_quic_max_streams_window_divisor) -
+                     1;
+
+  // Should not get a control-frame transmission since the peer should have
+  // "plenty" of stream IDs to use.
+  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
+
+  // Get the first incoming stream ID to try and allocate.
+  QuicStreamId stream_id = GetNthIncomingStreamId(0);
+  size_t old_available_incoming_streams =
+      stream_id_manager_.available_incoming_streams();
+  auto i = stream_count;
+  while (i) {
+    EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id,
+                                                                    nullptr));
+
+    // This node should think that the peer believes it has one fewer
+    // stream it can create.
+    old_available_incoming_streams--;
+    EXPECT_EQ(old_available_incoming_streams,
+              stream_id_manager_.available_incoming_streams());
+
+    i--;
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+
+  // Now close them, still should get no MAX_STREAMS
+  stream_id = GetNthIncomingStreamId(0);
+  QuicStreamCount expected_actual_max =
+      stream_id_manager_.incoming_actual_max_streams();
+  QuicStreamCount expected_advertised_max_streams =
+      stream_id_manager_.incoming_advertised_max_streams();
+  while (stream_count) {
+    stream_id_manager_.OnStreamClosed(stream_id);
+    stream_count--;
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+    expected_actual_max++;
+    EXPECT_EQ(expected_actual_max,
+              stream_id_manager_.incoming_actual_max_streams());
+    // Advertised maximum should remain the same.
+    EXPECT_EQ(expected_advertised_max_streams,
+              stream_id_manager_.incoming_advertised_max_streams());
+  }
+
+  // This should not change.
+  EXPECT_EQ(old_available_incoming_streams,
+            stream_id_manager_.available_incoming_streams());
+
+  // Now whenever we close a stream we should get a MAX_STREAMS frame.
+  // Above code closed all the open streams, so we have to open/close
+  //  EXPECT_CALL(delegate_,
+  //  SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
+  //  IsUnidirectional()));
+  EXPECT_CALL(delegate_, SendMaxStreams(_, IsUnidirectional()));
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
+  stream_id_manager_.OnStreamClosed(stream_id);
+}
+
+TEST_P(QuicStreamIdManagerTest, StreamsBlockedEdgeConditions) {
+  QuicStreamsBlockedFrame frame;
+  frame.unidirectional = IsUnidirectional();
+
+  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 does nothing
+  // when max_allowed_incoming_streams is 0.
+  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
+  stream_id_manager_.SetMaxOpenIncomingStreams(0);
+  frame.stream_count = 0;
+  std::string error_details;
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+
+  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 invokes a
+  // MAX STREAMS, count = 123, when the MaxOpen... is set to 123.
+  EXPECT_CALL(delegate_, SendMaxStreams(123u, IsUnidirectional()));
+  QuicStreamIdManagerPeer::set_incoming_actual_max_streams(&stream_id_manager_,
+                                                           123);
+  frame.stream_count = 0;
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+}
+
+// Test that a MAX_STREAMS frame is generated when half the stream ids become
+// available. This has a useful side effect of testing that when streams are
+// closed, the number of available stream ids increases.
+TEST_P(QuicStreamIdManagerTest, MaxStreamsSlidingWindow) {
+  QuicStreamCount first_advert =
+      stream_id_manager_.incoming_advertised_max_streams();
+
+  // Open/close enough streams to shrink the window without causing a MAX
+  // STREAMS to be generated. The loop
+  // will make that many stream IDs available, so the last CloseStream should
+  // cause a MAX STREAMS frame to be generated.
+  int i =
+      static_cast<int>(stream_id_manager_.incoming_initial_max_open_streams() /
+                       GetQuicFlag(FLAGS_quic_max_streams_window_divisor));
+  QuicStreamId id =
+      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_);
+  EXPECT_CALL(delegate_, SendMaxStreams(first_advert + i, IsUnidirectional()));
+  while (i) {
+    EXPECT_TRUE(
+        stream_id_manager_.MaybeIncreaseLargestPeerStreamId(id, nullptr));
+    stream_id_manager_.OnStreamClosed(id);
+    i--;
+    id += QuicUtils::StreamIdDelta(transport_version());
+  }
+}
+
+TEST_P(QuicStreamIdManagerTest, NewStreamDoesNotExceedLimit) {
+  EXPECT_TRUE(stream_id_manager_.MaybeAllowNewOutgoingStreams(100));
+
+  size_t stream_count = stream_id_manager_.outgoing_max_streams();
+  EXPECT_NE(0u, stream_count);
+
+  while (stream_count) {
+    EXPECT_TRUE(stream_id_manager_.CanOpenNextOutgoingStream());
+    stream_id_manager_.GetNextOutgoingStreamId();
+    stream_count--;
+  }
+
+  EXPECT_EQ(stream_id_manager_.outgoing_stream_count(),
+            stream_id_manager_.outgoing_max_streams());
+  // Create another, it should fail.
+  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
+}
+
+TEST_P(QuicStreamIdManagerTest, AvailableStreams) {
+  stream_id_manager_.MaybeIncreaseLargestPeerStreamId(GetNthIncomingStreamId(3),
+                                                      nullptr);
+
+  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(1)));
+  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(2)));
+  EXPECT_FALSE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(3)));
+  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(4)));
+}
+
+// Tests that if MaybeIncreaseLargestPeerStreamId is given an extremely
+// large stream ID (larger than the limit) it is rejected.
+// This is a regression for Chromium bugs 909987 and 910040
+TEST_P(QuicStreamIdManagerTest, ExtremeMaybeIncreaseLargestPeerStreamId) {
+  QuicStreamId too_big_stream_id = GetNthIncomingStreamId(
+      stream_id_manager_.incoming_actual_max_streams() + 20);
+
+  std::string error_details;
+  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      too_big_stream_id, &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat("Stream id ", too_big_stream_id,
+                         " would exceed stream count limit 100"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_send_buffer.cc b/quiche/quic/core/quic_stream_send_buffer.cc
new file mode 100644
index 0000000..21decfd
--- /dev/null
+++ b/quiche/quic/core/quic_stream_send_buffer.cc
@@ -0,0 +1,298 @@
+// Copyright (c) 2017 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 "quiche/quic/core/quic_stream_send_buffer.h"
+
+#include <algorithm>
+
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+namespace {
+
+struct CompareOffset {
+  bool operator()(const BufferedSlice& slice, QuicStreamOffset offset) const {
+    return slice.offset + slice.slice.length() < offset;
+  }
+};
+
+}  // namespace
+
+BufferedSlice::BufferedSlice(quiche::QuicheMemSlice mem_slice,
+                             QuicStreamOffset offset)
+    : slice(std::move(mem_slice)), offset(offset) {}
+
+BufferedSlice::BufferedSlice(BufferedSlice&& other) = default;
+
+BufferedSlice& BufferedSlice::operator=(BufferedSlice&& other) = default;
+
+BufferedSlice::~BufferedSlice() {}
+
+QuicInterval<std::size_t> BufferedSlice::interval() const {
+  const std::size_t length = slice.length();
+  return QuicInterval<std::size_t>(offset, offset + length);
+}
+
+bool StreamPendingRetransmission::operator==(
+    const StreamPendingRetransmission& other) const {
+  return offset == other.offset && length == other.length;
+}
+
+QuicStreamSendBuffer::QuicStreamSendBuffer(
+    quiche::QuicheBufferAllocator* allocator)
+    : current_end_offset_(0),
+      stream_offset_(0),
+      allocator_(allocator),
+      stream_bytes_written_(0),
+      stream_bytes_outstanding_(0),
+      write_index_(-1) {}
+
+QuicStreamSendBuffer::~QuicStreamSendBuffer() {}
+
+void QuicStreamSendBuffer::SaveStreamData(absl::string_view data) {
+  QUICHE_DCHECK(!data.empty());
+
+  // Latch the maximum data slice size.
+  const QuicByteCount max_data_slice_size =
+      GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size);
+  while (!data.empty()) {
+    auto slice_len = std::min<absl::string_view::size_type>(
+        data.length(), max_data_slice_size);
+    auto buffer =
+        quiche::QuicheBuffer::Copy(allocator_, data.substr(0, slice_len));
+    SaveMemSlice(quiche::QuicheMemSlice(std::move(buffer)));
+
+    data = data.substr(slice_len);
+  }
+}
+
+void QuicStreamSendBuffer::SaveMemSlice(quiche::QuicheMemSlice slice) {
+  QUIC_DVLOG(2) << "Save slice offset " << stream_offset_ << " length "
+                << slice.length();
+  if (slice.empty()) {
+    QUIC_BUG(quic_bug_10853_1) << "Try to save empty MemSlice to send buffer.";
+    return;
+  }
+  size_t length = slice.length();
+  // Need to start the offsets at the right interval.
+  if (interval_deque_.Empty()) {
+    const QuicStreamOffset end = stream_offset_ + length;
+    current_end_offset_ = std::max(current_end_offset_, end);
+  }
+  BufferedSlice bs = BufferedSlice(std::move(slice), stream_offset_);
+  interval_deque_.PushBack(std::move(bs));
+  stream_offset_ += length;
+}
+
+QuicByteCount QuicStreamSendBuffer::SaveMemSliceSpan(
+    absl::Span<quiche::QuicheMemSlice> span) {
+  QuicByteCount total = 0;
+  for (quiche::QuicheMemSlice& slice : span) {
+    if (slice.length() == 0) {
+      // Skip empty slices.
+      continue;
+    }
+    total += slice.length();
+    SaveMemSlice(std::move(slice));
+  }
+  return total;
+}
+
+void QuicStreamSendBuffer::OnStreamDataConsumed(size_t bytes_consumed) {
+  stream_bytes_written_ += bytes_consumed;
+  stream_bytes_outstanding_ += bytes_consumed;
+}
+
+bool QuicStreamSendBuffer::WriteStreamData(QuicStreamOffset offset,
+                                           QuicByteCount data_length,
+                                           QuicDataWriter* writer) {
+  QUIC_BUG_IF(quic_bug_12823_1, current_end_offset_ < offset)
+      << "Tried to write data out of sequence. last_offset_end:"
+      << current_end_offset_ << ", offset:" << offset;
+  // The iterator returned from |interval_deque_| will automatically advance
+  // the internal write index for the QuicIntervalDeque. The incrementing is
+  // done in operator++.
+  for (auto slice_it = interval_deque_.DataAt(offset);
+       slice_it != interval_deque_.DataEnd(); ++slice_it) {
+    if (data_length == 0 || offset < slice_it->offset) {
+      break;
+    }
+
+    QuicByteCount slice_offset = offset - slice_it->offset;
+    QuicByteCount available_bytes_in_slice =
+        slice_it->slice.length() - slice_offset;
+    QuicByteCount copy_length = std::min(data_length, available_bytes_in_slice);
+    if (!writer->WriteBytes(slice_it->slice.data() + slice_offset,
+                            copy_length)) {
+      QUIC_BUG(quic_bug_10853_2) << "Writer fails to write.";
+      return false;
+    }
+    offset += copy_length;
+    data_length -= copy_length;
+    const QuicStreamOffset new_end =
+        slice_it->offset + slice_it->slice.length();
+    current_end_offset_ = std::max(current_end_offset_, new_end);
+  }
+  return data_length == 0;
+}
+
+bool QuicStreamSendBuffer::OnStreamDataAcked(
+    QuicStreamOffset offset,
+    QuicByteCount data_length,
+    QuicByteCount* newly_acked_length) {
+  *newly_acked_length = 0;
+  if (data_length == 0) {
+    return true;
+  }
+  if (bytes_acked_.Empty() || offset >= bytes_acked_.rbegin()->max() ||
+      bytes_acked_.IsDisjoint(
+          QuicInterval<QuicStreamOffset>(offset, offset + data_length))) {
+    // Optimization for the typical case, when all data is newly acked.
+    if (stream_bytes_outstanding_ < data_length) {
+      return false;
+    }
+    bytes_acked_.AddOptimizedForAppend(offset, offset + data_length);
+    *newly_acked_length = data_length;
+    stream_bytes_outstanding_ -= data_length;
+    pending_retransmissions_.Difference(offset, offset + data_length);
+    if (!FreeMemSlices(offset, offset + data_length)) {
+      return false;
+    }
+    CleanUpBufferedSlices();
+    return true;
+  }
+  // Exit if no new data gets acked.
+  if (bytes_acked_.Contains(offset, offset + data_length)) {
+    return true;
+  }
+  // Execute the slow path if newly acked data fill in existing holes.
+  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+  newly_acked.Difference(bytes_acked_);
+  for (const auto& interval : newly_acked) {
+    *newly_acked_length += (interval.max() - interval.min());
+  }
+  if (stream_bytes_outstanding_ < *newly_acked_length) {
+    return false;
+  }
+  stream_bytes_outstanding_ -= *newly_acked_length;
+  bytes_acked_.Add(offset, offset + data_length);
+  pending_retransmissions_.Difference(offset, offset + data_length);
+  if (newly_acked.Empty()) {
+    return true;
+  }
+  if (!FreeMemSlices(newly_acked.begin()->min(), newly_acked.rbegin()->max())) {
+    return false;
+  }
+  CleanUpBufferedSlices();
+  return true;
+}
+
+void QuicStreamSendBuffer::OnStreamDataLost(QuicStreamOffset offset,
+                                            QuicByteCount data_length) {
+  if (data_length == 0) {
+    return;
+  }
+  QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
+  bytes_lost.Difference(bytes_acked_);
+  if (bytes_lost.Empty()) {
+    return;
+  }
+  for (const auto& lost : bytes_lost) {
+    pending_retransmissions_.Add(lost.min(), lost.max());
+  }
+}
+
+void QuicStreamSendBuffer::OnStreamDataRetransmitted(
+    QuicStreamOffset offset,
+    QuicByteCount data_length) {
+  if (data_length == 0) {
+    return;
+  }
+  pending_retransmissions_.Difference(offset, offset + data_length);
+}
+
+bool QuicStreamSendBuffer::HasPendingRetransmission() const {
+  return !pending_retransmissions_.Empty();
+}
+
+StreamPendingRetransmission QuicStreamSendBuffer::NextPendingRetransmission()
+    const {
+  if (HasPendingRetransmission()) {
+    const auto pending = pending_retransmissions_.begin();
+    return {pending->min(), pending->max() - pending->min()};
+  }
+  QUIC_BUG(quic_bug_10853_3)
+      << "NextPendingRetransmission is called unexpected with no "
+         "pending retransmissions.";
+  return {0, 0};
+}
+
+bool QuicStreamSendBuffer::FreeMemSlices(QuicStreamOffset start,
+                                         QuicStreamOffset end) {
+  auto it = interval_deque_.DataBegin();
+  if (it == interval_deque_.DataEnd() || it->slice.empty()) {
+    QUIC_BUG(quic_bug_10853_4)
+        << "Trying to ack stream data [" << start << ", " << end << "), "
+        << (it == interval_deque_.DataEnd()
+                ? "and there is no outstanding data."
+                : "and the first slice is empty.");
+    return false;
+  }
+  if (!it->interval().Contains(start)) {
+    // Slow path that not the earliest outstanding data gets acked.
+    it = std::lower_bound(interval_deque_.DataBegin(),
+                          interval_deque_.DataEnd(), start, CompareOffset());
+  }
+  if (it == interval_deque_.DataEnd() || it->slice.empty()) {
+    QUIC_BUG(quic_bug_10853_5)
+        << "Offset " << start << " with iterator offset: " << it->offset
+        << (it == interval_deque_.DataEnd() ? " does not exist."
+                                            : " has already been acked.");
+    return false;
+  }
+  for (; it != interval_deque_.DataEnd(); ++it) {
+    if (it->offset >= end) {
+      break;
+    }
+    if (!it->slice.empty() &&
+        bytes_acked_.Contains(it->offset, it->offset + it->slice.length())) {
+      it->slice.Reset();
+    }
+  }
+  return true;
+}
+
+void QuicStreamSendBuffer::CleanUpBufferedSlices() {
+  while (!interval_deque_.Empty() &&
+         interval_deque_.DataBegin()->slice.empty()) {
+    QUIC_BUG_IF(quic_bug_12823_2,
+                interval_deque_.DataBegin()->offset > current_end_offset_)
+        << "Fail to pop front from interval_deque_. Front element contained "
+           "a slice whose data has not all be written. Front offset "
+        << interval_deque_.DataBegin()->offset << " length "
+        << interval_deque_.DataBegin()->slice.length();
+    interval_deque_.PopFront();
+  }
+}
+
+bool QuicStreamSendBuffer::IsStreamDataOutstanding(
+    QuicStreamOffset offset,
+    QuicByteCount data_length) const {
+  return data_length > 0 &&
+         !bytes_acked_.Contains(offset, offset + data_length);
+}
+
+size_t QuicStreamSendBuffer::size() const {
+  return interval_deque_.Size();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_send_buffer.h b/quiche/quic/core/quic_stream_send_buffer.h
new file mode 100644
index 0000000..c763c19
--- /dev/null
+++ b/quiche/quic/core/quic_stream_send_buffer.h
@@ -0,0 +1,173 @@
+// Copyright (c) 2017 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_STREAM_SEND_BUFFER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
+
+#include "absl/types/span.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_interval_deque.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class QuicStreamSendBufferPeer;
+class QuicStreamPeer;
+}  // namespace test
+
+class QuicDataWriter;
+
+// BufferedSlice comprises information of a piece of stream data stored in
+// contiguous memory space. Please note, BufferedSlice is constructed when
+// stream data is saved in send buffer and is removed when stream data is fully
+// acked. It is move-only.
+struct QUIC_EXPORT_PRIVATE BufferedSlice {
+  BufferedSlice(quiche::QuicheMemSlice mem_slice, QuicStreamOffset offset);
+  BufferedSlice(BufferedSlice&& other);
+  BufferedSlice& operator=(BufferedSlice&& other);
+
+  BufferedSlice(const BufferedSlice& other) = delete;
+  BufferedSlice& operator=(const BufferedSlice& other) = delete;
+  ~BufferedSlice();
+
+  // Return an interval representing the offset and length.
+  QuicInterval<std::size_t> interval() const;
+
+  // Stream data of this data slice.
+  quiche::QuicheMemSlice slice;
+  // Location of this data slice in the stream.
+  QuicStreamOffset offset;
+};
+
+struct QUIC_EXPORT_PRIVATE StreamPendingRetransmission {
+  constexpr StreamPendingRetransmission(QuicStreamOffset offset,
+                                        QuicByteCount length)
+      : offset(offset), length(length) {}
+
+  // Starting offset of this pending retransmission.
+  QuicStreamOffset offset;
+  // Length of this pending retransmission.
+  QuicByteCount length;
+
+  bool operator==(const StreamPendingRetransmission& other) const;
+};
+
+// QuicStreamSendBuffer contains a list of QuicStreamDataSlices. New data slices
+// are added to the tail of the list. Data slices are removed from the head of
+// the list when they get fully acked. Stream data can be retrieved and acked
+// across slice boundaries.
+class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
+ public:
+  explicit QuicStreamSendBuffer(quiche::QuicheBufferAllocator* allocator);
+  QuicStreamSendBuffer(const QuicStreamSendBuffer& other) = delete;
+  QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = delete;
+  ~QuicStreamSendBuffer();
+
+  // Save |data| to send buffer.
+  void SaveStreamData(absl::string_view data);
+
+  // Save |slice| to send buffer.
+  void SaveMemSlice(quiche::QuicheMemSlice slice);
+
+  // Save all slices in |span| to send buffer. Return total bytes saved.
+  QuicByteCount SaveMemSliceSpan(absl::Span<quiche::QuicheMemSlice> span);
+
+  // Called when |bytes_consumed| bytes has been consumed by the stream.
+  void OnStreamDataConsumed(size_t bytes_consumed);
+
+  // Write |data_length| of data starts at |offset|.
+  bool WriteStreamData(QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer);
+
+  // Called when data [offset, offset + data_length) is acked or removed as
+  // stream is canceled. Removes fully acked data slice from send buffer. Set
+  // |newly_acked_length|. Returns false if trying to ack unsent data.
+  bool OnStreamDataAcked(QuicStreamOffset offset,
+                         QuicByteCount data_length,
+                         QuicByteCount* newly_acked_length);
+
+  // Called when data [offset, offset + data_length) is considered as lost.
+  void OnStreamDataLost(QuicStreamOffset offset, QuicByteCount data_length);
+
+  // Called when data [offset, offset + length) was retransmitted.
+  void OnStreamDataRetransmitted(QuicStreamOffset offset,
+                                 QuicByteCount data_length);
+
+  // Returns true if there is pending retransmissions.
+  bool HasPendingRetransmission() const;
+
+  // Returns next pending retransmissions.
+  StreamPendingRetransmission NextPendingRetransmission() const;
+
+  // Returns true if data [offset, offset + data_length) is outstanding and
+  // waiting to be acked. Returns false otherwise.
+  bool IsStreamDataOutstanding(QuicStreamOffset offset,
+                               QuicByteCount data_length) const;
+
+  // Number of data slices in send buffer.
+  size_t size() const;
+
+  QuicStreamOffset stream_offset() const { return stream_offset_; }
+
+  uint64_t stream_bytes_written() const { return stream_bytes_written_; }
+
+  uint64_t stream_bytes_outstanding() const {
+    return stream_bytes_outstanding_;
+  }
+
+  const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const {
+    return bytes_acked_;
+  }
+
+  const QuicIntervalSet<QuicStreamOffset>& pending_retransmissions() const {
+    return pending_retransmissions_;
+  }
+
+ private:
+  friend class test::QuicStreamSendBufferPeer;
+  friend class test::QuicStreamPeer;
+
+  // Called when data within offset [start, end) gets acked. Frees fully
+  // acked buffered slices if any. Returns false if the corresponding data does
+  // not exist or has been acked.
+  bool FreeMemSlices(QuicStreamOffset start, QuicStreamOffset end);
+
+  // Cleanup empty slices in order from buffered_slices_.
+  void CleanUpBufferedSlices();
+
+  // |current_end_offset_| stores the end offset of the current slice to ensure
+  // data isn't being written out of order when using the |interval_deque_|.
+  QuicStreamOffset current_end_offset_;
+  QuicIntervalDeque<BufferedSlice> interval_deque_;
+
+  // Offset of next inserted byte.
+  QuicStreamOffset stream_offset_;
+
+  quiche::QuicheBufferAllocator* allocator_;
+
+  // Bytes that have been consumed by the stream.
+  uint64_t stream_bytes_written_;
+
+  // Bytes that have been consumed and are waiting to be acked.
+  uint64_t stream_bytes_outstanding_;
+
+  // Offsets of data that has been acked.
+  QuicIntervalSet<QuicStreamOffset> bytes_acked_;
+
+  // Data considered as lost and needs to be retransmitted.
+  QuicIntervalSet<QuicStreamOffset> pending_retransmissions_;
+
+  // Index of slice which contains data waiting to be written for the first
+  // time. -1 if send buffer is empty or all data has been written.
+  int32_t write_index_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
diff --git a/quiche/quic/core/quic_stream_send_buffer_test.cc b/quiche/quic/core/quic_stream_send_buffer_test.cc
new file mode 100644
index 0000000..7abd791
--- /dev/null
+++ b/quiche/quic/core/quic_stream_send_buffer_test.cc
@@ -0,0 +1,345 @@
+// Copyright (c) 2017 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 "quiche/quic/core/quic_stream_send_buffer.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicStreamSendBufferTest : public QuicTest {
+ public:
+  QuicStreamSendBufferTest() : send_buffer_(&allocator_) {
+    EXPECT_EQ(0u, send_buffer_.size());
+    EXPECT_EQ(0u, send_buffer_.stream_bytes_written());
+    EXPECT_EQ(0u, send_buffer_.stream_bytes_outstanding());
+    // The stream offset should be 0 since nothing is written.
+    EXPECT_EQ(0u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+
+    std::string data1 = absl::StrCat(
+        std::string(1536, 'a'), std::string(256, 'b'), std::string(256, 'c'));
+
+    quiche::QuicheBuffer buffer1(&allocator_, 1024);
+    memset(buffer1.data(), 'c', buffer1.size());
+    quiche::QuicheMemSlice slice1(std::move(buffer1));
+
+    quiche::QuicheBuffer buffer2(&allocator_, 768);
+    memset(buffer2.data(), 'd', buffer2.size());
+    quiche::QuicheMemSlice slice2(std::move(buffer2));
+
+    // `data` will be split into two BufferedSlices.
+    SetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size, 1024);
+    send_buffer_.SaveStreamData(data1);
+
+    send_buffer_.SaveMemSlice(std::move(slice1));
+    EXPECT_TRUE(slice1.empty());
+    send_buffer_.SaveMemSlice(std::move(slice2));
+    EXPECT_TRUE(slice2.empty());
+
+    EXPECT_EQ(4u, send_buffer_.size());
+    // At this point, `send_buffer_.interval_deque_` looks like this:
+    // BufferedSlice1: 'a' * 1024
+    // BufferedSlice2: 'a' * 512 + 'b' * 256 + 'c' * 256
+    // BufferedSlice3: 'c' * 1024
+    // BufferedSlice4: 'd' * 768
+  }
+
+  void WriteAllData() {
+    // Write all data.
+    char buf[4000];
+    QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
+    send_buffer_.WriteStreamData(0, 3840u, &writer);
+
+    send_buffer_.OnStreamDataConsumed(3840u);
+    EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
+    EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
+  }
+
+  quiche::SimpleBufferAllocator allocator_;
+  QuicStreamSendBuffer send_buffer_;
+};
+
+TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) {
+  char buf[4000];
+  QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
+  std::string copy1(1024, 'a');
+  std::string copy2 =
+      std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
+  std::string copy3(1024, 'c');
+  std::string copy4(768, 'd');
+
+  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
+  EXPECT_EQ(copy1, absl::string_view(buf, 1024));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 1024, &writer));
+  EXPECT_EQ(copy2, absl::string_view(buf + 1024, 1024));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1024, &writer));
+  EXPECT_EQ(copy3, absl::string_view(buf + 2048, 1024));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(3072, 768, &writer));
+  EXPECT_EQ(copy4, absl::string_view(buf + 3072, 768));
+
+  // Test data piece across boundries.
+  QuicDataWriter writer2(4000, buf, quiche::HOST_BYTE_ORDER);
+  std::string copy5 =
+      std::string(536, 'a') + std::string(256, 'b') + std::string(232, 'c');
+  ASSERT_TRUE(send_buffer_.WriteStreamData(1000, 1024, &writer2));
+  EXPECT_EQ(copy5, absl::string_view(buf, 1024));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(2500, 1024, &writer2));
+  std::string copy6 = std::string(572, 'c') + std::string(452, 'd');
+  EXPECT_EQ(copy6, absl::string_view(buf + 1024, 1024));
+
+  // Invalid data copy.
+  QuicDataWriter writer3(4000, buf, quiche::HOST_BYTE_ORDER);
+  EXPECT_FALSE(send_buffer_.WriteStreamData(3000, 1024, &writer3));
+  EXPECT_QUIC_BUG(send_buffer_.WriteStreamData(0, 4000, &writer3),
+                  "Writer fails to write.");
+
+  send_buffer_.OnStreamDataConsumed(3840);
+  EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
+  EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
+}
+
+// Regression test for b/143491027.
+TEST_F(QuicStreamSendBufferTest,
+       WriteStreamDataContainsBothRetransmissionAndNewData) {
+  std::string copy1(1024, 'a');
+  std::string copy2 =
+      std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
+  std::string copy3 = std::string(1024, 'c') + std::string(100, 'd');
+  char buf[6000];
+  QuicDataWriter writer(6000, buf, quiche::HOST_BYTE_ORDER);
+  // Write more than one slice.
+  EXPECT_EQ(0, QuicStreamSendBufferPeer::write_index(&send_buffer_));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
+  EXPECT_EQ(copy1, absl::string_view(buf, 1024));
+  EXPECT_EQ(1, QuicStreamSendBufferPeer::write_index(&send_buffer_));
+
+  // Retransmit the first frame and also send new data.
+  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 2048, &writer));
+  EXPECT_EQ(copy1 + copy2, absl::string_view(buf + 1024, 2048));
+
+  // Write new data.
+  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 50, &writer));
+  EXPECT_EQ(std::string(50, 'c'), absl::string_view(buf + 1024 + 2048, 50));
+  EXPECT_EQ(3072u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1124, &writer));
+  EXPECT_EQ(copy3, absl::string_view(buf + 1024 + 2048 + 50, 1124));
+  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+}
+
+TEST_F(QuicStreamSendBufferTest, RemoveStreamFrame) {
+  WriteAllData();
+
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1024, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2048, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+
+  // Send buffer is cleaned up in order.
+  EXPECT_EQ(1u, send_buffer_.size());
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3072, 768, &newly_acked_length));
+  EXPECT_EQ(768u, newly_acked_length);
+  EXPECT_EQ(0u, send_buffer_.size());
+}
+
+TEST_F(QuicStreamSendBufferTest, RemoveStreamFrameAcrossBoundries) {
+  WriteAllData();
+
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2024, 576, &newly_acked_length));
+  EXPECT_EQ(576u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
+  EXPECT_EQ(1000u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1000, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+  // Send buffer is cleaned up in order.
+  EXPECT_EQ(2u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2600, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+  EXPECT_EQ(1u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3624, 216, &newly_acked_length));
+  EXPECT_EQ(216u, newly_acked_length);
+  EXPECT_EQ(0u, send_buffer_.size());
+}
+
+TEST_F(QuicStreamSendBufferTest, AckStreamDataMultipleTimes) {
+  WriteAllData();
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(100, 1500, &newly_acked_length));
+  EXPECT_EQ(1500u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 500, &newly_acked_length));
+  EXPECT_EQ(500u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 2600, &newly_acked_length));
+  EXPECT_EQ(600u, newly_acked_length);
+  // Send buffer is cleaned up in order.
+  EXPECT_EQ(2u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2200, 1640, &newly_acked_length));
+  EXPECT_EQ(1240u, newly_acked_length);
+  EXPECT_EQ(0u, send_buffer_.size());
+
+  EXPECT_FALSE(send_buffer_.OnStreamDataAcked(4000, 100, &newly_acked_length));
+}
+
+TEST_F(QuicStreamSendBufferTest, AckStreamDataOutOfOrder) {
+  WriteAllData();
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 1000, &newly_acked_length));
+  EXPECT_EQ(1000u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1200, 1000, &newly_acked_length));
+  EXPECT_EQ(700u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+  // Slice 2 gets fully acked.
+  EXPECT_EQ(2816u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 1840, &newly_acked_length));
+  EXPECT_EQ(1640u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+  // Slices 3 and 4 get fully acked.
+  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
+  EXPECT_EQ(500u, newly_acked_length);
+  EXPECT_EQ(0u, send_buffer_.size());
+  EXPECT_EQ(0u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+}
+
+TEST_F(QuicStreamSendBufferTest, PendingRetransmission) {
+  WriteAllData();
+  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 3840));
+  EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
+  // Lost data [0, 1200).
+  send_buffer_.OnStreamDataLost(0, 1200);
+  // Lost data [1500, 2000).
+  send_buffer_.OnStreamDataLost(1500, 500);
+  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
+
+  EXPECT_EQ(StreamPendingRetransmission(0, 1200),
+            send_buffer_.NextPendingRetransmission());
+  // Retransmit data [0, 500).
+  send_buffer_.OnStreamDataRetransmitted(0, 500);
+  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 500));
+  EXPECT_EQ(StreamPendingRetransmission(500, 700),
+            send_buffer_.NextPendingRetransmission());
+  // Ack data [500, 1200).
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 700, &newly_acked_length));
+  EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(500, 700));
+  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
+  EXPECT_EQ(StreamPendingRetransmission(1500, 500),
+            send_buffer_.NextPendingRetransmission());
+  // Retransmit data [1500, 2000).
+  send_buffer_.OnStreamDataRetransmitted(1500, 500);
+  EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
+
+  // Lost [200, 800).
+  send_buffer_.OnStreamDataLost(200, 600);
+  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
+  // Verify [200, 500) is considered as lost, as [500, 800) has been acked.
+  EXPECT_EQ(StreamPendingRetransmission(200, 300),
+            send_buffer_.NextPendingRetransmission());
+
+  // Verify 0 length data is not outstanding.
+  EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(100, 0));
+  // Verify partially acked data is outstanding.
+  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(400, 800));
+}
+
+TEST_F(QuicStreamSendBufferTest, EndOffset) {
+  char buf[4000];
+  QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
+
+  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
+  // Last offset we've seen is 1024
+  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+
+  ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 512, &writer));
+  // Last offset is now 2048 as that's the end of the next slice.
+  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  send_buffer_.OnStreamDataConsumed(1024);
+
+  // If data in 1st slice gets ACK'ed, it shouldn't change the indexed slice
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
+  // Last offset is still 2048.
+  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+
+  ASSERT_TRUE(
+      send_buffer_.WriteStreamData(1024 + 512, 3840 - 1024 - 512, &writer));
+
+  // Last offset is end offset of last slice.
+  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  quiche::QuicheBuffer buffer(&allocator_, 60);
+  memset(buffer.data(), 'e', buffer.size());
+  quiche::QuicheMemSlice slice(std::move(buffer));
+  send_buffer_.SaveMemSlice(std::move(slice));
+
+  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+}
+
+TEST_F(QuicStreamSendBufferTest, SaveMemSliceSpan) {
+  quiche::SimpleBufferAllocator allocator;
+  QuicStreamSendBuffer send_buffer(&allocator);
+
+  std::string data(1024, 'a');
+  std::vector<quiche::QuicheMemSlice> buffers;
+  for (size_t i = 0; i < 10; ++i) {
+    buffers.push_back(MemSliceFromString(data));
+  }
+
+  EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(absl::MakeSpan(buffers)));
+  EXPECT_EQ(10u, send_buffer.size());
+}
+
+TEST_F(QuicStreamSendBufferTest, SaveEmptyMemSliceSpan) {
+  quiche::SimpleBufferAllocator allocator;
+  QuicStreamSendBuffer send_buffer(&allocator);
+
+  std::string data(1024, 'a');
+  std::vector<quiche::QuicheMemSlice> buffers;
+  for (size_t i = 0; i < 10; ++i) {
+    buffers.push_back(MemSliceFromString(data));
+  }
+
+  EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(absl::MakeSpan(buffers)));
+  // Verify the empty slice does not get saved.
+  EXPECT_EQ(10u, send_buffer.size());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_sequencer.cc b/quiche/quic/core/quic_stream_sequencer.cc
new file mode 100644
index 0000000..61eec53
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer.cc
@@ -0,0 +1,309 @@
+// 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 "quiche/quic/core/quic_stream_sequencer.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_stream_sequencer_buffer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+
+namespace quic {
+
+QuicStreamSequencer::QuicStreamSequencer(StreamInterface* quic_stream)
+    : stream_(quic_stream),
+      buffered_frames_(kStreamReceiveWindowLimit),
+      highest_offset_(0),
+      close_offset_(std::numeric_limits<QuicStreamOffset>::max()),
+      blocked_(false),
+      num_frames_received_(0),
+      num_duplicate_frames_received_(0),
+      ignore_read_data_(false),
+      level_triggered_(false) {}
+
+QuicStreamSequencer::~QuicStreamSequencer() {
+  if (stream_ == nullptr) {
+    QUIC_BUG(quic_bug_10858_1) << "Double free'ing QuicStreamSequencer at "
+                               << this << ". " << QuicStackTrace();
+  }
+  stream_ = nullptr;
+}
+
+void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
+  QUICHE_DCHECK_LE(frame.offset + frame.data_length, close_offset_);
+  ++num_frames_received_;
+  const QuicStreamOffset byte_offset = frame.offset;
+  const size_t data_len = frame.data_length;
+
+  if (frame.fin &&
+      (!CloseStreamAtOffset(frame.offset + data_len) || data_len == 0)) {
+    return;
+  }
+  if (stream_->version().HasIetfQuicFrames() && data_len == 0) {
+    QUICHE_DCHECK(!frame.fin);
+    // Ignore empty frame with no fin.
+    return;
+  }
+  OnFrameData(byte_offset, data_len, frame.data_buffer);
+}
+
+void QuicStreamSequencer::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  ++num_frames_received_;
+  if (frame.data_length == 0) {
+    // Ignore empty crypto frame.
+    return;
+  }
+  OnFrameData(frame.offset, frame.data_length, frame.data_buffer);
+}
+
+void QuicStreamSequencer::OnFrameData(QuicStreamOffset byte_offset,
+                                      size_t data_len,
+                                      const char* data_buffer) {
+  highest_offset_ = std::max(highest_offset_, byte_offset + data_len);
+  const size_t previous_readable_bytes = buffered_frames_.ReadableBytes();
+  size_t bytes_written;
+  std::string error_details;
+  QuicErrorCode result = buffered_frames_.OnStreamData(
+      byte_offset, absl::string_view(data_buffer, data_len), &bytes_written,
+      &error_details);
+  if (result != QUIC_NO_ERROR) {
+    std::string details =
+        absl::StrCat("Stream ", stream_->id(), ": ",
+                     QuicErrorCodeToString(result), ": ", error_details);
+    QUIC_LOG_FIRST_N(WARNING, 50) << QuicErrorCodeToString(result);
+    QUIC_LOG_FIRST_N(WARNING, 50) << details;
+    stream_->OnUnrecoverableError(result, details);
+    return;
+  }
+
+  if (bytes_written == 0) {
+    ++num_duplicate_frames_received_;
+    // Silently ignore duplicates.
+    return;
+  }
+
+  if (blocked_) {
+    return;
+  }
+
+  if (level_triggered_) {
+    if (buffered_frames_.ReadableBytes() > previous_readable_bytes) {
+      // Readable bytes has changed, let stream decide if to inform application
+      // or not.
+      if (ignore_read_data_) {
+        FlushBufferedFrames();
+      } else {
+        stream_->OnDataAvailable();
+      }
+    }
+    return;
+  }
+  const bool stream_unblocked =
+      previous_readable_bytes == 0 && buffered_frames_.ReadableBytes() > 0;
+  if (stream_unblocked) {
+    if (ignore_read_data_) {
+      FlushBufferedFrames();
+    } else {
+      stream_->OnDataAvailable();
+    }
+  }
+}
+
+bool QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset) {
+  const QuicStreamOffset kMaxOffset =
+      std::numeric_limits<QuicStreamOffset>::max();
+
+  // If there is a scheduled close, the new offset should match it.
+  if (close_offset_ != kMaxOffset && offset != close_offset_) {
+    stream_->OnUnrecoverableError(
+        QUIC_STREAM_SEQUENCER_INVALID_STATE,
+        absl::StrCat(
+            "Stream ", stream_->id(), " received new final offset: ", offset,
+            ", which is different from close offset: ", close_offset_));
+    return false;
+  }
+
+  // The final offset should be no less than the highest offset that is
+  // received.
+  if (offset < highest_offset_) {
+    stream_->OnUnrecoverableError(
+        QUIC_STREAM_SEQUENCER_INVALID_STATE,
+        absl::StrCat(
+            "Stream ", stream_->id(), " received fin with offset: ", offset,
+            ", which reduces current highest offset: ", highest_offset_));
+    return false;
+  }
+
+  close_offset_ = offset;
+
+  MaybeCloseStream();
+  return true;
+}
+
+void QuicStreamSequencer::MaybeCloseStream() {
+  if (blocked_ || !IsClosed()) {
+    return;
+  }
+
+  QUIC_DVLOG(1) << "Passing up termination, as we've processed "
+                << buffered_frames_.BytesConsumed() << " of " << close_offset_
+                << " bytes.";
+  // This will cause the stream to consume the FIN.
+  // Technically it's an error if |num_bytes_consumed| isn't exactly
+  // equal to |close_offset|, but error handling seems silly at this point.
+  if (ignore_read_data_) {
+    // The sequencer is discarding stream data and must notify the stream on
+    // receipt of a FIN because the consumer won't.
+    stream_->OnFinRead();
+  } else {
+    stream_->OnDataAvailable();
+  }
+  buffered_frames_.Clear();
+}
+
+int QuicStreamSequencer::GetReadableRegions(iovec* iov, size_t iov_len) const {
+  QUICHE_DCHECK(!blocked_);
+  return buffered_frames_.GetReadableRegions(iov, iov_len);
+}
+
+bool QuicStreamSequencer::GetReadableRegion(iovec* iov) const {
+  QUICHE_DCHECK(!blocked_);
+  return buffered_frames_.GetReadableRegion(iov);
+}
+
+bool QuicStreamSequencer::PeekRegion(QuicStreamOffset offset,
+                                     iovec* iov) const {
+  QUICHE_DCHECK(!blocked_);
+  return buffered_frames_.PeekRegion(offset, iov);
+}
+
+void QuicStreamSequencer::Read(std::string* buffer) {
+  QUICHE_DCHECK(!blocked_);
+  buffer->resize(buffer->size() + ReadableBytes());
+  iovec iov;
+  iov.iov_len = ReadableBytes();
+  iov.iov_base = &(*buffer)[buffer->size() - iov.iov_len];
+  Readv(&iov, 1);
+}
+
+size_t QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) {
+  QUICHE_DCHECK(!blocked_);
+  std::string error_details;
+  size_t bytes_read;
+  QuicErrorCode read_error =
+      buffered_frames_.Readv(iov, iov_len, &bytes_read, &error_details);
+  if (read_error != QUIC_NO_ERROR) {
+    std::string details =
+        absl::StrCat("Stream ", stream_->id(), ": ", error_details);
+    stream_->OnUnrecoverableError(read_error, details);
+    return bytes_read;
+  }
+
+  stream_->AddBytesConsumed(bytes_read);
+  return bytes_read;
+}
+
+bool QuicStreamSequencer::HasBytesToRead() const {
+  return buffered_frames_.HasBytesToRead();
+}
+
+size_t QuicStreamSequencer::ReadableBytes() const {
+  return buffered_frames_.ReadableBytes();
+}
+
+bool QuicStreamSequencer::IsClosed() const {
+  return buffered_frames_.BytesConsumed() >= close_offset_;
+}
+
+void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) {
+  QUICHE_DCHECK(!blocked_);
+  bool result = buffered_frames_.MarkConsumed(num_bytes_consumed);
+  if (!result) {
+    QUIC_BUG(quic_bug_10858_2)
+        << "Invalid argument to MarkConsumed."
+        << " expect to consume: " << num_bytes_consumed
+        << ", but not enough bytes available. " << DebugString();
+    stream_->ResetWithError(
+        QuicResetStreamError::FromInternal(QUIC_ERROR_PROCESSING_STREAM));
+    return;
+  }
+  stream_->AddBytesConsumed(num_bytes_consumed);
+}
+
+void QuicStreamSequencer::SetBlockedUntilFlush() {
+  blocked_ = true;
+}
+
+void QuicStreamSequencer::SetUnblocked() {
+  blocked_ = false;
+  if (IsClosed() || HasBytesToRead()) {
+    stream_->OnDataAvailable();
+  }
+}
+
+void QuicStreamSequencer::StopReading() {
+  if (ignore_read_data_) {
+    return;
+  }
+  ignore_read_data_ = true;
+  FlushBufferedFrames();
+}
+
+void QuicStreamSequencer::ReleaseBuffer() {
+  buffered_frames_.ReleaseWholeBuffer();
+}
+
+void QuicStreamSequencer::ReleaseBufferIfEmpty() {
+  if (buffered_frames_.Empty()) {
+    buffered_frames_.ReleaseWholeBuffer();
+  }
+}
+
+void QuicStreamSequencer::FlushBufferedFrames() {
+  QUICHE_DCHECK(ignore_read_data_);
+  size_t bytes_flushed = buffered_frames_.FlushBufferedFrames();
+  QUIC_DVLOG(1) << "Flushing buffered data at offset "
+                << buffered_frames_.BytesConsumed() << " length "
+                << bytes_flushed << " for stream " << stream_->id();
+  stream_->AddBytesConsumed(bytes_flushed);
+  MaybeCloseStream();
+}
+
+size_t QuicStreamSequencer::NumBytesBuffered() const {
+  return buffered_frames_.BytesBuffered();
+}
+
+QuicStreamOffset QuicStreamSequencer::NumBytesConsumed() const {
+  return buffered_frames_.BytesConsumed();
+}
+
+const std::string QuicStreamSequencer::DebugString() const {
+  // clang-format off
+  return absl::StrCat("QuicStreamSequencer:",
+                "\n  bytes buffered: ", NumBytesBuffered(),
+                "\n  bytes consumed: ", NumBytesConsumed(),
+                "\n  has bytes to read: ", HasBytesToRead() ? "true" : "false",
+                "\n  frames received: ", num_frames_received(),
+                "\n  close offset bytes: ", close_offset_,
+                "\n  is closed: ", IsClosed() ? "true" : "false");
+  // clang-format on
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_sequencer.h b/quiche/quic/core/quic_stream_sequencer.h
new file mode 100644
index 0000000..0e8d2d2
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer.h
@@ -0,0 +1,217 @@
+// 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_STREAM_SEQUENCER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
+
+#include <cstddef>
+#include <map>
+#include <string>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_sequencer_buffer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicStreamSequencerPeer;
+}  // namespace test
+
+// Buffers frames until we have something which can be passed
+// up to the next layer.
+class QUIC_EXPORT_PRIVATE QuicStreamSequencer {
+ public:
+  // Interface that thie Sequencer uses to communicate with the Stream.
+  class QUIC_EXPORT_PRIVATE StreamInterface {
+   public:
+    virtual ~StreamInterface() = default;
+
+    // Called when new data is available to be read from the sequencer.
+    virtual void OnDataAvailable() = 0;
+    // Called when the end of the stream has been read.
+    virtual void OnFinRead() = 0;
+    // Called when bytes have been consumed from the sequencer.
+    virtual void AddBytesConsumed(QuicByteCount bytes) = 0;
+    // Called when an error has occurred which should result in the stream
+    // being reset.
+    virtual void ResetWithError(QuicResetStreamError error) = 0;
+    // Called when an error has occurred which should result in the connection
+    // being closed.
+    virtual void OnUnrecoverableError(QuicErrorCode error,
+                                      const std::string& details) = 0;
+    // Called when an error has occurred which should result in the connection
+    // being closed, specifying the wire error code |ietf_error| explicitly.
+    virtual void OnUnrecoverableError(QuicErrorCode error,
+                                      QuicIetfTransportErrorCodes ietf_error,
+                                      const std::string& details) = 0;
+    // Returns the stream id of this stream.
+    virtual QuicStreamId id() const = 0;
+
+    // Returns the QUIC version being used by this stream.
+    virtual ParsedQuicVersion version() const = 0;
+  };
+
+  explicit QuicStreamSequencer(StreamInterface* quic_stream);
+  QuicStreamSequencer(const QuicStreamSequencer&) = delete;
+  QuicStreamSequencer(QuicStreamSequencer&&) = default;
+  QuicStreamSequencer& operator=(const QuicStreamSequencer&) = delete;
+  QuicStreamSequencer& operator=(QuicStreamSequencer&&) = default;
+  virtual ~QuicStreamSequencer();
+
+  // If the frame is the next one we need in order to process in-order data,
+  // ProcessData will be immediately called on the stream until all buffered
+  // data is processed or the stream fails to consume data.  Any unconsumed
+  // data will be buffered. If the frame is not the next in line, it will be
+  // buffered.
+  void OnStreamFrame(const QuicStreamFrame& frame);
+
+  // If the frame is the next one we need in order to process in-order data,
+  // ProcessData will be immediately called on the crypto stream until all
+  // buffered data is processed or the crypto stream fails to consume data. Any
+  // unconsumed data will be buffered. If the frame is not the next in line, it
+  // will be buffered.
+  void OnCryptoFrame(const QuicCryptoFrame& frame);
+
+  // Once data is buffered, it's up to the stream to read it when the stream
+  // can handle more data.  The following three functions make that possible.
+
+  // Fills in up to iov_len iovecs with the next readable regions.  Returns the
+  // number of iovs used.  Non-destructive of the underlying data.
+  int GetReadableRegions(iovec* iov, size_t iov_len) const;
+
+  // Fills in one iovec with the next readable region.  Returns false if there
+  // is no readable region available.
+  bool GetReadableRegion(iovec* iov) const;
+
+  // Fills in one iovec with the region starting at |offset| and returns true.
+  // Returns false if no readable region is available, either because data has
+  // not been received yet or has already been consumed.
+  bool PeekRegion(QuicStreamOffset offset, iovec* iov) const;
+
+  // Copies the data into the iov_len buffers provided.  Returns the number of
+  // bytes read.  Any buffered data no longer in use will be released.
+  // TODO(rch): remove this method and instead implement it as a helper method
+  // based on GetReadableRegions and MarkConsumed.
+  size_t Readv(const struct iovec* iov, size_t iov_len);
+
+  // Consumes |num_bytes| data.  Used in conjunction with |GetReadableRegions|
+  // to do zero-copy reads.
+  void MarkConsumed(size_t num_bytes);
+
+  // Appends all of the readable data to |buffer| and marks all of the appended
+  // data as consumed.
+  void Read(std::string* buffer);
+
+  // Returns true if the sequncer has bytes available for reading.
+  bool HasBytesToRead() const;
+
+  // Number of bytes available to read.
+  size_t ReadableBytes() const;
+
+  // Returns true if the sequencer has delivered the fin.
+  bool IsClosed() const;
+
+  // Calls |OnDataAvailable| on |stream_| if there is buffered data that can
+  // be processed, and causes |OnDataAvailable| to be called as new data
+  // arrives.
+  void SetUnblocked();
+
+  // Blocks processing of frames until |SetUnblocked| is called.
+  void SetBlockedUntilFlush();
+
+  // Sets the sequencer to discard all incoming data itself and not call
+  // |stream_->OnDataAvailable()|.  |stream_->OnFinRead()| will be called
+  // automatically when the FIN is consumed (which may be immediately).
+  void StopReading();
+
+  // Free the memory of underlying buffer.
+  void ReleaseBuffer();
+
+  // Free the memory of underlying buffer when no bytes remain in it.
+  void ReleaseBufferIfEmpty();
+
+  // Number of bytes in the buffer right now.
+  size_t NumBytesBuffered() const;
+
+  // Number of bytes has been consumed.
+  QuicStreamOffset NumBytesConsumed() const;
+
+  QuicStreamOffset close_offset() const { return close_offset_; }
+
+  int num_frames_received() const { return num_frames_received_; }
+
+  int num_duplicate_frames_received() const {
+    return num_duplicate_frames_received_;
+  }
+
+  bool ignore_read_data() const { return ignore_read_data_; }
+
+  void set_level_triggered(bool level_triggered) {
+    level_triggered_ = level_triggered;
+  }
+
+  bool level_triggered() const { return level_triggered_; }
+
+  void set_stream(StreamInterface* stream) { stream_ = stream; }
+
+  // Returns string describing internal state.
+  const std::string DebugString() const;
+
+ private:
+  friend class test::QuicStreamSequencerPeer;
+
+  // Deletes and records as consumed any buffered data that is now in-sequence.
+  // (To be called only after StopReading has been called.)
+  void FlushBufferedFrames();
+
+  // Wait until we've seen 'offset' bytes, and then terminate the stream.
+  // Returns true if |stream_| is still available to receive data, and false if
+  // |stream_| is reset.
+  bool CloseStreamAtOffset(QuicStreamOffset offset);
+
+  // If we've received a FIN and have processed all remaining data, then inform
+  // the stream of FIN, and clear buffers.
+  void MaybeCloseStream();
+
+  // Shared implementation between OnStreamFrame and OnCryptoFrame.
+  void OnFrameData(QuicStreamOffset byte_offset,
+                   size_t data_len,
+                   const char* data_buffer);
+
+  // The stream which owns this sequencer.
+  StreamInterface* stream_;
+
+  // Stores received data in offset order.
+  QuicStreamSequencerBuffer buffered_frames_;
+
+  // The highest offset that is received so far.
+  QuicStreamOffset highest_offset_;
+
+  // The offset, if any, we got a stream termination for.  When this many bytes
+  // have been processed, the sequencer will be closed.
+  QuicStreamOffset close_offset_;
+
+  // If true, the sequencer is blocked from passing data to the stream and will
+  // buffer all new incoming data until FlushBufferedFrames is called.
+  bool blocked_;
+
+  // Count of the number of frames received.
+  int num_frames_received_;
+
+  // Count of the number of duplicate frames received.
+  int num_duplicate_frames_received_;
+
+  // If true, all incoming data will be discarded.
+  bool ignore_read_data_;
+
+  // If false, only call OnDataAvailable() when it becomes newly unblocked.
+  // Otherwise, call OnDataAvailable() when number of readable bytes changes.
+  bool level_triggered_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
diff --git a/quiche/quic/core/quic_stream_sequencer_buffer.cc b/quiche/quic/core/quic_stream_sequencer_buffer.cc
new file mode 100644
index 0000000..9f7e0c9
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer_buffer.cc
@@ -0,0 +1,546 @@
+// Copyright (c) 2015 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 "quiche/quic/core/quic_stream_sequencer_buffer.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace {
+
+size_t CalculateBlockCount(size_t max_capacity_bytes) {
+  return (max_capacity_bytes + QuicStreamSequencerBuffer::kBlockSizeBytes - 1) /
+         QuicStreamSequencerBuffer::kBlockSizeBytes;
+}
+
+// Upper limit of how many gaps allowed in buffer, which ensures a reasonable
+// number of iterations needed to find the right gap to fill when a frame
+// arrives.
+const size_t kMaxNumDataIntervalsAllowed = 2 * kMaxPacketGap;
+
+// Number of blocks allocated initially.
+constexpr size_t kInitialBlockCount = 8u;
+
+// How fast block pointers container grow in size.
+// Choose 4 to reduce the amount of reallocation.
+constexpr int kBlocksGrowthFactor = 4;
+
+}  // namespace
+
+QuicStreamSequencerBuffer::QuicStreamSequencerBuffer(size_t max_capacity_bytes)
+    : max_buffer_capacity_bytes_(max_capacity_bytes),
+      max_blocks_count_(CalculateBlockCount(max_capacity_bytes)),
+      current_blocks_count_(0u),
+      total_bytes_read_(0),
+      blocks_(nullptr) {
+  QUICHE_DCHECK_GE(max_blocks_count_, kInitialBlockCount);
+  Clear();
+}
+
+QuicStreamSequencerBuffer::~QuicStreamSequencerBuffer() {
+  Clear();
+}
+
+void QuicStreamSequencerBuffer::Clear() {
+  if (blocks_ != nullptr) {
+    for (size_t i = 0; i < current_blocks_count_; ++i) {
+      if (blocks_[i] != nullptr) {
+        RetireBlock(i);
+      }
+    }
+  }
+  num_bytes_buffered_ = 0;
+  bytes_received_.Clear();
+  bytes_received_.Add(0, total_bytes_read_);
+}
+
+bool QuicStreamSequencerBuffer::RetireBlock(size_t index) {
+  if (blocks_[index] == nullptr) {
+    QUIC_BUG(quic_bug_10610_1) << "Try to retire block twice";
+    return false;
+  }
+  delete blocks_[index];
+  blocks_[index] = nullptr;
+  QUIC_DVLOG(1) << "Retired block with index: " << index;
+  return true;
+}
+
+void QuicStreamSequencerBuffer::MaybeAddMoreBlocks(
+    QuicStreamOffset next_expected_byte) {
+  if (current_blocks_count_ == max_blocks_count_) {
+    return;
+  }
+  QuicStreamOffset last_byte = next_expected_byte - 1;
+  size_t num_of_blocks_needed;
+  // As long as last_byte does not wrap around, its index plus one blocks are
+  // needed. Otherwise, block_count_ blocks are needed.
+  if (last_byte < max_buffer_capacity_bytes_) {
+    num_of_blocks_needed =
+        std::max(GetBlockIndex(last_byte) + 1, kInitialBlockCount);
+  } else {
+    num_of_blocks_needed = max_blocks_count_;
+  }
+  if (current_blocks_count_ >= num_of_blocks_needed) {
+    return;
+  }
+  size_t new_block_count = kBlocksGrowthFactor * current_blocks_count_;
+  new_block_count = std::min(std::max(new_block_count, num_of_blocks_needed),
+                             max_blocks_count_);
+  auto new_blocks = std::make_unique<BufferBlock*[]>(new_block_count);
+  if (blocks_ != nullptr) {
+    memcpy(new_blocks.get(), blocks_.get(),
+           current_blocks_count_ * sizeof(BufferBlock*));
+  }
+  blocks_ = std::move(new_blocks);
+  current_blocks_count_ = new_block_count;
+}
+
+QuicErrorCode QuicStreamSequencerBuffer::OnStreamData(
+    QuicStreamOffset starting_offset,
+    absl::string_view data,
+    size_t* const bytes_buffered,
+    std::string* error_details) {
+  *bytes_buffered = 0;
+  size_t size = data.size();
+  if (size == 0) {
+    *error_details = "Received empty stream frame without FIN.";
+    return QUIC_EMPTY_STREAM_FRAME_NO_FIN;
+  }
+  // Write beyond the current range this buffer is covering.
+  if (starting_offset + size > total_bytes_read_ + max_buffer_capacity_bytes_ ||
+      starting_offset + size < starting_offset) {
+    *error_details = "Received data beyond available range.";
+    return QUIC_INTERNAL_ERROR;
+  }
+
+  if (bytes_received_.Empty() ||
+      starting_offset >= bytes_received_.rbegin()->max() ||
+      bytes_received_.IsDisjoint(QuicInterval<QuicStreamOffset>(
+          starting_offset, starting_offset + size))) {
+    // Optimization for the typical case, when all data is newly received.
+    bytes_received_.AddOptimizedForAppend(starting_offset,
+                                          starting_offset + size);
+    if (bytes_received_.Size() >= kMaxNumDataIntervalsAllowed) {
+      // This frame is going to create more intervals than allowed. Stop
+      // processing.
+      *error_details = "Too many data intervals received for this stream.";
+      return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
+    }
+    MaybeAddMoreBlocks(starting_offset + size);
+
+    size_t bytes_copy = 0;
+    if (!CopyStreamData(starting_offset, data, &bytes_copy, error_details)) {
+      return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+    }
+    *bytes_buffered += bytes_copy;
+    num_bytes_buffered_ += *bytes_buffered;
+    return QUIC_NO_ERROR;
+  }
+  // Slow path, received data overlaps with received data.
+  QuicIntervalSet<QuicStreamOffset> newly_received(starting_offset,
+                                                   starting_offset + size);
+  newly_received.Difference(bytes_received_);
+  if (newly_received.Empty()) {
+    return QUIC_NO_ERROR;
+  }
+  bytes_received_.Add(starting_offset, starting_offset + size);
+  if (bytes_received_.Size() >= kMaxNumDataIntervalsAllowed) {
+    // This frame is going to create more intervals than allowed. Stop
+    // processing.
+    *error_details = "Too many data intervals received for this stream.";
+    return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
+  }
+  MaybeAddMoreBlocks(starting_offset + size);
+  for (const auto& interval : newly_received) {
+    const QuicStreamOffset copy_offset = interval.min();
+    const QuicByteCount copy_length = interval.max() - interval.min();
+    size_t bytes_copy = 0;
+    if (!CopyStreamData(copy_offset,
+                        data.substr(copy_offset - starting_offset, copy_length),
+                        &bytes_copy, error_details)) {
+      return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+    }
+    *bytes_buffered += bytes_copy;
+  }
+  num_bytes_buffered_ += *bytes_buffered;
+  return QUIC_NO_ERROR;
+}
+
+bool QuicStreamSequencerBuffer::CopyStreamData(QuicStreamOffset offset,
+                                               absl::string_view data,
+                                               size_t* bytes_copy,
+                                               std::string* error_details) {
+  *bytes_copy = 0;
+  size_t source_remaining = data.size();
+  if (source_remaining == 0) {
+    return true;
+  }
+  const char* source = data.data();
+  // Write data block by block. If corresponding block has not created yet,
+  // create it first.
+  // Stop when all data are written or reaches the logical end of the buffer.
+  while (source_remaining > 0) {
+    const size_t write_block_num = GetBlockIndex(offset);
+    const size_t write_block_offset = GetInBlockOffset(offset);
+    size_t current_blocks_count = current_blocks_count_;
+    QUICHE_DCHECK_GT(current_blocks_count, write_block_num);
+
+    size_t block_capacity = GetBlockCapacity(write_block_num);
+    size_t bytes_avail = block_capacity - write_block_offset;
+
+    // If this write meets the upper boundary of the buffer,
+    // reduce the available free bytes.
+    if (offset + bytes_avail > total_bytes_read_ + max_buffer_capacity_bytes_) {
+      bytes_avail = total_bytes_read_ + max_buffer_capacity_bytes_ - offset;
+    }
+
+    if (write_block_num >= current_blocks_count) {
+      *error_details = absl::StrCat(
+          "QuicStreamSequencerBuffer error: OnStreamData() exceed array bounds."
+          "write offset = ",
+          offset, " write_block_num = ", write_block_num,
+          " current_blocks_count_ = ", current_blocks_count);
+      return false;
+    }
+    if (blocks_ == nullptr) {
+      *error_details =
+          "QuicStreamSequencerBuffer error: OnStreamData() blocks_ is null";
+      return false;
+    }
+    if (blocks_[write_block_num] == nullptr) {
+      // TODO(danzh): Investigate if using a freelist would improve performance.
+      // Same as RetireBlock().
+      blocks_[write_block_num] = new BufferBlock();
+    }
+
+    const size_t bytes_to_copy =
+        std::min<size_t>(bytes_avail, source_remaining);
+    char* dest = blocks_[write_block_num]->buffer + write_block_offset;
+    QUIC_DVLOG(1) << "Write at offset: " << offset
+                  << " length: " << bytes_to_copy;
+
+    if (dest == nullptr || source == nullptr) {
+      *error_details = absl::StrCat(
+          "QuicStreamSequencerBuffer error: OnStreamData()"
+          " dest == nullptr: ",
+          (dest == nullptr), " source == nullptr: ", (source == nullptr),
+          " Writing at offset ", offset,
+          " Received frames: ", ReceivedFramesDebugString(),
+          " total_bytes_read_ = ", total_bytes_read_);
+      return false;
+    }
+    memcpy(dest, source, bytes_to_copy);
+    source += bytes_to_copy;
+    source_remaining -= bytes_to_copy;
+    offset += bytes_to_copy;
+    *bytes_copy += bytes_to_copy;
+  }
+  return true;
+}
+
+QuicErrorCode QuicStreamSequencerBuffer::Readv(const iovec* dest_iov,
+                                               size_t dest_count,
+                                               size_t* bytes_read,
+                                               std::string* error_details) {
+  *bytes_read = 0;
+  for (size_t i = 0; i < dest_count && ReadableBytes() > 0; ++i) {
+    char* dest = reinterpret_cast<char*>(dest_iov[i].iov_base);
+    QUICHE_DCHECK(dest != nullptr);
+    size_t dest_remaining = dest_iov[i].iov_len;
+    while (dest_remaining > 0 && ReadableBytes() > 0) {
+      size_t block_idx = NextBlockToRead();
+      size_t start_offset_in_block = ReadOffset();
+      size_t block_capacity = GetBlockCapacity(block_idx);
+      size_t bytes_available_in_block = std::min<size_t>(
+          ReadableBytes(), block_capacity - start_offset_in_block);
+      size_t bytes_to_copy =
+          std::min<size_t>(bytes_available_in_block, dest_remaining);
+      QUICHE_DCHECK_GT(bytes_to_copy, 0u);
+      if (blocks_[block_idx] == nullptr || dest == nullptr) {
+        *error_details = absl::StrCat(
+            "QuicStreamSequencerBuffer error:"
+            " Readv() dest == nullptr: ",
+            (dest == nullptr), " blocks_[", block_idx,
+            "] == nullptr: ", (blocks_[block_idx] == nullptr),
+            " Received frames: ", ReceivedFramesDebugString(),
+            " total_bytes_read_ = ", total_bytes_read_);
+        return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+      }
+      memcpy(dest, blocks_[block_idx]->buffer + start_offset_in_block,
+             bytes_to_copy);
+      dest += bytes_to_copy;
+      dest_remaining -= bytes_to_copy;
+      num_bytes_buffered_ -= bytes_to_copy;
+      total_bytes_read_ += bytes_to_copy;
+      *bytes_read += bytes_to_copy;
+
+      // Retire the block if all the data is read out and no other data is
+      // stored in this block.
+      // In case of failing to retire a block which is ready to retire, return
+      // immediately.
+      if (bytes_to_copy == bytes_available_in_block) {
+        bool retire_successfully = RetireBlockIfEmpty(block_idx);
+        if (!retire_successfully) {
+          *error_details = absl::StrCat(
+              "QuicStreamSequencerBuffer error: fail to retire block ",
+              block_idx,
+              " as the block is already released, total_bytes_read_ = ",
+              total_bytes_read_,
+              " Received frames: ", ReceivedFramesDebugString());
+          return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+        }
+      }
+    }
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+int QuicStreamSequencerBuffer::GetReadableRegions(struct iovec* iov,
+                                                  int iov_len) const {
+  QUICHE_DCHECK(iov != nullptr);
+  QUICHE_DCHECK_GT(iov_len, 0);
+
+  if (ReadableBytes() == 0) {
+    iov[0].iov_base = nullptr;
+    iov[0].iov_len = 0;
+    return 0;
+  }
+
+  size_t start_block_idx = NextBlockToRead();
+  QuicStreamOffset readable_offset_end = FirstMissingByte() - 1;
+  QUICHE_DCHECK_GE(readable_offset_end + 1, total_bytes_read_);
+  size_t end_block_offset = GetInBlockOffset(readable_offset_end);
+  size_t end_block_idx = GetBlockIndex(readable_offset_end);
+
+  // If readable region is within one block, deal with it seperately.
+  if (start_block_idx == end_block_idx && ReadOffset() <= end_block_offset) {
+    iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
+    iov[0].iov_len = ReadableBytes();
+    QUIC_DVLOG(1) << "Got only a single block with index: " << start_block_idx;
+    return 1;
+  }
+
+  // Get first block
+  iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
+  iov[0].iov_len = GetBlockCapacity(start_block_idx) - ReadOffset();
+  QUIC_DVLOG(1) << "Got first block " << start_block_idx << " with len "
+                << iov[0].iov_len;
+  QUICHE_DCHECK_GT(readable_offset_end + 1, total_bytes_read_ + iov[0].iov_len)
+      << "there should be more available data";
+
+  // Get readable regions of the rest blocks till either 2nd to last block
+  // before gap is met or |iov| is filled. For these blocks, one whole block is
+  // a region.
+  int iov_used = 1;
+  size_t block_idx = (start_block_idx + iov_used) % max_blocks_count_;
+  while (block_idx != end_block_idx && iov_used < iov_len) {
+    QUICHE_DCHECK(nullptr != blocks_[block_idx]);
+    iov[iov_used].iov_base = blocks_[block_idx]->buffer;
+    iov[iov_used].iov_len = GetBlockCapacity(block_idx);
+    QUIC_DVLOG(1) << "Got block with index: " << block_idx;
+    ++iov_used;
+    block_idx = (start_block_idx + iov_used) % max_blocks_count_;
+  }
+
+  // Deal with last block if |iov| can hold more.
+  if (iov_used < iov_len) {
+    QUICHE_DCHECK(nullptr != blocks_[block_idx]);
+    iov[iov_used].iov_base = blocks_[end_block_idx]->buffer;
+    iov[iov_used].iov_len = end_block_offset + 1;
+    QUIC_DVLOG(1) << "Got last block with index: " << end_block_idx;
+    ++iov_used;
+  }
+  return iov_used;
+}
+
+bool QuicStreamSequencerBuffer::GetReadableRegion(iovec* iov) const {
+  return GetReadableRegions(iov, 1) == 1;
+}
+
+bool QuicStreamSequencerBuffer::PeekRegion(QuicStreamOffset offset,
+                                           iovec* iov) const {
+  QUICHE_DCHECK(iov);
+
+  if (offset < total_bytes_read_) {
+    // Data at |offset| has already been consumed.
+    return false;
+  }
+
+  if (offset >= FirstMissingByte()) {
+    // Data at |offset| has not been received yet.
+    return false;
+  }
+
+  // Beginning of region.
+  size_t block_idx = GetBlockIndex(offset);
+  size_t block_offset = GetInBlockOffset(offset);
+  iov->iov_base = blocks_[block_idx]->buffer + block_offset;
+
+  // Determine if entire block has been received.
+  size_t end_block_idx = GetBlockIndex(FirstMissingByte());
+  if (block_idx == end_block_idx) {
+    // Only read part of block before FirstMissingByte().
+    iov->iov_len = GetInBlockOffset(FirstMissingByte()) - block_offset;
+  } else {
+    // Read entire block.
+    iov->iov_len = GetBlockCapacity(block_idx) - block_offset;
+  }
+
+  return true;
+}
+
+bool QuicStreamSequencerBuffer::MarkConsumed(size_t bytes_consumed) {
+  if (bytes_consumed > ReadableBytes()) {
+    return false;
+  }
+  size_t bytes_to_consume = bytes_consumed;
+  while (bytes_to_consume > 0) {
+    size_t block_idx = NextBlockToRead();
+    size_t offset_in_block = ReadOffset();
+    size_t bytes_available = std::min<size_t>(
+        ReadableBytes(), GetBlockCapacity(block_idx) - offset_in_block);
+    size_t bytes_read = std::min<size_t>(bytes_to_consume, bytes_available);
+    total_bytes_read_ += bytes_read;
+    num_bytes_buffered_ -= bytes_read;
+    bytes_to_consume -= bytes_read;
+    // If advanced to the end of current block and end of buffer hasn't wrapped
+    // to this block yet.
+    if (bytes_available == bytes_read) {
+      RetireBlockIfEmpty(block_idx);
+    }
+  }
+
+  return true;
+}
+
+size_t QuicStreamSequencerBuffer::FlushBufferedFrames() {
+  size_t prev_total_bytes_read = total_bytes_read_;
+  total_bytes_read_ = NextExpectedByte();
+  Clear();
+  return total_bytes_read_ - prev_total_bytes_read;
+}
+
+void QuicStreamSequencerBuffer::ReleaseWholeBuffer() {
+  Clear();
+  current_blocks_count_ = 0;
+  blocks_.reset(nullptr);
+}
+
+size_t QuicStreamSequencerBuffer::ReadableBytes() const {
+  return FirstMissingByte() - total_bytes_read_;
+}
+
+bool QuicStreamSequencerBuffer::HasBytesToRead() const {
+  return ReadableBytes() > 0;
+}
+
+QuicStreamOffset QuicStreamSequencerBuffer::BytesConsumed() const {
+  return total_bytes_read_;
+}
+
+size_t QuicStreamSequencerBuffer::BytesBuffered() const {
+  return num_bytes_buffered_;
+}
+
+size_t QuicStreamSequencerBuffer::GetBlockIndex(QuicStreamOffset offset) const {
+  return (offset % max_buffer_capacity_bytes_) / kBlockSizeBytes;
+}
+
+size_t QuicStreamSequencerBuffer::GetInBlockOffset(
+    QuicStreamOffset offset) const {
+  return (offset % max_buffer_capacity_bytes_) % kBlockSizeBytes;
+}
+
+size_t QuicStreamSequencerBuffer::ReadOffset() const {
+  return GetInBlockOffset(total_bytes_read_);
+}
+
+size_t QuicStreamSequencerBuffer::NextBlockToRead() const {
+  return GetBlockIndex(total_bytes_read_);
+}
+
+bool QuicStreamSequencerBuffer::RetireBlockIfEmpty(size_t block_index) {
+  QUICHE_DCHECK(ReadableBytes() == 0 ||
+                GetInBlockOffset(total_bytes_read_) == 0)
+      << "RetireBlockIfEmpty() should only be called when advancing to next "
+      << "block or a gap has been reached.";
+  // If the whole buffer becomes empty, the last piece of data has been read.
+  if (Empty()) {
+    return RetireBlock(block_index);
+  }
+
+  // Check where the logical end of this buffer is.
+  // Not empty if the end of circular buffer has been wrapped to this block.
+  if (GetBlockIndex(NextExpectedByte() - 1) == block_index) {
+    return true;
+  }
+
+  // Read index remains in this block, which means a gap has been reached.
+  if (NextBlockToRead() == block_index) {
+    if (bytes_received_.Size() > 1) {
+      auto it = bytes_received_.begin();
+      ++it;
+      if (GetBlockIndex(it->min()) == block_index) {
+        // Do not retire the block if next data interval is in this block.
+        return true;
+      }
+    } else {
+      QUIC_BUG(quic_bug_10610_2) << "Read stopped at where it shouldn't.";
+      return false;
+    }
+  }
+  return RetireBlock(block_index);
+}
+
+bool QuicStreamSequencerBuffer::Empty() const {
+  return bytes_received_.Empty() ||
+         (bytes_received_.Size() == 1 && total_bytes_read_ > 0 &&
+          bytes_received_.begin()->max() == total_bytes_read_);
+}
+
+size_t QuicStreamSequencerBuffer::GetBlockCapacity(size_t block_index) const {
+  if ((block_index + 1) == max_blocks_count_) {
+    size_t result = max_buffer_capacity_bytes_ % kBlockSizeBytes;
+    if (result == 0) {  // whole block
+      result = kBlockSizeBytes;
+    }
+    return result;
+  } else {
+    return kBlockSizeBytes;
+  }
+}
+
+std::string QuicStreamSequencerBuffer::ReceivedFramesDebugString() const {
+  return bytes_received_.ToString();
+}
+
+QuicStreamOffset QuicStreamSequencerBuffer::FirstMissingByte() const {
+  if (bytes_received_.Empty() || bytes_received_.begin()->min() > 0) {
+    // Offset 0 is not received yet.
+    return 0;
+  }
+  return bytes_received_.begin()->max();
+}
+
+QuicStreamOffset QuicStreamSequencerBuffer::NextExpectedByte() const {
+  if (bytes_received_.Empty()) {
+    return 0;
+  }
+  return bytes_received_.rbegin()->max();
+}
+
+}  //  namespace quic
diff --git a/quiche/quic/core/quic_stream_sequencer_buffer.h b/quiche/quic/core/quic_stream_sequencer_buffer.h
new file mode 100644
index 0000000..c4aaa0a
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer_buffer.h
@@ -0,0 +1,246 @@
+// Copyright (c) 2015 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_STREAM_SEQUENCER_BUFFER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
+
+// QuicStreamSequencerBuffer is a circular stream buffer with random write and
+// in-sequence read. It consists of a vector of pointers pointing
+// to memory blocks created as needed and an interval set recording received
+// data.
+// - Data are written in with offset indicating where it should be in the
+// stream, and the buffer grown as needed (up to the maximum buffer capacity),
+// without expensive copying (extra blocks are allocated).
+// - Data can be read from the buffer if there is no gap before it,
+// and the buffer shrinks as the data are consumed.
+// - An upper limit on the number of blocks in the buffer provides an upper
+//   bound on memory use.
+//
+// This class is thread-unsafe.
+//
+// QuicStreamSequencerBuffer maintains a concept of the readable region, which
+// contains all written data that has not been read.
+// It promises stability of the underlying memory addresses in the readable
+// region, so pointers into it can be maintained, and the offset of a pointer
+// from the start of the read region can be calculated.
+//
+// Expected Use:
+//  QuicStreamSequencerBuffer buffer(2.5 * 8 * 1024);
+//  std::string source(1024, 'a');
+//  absl::string_view string_piece(source.data(), source.size());
+//  size_t written = 0;
+//  buffer.OnStreamData(800, string_piece, GetEpollClockNow(), &written);
+//  source = std::string{800, 'b'};
+//  absl::string_view string_piece1(source.data(), 800);
+//  // Try to write to [1, 801), but should fail due to overlapping,
+//  // res should be QUIC_INVALID_STREAM_DATA
+//  auto res = buffer.OnStreamData(1, string_piece1, &written));
+//  // write to [0, 800), res should be QUIC_NO_ERROR
+//  auto res = buffer.OnStreamData(0, string_piece1, GetEpollClockNow(),
+//                                  &written);
+//
+//  // Read into a iovec array with total capacity of 120 bytes.
+//  char dest[120];
+//  iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40},
+//                  iovec{dest + 80, 40}};
+//  size_t read = buffer.Readv(iovecs, 3);
+//
+//  // Get single readable region.
+//  iovec iov;
+//  buffer.GetReadableRegion(iov);
+//
+//  // Get readable regions from [256, 1024) and consume some of it.
+//  iovec iovs[2];
+//  int iov_count = buffer.GetReadableRegions(iovs, 2);
+//  // Consume some bytes in iovs, returning number of bytes having been
+//  consumed.
+//  size_t consumed = consume_iovs(iovs, iov_count);
+//  buffer.MarkConsumed(consumed);
+
+#include <cstddef>
+#include <functional>
+#include <list>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_iovec.h"
+
+namespace quic {
+
+namespace test {
+class QuicStreamSequencerBufferPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
+ public:
+  // Size of blocks used by this buffer.
+  // Choose 8K to make block large enough to hold multiple frames, each of
+  // which could be up to 1.5 KB.
+  static const size_t kBlockSizeBytes = 8 * 1024;  // 8KB
+
+  // The basic storage block used by this buffer.
+  struct QUIC_EXPORT_PRIVATE BufferBlock {
+    char buffer[kBlockSizeBytes];
+  };
+
+  explicit QuicStreamSequencerBuffer(size_t max_capacity_bytes);
+  QuicStreamSequencerBuffer(const QuicStreamSequencerBuffer&) = delete;
+  QuicStreamSequencerBuffer(QuicStreamSequencerBuffer&&) = default;
+  QuicStreamSequencerBuffer& operator=(const QuicStreamSequencerBuffer&) =
+      delete;
+  QuicStreamSequencerBuffer& operator=(QuicStreamSequencerBuffer&&) = default;
+  ~QuicStreamSequencerBuffer();
+
+  // Free the space used to buffer data.
+  void Clear();
+
+  // Returns true if there is nothing to read in this buffer.
+  bool Empty() const;
+
+  // Called to buffer new data received for this stream.  If the data was
+  // successfully buffered, returns QUIC_NO_ERROR and stores the number of
+  // bytes buffered in |bytes_buffered|. Returns an error otherwise.
+  QuicErrorCode OnStreamData(QuicStreamOffset offset,
+                             absl::string_view data,
+                             size_t* bytes_buffered,
+                             std::string* error_details);
+
+  // Reads from this buffer into given iovec array, up to number of iov_len
+  // iovec objects and returns the number of bytes read.
+  QuicErrorCode Readv(const struct iovec* dest_iov,
+                      size_t dest_count,
+                      size_t* bytes_read,
+                      std::string* error_details);
+
+  // Returns the readable region of valid data in iovec format. The readable
+  // region is the buffer region where there is valid data not yet read by
+  // client.
+  // Returns the number of iovec entries in |iov| which were populated.
+  // If the region is empty, one iovec entry with 0 length
+  // is returned, and the function returns 0. If there are more readable
+  // regions than |iov_size|, the function only processes the first
+  // |iov_size| of them.
+  int GetReadableRegions(struct iovec* iov, int iov_len) const;
+
+  // Fills in one iovec with data from the next readable region.
+  // Returns false if there is no readable region available.
+  bool GetReadableRegion(iovec* iov) const;
+
+  // Returns true and sets |*iov| to point to a region starting at |offset|.
+  // Returns false if no data can be read at |offset|, which can be because data
+  // has not been received yet or it is already consumed.
+  // Does not consume data.
+  bool PeekRegion(QuicStreamOffset offset, iovec* iov) const;
+
+  // Called after GetReadableRegions() to free up |bytes_consumed| space if
+  // these bytes are processed.
+  // Pre-requisite: bytes_consumed <= available bytes to read.
+  bool MarkConsumed(size_t bytes_consumed);
+
+  // Deletes and records as consumed any buffered data and clear the buffer.
+  // (To be called only after sequencer's StopReading has been called.)
+  size_t FlushBufferedFrames();
+
+  // Free the memory of buffered data.
+  void ReleaseWholeBuffer();
+
+  // Whether there are bytes can be read out.
+  bool HasBytesToRead() const;
+
+  // Count how many bytes have been consumed (read out of buffer).
+  QuicStreamOffset BytesConsumed() const;
+
+  // Count how many bytes are in buffer at this moment.
+  size_t BytesBuffered() const;
+
+  // Returns number of bytes available to be read out.
+  size_t ReadableBytes() const;
+
+ private:
+  friend class test::QuicStreamSequencerBufferPeer;
+
+  // Copies |data| to blocks_, sets |bytes_copy|. Returns true if the copy is
+  // successful. Otherwise, sets |error_details| and returns false.
+  bool CopyStreamData(QuicStreamOffset offset,
+                      absl::string_view data,
+                      size_t* bytes_copy,
+                      std::string* error_details);
+
+  // Dispose the given buffer block.
+  // After calling this method, blocks_[index] is set to nullptr
+  // in order to indicate that no memory set is allocated for that block.
+  // Returns true on success, false otherwise.
+  bool RetireBlock(size_t index);
+
+  // Should only be called after the indexed block is read till the end of the
+  // block or missing data has been reached.
+  // If the block at |block_index| contains no buffered data, the block
+  // should be retired.
+  // Returns true on success, or false otherwise.
+  bool RetireBlockIfEmpty(size_t block_index);
+
+  // Calculate the capacity of block at specified index.
+  // Return value should be either kBlockSizeBytes for non-trailing blocks and
+  // max_buffer_capacity % kBlockSizeBytes for trailing block.
+  size_t GetBlockCapacity(size_t index) const;
+
+  // Does not check if offset is within reasonable range.
+  size_t GetBlockIndex(QuicStreamOffset offset) const;
+
+  // Given an offset in the stream, return the offset from the beginning of the
+  // block which contains this data.
+  size_t GetInBlockOffset(QuicStreamOffset offset) const;
+
+  // Get offset relative to index 0 in logical 1st block to start next read.
+  size_t ReadOffset() const;
+
+  // Get the index of the logical 1st block to start next read.
+  size_t NextBlockToRead() const;
+
+  // Returns offset of first missing byte.
+  QuicStreamOffset FirstMissingByte() const;
+
+  // Returns offset of highest received byte + 1.
+  QuicStreamOffset NextExpectedByte() const;
+
+  // Return all received frames as a string.
+  std::string ReceivedFramesDebugString() const;
+
+  // Resize blocks_ if more blocks are needed to accomodate bytes before
+  // next_expected_byte.
+  void MaybeAddMoreBlocks(QuicStreamOffset next_expected_byte);
+
+  // The maximum total capacity of this buffer in byte, as constructed.
+  size_t max_buffer_capacity_bytes_;
+
+  // Number of blocks this buffer would have when it reaches full capacity,
+  // i.e., maximal number of blocks in blocks_.
+  size_t max_blocks_count_;
+
+  // Number of blocks this buffer currently has.
+  size_t current_blocks_count_;
+
+  // Number of bytes read out of buffer.
+  QuicStreamOffset total_bytes_read_;
+
+  // An ordered, variable-length list of blocks, with the length limited
+  // such that the number of blocks never exceeds max_blocks_count_.
+  // Each list entry can hold up to kBlockSizeBytes bytes.
+  std::unique_ptr<BufferBlock*[]> blocks_;
+
+  // Number of bytes in buffer.
+  size_t num_bytes_buffered_;
+
+  // Currently received data.
+  QuicIntervalSet<QuicStreamOffset> bytes_received_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
diff --git a/quiche/quic/core/quic_stream_sequencer_buffer_test.cc b/quiche/quic/core/quic_stream_sequencer_buffer_test.cc
new file mode 100644
index 0000000..d1cdf34
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer_buffer_test.cc
@@ -0,0 +1,1139 @@
+// Copyright (c) 2015 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 "quiche/quic/core/quic_stream_sequencer_buffer.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+absl::string_view IovecToStringPiece(iovec iov) {
+  return absl::string_view(reinterpret_cast<const char*>(iov.iov_base),
+                           iov.iov_len);
+}
+
+char GetCharFromIOVecs(size_t offset, iovec iov[], size_t count) {
+  size_t start_offset = 0;
+  for (size_t i = 0; i < count; i++) {
+    if (iov[i].iov_len == 0) {
+      continue;
+    }
+    size_t end_offset = start_offset + iov[i].iov_len - 1;
+    if (offset >= start_offset && offset <= end_offset) {
+      const char* buf = reinterpret_cast<const char*>(iov[i].iov_base);
+      return buf[offset - start_offset];
+    }
+    start_offset += iov[i].iov_len;
+  }
+  QUIC_LOG(ERROR) << "Could not locate char at offset " << offset << " in "
+                  << count << " iovecs";
+  for (size_t i = 0; i < count; ++i) {
+    QUIC_LOG(ERROR) << "  iov[" << i << "].iov_len = " << iov[i].iov_len;
+  }
+  return '\0';
+}
+
+const size_t kMaxNumGapsAllowed = 2 * kMaxPacketGap;
+
+static const size_t kBlockSizeBytes =
+    QuicStreamSequencerBuffer::kBlockSizeBytes;
+using BufferBlock = QuicStreamSequencerBuffer::BufferBlock;
+
+namespace {
+
+class QuicStreamSequencerBufferTest : public QuicTest {
+ public:
+  void SetUp() override { Initialize(); }
+
+  void ResetMaxCapacityBytes(size_t max_capacity_bytes) {
+    max_capacity_bytes_ = max_capacity_bytes;
+    Initialize();
+  }
+
+ protected:
+  void Initialize() {
+    buffer_ =
+        std::make_unique<QuicStreamSequencerBuffer>((max_capacity_bytes_));
+    helper_ = std::make_unique<QuicStreamSequencerBufferPeer>((buffer_.get()));
+  }
+
+  // Use 8.5 here to make sure that the buffer has more than
+  // QuicStreamSequencerBuffer::kInitialBlockCount block and its end doesn't
+  // align with the end of a block in order to test all the offset calculation.
+  size_t max_capacity_bytes_ = 8.5 * kBlockSizeBytes;
+
+  std::unique_ptr<QuicStreamSequencerBuffer> buffer_;
+  std::unique_ptr<QuicStreamSequencerBufferPeer> helper_;
+  size_t written_ = 0;
+  std::string error_details_;
+};
+
+TEST_F(QuicStreamSequencerBufferTest, InitializeWithMaxRecvWindowSize) {
+  ResetMaxCapacityBytes(16 * 1024 * 1024);  // 16MB
+  EXPECT_EQ(2 * 1024u,                      // 16MB / 8KB = 2K
+            helper_->max_blocks_count());
+  EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity());
+  EXPECT_TRUE(helper_->CheckInitialState());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, InitializationWithDifferentSizes) {
+  const size_t kCapacity = 16 * QuicStreamSequencerBuffer::kBlockSizeBytes;
+  ResetMaxCapacityBytes(kCapacity);
+  EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity());
+  EXPECT_TRUE(helper_->CheckInitialState());
+
+  const size_t kCapacity1 = 32 * QuicStreamSequencerBuffer::kBlockSizeBytes;
+  ResetMaxCapacityBytes(kCapacity1);
+  EXPECT_EQ(kCapacity1, helper_->max_buffer_capacity());
+  EXPECT_TRUE(helper_->CheckInitialState());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ClearOnEmpty) {
+  buffer_->Clear();
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamData0length) {
+  QuicErrorCode error =
+      buffer_->OnStreamData(800, "", &written_, &error_details_);
+  EXPECT_THAT(error, IsError(QUIC_EMPTY_STREAM_FRAME_NO_FIN));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithinBlock) {
+  EXPECT_FALSE(helper_->IsBufferAllocated());
+  std::string source(1024, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsQuicNoError());
+  BufferBlock* block_ptr = helper_->GetBlock(0);
+  for (size_t i = 0; i < source.size(); ++i) {
+    ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
+  }
+  EXPECT_EQ(2, helper_->IntervalSize());
+  EXPECT_EQ(0u, helper_->ReadableBytes());
+  EXPECT_EQ(1u, helper_->bytes_received().Size());
+  EXPECT_EQ(800u, helper_->bytes_received().begin()->min());
+  EXPECT_EQ(1824u, helper_->bytes_received().begin()->max());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+  EXPECT_TRUE(helper_->IsBufferAllocated());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, Move) {
+  EXPECT_FALSE(helper_->IsBufferAllocated());
+  std::string source(1024, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsQuicNoError());
+  BufferBlock* block_ptr = helper_->GetBlock(0);
+  for (size_t i = 0; i < source.size(); ++i) {
+    ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
+  }
+
+  QuicStreamSequencerBuffer buffer2(std::move(*buffer_));
+  QuicStreamSequencerBufferPeer helper2(&buffer2);
+
+  EXPECT_FALSE(helper_->IsBufferAllocated());
+
+  EXPECT_EQ(2, helper2.IntervalSize());
+  EXPECT_EQ(0u, helper2.ReadableBytes());
+  EXPECT_EQ(1u, helper2.bytes_received().Size());
+  EXPECT_EQ(800u, helper2.bytes_received().begin()->min());
+  EXPECT_EQ(1824u, helper2.bytes_received().begin()->max());
+  EXPECT_TRUE(helper2.CheckBufferInvariants());
+  EXPECT_TRUE(helper2.IsBufferAllocated());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, DISABLED_OnStreamDataInvalidSource) {
+  // Pass in an invalid source, expects to return error.
+  absl::string_view source;
+  source = absl::string_view(nullptr, 1024);
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsError(QUIC_STREAM_SEQUENCER_INVALID_STATE));
+  EXPECT_EQ(0u, error_details_.find(absl::StrCat(
+                    "QuicStreamSequencerBuffer error: OnStreamData() "
+                    "dest == nullptr: ",
+                    false, " source == nullptr: ", true)));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithOverlap) {
+  std::string source(1024, 'a');
+  // Write something into [800, 1824)
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsQuicNoError());
+  // Try to write to [0, 1024) and [1024, 2048).
+  EXPECT_THAT(buffer_->OnStreamData(0, source, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_THAT(buffer_->OnStreamData(1024, source, &written_, &error_details_),
+              IsQuicNoError());
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       OnStreamDataOverlapAndDuplicateCornerCases) {
+  std::string source(1024, 'a');
+  // Write something into [800, 1824)
+  buffer_->OnStreamData(800, source, &written_, &error_details_);
+  source = std::string(800, 'b');
+  std::string one_byte = "c";
+  // Write [1, 801).
+  EXPECT_THAT(buffer_->OnStreamData(1, source, &written_, &error_details_),
+              IsQuicNoError());
+  // Write [0, 800).
+  EXPECT_THAT(buffer_->OnStreamData(0, source, &written_, &error_details_),
+              IsQuicNoError());
+  // Write [1823, 1824).
+  EXPECT_THAT(buffer_->OnStreamData(1823, one_byte, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(0u, written_);
+  // write one byte to [1824, 1825)
+  EXPECT_THAT(buffer_->OnStreamData(1824, one_byte, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithoutOverlap) {
+  std::string source(1024, 'a');
+  // Write something into [800, 1824).
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsQuicNoError());
+  source = std::string(100, 'b');
+  // Write something into [kBlockSizeBytes * 2 - 20, kBlockSizeBytes * 2 + 80).
+  EXPECT_THAT(buffer_->OnStreamData(kBlockSizeBytes * 2 - 20, source, &written_,
+                                    &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(3, helper_->IntervalSize());
+  EXPECT_EQ(1024u + 100u, buffer_->BytesBuffered());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataInLongStreamWithOverlap) {
+  // Assume a stream has already buffered almost 4GB.
+  uint64_t total_bytes_read = pow(2, 32) - 1;
+  helper_->set_total_bytes_read(total_bytes_read);
+  helper_->AddBytesReceived(0, total_bytes_read);
+
+  // Three new out of order frames arrive.
+  const size_t kBytesToWrite = 100;
+  std::string source(kBytesToWrite, 'a');
+  // Frame [2^32 + 500, 2^32 + 600).
+  QuicStreamOffset offset = pow(2, 32) + 500;
+  EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(2, helper_->IntervalSize());
+
+  // Frame [2^32 + 700, 2^32 + 800).
+  offset = pow(2, 32) + 700;
+  EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(3, helper_->IntervalSize());
+
+  // Another frame [2^32 + 300, 2^32 + 400).
+  offset = pow(2, 32) + 300;
+  EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(4, helper_->IntervalSize());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataTillEnd) {
+  // Write 50 bytes to the end.
+  const size_t kBytesToWrite = 50;
+  std::string source(kBytesToWrite, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
+                                    &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(50u, buffer_->BytesBuffered());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataTillEndCorner) {
+  // Write 1 byte to the end.
+  const size_t kBytesToWrite = 1;
+  std::string source(kBytesToWrite, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
+                                    &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(1u, buffer_->BytesBuffered());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataBeyondCapacity) {
+  std::string source(60, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - 50, source, &written_,
+                                    &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  source = "b";
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
+                                    &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ * 1000, source,
+                                    &written_, &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  // Disallow current_gap != gaps_.end()
+  EXPECT_THAT(buffer_->OnStreamData(static_cast<QuicStreamOffset>(-1), source,
+                                    &written_, &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  // Disallow offset + size overflow
+  source = "bbb";
+  EXPECT_THAT(buffer_->OnStreamData(static_cast<QuicStreamOffset>(-2), source,
+                                    &written_, &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+  EXPECT_EQ(0u, buffer_->BytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, Readv100Bytes) {
+  std::string source(1024, 'a');
+  // Write something into [kBlockSizeBytes, kBlockSizeBytes + 1024).
+  buffer_->OnStreamData(kBlockSizeBytes, source, &written_, &error_details_);
+  EXPECT_FALSE(buffer_->HasBytesToRead());
+  source = std::string(100, 'b');
+  // Write something into [0, 100).
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  EXPECT_TRUE(buffer_->HasBytesToRead());
+  // Read into a iovec array with total capacity of 120 bytes.
+  char dest[120];
+  iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, iovec{dest + 80, 40}};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(iovecs, 3, &read, &error_details_),
+              IsQuicNoError());
+  QUIC_LOG(ERROR) << error_details_;
+  EXPECT_EQ(100u, read);
+  EXPECT_EQ(100u, buffer_->BytesConsumed());
+  EXPECT_EQ(source, absl::string_view(dest, read));
+  // The first block should be released as its data has been read out.
+  EXPECT_EQ(nullptr, helper_->GetBlock(0));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ReadvAcrossBlocks) {
+  std::string source(kBlockSizeBytes + 50, 'a');
+  // Write 1st block to full and extand 50 bytes to next block.
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  EXPECT_EQ(source.size(), helper_->ReadableBytes());
+  // Iteratively read 512 bytes from buffer_-> Overwrite dest[] each time.
+  char dest[512];
+  while (helper_->ReadableBytes()) {
+    std::fill(dest, dest + 512, 0);
+    iovec iovecs[2]{iovec{dest, 256}, iovec{dest + 256, 256}};
+    size_t read;
+    EXPECT_THAT(buffer_->Readv(iovecs, 2, &read, &error_details_),
+                IsQuicNoError());
+  }
+  // The last read only reads the rest 50 bytes in 2nd block.
+  EXPECT_EQ(std::string(50, 'a'), std::string(dest, 50));
+  EXPECT_EQ(0, dest[50]) << "Dest[50] shouln't be filled.";
+  EXPECT_EQ(source.size(), buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ClearAfterRead) {
+  std::string source(kBlockSizeBytes + 50, 'a');
+  // Write 1st block to full with 'a'.
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  // Read first 512 bytes from buffer to make space at the beginning.
+  char dest[512]{0};
+  const iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+  // Clear() should make buffer empty while preserving BytesConsumed()
+  buffer_->Clear();
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       OnStreamDataAcrossLastBlockAndFillCapacity) {
+  std::string source(kBlockSizeBytes + 50, 'a');
+  // Write 1st block to full with 'a'.
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  // Read first 512 bytes from buffer to make space at the beginning.
+  char dest[512]{0};
+  const iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+  EXPECT_EQ(source.size(), written_);
+
+  // Write more than half block size of bytes in the last block with 'b', which
+  // will wrap to the beginning and reaches the full capacity.
+  source = std::string(0.5 * kBlockSizeBytes + 512, 'b');
+  EXPECT_THAT(buffer_->OnStreamData(2 * kBlockSizeBytes, source, &written_,
+                                    &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(source.size(), written_);
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       OnStreamDataAcrossLastBlockAndExceedCapacity) {
+  std::string source(kBlockSizeBytes + 50, 'a');
+  // Write 1st block to full.
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  // Read first 512 bytes from buffer to make space at the beginning.
+  char dest[512]{0};
+  const iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+
+  // Try to write from [max_capacity_bytes_ - 0.5 * kBlockSizeBytes,
+  // max_capacity_bytes_ +  512 + 1). But last bytes exceeds current capacity.
+  source = std::string(0.5 * kBlockSizeBytes + 512 + 1, 'b');
+  EXPECT_THAT(buffer_->OnStreamData(8 * kBlockSizeBytes, source, &written_,
+                                    &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ReadvAcrossLastBlock) {
+  // Write to full capacity and read out 512 bytes at beginning and continue
+  // appending 256 bytes.
+  std::string source(max_capacity_bytes_, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[512]{0};
+  const iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+  source = std::string(256, 'b');
+  buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
+                        &error_details_);
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  // Read all data out.
+  std::unique_ptr<char[]> dest1{new char[max_capacity_bytes_]};
+  dest1[0] = 0;
+  const iovec iov1{dest1.get(), max_capacity_bytes_};
+  EXPECT_THAT(buffer_->Readv(&iov1, 1, &read, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(max_capacity_bytes_ - 512 + 256, read);
+  EXPECT_EQ(max_capacity_bytes_ + 256, buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ReadvEmpty) {
+  char dest[512]{0};
+  iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+  EXPECT_EQ(0u, read);
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsEmpty) {
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(0, iov_count);
+  EXPECT_EQ(nullptr, iovs[iov_count].iov_base);
+  EXPECT_EQ(0u, iovs[iov_count].iov_len);
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ReleaseWholeBuffer) {
+  // Tests that buffer is not deallocated unless ReleaseWholeBuffer() is called.
+  std::string source(100, 'b');
+  // Write something into [0, 100).
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  EXPECT_TRUE(buffer_->HasBytesToRead());
+  char dest[120];
+  iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, iovec{dest + 80, 40}};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(iovecs, 3, &read, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(100u, read);
+  EXPECT_EQ(100u, buffer_->BytesConsumed());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+  EXPECT_TRUE(helper_->IsBufferAllocated());
+  buffer_->ReleaseWholeBuffer();
+  EXPECT_FALSE(helper_->IsBufferAllocated());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsBlockedByGap) {
+  // Write into [1, 1024).
+  std::string source(1023, 'a');
+  buffer_->OnStreamData(1, source, &written_, &error_details_);
+  // Try to get readable regions, but none is there.
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(0, iov_count);
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsTillEndOfBlock) {
+  // Write first block to full with [0, 256) 'a' and the rest 'b' then read out
+  // [0, 256)
+  std::string source(kBlockSizeBytes, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+  // Get readable region from [256, 1024)
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(1, iov_count);
+  EXPECT_EQ(std::string(kBlockSizeBytes - 256, 'a'),
+            IovecToStringPiece(iovs[0]));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsWithinOneBlock) {
+  // Write into [0, 1024) and then read out [0, 256)
+  std::string source(1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+  // Get readable region from [256, 1024)
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(1, iov_count);
+  EXPECT_EQ(std::string(1024 - 256, 'a'), IovecToStringPiece(iovs[0]));
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       GetReadableRegionsAcrossBlockWithLongIOV) {
+  // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
+  std::string source(2 * kBlockSizeBytes + 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+
+  iovec iovs[4];
+  int iov_count = buffer_->GetReadableRegions(iovs, 4);
+  EXPECT_EQ(3, iov_count);
+  EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
+  EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
+  EXPECT_EQ(1024u, iovs[2].iov_len);
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       GetReadableRegionsWithMultipleIOVsAcrossEnd) {
+  // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024)
+  // and then append 1024 + 512 bytes.
+  std::string source(8.5 * kBlockSizeBytes - 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+  // Write across the end.
+  source = std::string(1024 + 512, 'b');
+  buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_,
+                        &error_details_);
+  // Use short iovec's.
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(2, iov_count);
+  EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
+  EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
+  // Use long iovec's and wrap the end of buffer.
+  iovec iovs1[11];
+  EXPECT_EQ(10, buffer_->GetReadableRegions(iovs1, 11));
+  EXPECT_EQ(0.5 * kBlockSizeBytes, iovs1[8].iov_len);
+  EXPECT_EQ(512u, iovs1[9].iov_len);
+  EXPECT_EQ(std::string(512, 'b'), IovecToStringPiece(iovs1[9]));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionEmpty) {
+  iovec iov;
+  EXPECT_FALSE(buffer_->GetReadableRegion(&iov));
+  EXPECT_EQ(nullptr, iov.iov_base);
+  EXPECT_EQ(0u, iov.iov_len);
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionBeforeGap) {
+  // Write into [1, 1024).
+  std::string source(1023, 'a');
+  buffer_->OnStreamData(1, source, &written_, &error_details_);
+  // GetReadableRegion should return false because range  [0,1) hasn't been
+  // filled yet.
+  iovec iov;
+  EXPECT_FALSE(buffer_->GetReadableRegion(&iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionTillEndOfBlock) {
+  // Write into [0, kBlockSizeBytes + 1) and then read out [0, 256)
+  std::string source(kBlockSizeBytes + 1, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+  // Get readable region from [256, 1024)
+  iovec iov;
+  EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
+  EXPECT_EQ(std::string(kBlockSizeBytes - 256, 'a'), IovecToStringPiece(iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionTillGap) {
+  // Write into [0, kBlockSizeBytes - 1) and then read out [0, 256)
+  std::string source(kBlockSizeBytes - 1, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+  // Get readable region from [256, 1023)
+  iovec iov;
+  EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
+  EXPECT_EQ(std::string(kBlockSizeBytes - 1 - 256, 'a'),
+            IovecToStringPiece(iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekEmptyBuffer) {
+  iovec iov;
+  EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(1, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(100, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekSingleBlock) {
+  std::string source(kBlockSizeBytes, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source, IovecToStringPiece(iov));
+
+  // Peeking again gives the same result.
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source, IovecToStringPiece(iov));
+
+  // Peek at a different offset.
+  EXPECT_TRUE(buffer_->PeekRegion(100, &iov));
+  EXPECT_EQ(absl::string_view(source).substr(100), IovecToStringPiece(iov));
+
+  // Peeking at or after FirstMissingByte() returns false.
+  EXPECT_FALSE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(kBlockSizeBytes + 1, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekTwoWritesInSingleBlock) {
+  const size_t length1 = 1024;
+  std::string source1(length1, 'a');
+  buffer_->OnStreamData(0, source1, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+
+  // The second frame goes into the same block.
+  const size_t length2 = 800;
+  std::string source2(length2, 'b');
+  buffer_->OnStreamData(length1, source2, &written_, &error_details_);
+
+  EXPECT_TRUE(buffer_->PeekRegion(length1, &iov));
+  EXPECT_EQ(source2, IovecToStringPiece(iov));
+
+  // Peek with an offset inside the first write.
+  const QuicStreamOffset offset1 = 500;
+  EXPECT_TRUE(buffer_->PeekRegion(offset1, &iov));
+  EXPECT_EQ(absl::string_view(source1).substr(offset1),
+            IovecToStringPiece(iov).substr(0, length1 - offset1));
+  EXPECT_EQ(absl::string_view(source2),
+            IovecToStringPiece(iov).substr(length1 - offset1));
+
+  // Peek with an offset inside the second write.
+  const QuicStreamOffset offset2 = 1500;
+  EXPECT_TRUE(buffer_->PeekRegion(offset2, &iov));
+  EXPECT_EQ(absl::string_view(source2).substr(offset2 - length1),
+            IovecToStringPiece(iov));
+
+  // Peeking at or after FirstMissingByte() returns false.
+  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2 + 1, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekBufferWithMultipleBlocks) {
+  const size_t length1 = 1024;
+  std::string source1(length1, 'a');
+  buffer_->OnStreamData(0, source1, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+
+  const size_t length2 = kBlockSizeBytes + 2;
+  std::string source2(length2, 'b');
+  buffer_->OnStreamData(length1, source2, &written_, &error_details_);
+
+  // Peek with offset 0 returns the entire block.
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(kBlockSizeBytes, iov.iov_len);
+  EXPECT_EQ(source1, IovecToStringPiece(iov).substr(0, length1));
+  EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1),
+            IovecToStringPiece(iov).substr(length1));
+
+  EXPECT_TRUE(buffer_->PeekRegion(length1, &iov));
+  EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1),
+            IovecToStringPiece(iov));
+
+  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
+  EXPECT_EQ(absl::string_view(source2).substr(kBlockSizeBytes - length1),
+            IovecToStringPiece(iov));
+
+  // Peeking at or after FirstMissingByte() returns false.
+  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2 + 1, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekAfterConsumed) {
+  std::string source1(kBlockSizeBytes, 'a');
+  buffer_->OnStreamData(0, source1, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+
+  // Consume some data.
+  EXPECT_TRUE(buffer_->MarkConsumed(1024));
+
+  // Peeking into consumed data fails.
+  EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(512, &iov));
+
+  EXPECT_TRUE(buffer_->PeekRegion(1024, &iov));
+  EXPECT_EQ(absl::string_view(source1).substr(1024), IovecToStringPiece(iov));
+
+  EXPECT_TRUE(buffer_->PeekRegion(1500, &iov));
+  EXPECT_EQ(absl::string_view(source1).substr(1500), IovecToStringPiece(iov));
+
+  // Consume rest of block.
+  EXPECT_TRUE(buffer_->MarkConsumed(kBlockSizeBytes - 1024));
+
+  // Read new data.
+  std::string source2(300, 'b');
+  buffer_->OnStreamData(kBlockSizeBytes, source2, &written_, &error_details_);
+
+  // Peek into new data.
+  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
+  EXPECT_EQ(source2, IovecToStringPiece(iov));
+
+  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes + 128, &iov));
+  EXPECT_EQ(absl::string_view(source2).substr(128), IovecToStringPiece(iov));
+
+  // Peeking into consumed data still fails.
+  EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(512, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(1024, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(1500, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekContinously) {
+  std::string source1(kBlockSizeBytes, 'a');
+  buffer_->OnStreamData(0, source1, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+
+  std::string source2(kBlockSizeBytes, 'b');
+  buffer_->OnStreamData(kBlockSizeBytes, source2, &written_, &error_details_);
+
+  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
+  EXPECT_EQ(source2, IovecToStringPiece(iov));
+
+  // First block is still there.
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, MarkConsumedInOneBlock) {
+  // Write into [0, 1024) and then read out [0, 256)
+  std::string source(1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+
+  EXPECT_TRUE(buffer_->MarkConsumed(512));
+  EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
+  EXPECT_EQ(256u, helper_->ReadableBytes());
+  buffer_->MarkConsumed(256);
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, MarkConsumedNotEnoughBytes) {
+  // Write into [0, 1024) and then read out [0, 256)
+  std::string source(1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+
+  // Consume 1st 512 bytes
+  EXPECT_TRUE(buffer_->MarkConsumed(512));
+  EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
+  EXPECT_EQ(256u, helper_->ReadableBytes());
+  // Try to consume one bytes more than available. Should return false.
+  EXPECT_FALSE(buffer_->MarkConsumed(257));
+  EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
+  iovec iov;
+  EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossBlock) {
+  // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
+  std::string source(2 * kBlockSizeBytes + 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+
+  buffer_->MarkConsumed(2 * kBlockSizeBytes);
+  EXPECT_EQ(source.size(), buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossEnd) {
+  // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024)
+  // and then append 1024 + 512 bytes.
+  std::string source(8.5 * kBlockSizeBytes - 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+  source = std::string(1024 + 512, 'b');
+  buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_,
+                        &error_details_);
+  EXPECT_EQ(1024u, buffer_->BytesConsumed());
+
+  // Consume to the end of 8th block.
+  buffer_->MarkConsumed(8 * kBlockSizeBytes - 1024);
+  EXPECT_EQ(8 * kBlockSizeBytes, buffer_->BytesConsumed());
+  // Consume across the physical end of buffer
+  buffer_->MarkConsumed(0.5 * kBlockSizeBytes + 500);
+  EXPECT_EQ(max_capacity_bytes_ + 500, buffer_->BytesConsumed());
+  EXPECT_EQ(12u, helper_->ReadableBytes());
+  // Consume to the logical end of buffer
+  buffer_->MarkConsumed(12);
+  EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, FlushBufferedFrames) {
+  // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024).
+  std::string source(max_capacity_bytes_ - 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+  EXPECT_EQ(1024u, buffer_->BytesConsumed());
+  // Write [1024, 512) to the physical beginning.
+  source = std::string(512, 'b');
+  buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
+                        &error_details_);
+  EXPECT_EQ(512u, written_);
+  EXPECT_EQ(max_capacity_bytes_ - 1024 + 512, buffer_->FlushBufferedFrames());
+  EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+  // Clear buffer at this point should still preserve BytesConsumed().
+  buffer_->Clear();
+  EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, TooManyGaps) {
+  // Make sure max capacity is large enough that it is possible to have more
+  // than |kMaxNumGapsAllowed| number of gaps.
+  max_capacity_bytes_ = 3 * kBlockSizeBytes;
+  // Feed buffer with 1-byte discontiguous frames. e.g. [1,2), [3,4), [5,6)...
+  for (QuicStreamOffset begin = 1; begin <= max_capacity_bytes_; begin += 2) {
+    QuicErrorCode rs =
+        buffer_->OnStreamData(begin, "a", &written_, &error_details_);
+
+    QuicStreamOffset last_straw = 2 * kMaxNumGapsAllowed - 1;
+    if (begin == last_straw) {
+      EXPECT_THAT(rs, IsError(QUIC_TOO_MANY_STREAM_DATA_INTERVALS));
+      EXPECT_EQ("Too many data intervals received for this stream.",
+                error_details_);
+      break;
+    }
+  }
+}
+
+class QuicStreamSequencerBufferRandomIOTest
+    : public QuicStreamSequencerBufferTest {
+ public:
+  using OffsetSizePair = std::pair<QuicStreamOffset, size_t>;
+
+  void SetUp() override {
+    // Test against a larger capacity then above tests. Also make sure the last
+    // block is partially available to use.
+    max_capacity_bytes_ = 8.25 * kBlockSizeBytes;
+    // Stream to be buffered should be larger than the capacity to test wrap
+    // around.
+    bytes_to_buffer_ = 2 * max_capacity_bytes_;
+    Initialize();
+
+    uint64_t seed = QuicRandom::GetInstance()->RandUint64();
+    QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****";
+    rng_.set_seed(seed);
+  }
+
+  // Create an out-of-order source stream with given size to populate
+  // shuffled_buf_.
+  void CreateSourceAndShuffle(size_t max_chunk_size_bytes) {
+    max_chunk_size_bytes_ = max_chunk_size_bytes;
+    std::unique_ptr<OffsetSizePair[]> chopped_stream(
+        new OffsetSizePair[bytes_to_buffer_]);
+
+    // Split stream into small chunks with random length. chopped_stream will be
+    // populated with segmented stream chunks.
+    size_t start_chopping_offset = 0;
+    size_t iterations = 0;
+    while (start_chopping_offset < bytes_to_buffer_) {
+      size_t max_chunk = std::min<size_t>(
+          max_chunk_size_bytes_, bytes_to_buffer_ - start_chopping_offset);
+      size_t chunk_size = rng_.RandUint64() % max_chunk + 1;
+      chopped_stream[iterations] =
+          OffsetSizePair(start_chopping_offset, chunk_size);
+      start_chopping_offset += chunk_size;
+      ++iterations;
+    }
+    QUICHE_DCHECK(start_chopping_offset == bytes_to_buffer_);
+    size_t chunk_num = iterations;
+
+    // Randomly change the sequence of in-ordered OffsetSizePairs to make a
+    // out-of-order array of OffsetSizePairs.
+    for (int i = chunk_num - 1; i >= 0; --i) {
+      size_t random_idx = rng_.RandUint64() % (i + 1);
+      QUIC_DVLOG(1) << "chunk offset " << chopped_stream[random_idx].first
+                    << " size " << chopped_stream[random_idx].second;
+      shuffled_buf_.push_front(chopped_stream[random_idx]);
+      chopped_stream[random_idx] = chopped_stream[i];
+    }
+  }
+
+  // Write the currently first chunk of data in the out-of-order stream into
+  // QuicStreamSequencerBuffer. If current chuck cannot be written into buffer
+  // because it goes beyond current capacity, move it to the end of
+  // shuffled_buf_ and write it later.
+  void WriteNextChunkToBuffer() {
+    OffsetSizePair& chunk = shuffled_buf_.front();
+    QuicStreamOffset offset = chunk.first;
+    const size_t num_to_write = chunk.second;
+    std::unique_ptr<char[]> write_buf{new char[max_chunk_size_bytes_]};
+    for (size_t i = 0; i < num_to_write; ++i) {
+      write_buf[i] = (offset + i) % 256;
+    }
+    absl::string_view string_piece_w(write_buf.get(), num_to_write);
+    auto result = buffer_->OnStreamData(offset, string_piece_w, &written_,
+                                        &error_details_);
+    if (result == QUIC_NO_ERROR) {
+      shuffled_buf_.pop_front();
+      total_bytes_written_ += num_to_write;
+    } else {
+      // This chunk offset exceeds window size.
+      shuffled_buf_.push_back(chunk);
+      shuffled_buf_.pop_front();
+    }
+    QUIC_DVLOG(1) << " write at offset: " << offset
+                  << " len to write: " << num_to_write
+                  << " write result: " << result
+                  << " left over: " << shuffled_buf_.size();
+  }
+
+ protected:
+  std::list<OffsetSizePair> shuffled_buf_;
+  size_t max_chunk_size_bytes_;
+  QuicStreamOffset bytes_to_buffer_;
+  size_t total_bytes_written_ = 0;
+  size_t total_bytes_read_ = 0;
+  SimpleRandom rng_;
+};
+
+TEST_F(QuicStreamSequencerBufferRandomIOTest, RandomWriteAndReadv) {
+  // Set kMaxReadSize larger than kBlockSizeBytes to test both small and large
+  // read.
+  const size_t kMaxReadSize = kBlockSizeBytes * 2;
+  // kNumReads is larger than 1 to test how multiple read destinations work.
+  const size_t kNumReads = 2;
+  // Since write and read operation have equal possibility to be called. Bytes
+  // to be written into and read out of should roughly the same.
+  const size_t kMaxWriteSize = kNumReads * kMaxReadSize;
+  size_t iterations = 0;
+
+  CreateSourceAndShuffle(kMaxWriteSize);
+
+  while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
+         iterations <= 2 * bytes_to_buffer_) {
+    uint8_t next_action =
+        shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
+    QUIC_DVLOG(1) << "iteration: " << iterations;
+    switch (next_action) {
+      case 0: {  // write
+        WriteNextChunkToBuffer();
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        break;
+      }
+      case 1: {  // readv
+        std::unique_ptr<char[][kMaxReadSize]> read_buf{
+            new char[kNumReads][kMaxReadSize]};
+        iovec dest_iov[kNumReads];
+        size_t num_to_read = 0;
+        for (size_t i = 0; i < kNumReads; ++i) {
+          dest_iov[i].iov_base =
+              reinterpret_cast<void*>(const_cast<char*>(read_buf[i]));
+          dest_iov[i].iov_len = rng_.RandUint64() % kMaxReadSize;
+          num_to_read += dest_iov[i].iov_len;
+        }
+        size_t actually_read;
+        EXPECT_THAT(buffer_->Readv(dest_iov, kNumReads, &actually_read,
+                                   &error_details_),
+                    IsQuicNoError());
+        ASSERT_LE(actually_read, num_to_read);
+        QUIC_DVLOG(1) << " read from offset: " << total_bytes_read_
+                      << " size: " << num_to_read
+                      << " actual read: " << actually_read;
+        for (size_t i = 0; i < actually_read; ++i) {
+          char ch = (i + total_bytes_read_) % 256;
+          ASSERT_EQ(ch, GetCharFromIOVecs(i, dest_iov, kNumReads))
+              << " at iteration " << iterations;
+        }
+        total_bytes_read_ += actually_read;
+        ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        break;
+      }
+    }
+    ++iterations;
+    ASSERT_LE(total_bytes_read_, total_bytes_written_);
+  }
+  EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
+  EXPECT_LE(bytes_to_buffer_, total_bytes_read_)
+      << "iterations: " << iterations;
+  EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
+}
+
+TEST_F(QuicStreamSequencerBufferRandomIOTest, RandomWriteAndConsumeInPlace) {
+  // The value 4 is chosen such that the max write size is no larger than the
+  // maximum buffer capacity.
+  const size_t kMaxNumReads = 4;
+  // Adjust write amount be roughly equal to that GetReadableRegions() can get.
+  const size_t kMaxWriteSize = kMaxNumReads * kBlockSizeBytes;
+  ASSERT_LE(kMaxWriteSize, max_capacity_bytes_);
+  size_t iterations = 0;
+
+  CreateSourceAndShuffle(kMaxWriteSize);
+
+  while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
+         iterations <= 2 * bytes_to_buffer_) {
+    uint8_t next_action =
+        shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
+    QUIC_DVLOG(1) << "iteration: " << iterations;
+    switch (next_action) {
+      case 0: {  // write
+        WriteNextChunkToBuffer();
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        break;
+      }
+      case 1: {  // GetReadableRegions and then MarkConsumed
+        size_t num_read = rng_.RandUint64() % kMaxNumReads + 1;
+        iovec dest_iov[kMaxNumReads];
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        size_t actually_num_read =
+            buffer_->GetReadableRegions(dest_iov, num_read);
+        ASSERT_LE(actually_num_read, num_read);
+        size_t avail_bytes = 0;
+        for (size_t i = 0; i < actually_num_read; ++i) {
+          avail_bytes += dest_iov[i].iov_len;
+        }
+        // process random number of bytes (check the value of each byte).
+        size_t bytes_to_process = rng_.RandUint64() % (avail_bytes + 1);
+        size_t bytes_processed = 0;
+        for (size_t i = 0; i < actually_num_read; ++i) {
+          size_t bytes_in_block = std::min<size_t>(
+              bytes_to_process - bytes_processed, dest_iov[i].iov_len);
+          if (bytes_in_block == 0) {
+            break;
+          }
+          for (size_t j = 0; j < bytes_in_block; ++j) {
+            ASSERT_LE(bytes_processed, bytes_to_process);
+            char char_expected =
+                (buffer_->BytesConsumed() + bytes_processed) % 256;
+            ASSERT_EQ(char_expected,
+                      reinterpret_cast<const char*>(dest_iov[i].iov_base)[j])
+                << " at iteration " << iterations;
+            ++bytes_processed;
+          }
+        }
+
+        buffer_->MarkConsumed(bytes_processed);
+
+        QUIC_DVLOG(1) << "iteration " << iterations << ": try to get "
+                      << num_read << " readable regions, actually get "
+                      << actually_num_read
+                      << " from offset: " << total_bytes_read_
+                      << "\nprocesse bytes: " << bytes_processed;
+        total_bytes_read_ += bytes_processed;
+        ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        break;
+      }
+    }
+    ++iterations;
+    ASSERT_LE(total_bytes_read_, total_bytes_written_);
+  }
+  EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
+  EXPECT_LE(bytes_to_buffer_, total_bytes_read_)
+      << "iterations: " << iterations;
+  EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GrowBlockSizeOnDemand) {
+  max_capacity_bytes_ = 1024 * kBlockSizeBytes;
+  std::string source_of_one_block(kBlockSizeBytes, 'a');
+  Initialize();
+
+  ASSERT_EQ(helper_->current_blocks_count(), 0u);
+
+  // A minimum of 8 blocks are allocated
+  buffer_->OnStreamData(0, source_of_one_block, &written_, &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 8u);
+
+  // Number of blocks doesn't grow if the data is within the capacity.
+  buffer_->OnStreamData(kBlockSizeBytes * 7, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 8u);
+
+  // Number of blocks grows by a factor of 4 normally.
+  buffer_->OnStreamData(kBlockSizeBytes * 8, "a", &written_, &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 32u);
+
+  // Number of blocks grow to the demanded size of 140 instead of 128 since
+  // that's not enough.
+  buffer_->OnStreamData(kBlockSizeBytes * 139, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 140u);
+
+  // Number of blocks grows by a factor of 4 normally.
+  buffer_->OnStreamData(kBlockSizeBytes * 140, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 560u);
+
+  // max_capacity_bytes is reached and number of blocks is capped.
+  buffer_->OnStreamData(kBlockSizeBytes * 560, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 1024u);
+
+  // max_capacity_bytes is reached and number of blocks is capped.
+  buffer_->OnStreamData(kBlockSizeBytes * 1025, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 1024u);
+}
+
+}  // anonymous namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_sequencer_test.cc b/quiche/quic/core/quic_stream_sequencer_test.cc
new file mode 100644
index 0000000..8a1b2de
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer_test.cc
@@ -0,0 +1,781 @@
+// 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 "quiche/quic/core/quic_stream_sequencer.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::InSequence;
+
+namespace quic {
+namespace test {
+
+class MockStream : public QuicStreamSequencer::StreamInterface {
+ public:
+  MOCK_METHOD(void, OnFinRead, (), (override));
+  MOCK_METHOD(void, OnDataAvailable, (), (override));
+  MOCK_METHOD(void,
+              OnUnrecoverableError,
+              (QuicErrorCode error, const std::string& details),
+              (override));
+  MOCK_METHOD(void,
+              OnUnrecoverableError,
+              (QuicErrorCode error,
+               QuicIetfTransportErrorCodes ietf_error,
+               const std::string& details),
+              (override));
+  MOCK_METHOD(void, ResetWithError, (QuicResetStreamError error), (override));
+  MOCK_METHOD(void, AddBytesConsumed, (QuicByteCount bytes), (override));
+
+  QuicStreamId id() const override { return 1; }
+  ParsedQuicVersion version() const override {
+    return CurrentSupportedVersions()[0];
+  }
+};
+
+namespace {
+
+static const char kPayload[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+class QuicStreamSequencerTest : public QuicTest {
+ public:
+  void ConsumeData(size_t num_bytes) {
+    char buffer[1024];
+    ASSERT_GT(ABSL_ARRAYSIZE(buffer), num_bytes);
+    struct iovec iov;
+    iov.iov_base = buffer;
+    iov.iov_len = num_bytes;
+    ASSERT_EQ(num_bytes, sequencer_->Readv(&iov, 1));
+  }
+
+ protected:
+  QuicStreamSequencerTest()
+      : stream_(), sequencer_(new QuicStreamSequencer(&stream_)) {}
+
+  // Verify that the data in first region match with the expected[0].
+  bool VerifyReadableRegion(const std::vector<std::string>& expected) {
+    return VerifyReadableRegion(*sequencer_, expected);
+  }
+
+  // Verify that the data in each of currently readable regions match with each
+  // item given in |expected|.
+  bool VerifyReadableRegions(const std::vector<std::string>& expected) {
+    return VerifyReadableRegions(*sequencer_, expected);
+  }
+
+  bool VerifyIovecs(iovec* iovecs,
+                    size_t num_iovecs,
+                    const std::vector<std::string>& expected) {
+    return VerifyIovecs(*sequencer_, iovecs, num_iovecs, expected);
+  }
+
+  bool VerifyReadableRegion(const QuicStreamSequencer& sequencer,
+                            const std::vector<std::string>& expected) {
+    iovec iovecs[1];
+    if (sequencer.GetReadableRegions(iovecs, 1)) {
+      return (VerifyIovecs(sequencer, iovecs, 1,
+                           std::vector<std::string>{expected[0]}));
+    }
+    return false;
+  }
+
+  // Verify that the data in each of currently readable regions match with each
+  // item given in |expected|.
+  bool VerifyReadableRegions(const QuicStreamSequencer& sequencer,
+                             const std::vector<std::string>& expected) {
+    iovec iovecs[5];
+    size_t num_iovecs =
+        sequencer.GetReadableRegions(iovecs, ABSL_ARRAYSIZE(iovecs));
+    return VerifyReadableRegion(sequencer, expected) &&
+           VerifyIovecs(sequencer, iovecs, num_iovecs, expected);
+  }
+
+  bool VerifyIovecs(const QuicStreamSequencer& /*sequencer*/,
+                    iovec* iovecs,
+                    size_t num_iovecs,
+                    const std::vector<std::string>& expected) {
+    int start_position = 0;
+    for (size_t i = 0; i < num_iovecs; ++i) {
+      if (!VerifyIovec(iovecs[i],
+                       expected[0].substr(start_position, iovecs[i].iov_len))) {
+        return false;
+      }
+      start_position += iovecs[i].iov_len;
+    }
+    return true;
+  }
+
+  bool VerifyIovec(const iovec& iovec, absl::string_view expected) {
+    if (iovec.iov_len != expected.length()) {
+      QUIC_LOG(ERROR) << "Invalid length: " << iovec.iov_len << " vs "
+                      << expected.length();
+      return false;
+    }
+    if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) {
+      QUIC_LOG(ERROR) << "Invalid data: " << static_cast<char*>(iovec.iov_base)
+                      << " vs " << expected;
+      return false;
+    }
+    return true;
+  }
+
+  void OnFinFrame(QuicStreamOffset byte_offset, const char* data) {
+    QuicStreamFrame frame;
+    frame.stream_id = 1;
+    frame.offset = byte_offset;
+    frame.data_buffer = data;
+    frame.data_length = strlen(data);
+    frame.fin = true;
+    sequencer_->OnStreamFrame(frame);
+  }
+
+  void OnFrame(QuicStreamOffset byte_offset, const char* data) {
+    QuicStreamFrame frame;
+    frame.stream_id = 1;
+    frame.offset = byte_offset;
+    frame.data_buffer = data;
+    frame.data_length = strlen(data);
+    frame.fin = false;
+    sequencer_->OnStreamFrame(frame);
+  }
+
+  size_t NumBufferedBytes() {
+    return QuicStreamSequencerPeer::GetNumBufferedBytes(sequencer_.get());
+  }
+
+  testing::StrictMock<MockStream> stream_;
+  std::unique_ptr<QuicStreamSequencer> sequencer_;
+};
+
+// TODO(rch): reorder these tests so they build on each other.
+
+TEST_F(QuicStreamSequencerTest, RejectOldFrame) {
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+
+  OnFrame(0, "abc");
+
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+  // Ignore this - it matches a past packet number and we should not see it
+  // again.
+  OnFrame(0, "def");
+  EXPECT_EQ(0u, NumBufferedBytes());
+}
+
+TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+
+  // Ignore this - it matches a buffered frame.
+  // Right now there's no checking that the payload is consistent.
+  OnFrame(0, "def");
+  EXPECT_EQ(3u, NumBufferedBytes());
+}
+
+TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
+  sequencer_->SetBlockedUntilFlush();
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  sequencer_->SetUnblocked();
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  EXPECT_FALSE(sequencer_->IsClosed());
+  OnFinFrame(3, "def");
+  EXPECT_TRUE(sequencer_->IsClosed());
+}
+
+TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
+  sequencer_->SetBlockedUntilFlush();
+
+  OnFinFrame(0, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  EXPECT_FALSE(sequencer_->IsClosed());
+  sequencer_->SetUnblocked();
+  EXPECT_TRUE(sequencer_->IsClosed());
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, EmptyFrame) {
+  if (!stream_.version().HasIetfQuicFrames()) {
+    EXPECT_CALL(stream_,
+                OnUnrecoverableError(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _));
+  }
+  OnFrame(0, "");
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, EmptyFinFrame) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFinFrame(0, "");
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
+  EXPECT_CALL(stream_, AddBytesConsumed(2));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(2);
+  }));
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(1u, NumBufferedBytes());
+  EXPECT_EQ(2u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) {
+  OnFrame(3, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
+  // Buffer the first
+  OnFrame(6, "ghi");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
+  // Buffer the second
+  OnFrame(3, "def");
+  EXPECT_EQ(6u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(9));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(9);
+  }));
+
+  // Now process all of them at once.
+  OnFrame(0, "abc");
+  EXPECT_EQ(9u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+
+  EXPECT_EQ(0u, NumBufferedBytes());
+}
+
+TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) {
+  InSequence s;
+
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  OnFinFrame(0, "abc");
+
+  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+}
+
+TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) {
+  OnFinFrame(6, "");
+  EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+
+  OnFrame(3, "def");
+  EXPECT_CALL(stream_, AddBytesConsumed(6));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(6);
+  }));
+  EXPECT_FALSE(sequencer_->IsClosed());
+  OnFrame(0, "abc");
+  EXPECT_TRUE(sequencer_->IsClosed());
+}
+
+TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
+  OnFinFrame(3, "");
+  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  EXPECT_FALSE(sequencer_->IsClosed());
+  OnFrame(0, "abc");
+  EXPECT_TRUE(sequencer_->IsClosed());
+}
+
+TEST_F(QuicStreamSequencerTest, TerminateWithReadv) {
+  char buffer[3];
+
+  OnFinFrame(3, "");
+  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+
+  EXPECT_FALSE(sequencer_->IsClosed());
+
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFrame(0, "abc");
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  iovec iov = {&buffer[0], 3};
+  int bytes_read = sequencer_->Readv(&iov, 1);
+  EXPECT_EQ(3, bytes_read);
+  EXPECT_TRUE(sequencer_->IsClosed());
+}
+
+TEST_F(QuicStreamSequencerTest, MultipleOffsets) {
+  OnFinFrame(3, "");
+  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+
+  EXPECT_CALL(stream_, OnUnrecoverableError(
+                           QUIC_STREAM_SEQUENCER_INVALID_STATE,
+                           "Stream 1 received new final offset: 1, which is "
+                           "different from close offset: 3"));
+  OnFinFrame(1, "");
+}
+
+class QuicSequencerRandomTest : public QuicStreamSequencerTest {
+ public:
+  using Frame = std::pair<int, std::string>;
+  using FrameList = std::vector<Frame>;
+
+  void CreateFrames() {
+    int payload_size = ABSL_ARRAYSIZE(kPayload) - 1;
+    int remaining_payload = payload_size;
+    while (remaining_payload != 0) {
+      int size = std::min(OneToN(6), remaining_payload);
+      int index = payload_size - remaining_payload;
+      list_.push_back(
+          std::make_pair(index, std::string(kPayload + index, size)));
+      remaining_payload -= size;
+    }
+  }
+
+  QuicSequencerRandomTest() {
+    uint64_t seed = QuicRandom::GetInstance()->RandUint64();
+    QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****";
+    random_.set_seed(seed);
+
+    CreateFrames();
+  }
+
+  int OneToN(int n) { return random_.RandUint64() % n + 1; }
+
+  void ReadAvailableData() {
+    // Read all available data
+    char output[ABSL_ARRAYSIZE(kPayload) + 1];
+    iovec iov;
+    iov.iov_base = output;
+    iov.iov_len = ABSL_ARRAYSIZE(output);
+    int bytes_read = sequencer_->Readv(&iov, 1);
+    EXPECT_NE(0, bytes_read);
+    output_.append(output, bytes_read);
+  }
+
+  std::string output_;
+  // Data which peek at using GetReadableRegion if we back up.
+  std::string peeked_;
+  SimpleRandom random_;
+  FrameList list_;
+};
+
+// All frames are processed as soon as we have sequential data.
+// Infinite buffering, so all frames are acked right away.
+TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
+  EXPECT_CALL(stream_, OnDataAvailable())
+      .Times(AnyNumber())
+      .WillRepeatedly(
+          Invoke(this, &QuicSequencerRandomTest::ReadAvailableData));
+  QuicByteCount total_bytes_consumed = 0;
+  EXPECT_CALL(stream_, AddBytesConsumed(_))
+      .Times(AnyNumber())
+      .WillRepeatedly(
+          testing::Invoke([&total_bytes_consumed](QuicByteCount bytes) {
+            total_bytes_consumed += bytes;
+          }));
+
+  while (!list_.empty()) {
+    int index = OneToN(list_.size()) - 1;
+    QUIC_LOG(ERROR) << "Sending index " << index << " " << list_[index].second;
+    OnFrame(list_[index].first, list_[index].second.data());
+
+    list_.erase(list_.begin() + index);
+  }
+
+  ASSERT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, output_.size());
+  EXPECT_EQ(kPayload, output_);
+  EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed);
+}
+
+TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
+  char buffer[10];
+  iovec iov[2];
+  iov[0].iov_base = &buffer[0];
+  iov[0].iov_len = 5;
+  iov[1].iov_base = &buffer[5];
+  iov[1].iov_len = 5;
+
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(AnyNumber());
+  QuicByteCount total_bytes_consumed = 0;
+  EXPECT_CALL(stream_, AddBytesConsumed(_))
+      .Times(AnyNumber())
+      .WillRepeatedly(
+          testing::Invoke([&total_bytes_consumed](QuicByteCount bytes) {
+            total_bytes_consumed += bytes;
+          }));
+
+  while (output_.size() != ABSL_ARRAYSIZE(kPayload) - 1) {
+    if (!list_.empty() && OneToN(2) == 1) {  // Send data
+      int index = OneToN(list_.size()) - 1;
+      OnFrame(list_[index].first, list_[index].second.data());
+      list_.erase(list_.begin() + index);
+    } else {  // Read data
+      bool has_bytes = sequencer_->HasBytesToRead();
+      iovec peek_iov[20];
+      int iovs_peeked = sequencer_->GetReadableRegions(peek_iov, 20);
+      if (has_bytes) {
+        ASSERT_LT(0, iovs_peeked);
+        ASSERT_TRUE(sequencer_->GetReadableRegion(peek_iov));
+      } else {
+        ASSERT_EQ(0, iovs_peeked);
+        ASSERT_FALSE(sequencer_->GetReadableRegion(peek_iov));
+      }
+      int total_bytes_to_peek = ABSL_ARRAYSIZE(buffer);
+      for (int i = 0; i < iovs_peeked; ++i) {
+        int bytes_to_peek =
+            std::min<int>(peek_iov[i].iov_len, total_bytes_to_peek);
+        peeked_.append(static_cast<char*>(peek_iov[i].iov_base), bytes_to_peek);
+        total_bytes_to_peek -= bytes_to_peek;
+        if (total_bytes_to_peek == 0) {
+          break;
+        }
+      }
+      int bytes_read = sequencer_->Readv(iov, 2);
+      output_.append(buffer, bytes_read);
+      ASSERT_EQ(output_.size(), peeked_.size());
+    }
+  }
+  EXPECT_EQ(std::string(kPayload), output_);
+  EXPECT_EQ(std::string(kPayload), peeked_);
+  EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed);
+}
+
+// Same as above, just using a different method for reading.
+TEST_F(QuicStreamSequencerTest, MarkConsumed) {
+  InSequence s;
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  OnFrame(3, "def");
+  OnFrame(6, "ghi");
+
+  // abcdefghi buffered.
+  EXPECT_EQ(9u, sequencer_->NumBytesBuffered());
+
+  // Peek into the data.
+  std::vector<std::string> expected = {"abcdefghi"};
+  ASSERT_TRUE(VerifyReadableRegions(expected));
+
+  // Consume 1 byte.
+  EXPECT_CALL(stream_, AddBytesConsumed(1));
+  sequencer_->MarkConsumed(1);
+  // Verify data.
+  std::vector<std::string> expected2 = {"bcdefghi"};
+  ASSERT_TRUE(VerifyReadableRegions(expected2));
+  EXPECT_EQ(8u, sequencer_->NumBytesBuffered());
+
+  // Consume 2 bytes.
+  EXPECT_CALL(stream_, AddBytesConsumed(2));
+  sequencer_->MarkConsumed(2);
+  // Verify data.
+  std::vector<std::string> expected3 = {"defghi"};
+  ASSERT_TRUE(VerifyReadableRegions(expected3));
+  EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
+
+  // Consume 5 bytes.
+  EXPECT_CALL(stream_, AddBytesConsumed(5));
+  sequencer_->MarkConsumed(5);
+  // Verify data.
+  std::vector<std::string> expected4{"i"};
+  ASSERT_TRUE(VerifyReadableRegions(expected4));
+  EXPECT_EQ(1u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, MarkConsumedError) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  OnFrame(9, "jklmnopqrstuvwxyz");
+
+  // Peek into the data.  Only the first chunk should be readable because of the
+  // missing data.
+  std::vector<std::string> expected{"abc"};
+  ASSERT_TRUE(VerifyReadableRegions(expected));
+
+  // Now, attempt to mark consumed more data than was readable and expect the
+  // stream to be closed.
+  EXPECT_CALL(stream_, ResetWithError(QuicResetStreamError::FromInternal(
+                           QUIC_ERROR_PROCESSING_STREAM)));
+  EXPECT_QUIC_BUG(sequencer_->MarkConsumed(4),
+                  "Invalid argument to MarkConsumed."
+                  " expect to consume: 4, but not enough bytes available.");
+}
+
+TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
+  InSequence s;
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  OnFrame(3, "def");
+  // Missing packet: 6, ghi.
+  OnFrame(9, "jkl");
+
+  std::vector<std::string> expected = {"abcdef"};
+  ASSERT_TRUE(VerifyReadableRegions(expected));
+
+  EXPECT_CALL(stream_, AddBytesConsumed(6));
+  sequencer_->MarkConsumed(6);
+}
+
+TEST_F(QuicStreamSequencerTest, Move) {
+  InSequence s;
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  OnFrame(3, "def");
+  OnFrame(6, "ghi");
+
+  // abcdefghi buffered.
+  EXPECT_EQ(9u, sequencer_->NumBytesBuffered());
+
+  // Peek into the data.
+  std::vector<std::string> expected = {"abcdefghi"};
+  ASSERT_TRUE(VerifyReadableRegions(expected));
+
+  QuicStreamSequencer sequencer2(std::move(*sequencer_));
+  ASSERT_TRUE(VerifyReadableRegions(sequencer2, expected));
+}
+
+TEST_F(QuicStreamSequencerTest, OverlappingFramesReceived) {
+  // The peer should never send us non-identical stream frames which contain
+  // overlapping byte ranges - if they do, we close the connection.
+  QuicStreamId id = 1;
+
+  QuicStreamFrame frame1(id, false, 1, absl::string_view("hello"));
+  sequencer_->OnStreamFrame(frame1);
+
+  QuicStreamFrame frame2(id, false, 2, absl::string_view("hello"));
+  EXPECT_CALL(stream_, OnUnrecoverableError(QUIC_OVERLAPPING_STREAM_DATA, _))
+      .Times(0);
+  sequencer_->OnStreamFrame(frame2);
+}
+
+TEST_F(QuicStreamSequencerTest, DataAvailableOnOverlappingFrames) {
+  QuicStreamId id = 1;
+  const std::string data(1000, '.');
+
+  // Received [0, 1000).
+  QuicStreamFrame frame1(id, false, 0, data);
+  EXPECT_CALL(stream_, OnDataAvailable());
+  sequencer_->OnStreamFrame(frame1);
+  // Consume [0, 500).
+  EXPECT_CALL(stream_, AddBytesConsumed(500));
+  QuicStreamSequencerTest::ConsumeData(500);
+  EXPECT_EQ(500u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(500u, sequencer_->NumBytesBuffered());
+
+  // Received [500, 1500).
+  QuicStreamFrame frame2(id, false, 500, data);
+  // Do not call OnDataAvailable as there are readable bytes left in the buffer.
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  sequencer_->OnStreamFrame(frame2);
+  // Consume [1000, 1500).
+  EXPECT_CALL(stream_, AddBytesConsumed(1000));
+  QuicStreamSequencerTest::ConsumeData(1000);
+  EXPECT_EQ(1500u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+
+  // Received [1498, 1503).
+  QuicStreamFrame frame3(id, false, 1498, absl::string_view("hello"));
+  EXPECT_CALL(stream_, OnDataAvailable());
+  sequencer_->OnStreamFrame(frame3);
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  QuicStreamSequencerTest::ConsumeData(3);
+  EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+
+  // Received [1000, 1005).
+  QuicStreamFrame frame4(id, false, 1000, absl::string_view("hello"));
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  sequencer_->OnStreamFrame(frame4);
+  EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, OnDataAvailableWhenReadableBytesIncrease) {
+  sequencer_->set_level_triggered(true);
+  QuicStreamId id = 1;
+
+  // Received [0, 5).
+  QuicStreamFrame frame1(id, false, 0, "hello");
+  EXPECT_CALL(stream_, OnDataAvailable());
+  sequencer_->OnStreamFrame(frame1);
+  EXPECT_EQ(5u, sequencer_->NumBytesBuffered());
+
+  // Without consuming the buffer bytes, continue receiving [5, 11).
+  QuicStreamFrame frame2(id, false, 5, " world");
+  // OnDataAvailable should still be called because there are more data to read.
+  EXPECT_CALL(stream_, OnDataAvailable());
+  sequencer_->OnStreamFrame(frame2);
+  EXPECT_EQ(11u, sequencer_->NumBytesBuffered());
+
+  // Without consuming the buffer bytes, continue receiving [12, 13).
+  QuicStreamFrame frame3(id, false, 5, "a");
+  // OnDataAvailable shouldn't be called becasue there are still only 11 bytes
+  // available.
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  sequencer_->OnStreamFrame(frame3);
+  EXPECT_EQ(11u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, ReadSingleFrame) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFrame(0u, "abc");
+  std::string actual;
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  sequencer_->Read(&actual);
+  EXPECT_EQ("abc", actual);
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, ReadMultipleFramesWithMissingFrame) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFrame(0u, "abc");
+  OnFrame(3u, "def");
+  OnFrame(6u, "ghi");
+  OnFrame(10u, "xyz");  // Byte 9 is missing.
+  std::string actual;
+  EXPECT_CALL(stream_, AddBytesConsumed(9));
+  sequencer_->Read(&actual);
+  EXPECT_EQ("abcdefghi", actual);
+  EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, ReadAndAppendToString) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFrame(0u, "def");
+  OnFrame(3u, "ghi");
+  std::string actual = "abc";
+  EXPECT_CALL(stream_, AddBytesConsumed(6));
+  sequencer_->Read(&actual);
+  EXPECT_EQ("abcdefghi", actual);
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, StopReading) {
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  EXPECT_CALL(stream_, OnFinRead());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(0));
+  sequencer_->StopReading();
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  OnFrame(0u, "abc");
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  OnFrame(3u, "def");
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  OnFinFrame(6u, "ghi");
+}
+
+TEST_F(QuicStreamSequencerTest, StopReadingWithLevelTriggered) {
+  EXPECT_CALL(stream_, AddBytesConsumed(0));
+  EXPECT_CALL(stream_, AddBytesConsumed(3)).Times(3);
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  EXPECT_CALL(stream_, OnFinRead());
+
+  sequencer_->set_level_triggered(true);
+  sequencer_->StopReading();
+
+  OnFrame(0u, "abc");
+  OnFrame(3u, "def");
+  OnFinFrame(6u, "ghi");
+}
+
+// Regression test for https://crbug.com/992486.
+TEST_F(QuicStreamSequencerTest, CorruptFinFrames) {
+  EXPECT_CALL(stream_, OnUnrecoverableError(
+                           QUIC_STREAM_SEQUENCER_INVALID_STATE,
+                           "Stream 1 received new final offset: 1, which is "
+                           "different from close offset: 2"));
+
+  OnFinFrame(2u, "");
+  OnFinFrame(0u, "a");
+  EXPECT_FALSE(sequencer_->HasBytesToRead());
+}
+
+// Regression test for crbug.com/1015693
+TEST_F(QuicStreamSequencerTest, ReceiveFinLessThanHighestOffset) {
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(1);
+  EXPECT_CALL(stream_, OnUnrecoverableError(
+                           QUIC_STREAM_SEQUENCER_INVALID_STATE,
+                           "Stream 1 received fin with offset: 0, which "
+                           "reduces current highest offset: 3"));
+  OnFrame(0u, "abc");
+  OnFinFrame(0u, "");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_test.cc b/quiche/quic/core/quic_stream_test.cc
new file mode 100644
index 0000000..8a112ee
--- /dev/null
+++ b/quiche/quic/core/quic_stream_test.cc
@@ -0,0 +1,1738 @@
+// 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 "quiche/quic/core/quic_stream.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_mem_slice_storage.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::InSequence;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kData1[] = "FooAndBar";
+const char kData2[] = "EepAndBaz";
+const QuicByteCount kDataLen = 9;
+
+class TestStream : public QuicStream {
+ public:
+  TestStream(QuicStreamId id, QuicSession* session, StreamType type)
+      : QuicStream(id, session, /*is_static=*/false, type) {
+    sequencer()->set_level_triggered(true);
+  }
+
+  TestStream(PendingStream* pending, QuicSession* session, bool is_static)
+      : QuicStream(pending, session, is_static) {}
+
+  MOCK_METHOD(void, OnDataAvailable, (), (override));
+
+  MOCK_METHOD(void, OnCanWriteNewData, (), (override));
+
+  MOCK_METHOD(void, OnWriteSideInDataRecvdState, (), (override));
+
+  using QuicStream::CanWriteNewData;
+  using QuicStream::CanWriteNewDataAfterData;
+  using QuicStream::CloseWriteSide;
+  using QuicStream::fin_buffered;
+  using QuicStream::MaybeSendStopSending;
+  using QuicStream::OnClose;
+  using QuicStream::WriteMemSlices;
+  using QuicStream::WriteOrBufferData;
+
+ private:
+  std::string data_;
+};
+
+class QuicStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicStreamTest()
+      : zero_(QuicTime::Delta::Zero()),
+        supported_versions_(AllSupportedVersions()) {}
+
+  void Initialize(Perspective perspective = Perspective::IS_SERVER) {
+    ParsedQuicVersionVector version_vector;
+    version_vector.push_back(GetParam());
+    connection_ = new StrictMock<MockQuicConnection>(
+        &helper_, &alarm_factory_, perspective, version_vector);
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
+    session_->Initialize();
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 10);
+    session_->OnConfigNegotiated();
+
+    stream_ = new StrictMock<TestStream>(kTestStreamId, session_.get(),
+                                         BIDIRECTIONAL);
+    EXPECT_NE(nullptr, stream_);
+    // session_ now owns stream_.
+    session_->ActivateStream(absl::WrapUnique(stream_));
+    // Ignore resetting when session_ is terminated.
+    EXPECT_CALL(*session_, MaybeSendStopSendingFrame(kTestStreamId, _))
+        .Times(AnyNumber());
+    EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _))
+        .Times(AnyNumber());
+    write_blocked_list_ =
+        QuicSessionPeer::GetWriteBlockedStreams(session_.get());
+  }
+
+  bool fin_sent() { return stream_->fin_sent(); }
+  bool rst_sent() { return stream_->rst_sent(); }
+
+  bool HasWriteBlockedStreams() {
+    return write_blocked_list_->HasWriteBlockedSpecialStream() ||
+           write_blocked_list_->HasWriteBlockedDataStreams();
+  }
+
+  QuicConsumedData CloseStreamOnWriteError(
+      QuicStreamId id, QuicByteCount /*write_length*/,
+      QuicStreamOffset /*offset*/, StreamSendingState /*state*/,
+      TransmissionType /*type*/, absl::optional<EncryptionLevel> /*level*/) {
+    session_->ResetStream(id, QUIC_STREAM_CANCELLED);
+    return QuicConsumedData(1, false);
+  }
+
+  bool ClearResetStreamFrame(const QuicFrame& frame) {
+    EXPECT_EQ(RST_STREAM_FRAME, frame.type);
+    DeleteFrame(&const_cast<QuicFrame&>(frame));
+    return true;
+  }
+
+  bool ClearStopSendingFrame(const QuicFrame& frame) {
+    EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
+    DeleteFrame(&const_cast<QuicFrame&>(frame));
+    return true;
+  }
+
+ protected:
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  std::unique_ptr<MockQuicSession> session_;
+  StrictMock<TestStream>* stream_;
+  QuicWriteBlockedList* write_blocked_list_;
+  QuicTime::Delta zero_;
+  ParsedQuicVersionVector supported_versions_;
+  QuicStreamId kTestStreamId =
+      GetNthClientInitiatedBidirectionalStreamId(GetParam().transport_version,
+                                                 1);
+  const QuicStreamId kTestPendingStreamId =
+      GetNthClientInitiatedUnidirectionalStreamId(GetParam().transport_version,
+                                                  1);
+};
+
+INSTANTIATE_TEST_SUITE_P(QuicStreamTests, QuicStreamTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+using PendingStreamTest = QuicStreamTest;
+
+INSTANTIATE_TEST_SUITE_P(PendingStreamTests, PendingStreamTest,
+                         ::testing::ValuesIn(CurrentSupportedHttp3Versions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(PendingStreamTest, PendingStreamStaticness) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_FALSE(stream.is_static());
+
+  PendingStream pending2(kTestPendingStreamId + 4, session_.get());
+  TestStream stream2(&pending2, session_.get(), true);
+  EXPECT_TRUE(stream2.is_static());
+}
+
+TEST_P(PendingStreamTest, PendingStreamType) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
+}
+
+TEST_P(PendingStreamTest, PendingStreamTypeOnClient) {
+  Initialize(Perspective::IS_CLIENT);
+
+  QuicStreamId server_initiated_pending_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(session_->transport_version(),
+                                                  1);
+  PendingStream pending(server_initiated_pending_stream_id, session_.get());
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
+}
+
+TEST_P(PendingStreamTest, PendingStreamTooMuchData) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  // Receive a stream frame that violates flow control: the byte offset is
+  // higher than the receive window offset.
+  QuicStreamFrame frame(kTestPendingStreamId, false,
+                        kInitialSessionFlowControlWindowForTest + 1, ".");
+
+  // Stream should not accept the frame, and the connection should be closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  pending.OnStreamFrame(frame);
+}
+
+TEST_P(PendingStreamTest, PendingStreamTooMuchDataInRstStream) {
+  Initialize();
+
+  PendingStream pending1(kTestPendingStreamId, session_.get());
+  // Receive a rst stream frame that violates flow control: the byte offset is
+  // higher than the receive window offset.
+  QuicRstStreamFrame frame1(kInvalidControlFrameId, kTestPendingStreamId,
+                            QUIC_STREAM_CANCELLED,
+                            kInitialSessionFlowControlWindowForTest + 1);
+
+  // Pending stream should not accept the frame, and the connection should be
+  // closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  pending1.OnRstStreamFrame(frame1);
+
+  QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      session_->transport_version(), Perspective::IS_CLIENT);
+  PendingStream pending2(bidirection_stream_id, session_.get());
+  // Receive a rst stream frame that violates flow control: the byte offset is
+  // higher than the receive window offset.
+  QuicRstStreamFrame frame2(kInvalidControlFrameId, bidirection_stream_id,
+                            QUIC_STREAM_CANCELLED,
+                            kInitialSessionFlowControlWindowForTest + 1);
+  // Bidirectional Pending stream should not accept the frame, and the
+  // connection should be closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  pending2.OnRstStreamFrame(frame2);
+}
+
+TEST_P(PendingStreamTest, PendingStreamRstStream) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  QuicStreamOffset final_byte_offset = 7;
+  QuicRstStreamFrame frame(kInvalidControlFrameId, kTestPendingStreamId,
+                           QUIC_STREAM_CANCELLED, final_byte_offset);
+
+  // Pending stream should accept the frame and not close the connection.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  pending.OnRstStreamFrame(frame);
+}
+
+TEST_P(PendingStreamTest, PendingStreamWindowUpdate) {
+  Initialize();
+
+  QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      session_->transport_version(), Perspective::IS_CLIENT);
+  PendingStream pending(bidirection_stream_id, session_.get());
+  QuicWindowUpdateFrame frame(kInvalidControlFrameId, bidirection_stream_id,
+                              kDefaultFlowControlSendWindow * 2);
+  pending.OnWindowUpdateFrame(frame);
+  TestStream stream(&pending, session_.get(), false);
+
+  EXPECT_EQ(QuicStreamPeer::SendWindowSize(&stream),
+            kDefaultFlowControlSendWindow * 2);
+}
+
+TEST_P(PendingStreamTest, PendingStreamStopSending) {
+  Initialize();
+
+  QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      session_->transport_version(), Perspective::IS_CLIENT);
+  PendingStream pending(bidirection_stream_id, session_.get());
+  QuicResetStreamError error =
+      QuicResetStreamError::FromInternal(QUIC_STREAM_INTERNAL_ERROR);
+  pending.OnStopSending(error);
+  EXPECT_TRUE(pending.GetStopSendingErrorCode());
+  auto actual_error = *pending.GetStopSendingErrorCode();
+  EXPECT_EQ(actual_error, error);
+}
+
+TEST_P(PendingStreamTest, FromPendingStream) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+
+  QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
+  pending.OnStreamFrame(frame);
+  pending.OnStreamFrame(frame);
+  QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
+  pending.OnStreamFrame(frame2);
+
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_EQ(3, stream.num_frames_received());
+  EXPECT_EQ(3u, stream.stream_bytes_read());
+  EXPECT_EQ(1, stream.num_duplicate_frames_received());
+  EXPECT_EQ(true, stream.fin_received());
+  EXPECT_EQ(frame2.offset + 1, stream.highest_received_byte_offset());
+  EXPECT_EQ(frame2.offset + 1,
+            session_->flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(PendingStreamTest, FromPendingStreamThenData) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+
+  QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
+  pending.OnStreamFrame(frame);
+
+  auto stream = new TestStream(&pending, session_.get(), false);
+  session_->ActivateStream(absl::WrapUnique(stream));
+
+  QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
+  stream->OnStreamFrame(frame2);
+
+  EXPECT_EQ(2, stream->num_frames_received());
+  EXPECT_EQ(2u, stream->stream_bytes_read());
+  EXPECT_EQ(true, stream->fin_received());
+  EXPECT_EQ(frame2.offset + 1, stream->highest_received_byte_offset());
+  EXPECT_EQ(frame2.offset + 1,
+            session_->flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicStreamTest, WriteAllData) {
+  Initialize();
+
+  QuicByteCount length =
+      1 + QuicPacketCreator::StreamFramePacketOverhead(
+              connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
+              PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+              !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+              VARIABLE_LENGTH_INTEGER_LENGTH_0,
+              VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
+  connection_->SetMaxPacketLength(length);
+
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_FALSE(HasWriteBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, NoBlockingIfNoDataOrFin) {
+  Initialize();
+
+  // Write no data and no fin.  If we consume nothing we should not be write
+  // blocked.
+  EXPECT_QUIC_BUG(
+      stream_->WriteOrBufferData(absl::string_view(), false, nullptr), "");
+  EXPECT_FALSE(HasWriteBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, BlockIfOnlySomeDataConsumed) {
+  Initialize();
+
+  // Write some data and no fin.  If we consume some but not all of the data,
+  // we should be write blocked a not all the data was consumed.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
+  EXPECT_EQ(1u, stream_->BufferedDataBytes());
+}
+
+TEST_P(QuicStreamTest, BlockIfFinNotConsumedWithData) {
+  Initialize();
+
+  // Write some data and no fin.  If we consume all the data but not the fin,
+  // we should be write blocked because the fin was not consumed.
+  // (This should never actually happen as the fin should be sent out with the
+  // last data)
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 2u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, BlockIfSoloFinNotConsumed) {
+  Initialize();
+
+  // Write no data and a fin.  If we consume nothing we should be write blocked,
+  // as the fin was not consumed.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(0, false)));
+  stream_->WriteOrBufferData(absl::string_view(), true, nullptr);
+  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, CloseOnPartialWrite) {
+  Initialize();
+
+  // Write some data and no fin. However, while writing the data
+  // close the stream and verify that MarkConnectionLevelWriteBlocked does not
+  // crash with an unknown stream.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(Invoke(this, &QuicStreamTest::CloseStreamOnWriteError));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr);
+  ASSERT_EQ(0u, write_blocked_list_->NumBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, WriteOrBufferData) {
+  Initialize();
+
+  EXPECT_FALSE(HasWriteBlockedStreams());
+  QuicByteCount length =
+      1 + QuicPacketCreator::StreamFramePacketOverhead(
+              connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
+              PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+              !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+              VARIABLE_LENGTH_INTEGER_LENGTH_0,
+              VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
+  connection_->SetMaxPacketLength(length);
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), kDataLen - 1, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, stream_->BufferedDataBytes());
+  EXPECT_TRUE(HasWriteBlockedStreams());
+
+  // Queue a bytes_consumed write.
+  stream_->WriteOrBufferData(kData2, false, nullptr);
+  EXPECT_EQ(10u, stream_->BufferedDataBytes());
+  // Make sure we get the tail of the first write followed by the bytes_consumed
+  InSequence s;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), kDataLen - 1, kDataLen - 1,
+                                     NO_FIN, NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_CALL(*stream_, OnCanWriteNewData());
+  stream_->OnCanWrite();
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+
+  // And finally the end of the bytes_consumed.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 2u, 2 * kDataLen - 2,
+                                     NO_FIN, NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_CALL(*stream_, OnCanWriteNewData());
+  stream_->OnCanWrite();
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, WriteOrBufferDataReachStreamLimit) {
+  Initialize();
+  std::string data("aaaaa");
+  QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
+                                        stream_);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+  EXPECT_QUIC_BUG(stream_->WriteOrBufferData("a", false, nullptr),
+                  "Write too many data via stream");
+}
+
+TEST_P(QuicStreamTest, ConnectionCloseAfterStreamClose) {
+  Initialize();
+
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (VersionHasIetfQuicFrames(session_->transport_version())) {
+    // Create and inject a STOP SENDING frame to complete the close
+    // of the stream. This is only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
+                                      QUIC_STREAM_CANCELLED);
+    session_->OnStopSendingFrame(stop_sending);
+  }
+  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
+  EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
+  stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR,
+                              ConnectionCloseSource::FROM_SELF);
+  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
+  EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(QuicStreamTest, RstAlwaysSentIfNoFinSent) {
+  // For flow control accounting, a stream must send either a FIN or a RST frame
+  // before termination.
+  // Test that if no FIN has been sent, we send a RST.
+
+  Initialize();
+  EXPECT_FALSE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Write some data, with no FIN.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 1), false, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_FALSE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Now close the stream, and expect that we send a RST.
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _));
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (VersionHasIetfQuicFrames(session_->transport_version())) {
+    // Create and inject a STOP SENDING frame to complete the close
+    // of the stream. This is only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
+                                      QUIC_STREAM_CANCELLED);
+    session_->OnStopSendingFrame(stop_sending);
+  }
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_FALSE(fin_sent());
+  EXPECT_TRUE(rst_sent());
+}
+
+TEST_P(QuicStreamTest, RstNotSentIfFinSent) {
+  // For flow control accounting, a stream must send either a FIN or a RST frame
+  // before termination.
+  // Test that if a FIN has been sent, we don't also send a RST.
+
+  Initialize();
+  EXPECT_FALSE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Write some data, with FIN.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 1u, 0u, FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 1), true, nullptr);
+  EXPECT_TRUE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Now close the stream, and expect that we do not send a RST.
+  QuicStreamPeer::CloseReadSide(stream_);
+  stream_->CloseWriteSide();
+  EXPECT_TRUE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+}
+
+TEST_P(QuicStreamTest, OnlySendOneRst) {
+  // For flow control accounting, a stream must send either a FIN or a RST frame
+  // before termination.
+  // Test that if a stream sends a RST, it doesn't send an additional RST during
+  // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...)
+
+  Initialize();
+  EXPECT_FALSE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Reset the stream.
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _)).Times(1);
+  stream_->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_FALSE(fin_sent());
+  EXPECT_TRUE(rst_sent());
+
+  // Now close the stream (any further resets being sent would break the
+  // expectation above).
+  QuicStreamPeer::CloseReadSide(stream_);
+  stream_->CloseWriteSide();
+  EXPECT_FALSE(fin_sent());
+  EXPECT_TRUE(rst_sent());
+}
+
+TEST_P(QuicStreamTest, StreamFlowControlMultipleWindowUpdates) {
+  Initialize();
+
+  // If we receive multiple WINDOW_UPDATES (potentially out of order), then we
+  // want to make sure we latch the largest offset we see.
+
+  // Initially should be default.
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            QuicStreamPeer::SendWindowOffset(stream_));
+
+  // Check a single WINDOW_UPDATE results in correct offset.
+  QuicWindowUpdateFrame window_update_1(kInvalidControlFrameId, stream_->id(),
+                                        kMinimumFlowControlSendWindow + 5);
+  stream_->OnWindowUpdateFrame(window_update_1);
+  EXPECT_EQ(window_update_1.max_data,
+            QuicStreamPeer::SendWindowOffset(stream_));
+
+  // Now send a few more WINDOW_UPDATES and make sure that only the largest is
+  // remembered.
+  QuicWindowUpdateFrame window_update_2(kInvalidControlFrameId, stream_->id(),
+                                        1);
+  QuicWindowUpdateFrame window_update_3(kInvalidControlFrameId, stream_->id(),
+                                        kMinimumFlowControlSendWindow + 10);
+  QuicWindowUpdateFrame window_update_4(kInvalidControlFrameId, stream_->id(),
+                                        5678);
+  stream_->OnWindowUpdateFrame(window_update_2);
+  stream_->OnWindowUpdateFrame(window_update_3);
+  stream_->OnWindowUpdateFrame(window_update_4);
+  EXPECT_EQ(window_update_3.max_data,
+            QuicStreamPeer::SendWindowOffset(stream_));
+}
+
+TEST_P(QuicStreamTest, FrameStats) {
+  Initialize();
+
+  EXPECT_EQ(0, stream_->num_frames_received());
+  EXPECT_EQ(0, stream_->num_duplicate_frames_received());
+  QuicStreamFrame frame(stream_->id(), false, 0, ".");
+  EXPECT_CALL(*stream_, OnDataAvailable()).Times(2);
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(1, stream_->num_frames_received());
+  EXPECT_EQ(0, stream_->num_duplicate_frames_received());
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(2, stream_->num_frames_received());
+  EXPECT_EQ(1, stream_->num_duplicate_frames_received());
+  QuicStreamFrame frame2(stream_->id(), false, 1, "abc");
+  stream_->OnStreamFrame(frame2);
+}
+
+// Verify that when we receive a packet which violates flow control (i.e. sends
+// too much data on the stream) that the stream sequencer never sees this frame,
+// as we check for violation and close the connection early.
+TEST_P(QuicStreamTest, StreamSequencerNeverSeesPacketsViolatingFlowControl) {
+  Initialize();
+
+  // Receive a stream frame that violates flow control: the byte offset is
+  // higher than the receive window offset.
+  QuicStreamFrame frame(stream_->id(), false,
+                        kInitialSessionFlowControlWindowForTest + 1, ".");
+  EXPECT_GT(frame.offset, QuicStreamPeer::ReceiveWindowOffset(stream_));
+
+  // Stream should not accept the frame, and the connection should be closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamFrame(frame);
+}
+
+// Verify that after the consumer calls StopReading(), the stream still sends
+// flow control updates.
+TEST_P(QuicStreamTest, StopReadingSendsFlowControl) {
+  Initialize();
+
+  stream_->StopReading();
+
+  // Connection should not get terminated due to flow control errors.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
+      .Times(0);
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(AtLeast(1))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+
+  std::string data(1000, 'x');
+  for (QuicStreamOffset offset = 0;
+       offset < 2 * kInitialStreamFlowControlWindowForTest;
+       offset += data.length()) {
+    QuicStreamFrame frame(stream_->id(), false, offset, data);
+    stream_->OnStreamFrame(frame);
+  }
+  EXPECT_LT(kInitialStreamFlowControlWindowForTest,
+            QuicStreamPeer::ReceiveWindowOffset(stream_));
+}
+
+TEST_P(QuicStreamTest, FinalByteOffsetFromFin) {
+  Initialize();
+
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+
+  QuicStreamFrame stream_frame_no_fin(stream_->id(), false, 1234, ".");
+  stream_->OnStreamFrame(stream_frame_no_fin);
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+
+  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
+  stream_->OnStreamFrame(stream_frame_with_fin);
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+TEST_P(QuicStreamTest, FinalByteOffsetFromRst) {
+  Initialize();
+
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+TEST_P(QuicStreamTest, InvalidFinalByteOffsetFromRst) {
+  Initialize();
+
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 0xFFFFFFFFFFFF);
+  // Stream should not accept the frame, and the connection should be closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamReset(rst_frame);
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+TEST_P(QuicStreamTest, FinalByteOffsetFromZeroLengthStreamFrame) {
+  // When receiving Trailers, an empty stream frame is created with the FIN set,
+  // and is passed to OnStreamFrame. The Trailers may be sent in advance of
+  // queued body bytes being sent, and thus the final byte offset may exceed
+  // current flow control limits. Flow control should only be concerned with
+  // data that has actually been sent/received, so verify that flow control
+  // ignores such a stream frame.
+  Initialize();
+
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+  const QuicStreamOffset kByteOffsetExceedingFlowControlWindow =
+      kInitialSessionFlowControlWindowForTest + 1;
+  const QuicStreamOffset current_stream_flow_control_offset =
+      QuicStreamPeer::ReceiveWindowOffset(stream_);
+  const QuicStreamOffset current_connection_flow_control_offset =
+      QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller());
+  ASSERT_GT(kByteOffsetExceedingFlowControlWindow,
+            current_stream_flow_control_offset);
+  ASSERT_GT(kByteOffsetExceedingFlowControlWindow,
+            current_connection_flow_control_offset);
+  QuicStreamFrame zero_length_stream_frame_with_fin(
+      stream_->id(), /*fin=*/true, kByteOffsetExceedingFlowControlWindow,
+      absl::string_view());
+  EXPECT_EQ(0, zero_length_stream_frame_with_fin.data_length);
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  stream_->OnStreamFrame(zero_length_stream_frame_with_fin);
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+
+  // The flow control receive offset values should not have changed.
+  EXPECT_EQ(current_stream_flow_control_offset,
+            QuicStreamPeer::ReceiveWindowOffset(stream_));
+  EXPECT_EQ(
+      current_connection_flow_control_offset,
+      QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller()));
+}
+
+TEST_P(QuicStreamTest, OnStreamResetOffsetOverflow) {
+  Initialize();
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, kMaxStreamLength + 1);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+  stream_->OnStreamReset(rst_frame);
+}
+
+TEST_P(QuicStreamTest, OnStreamFrameUpperLimit) {
+  Initialize();
+
+  // Modify receive window offset and sequencer buffer total_bytes_read_ to
+  // avoid flow control violation.
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kMaxStreamLength + 5u);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
+                                                 kMaxStreamLength + 5u);
+  QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
+      QuicStreamPeer::sequencer(stream_), kMaxStreamLength - 10u);
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
+      .Times(0);
+  QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength - 1, ".");
+  stream_->OnStreamFrame(stream_frame);
+  QuicStreamFrame stream_frame2(stream_->id(), true, kMaxStreamLength, "");
+  stream_->OnStreamFrame(stream_frame2);
+}
+
+TEST_P(QuicStreamTest, StreamTooLong) {
+  Initialize();
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
+      .Times(1);
+  QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength, ".");
+  EXPECT_QUIC_PEER_BUG(
+      stream_->OnStreamFrame(stream_frame),
+      absl::StrCat("Receive stream frame on stream ", stream_->id(),
+                   " reaches max stream length"));
+}
+
+TEST_P(QuicStreamTest, SetDrainingIncomingOutgoing) {
+  // Don't have incoming data consumed.
+  Initialize();
+
+  // Incoming data with FIN.
+  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
+  stream_->OnStreamFrame(stream_frame_with_fin);
+  // The FIN has been received but not consumed.
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_FALSE(stream_->reading_stopped());
+
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Outgoing data with FIN.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
+  EXPECT_TRUE(stream_->write_side_closed());
+
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+}
+
+TEST_P(QuicStreamTest, SetDrainingOutgoingIncoming) {
+  // Don't have incoming data consumed.
+  Initialize();
+
+  // Outgoing data with FIN.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
+  EXPECT_TRUE(stream_->write_side_closed());
+
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Incoming data with FIN.
+  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
+  stream_->OnStreamFrame(stream_frame_with_fin);
+  // The FIN has been received but not consumed.
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_FALSE(stream_->reading_stopped());
+
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+}
+
+TEST_P(QuicStreamTest, EarlyResponseFinHandling) {
+  // Verify that if the server completes the response before reading the end of
+  // the request, the received FIN is recorded.
+
+  Initialize();
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+
+  // Receive data for the request.
+  EXPECT_CALL(*stream_, OnDataAvailable()).Times(1);
+  QuicStreamFrame frame1(stream_->id(), false, 0, "Start");
+  stream_->OnStreamFrame(frame1);
+  // When QuicSimpleServerStream sends the response, it calls
+  // QuicStream::CloseReadSide() first.
+  QuicStreamPeer::CloseReadSide(stream_);
+  // Send data and FIN for the response.
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
+  // Receive remaining data and FIN for the request.
+  QuicStreamFrame frame2(stream_->id(), true, 0, "End");
+  stream_->OnStreamFrame(frame2);
+  EXPECT_TRUE(stream_->fin_received());
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+TEST_P(QuicStreamTest, StreamWaitsForAcks) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  // Stream is not waiting for acks initially.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+
+  // Send kData1.
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(9u, newly_acked_length);
+  // Stream is not waiting for acks as all sent data is acked.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // Send kData2.
+  stream_->WriteOrBufferData(kData2, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Send FIN.
+  stream_->WriteOrBufferData("", true, nullptr);
+  // Fin only frame is not stored in send buffer.
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // kData2 is retransmitted.
+  stream_->OnStreamFrameRetransmitted(9, 9, false);
+
+  // kData2 is acked.
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(9u, newly_acked_length);
+  // Stream is waiting for acks as FIN is not acked.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // FIN is acked.
+  EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState());
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+}
+
+TEST_P(QuicStreamTest, StreamDataGetAckedOutOfOrder) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  // Send data.
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData("", true, nullptr);
+  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  // FIN is not acked yet.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState());
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, CancelStream) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Cancel stream.
+  stream_->MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
+  // stream still waits for acks as the error code is QUIC_STREAM_NO_ERROR, and
+  // data is going to be retransmitted.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_STREAM_CANCELLED));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(AtLeast(1))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        session_->ReallyMaybeSendRstStreamFrame(
+            stream_->id(), QUIC_STREAM_CANCELLED,
+            stream_->stream_bytes_written());
+      }));
+
+  stream_->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Stream stops waiting for acks as data is not going to be retransmitted.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, RstFrameReceivedStreamNotFinishSending) {
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // In IETF QUIC, receiving a RESET_STREAM will only close the read side. The
+    // stream itself is not closed and will not send reset.
+    return;
+  }
+
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // RST_STREAM received.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 9);
+
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 9));
+  stream_->OnStreamReset(rst_frame);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Stream stops waiting for acks as it does not finish sending and rst is
+  // sent.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, RstFrameReceivedStreamFinishSending) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  stream_->WriteOrBufferData(kData1, true, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+
+  // RST_STREAM received.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  // Stream still waits for acks as it finishes sending and has unacked data.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+}
+
+TEST_P(QuicStreamTest, ConnectionClosed) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 9));
+  QuicConnectionPeer::SetConnectionClose(connection_);
+  stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR,
+                              ConnectionCloseSource::FROM_SELF);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Stream stops waiting for acks as connection is going to close.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, CanWriteNewDataAfterData) {
+  SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
+  Initialize();
+  EXPECT_TRUE(stream_->CanWriteNewDataAfterData(99));
+  EXPECT_FALSE(stream_->CanWriteNewDataAfterData(100));
+}
+
+TEST_P(QuicStreamTest, WriteBufferedData) {
+  // Set buffered data low water mark to be 100.
+  SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
+
+  Initialize();
+  std::string data(1024, 'a');
+  EXPECT_TRUE(stream_->CanWriteNewData());
+
+  // Testing WriteOrBufferData.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  stream_->WriteOrBufferData(data, false, nullptr);
+  stream_->WriteOrBufferData(data, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+
+  // Verify all data is saved.
+  EXPECT_EQ(3 * data.length() - 100, stream_->BufferedDataBytes());
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 100, 100u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  // Buffered data size > threshold, do not ask upper layer for more data.
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
+  stream_->OnCanWrite();
+  EXPECT_EQ(3 * data.length() - 200, stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->CanWriteNewData());
+
+  // Send buffered data to make buffered data size < threshold.
+  QuicByteCount data_to_write =
+      3 * data.length() - 200 -
+      GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
+        return session_->ConsumeData(stream_->id(), data_to_write, 200u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  // Buffered data size < threshold, ask upper layer for more data.
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_EQ(static_cast<uint64_t>(
+                GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
+            stream_->BufferedDataBytes());
+  EXPECT_TRUE(stream_->CanWriteNewData());
+
+  // Flush all buffered data.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_EQ(0u, stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->HasBufferedData());
+  EXPECT_TRUE(stream_->CanWriteNewData());
+
+  // Testing Writev.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(0, false)));
+  struct iovec iov = {const_cast<char*>(data.data()), data.length()};
+  quiche::QuicheMemSliceStorage storage(
+      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  QuicConsumedData consumed = stream_->WriteMemSlices(storage.ToSpan(), false);
+
+  // There is no buffered data before, all data should be consumed without
+  // respecting buffered data upper limit.
+  EXPECT_EQ(data.length(), consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->CanWriteNewData());
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
+  quiche::QuicheMemSliceStorage storage2(
+      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  consumed = stream_->WriteMemSlices(storage2.ToSpan(), false);
+  // No Data can be consumed as buffered data is beyond upper limit.
+  EXPECT_EQ(0u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
+
+  data_to_write =
+      data.length() - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
+        return session_->ConsumeData(stream_->id(), data_to_write, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_EQ(static_cast<uint64_t>(
+                GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
+            stream_->BufferedDataBytes());
+  EXPECT_TRUE(stream_->CanWriteNewData());
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
+  // All data can be consumed as buffered data is below upper limit.
+  quiche::QuicheMemSliceStorage storage3(
+      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  consumed = stream_->WriteMemSlices(storage3.ToSpan(), false);
+  EXPECT_EQ(data.length(), consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(data.length() + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
+            stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->CanWriteNewData());
+}
+
+TEST_P(QuicStreamTest, WritevDataReachStreamLimit) {
+  Initialize();
+  std::string data("aaaaa");
+  QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
+                                        stream_);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  struct iovec iov = {const_cast<char*>(data.data()), 5u};
+  quiche::QuicheMemSliceStorage storage(
+      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  QuicConsumedData consumed = stream_->WriteMemSlices(storage.ToSpan(), false);
+  EXPECT_EQ(data.length(), consumed.bytes_consumed);
+  struct iovec iov2 = {const_cast<char*>(data.data()), 1u};
+  quiche::QuicheMemSliceStorage storage2(
+      &iov2, 1,
+      session_->connection()->helper()->GetStreamSendBufferAllocator(), 1024);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+  EXPECT_QUIC_BUG(stream_->WriteMemSlices(storage2.ToSpan(), false),
+                  "Write too many data via stream");
+}
+
+TEST_P(QuicStreamTest, WriteMemSlices) {
+  // Set buffered data low water mark to be 100.
+  SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
+
+  Initialize();
+  constexpr QuicByteCount kDataSize = 1024;
+  quiche::QuicheBufferAllocator* allocator =
+      connection_->helper()->GetStreamSendBufferAllocator();
+  std::vector<quiche::QuicheMemSlice> vector1;
+  vector1.push_back(
+      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
+  vector1.push_back(
+      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
+  std::vector<quiche::QuicheMemSlice> vector2;
+  vector2.push_back(
+      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
+  vector2.push_back(
+      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
+  absl::Span<quiche::QuicheMemSlice> span1(vector1);
+  absl::Span<quiche::QuicheMemSlice> span2(vector2);
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  // There is no buffered data before, all data should be consumed.
+  QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
+  EXPECT_EQ(2048u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(2 * kDataSize - 100, stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->fin_buffered());
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
+  // No Data can be consumed as buffered data is beyond upper limit.
+  consumed = stream_->WriteMemSlices(span2, true);
+  EXPECT_EQ(0u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(2 * kDataSize - 100, stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->fin_buffered());
+
+  QuicByteCount data_to_write =
+      2 * kDataSize - 100 - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
+        return session_->ConsumeData(stream_->id(), data_to_write, 100u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_EQ(static_cast<uint64_t>(
+                GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
+            stream_->BufferedDataBytes());
+  // Try to write slices2 again.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
+  consumed = stream_->WriteMemSlices(span2, true);
+  EXPECT_EQ(2048u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_EQ(2 * kDataSize + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
+            stream_->BufferedDataBytes());
+  EXPECT_TRUE(stream_->fin_buffered());
+
+  // Flush all buffered data.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->OnCanWrite();
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
+  EXPECT_FALSE(stream_->HasBufferedData());
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicStreamTest, WriteMemSlicesReachStreamLimit) {
+  Initialize();
+  QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - 5u, stream_);
+  std::vector<std::pair<char*, size_t>> buffers;
+  quiche::QuicheMemSlice slice1 = MemSliceFromString("12345");
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 5u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  // There is no buffered data before, all data should be consumed.
+  QuicConsumedData consumed = stream_->WriteMemSlice(std::move(slice1), false);
+  EXPECT_EQ(5u, consumed.bytes_consumed);
+
+  quiche::QuicheMemSlice slice2 = MemSliceFromString("6");
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+  EXPECT_QUIC_BUG(stream_->WriteMemSlice(std::move(slice2), false),
+                  "Write too many data via stream");
+}
+
+TEST_P(QuicStreamTest, StreamDataGetAckedMultipleTimes) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+
+  // Send [0, 27) and fin.
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, true, nullptr);
+  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  // Ack [0, 9), [5, 22) and [18, 26)
+  // Verify [0, 9) 9 bytes are acked.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [9, 22) 13 bytes are acked.
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(13u, newly_acked_length);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [22, 26) 4 bytes are acked.
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(4u, newly_acked_length);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+
+  // Ack [0, 27). Verify [26, 27) 1 byte is acked.
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(1u, newly_acked_length);
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+
+  // Ack Fin.
+  EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState()).Times(1);
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+
+  // Ack [10, 27) and fin. No new data is acked.
+  EXPECT_FALSE(
+      stream_->OnStreamFrameAcked(10, 17, true, QuicTime::Delta::Zero(),
+                                  QuicTime::Zero(), &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, OnStreamFrameLost) {
+  Initialize();
+
+  // Send [0, 9).
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_FALSE(stream_->HasBufferedData());
+  EXPECT_TRUE(stream_->IsStreamFrameOutstanding(0, 9, false));
+
+  // Try to send [9, 27), but connection is blocked.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(0, false)));
+  stream_->WriteOrBufferData(kData2, false, nullptr);
+  stream_->WriteOrBufferData(kData2, false, nullptr);
+  EXPECT_TRUE(stream_->HasBufferedData());
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+
+  // Lost [0, 9). When stream gets a chance to write, only lost data is
+  // transmitted.
+  stream_->OnStreamFrameLost(0, 9, false);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  EXPECT_TRUE(stream_->HasBufferedData());
+
+  // This OnCanWrite causes [9, 27) to be sent.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->OnCanWrite();
+  EXPECT_FALSE(stream_->HasBufferedData());
+
+  // Send a fin only frame.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData("", true, nullptr);
+
+  // Lost [9, 27) and fin.
+  stream_->OnStreamFrameLost(9, 18, false);
+  stream_->OnStreamFrameLost(27, 0, true);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+
+  // Ack [9, 18).
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_FALSE(stream_->IsStreamFrameOutstanding(9, 3, false));
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  // This OnCanWrite causes [18, 27) and fin to be retransmitted. Verify fin can
+  // be bundled with data.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 9u, 18u, FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->OnCanWrite();
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  // Lost [9, 18) again, but it is not considered as lost because kData2
+  // has been acked.
+  stream_->OnStreamFrameLost(9, 9, false);
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  EXPECT_TRUE(stream_->IsStreamFrameOutstanding(27, 0, true));
+}
+
+TEST_P(QuicStreamTest, CannotBundleLostFin) {
+  Initialize();
+
+  // Send [0, 18) and fin.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData2, true, nullptr);
+
+  // Lost [0, 9) and fin.
+  stream_->OnStreamFrameLost(0, 9, false);
+  stream_->OnStreamFrameLost(18, 0, true);
+
+  // Retransmit lost data. Verify [0, 9) and fin are retransmitted in two
+  // frames.
+  InSequence s;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 9u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(0, true)));
+  stream_->OnCanWrite();
+}
+
+TEST_P(QuicStreamTest, MarkConnectionLevelWriteBlockedOnWindowUpdateFrame) {
+  Initialize();
+
+  // Set the config to a small value so that a newly created stream has small
+  // send flow control window.
+  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_->config(),
+                                                            100);
+  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+      session_->config(), 100);
+  auto stream = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
+                                   GetParam().transport_version, 2),
+                               session_.get(), BIDIRECTIONAL);
+  session_->ActivateStream(absl::WrapUnique(stream));
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+  std::string data(1024, '.');
+  stream->WriteOrBufferData(data, false, nullptr);
+  EXPECT_FALSE(HasWriteBlockedStreams());
+
+  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream_->id(),
+                                      1234);
+
+  stream->OnWindowUpdateFrame(window_update);
+  // Verify stream is marked connection level write blocked.
+  EXPECT_TRUE(HasWriteBlockedStreams());
+  EXPECT_TRUE(stream->HasBufferedData());
+}
+
+// Regression test for b/73282665.
+TEST_P(QuicStreamTest,
+       MarkConnectionLevelWriteBlockedOnWindowUpdateFrameWithNoBufferedData) {
+  Initialize();
+
+  // Set the config to a small value so that a newly created stream has small
+  // send flow control window.
+  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_->config(),
+                                                            100);
+  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+      session_->config(), 100);
+  auto stream = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
+                                   GetParam().transport_version, 2),
+                               session_.get(), BIDIRECTIONAL);
+  session_->ActivateStream(absl::WrapUnique(stream));
+
+  std::string data(100, '.');
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+  stream->WriteOrBufferData(data, false, nullptr);
+  EXPECT_FALSE(HasWriteBlockedStreams());
+
+  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream_->id(),
+                                      120);
+  stream->OnWindowUpdateFrame(window_update);
+  EXPECT_FALSE(stream->HasBufferedData());
+  // Verify stream is marked as blocked although there is no buffered data.
+  EXPECT_TRUE(HasWriteBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, RetransmitStreamData) {
+  Initialize();
+  InSequence s;
+
+  // Send [0, 18) with fin.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, true, nullptr);
+  // Ack [10, 13).
+  QuicByteCount newly_acked_length = 0;
+  stream_->OnStreamFrameAcked(10, 3, false, QuicTime::Delta::Zero(),
+                              QuicTime::Zero(), &newly_acked_length);
+  EXPECT_EQ(3u, newly_acked_length);
+  // Retransmit [0, 18) with fin, and only [0, 8) is consumed.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 8, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_FALSE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION));
+
+  // Retransmit [0, 18) with fin, and all is consumed.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 5, 13, FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_TRUE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION));
+
+  // Retransmit [0, 8) with fin, and all is consumed.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 8, 0, NO_FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 0, 18, FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_TRUE(stream_->RetransmitStreamData(0, 8, true, PTO_RETRANSMISSION));
+}
+
+TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresRetransmitLostData) {
+  Initialize();
+
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  std::string body(200, 'a');
+  stream_->WriteOrBufferData(body, true, nullptr);
+
+  // Set TTL to be 1 s.
+  QuicTime::Delta ttl = QuicTime::Delta::FromSeconds(1);
+  ASSERT_TRUE(stream_->MaybeSetTtl(ttl));
+  // Verify data gets retransmitted because TTL does not expire.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 100, 0, NO_FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_TRUE(stream_->RetransmitStreamData(0, 100, false, PTO_RETRANSMISSION));
+  stream_->OnStreamFrameLost(100, 100, true);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  // Verify stream gets reset because TTL expires.
+  if (session_->version().UsesHttp3()) {
+    EXPECT_CALL(*session_,
+                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
+                                                 QUIC_STREAM_TTL_EXPIRED)))
+        .Times(1);
+  }
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_STREAM_TTL_EXPIRED), _))
+      .Times(1);
+  stream_->OnCanWrite();
+}
+
+TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresEarlyRetransmitData) {
+  Initialize();
+
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  std::string body(200, 'a');
+  stream_->WriteOrBufferData(body, true, nullptr);
+
+  // Set TTL to be 1 s.
+  QuicTime::Delta ttl = QuicTime::Delta::FromSeconds(1);
+  ASSERT_TRUE(stream_->MaybeSetTtl(ttl));
+
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  // Verify stream gets reset because TTL expires.
+  if (session_->version().UsesHttp3()) {
+    EXPECT_CALL(*session_,
+                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
+                                                 QUIC_STREAM_TTL_EXPIRED)))
+        .Times(1);
+  }
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_STREAM_TTL_EXPIRED), _))
+      .Times(1);
+  stream_->RetransmitStreamData(0, 100, false, PTO_RETRANSMISSION);
+}
+
+// Test that OnStreamReset does one-way (read) closes if version 99, two way
+// (read and write) if not version 99.
+TEST_P(QuicStreamTest, OnStreamResetReadOrReadWrite) {
+  Initialize();
+  EXPECT_FALSE(stream_->write_side_closed());
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    // Version 99/IETF QUIC should close just the read side.
+    EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
+    EXPECT_FALSE(stream_->write_side_closed());
+  } else {
+    // Google QUIC should close both sides of the stream.
+    EXPECT_TRUE(stream_->write_side_closed());
+    EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
+  }
+}
+
+TEST_P(QuicStreamTest, WindowUpdateForReadOnlyStream) {
+  Initialize();
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      connection_->transport_version(), Perspective::IS_CLIENT);
+  TestStream stream(stream_id, session_.get(), READ_UNIDIRECTIONAL);
+  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
+                                            0);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
+          "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.", _));
+  stream.OnWindowUpdateFrame(window_update_frame);
+}
+
+TEST_P(QuicStreamTest, RstStreamFrameChangesCloseOffset) {
+  Initialize();
+
+  QuicStreamFrame stream_frame(stream_->id(), true, 0, "abc");
+  EXPECT_CALL(*stream_, OnDataAvailable());
+  stream_->OnStreamFrame(stream_frame);
+  QuicRstStreamFrame rst(kInvalidControlFrameId, stream_->id(),
+                         QUIC_STREAM_CANCELLED, 0u);
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_MULTIPLE_OFFSET, _, _));
+  stream_->OnStreamReset(rst);
+}
+
+// Regression test for b/176073284.
+TEST_P(QuicStreamTest, EmptyStreamFrameWithNoFin) {
+  Initialize();
+  QuicStreamFrame empty_stream_frame(stream_->id(), false, 0, "");
+  if (stream_->version().HasIetfQuicFrames()) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _))
+        .Times(0);
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _));
+  }
+  EXPECT_CALL(*stream_, OnDataAvailable()).Times(0);
+  stream_->OnStreamFrame(empty_stream_frame);
+}
+
+TEST_P(QuicStreamTest, SendRstWithCustomIetfCode) {
+  Initialize();
+  QuicResetStreamError error(QUIC_STREAM_CANCELLED, 0x1234abcd);
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, error, _))
+      .Times(1);
+  stream_->ResetWithError(error);
+  EXPECT_TRUE(rst_sent());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_sustained_bandwidth_recorder.cc b/quiche/quic/core/quic_sustained_bandwidth_recorder.cc
new file mode 100644
index 0000000..c67e24f
--- /dev/null
+++ b/quiche/quic/core/quic_sustained_bandwidth_recorder.cc
@@ -0,0 +1,62 @@
+// 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 "quiche/quic/core/quic_sustained_bandwidth_recorder.h"
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSustainedBandwidthRecorder::QuicSustainedBandwidthRecorder()
+    : has_estimate_(false),
+      is_recording_(false),
+      bandwidth_estimate_recorded_during_slow_start_(false),
+      bandwidth_estimate_(QuicBandwidth::Zero()),
+      max_bandwidth_estimate_(QuicBandwidth::Zero()),
+      max_bandwidth_timestamp_(0),
+      start_time_(QuicTime::Zero()) {}
+
+void QuicSustainedBandwidthRecorder::RecordEstimate(bool in_recovery,
+                                                    bool in_slow_start,
+                                                    QuicBandwidth bandwidth,
+                                                    QuicTime estimate_time,
+                                                    QuicWallTime wall_time,
+                                                    QuicTime::Delta srtt) {
+  if (in_recovery) {
+    is_recording_ = false;
+    QUIC_DVLOG(1) << "Stopped recording at: "
+                  << estimate_time.ToDebuggingValue();
+    return;
+  }
+
+  if (!is_recording_) {
+    // This is the first estimate of a new recording period.
+    start_time_ = estimate_time;
+    is_recording_ = true;
+    QUIC_DVLOG(1) << "Started recording at: " << start_time_.ToDebuggingValue();
+    return;
+  }
+
+  // If we have been recording for at least 3 * srtt, then record the latest
+  // bandwidth estimate as a valid sustained bandwidth estimate.
+  if (estimate_time - start_time_ >= 3 * srtt) {
+    has_estimate_ = true;
+    bandwidth_estimate_recorded_during_slow_start_ = in_slow_start;
+    bandwidth_estimate_ = bandwidth;
+    QUIC_DVLOG(1) << "New sustained bandwidth estimate (KBytes/s): "
+                  << bandwidth_estimate_.ToKBytesPerSecond();
+  }
+
+  // Check for an increase in max bandwidth.
+  if (bandwidth > max_bandwidth_estimate_) {
+    max_bandwidth_estimate_ = bandwidth;
+    max_bandwidth_timestamp_ = wall_time.ToUNIXSeconds();
+    QUIC_DVLOG(1) << "New max bandwidth estimate (KBytes/s): "
+                  << max_bandwidth_estimate_.ToKBytesPerSecond();
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_sustained_bandwidth_recorder.h b/quiche/quic/core/quic_sustained_bandwidth_recorder.h
new file mode 100644
index 0000000..1a82d22
--- /dev/null
+++ b/quiche/quic/core/quic_sustained_bandwidth_recorder.h
@@ -0,0 +1,95 @@
+// 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_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
+#define QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace test {
+class QuicSustainedBandwidthRecorderPeer;
+}  // namespace test
+
+// This class keeps track of a sustained bandwidth estimate to ultimately send
+// to the client in a server config update message. A sustained bandwidth
+// estimate is only marked as valid if the QuicSustainedBandwidthRecorder has
+// been given uninterrupted reliable estimates over a certain period of time.
+class QUIC_EXPORT_PRIVATE QuicSustainedBandwidthRecorder {
+ public:
+  QuicSustainedBandwidthRecorder();
+  QuicSustainedBandwidthRecorder(const QuicSustainedBandwidthRecorder&) =
+      delete;
+  QuicSustainedBandwidthRecorder& operator=(
+      const QuicSustainedBandwidthRecorder&) = delete;
+
+  // As long as |in_recovery| is consistently false, multiple calls to this
+  // method over a 3 * srtt period results in storage of a valid sustained
+  // bandwidth estimate.
+  // |time_now| is used as a max bandwidth timestamp if needed.
+  void RecordEstimate(bool in_recovery,
+                      bool in_slow_start,
+                      QuicBandwidth bandwidth,
+                      QuicTime estimate_time,
+                      QuicWallTime wall_time,
+                      QuicTime::Delta srtt);
+
+  bool HasEstimate() const { return has_estimate_; }
+
+  QuicBandwidth BandwidthEstimate() const {
+    QUICHE_DCHECK(has_estimate_);
+    return bandwidth_estimate_;
+  }
+
+  QuicBandwidth MaxBandwidthEstimate() const {
+    QUICHE_DCHECK(has_estimate_);
+    return max_bandwidth_estimate_;
+  }
+
+  int64_t MaxBandwidthTimestamp() const {
+    QUICHE_DCHECK(has_estimate_);
+    return max_bandwidth_timestamp_;
+  }
+
+  bool EstimateRecordedDuringSlowStart() const {
+    QUICHE_DCHECK(has_estimate_);
+    return bandwidth_estimate_recorded_during_slow_start_;
+  }
+
+ private:
+  friend class test::QuicSustainedBandwidthRecorderPeer;
+
+  // True if we have been able to calculate sustained bandwidth, over at least
+  // one recording period (3 * rtt).
+  bool has_estimate_;
+
+  // True if the last call to RecordEstimate had a reliable estimate.
+  bool is_recording_;
+
+  // True if the current sustained bandwidth estimate was generated while in
+  // slow start.
+  bool bandwidth_estimate_recorded_during_slow_start_;
+
+  // The latest sustained bandwidth estimate.
+  QuicBandwidth bandwidth_estimate_;
+
+  // The maximum sustained bandwidth seen over the lifetime of the connection.
+  QuicBandwidth max_bandwidth_estimate_;
+
+  // Timestamp indicating when the max_bandwidth_estimate_ was seen.
+  int64_t max_bandwidth_timestamp_;
+
+  // Timestamp marking the beginning of the latest recording period.
+  QuicTime start_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
diff --git a/quiche/quic/core/quic_sustained_bandwidth_recorder_test.cc b/quiche/quic/core/quic_sustained_bandwidth_recorder_test.cc
new file mode 100644
index 0000000..6f53350
--- /dev/null
+++ b/quiche/quic/core/quic_sustained_bandwidth_recorder_test.cc
@@ -0,0 +1,133 @@
+// 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 "quiche/quic/core/quic_sustained_bandwidth_recorder.h"
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicSustainedBandwidthRecorderTest : public QuicTest {};
+
+TEST_F(QuicSustainedBandwidthRecorderTest, BandwidthEstimates) {
+  QuicSustainedBandwidthRecorder recorder;
+  EXPECT_FALSE(recorder.HasEstimate());
+
+  QuicTime estimate_time = QuicTime::Zero();
+  QuicWallTime wall_time = QuicWallTime::Zero();
+  QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
+  const int kBandwidthBitsPerSecond = 12345678;
+  QuicBandwidth bandwidth =
+      QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
+
+  bool in_recovery = false;
+  bool in_slow_start = false;
+
+  // This triggers recording, but should not yield a valid estimate yet.
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_FALSE(recorder.HasEstimate());
+
+  // Send a second reading, again this should not result in a valid estimate,
+  // as not enough time has passed.
+  estimate_time = estimate_time + srtt;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_FALSE(recorder.HasEstimate());
+
+  // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
+  estimate_time = estimate_time + srtt;
+  estimate_time = estimate_time + srtt;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_TRUE(recorder.HasEstimate());
+  EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
+  EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
+
+  // Resetting, and sending a different estimate will only change output after
+  // a further 3 * kSRTT has passed.
+  QuicBandwidth second_bandwidth =
+      QuicBandwidth::FromBitsPerSecond(2 * kBandwidthBitsPerSecond);
+  // Reset the recorder by passing in a measurement while in recovery.
+  in_recovery = true;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  in_recovery = false;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
+
+  estimate_time = estimate_time + 3 * srtt;
+  const int64_t kSeconds = 556677;
+  QuicWallTime second_bandwidth_wall_time =
+      QuicWallTime::FromUNIXSeconds(kSeconds);
+  recorder.RecordEstimate(in_recovery, in_slow_start, second_bandwidth,
+                          estimate_time, second_bandwidth_wall_time, srtt);
+  EXPECT_EQ(recorder.BandwidthEstimate(), second_bandwidth);
+  EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
+  EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
+
+  // Reset again, this time recording a lower bandwidth than before.
+  QuicBandwidth third_bandwidth =
+      QuicBandwidth::FromBitsPerSecond(0.5 * kBandwidthBitsPerSecond);
+  // Reset the recorder by passing in an unreliable measurement.
+  recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
+                          estimate_time, wall_time, srtt);
+  recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
+                          estimate_time, wall_time, srtt);
+  EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
+
+  estimate_time = estimate_time + 3 * srtt;
+  recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
+                          estimate_time, wall_time, srtt);
+  EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
+
+  // Max bandwidth should not have changed.
+  EXPECT_LT(third_bandwidth, second_bandwidth);
+  EXPECT_EQ(recorder.MaxBandwidthEstimate(), second_bandwidth);
+  EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
+}
+
+TEST_F(QuicSustainedBandwidthRecorderTest, SlowStart) {
+  // Verify that slow start status is correctly recorded.
+  QuicSustainedBandwidthRecorder recorder;
+  EXPECT_FALSE(recorder.HasEstimate());
+
+  QuicTime estimate_time = QuicTime::Zero();
+  QuicWallTime wall_time = QuicWallTime::Zero();
+  QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
+  const int kBandwidthBitsPerSecond = 12345678;
+  QuicBandwidth bandwidth =
+      QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
+
+  bool in_recovery = false;
+  bool in_slow_start = true;
+
+  // This triggers recording, but should not yield a valid estimate yet.
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+
+  // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
+  estimate_time = estimate_time + 3 * srtt;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_TRUE(recorder.HasEstimate());
+  EXPECT_TRUE(recorder.EstimateRecordedDuringSlowStart());
+
+  // Now send another estimate, this time not in slow start.
+  estimate_time = estimate_time + 3 * srtt;
+  in_slow_start = false;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_TRUE(recorder.HasEstimate());
+  EXPECT_FALSE(recorder.EstimateRecordedDuringSlowStart());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_syscall_wrapper.cc b/quiche/quic/core/quic_syscall_wrapper.cc
new file mode 100644
index 0000000..2214da1
--- /dev/null
+++ b/quiche/quic/core/quic_syscall_wrapper.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_syscall_wrapper.h"
+
+#include <atomic>
+#include <cerrno>
+
+namespace quic {
+namespace {
+std::atomic<QuicSyscallWrapper*> global_syscall_wrapper(new QuicSyscallWrapper);
+}  // namespace
+
+ssize_t QuicSyscallWrapper::Sendmsg(int sockfd, const msghdr* msg, int flags) {
+  return ::sendmsg(sockfd, msg, flags);
+}
+
+int QuicSyscallWrapper::Sendmmsg(int sockfd,
+                                 mmsghdr* msgvec,
+                                 unsigned int vlen,
+                                 int flags) {
+#if defined(__linux__) && !defined(__ANDROID__)
+  return ::sendmmsg(sockfd, msgvec, vlen, flags);
+#else
+  errno = ENOSYS;
+  return -1;
+#endif
+}
+
+QuicSyscallWrapper* GetGlobalSyscallWrapper() {
+  return global_syscall_wrapper.load();
+}
+
+void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper) {
+  global_syscall_wrapper.store(wrapper);
+}
+
+ScopedGlobalSyscallWrapperOverride::ScopedGlobalSyscallWrapperOverride(
+    QuicSyscallWrapper* wrapper_in_scope)
+    : original_wrapper_(GetGlobalSyscallWrapper()) {
+  SetGlobalSyscallWrapper(wrapper_in_scope);
+}
+
+ScopedGlobalSyscallWrapperOverride::~ScopedGlobalSyscallWrapperOverride() {
+  SetGlobalSyscallWrapper(original_wrapper_);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_syscall_wrapper.h b/quiche/quic/core/quic_syscall_wrapper.h
new file mode 100644
index 0000000..f7a6271
--- /dev/null
+++ b/quiche/quic/core/quic_syscall_wrapper.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2019 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_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+struct mmsghdr;
+namespace quic {
+
+// QuicSyscallWrapper is a pass-through proxy to the real syscalls.
+class QUIC_EXPORT_PRIVATE QuicSyscallWrapper {
+ public:
+  virtual ~QuicSyscallWrapper() = default;
+
+  virtual ssize_t Sendmsg(int sockfd, const msghdr* msg, int flags);
+
+  virtual int Sendmmsg(int sockfd,
+                       mmsghdr* msgvec,
+                       unsigned int vlen,
+                       int flags);
+};
+
+// A global instance of QuicSyscallWrapper, used by some socket util functions.
+QuicSyscallWrapper* GetGlobalSyscallWrapper();
+
+// Change the global QuicSyscallWrapper to |wrapper|, for testing.
+void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper);
+
+// ScopedGlobalSyscallWrapperOverride changes the global QuicSyscallWrapper
+// during its lifetime, for testing.
+class QUIC_EXPORT_PRIVATE ScopedGlobalSyscallWrapperOverride {
+ public:
+  explicit ScopedGlobalSyscallWrapperOverride(
+      QuicSyscallWrapper* wrapper_in_scope);
+  ~ScopedGlobalSyscallWrapperOverride();
+
+ private:
+  QuicSyscallWrapper* original_wrapper_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
diff --git a/quiche/quic/core/quic_tag.cc b/quiche/quic/core/quic_tag.cc
new file mode 100644
index 0000000..48ae70a
--- /dev/null
+++ b/quiche/quic/core/quic_tag.cc
@@ -0,0 +1,110 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_tag.h"
+
+#include <algorithm>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_split.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+bool FindMutualQuicTag(const QuicTagVector& our_tags,
+                       const QuicTagVector& their_tags,
+                       QuicTag* out_result,
+                       size_t* out_index) {
+  const size_t num_our_tags = our_tags.size();
+  const size_t num_their_tags = their_tags.size();
+  for (size_t i = 0; i < num_our_tags; i++) {
+    for (size_t j = 0; j < num_their_tags; j++) {
+      if (our_tags[i] == their_tags[j]) {
+        *out_result = our_tags[i];
+        if (out_index != nullptr) {
+          *out_index = j;
+        }
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+std::string QuicTagToString(QuicTag tag) {
+  if (tag == 0) {
+    return "0";
+  }
+  char chars[sizeof tag];
+  bool ascii = true;
+  const QuicTag orig_tag = tag;
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(chars); i++) {
+    chars[i] = static_cast<char>(tag);
+    if ((chars[i] == 0 || chars[i] == '\xff') &&
+        i == ABSL_ARRAYSIZE(chars) - 1) {
+      chars[i] = ' ';
+    }
+    if (!isprint(static_cast<unsigned char>(chars[i]))) {
+      ascii = false;
+      break;
+    }
+    tag >>= 8;
+  }
+
+  if (ascii) {
+    return std::string(chars, sizeof(chars));
+  }
+
+  return absl::BytesToHexString(absl::string_view(
+      reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag)));
+}
+
+uint32_t MakeQuicTag(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+  return static_cast<uint32_t>(a) | static_cast<uint32_t>(b) << 8 |
+         static_cast<uint32_t>(c) << 16 | static_cast<uint32_t>(d) << 24;
+}
+
+bool ContainsQuicTag(const QuicTagVector& tag_vector, QuicTag tag) {
+  return std::find(tag_vector.begin(), tag_vector.end(), tag) !=
+         tag_vector.end();
+}
+
+QuicTag ParseQuicTag(absl::string_view tag_string) {
+  quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tag_string);
+  std::string tag_bytes;
+  if (tag_string.length() == 8) {
+    tag_bytes = absl::HexStringToBytes(tag_string);
+    tag_string = tag_bytes;
+  }
+  QuicTag tag = 0;
+  // Iterate over every character from right to left.
+  for (auto it = tag_string.rbegin(); it != tag_string.rend(); ++it) {
+    // The cast here is required on platforms where char is signed.
+    unsigned char token_char = static_cast<unsigned char>(*it);
+    tag <<= 8;
+    tag |= token_char;
+  }
+  return tag;
+}
+
+QuicTagVector ParseQuicTagVector(absl::string_view tags_string) {
+  QuicTagVector tag_vector;
+  quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tags_string);
+  if (!tags_string.empty()) {
+    std::vector<absl::string_view> tag_strings =
+        absl::StrSplit(tags_string, ',');
+    for (absl::string_view tag_string : tag_strings) {
+      tag_vector.push_back(ParseQuicTag(tag_string));
+    }
+  }
+  return tag_vector;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_tag.h b/quiche/quic/core/quic_tag.h
new file mode 100644
index 0000000..17c5968
--- /dev/null
+++ b/quiche/quic/core/quic_tag.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2016 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_TAG_H_
+#define QUICHE_QUIC_CORE_QUIC_TAG_H_
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A QuicTag is a 32-bit used as identifiers in the QUIC handshake.  The use of
+// a uint32_t seeks to provide a balance between the tyranny of magic number
+// registries and the verbosity of strings. As far as the wire protocol is
+// concerned, these are opaque, 32-bit values.
+//
+// Tags will often be referred to by their ASCII equivalent, e.g. EXMP. This is
+// just a mnemonic for the value 0x504d5845 (little-endian version of the ASCII
+// string E X M P).
+using QuicTag = uint32_t;
+using QuicTagValueMap = std::map<QuicTag, std::string>;
+using QuicTagVector = std::vector<QuicTag>;
+
+// MakeQuicTag returns a value given the four bytes. For example:
+//   MakeQuicTag('C', 'H', 'L', 'O');
+QUIC_EXPORT_PRIVATE QuicTag MakeQuicTag(uint8_t a, uint8_t b, uint8_t c,
+                                        uint8_t d);
+
+// Returns true if |tag_vector| contains |tag|.
+QUIC_EXPORT_PRIVATE bool ContainsQuicTag(const QuicTagVector& tag_vector,
+                                         QuicTag tag);
+
+// Sets |out_result| to the first tag in |our_tags| that is also in |their_tags|
+// and returns true. If there is no intersection it returns false.
+//
+// If |out_index| is non-nullptr and a match is found then the index of that
+// match in |their_tags| is written to |out_index|.
+QUIC_EXPORT_PRIVATE bool FindMutualQuicTag(const QuicTagVector& our_tags,
+                                           const QuicTagVector& their_tags,
+                                           QuicTag* out_result,
+                                           size_t* out_index);
+
+// A utility function that converts a tag to a string. It will try to maintain
+// the human friendly name if possible (i.e. kABCD -> "ABCD"), or will just
+// treat it as a number if not.
+QUIC_EXPORT_PRIVATE std::string QuicTagToString(QuicTag tag);
+
+// Utility function that converts a string of the form "ABCD" to its
+// corresponding QuicTag. Note that tags that are less than four characters
+// long are right-padded with zeroes. Tags that contain non-ASCII characters
+// are represented as 8-character-long hexadecimal strings.
+QUIC_EXPORT_PRIVATE QuicTag ParseQuicTag(absl::string_view tag_string);
+
+// Utility function that converts a string of the form "ABCD,EFGH" to a vector
+// of the form {kABCD,kEFGH}. Note the caveats on ParseQuicTag.
+QUIC_EXPORT_PRIVATE QuicTagVector
+ParseQuicTagVector(absl::string_view tags_string);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TAG_H_
diff --git a/quiche/quic/core/quic_tag_test.cc b/quiche/quic/core/quic_tag_test.cc
new file mode 100644
index 0000000..b3e6510
--- /dev/null
+++ b/quiche/quic/core/quic_tag_test.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_tag.h"
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicTagTest : public QuicTest {};
+
+TEST_F(QuicTagTest, TagToString) {
+  EXPECT_EQ("SCFG", QuicTagToString(kSCFG));
+  EXPECT_EQ("SNO ", QuicTagToString(kServerNonceTag));
+  EXPECT_EQ("CRT ", QuicTagToString(kCertificateTag));
+  EXPECT_EQ("CHLO", QuicTagToString(MakeQuicTag('C', 'H', 'L', 'O')));
+  // A tag that contains a non-printing character will be printed as hex.
+  EXPECT_EQ("43484c1f", QuicTagToString(MakeQuicTag('C', 'H', 'L', '\x1f')));
+}
+
+TEST_F(QuicTagTest, MakeQuicTag) {
+  QuicTag tag = MakeQuicTag('A', 'B', 'C', 'D');
+  char bytes[4];
+  memcpy(bytes, &tag, 4);
+  EXPECT_EQ('A', bytes[0]);
+  EXPECT_EQ('B', bytes[1]);
+  EXPECT_EQ('C', bytes[2]);
+  EXPECT_EQ('D', bytes[3]);
+}
+
+TEST_F(QuicTagTest, ParseQuicTag) {
+  QuicTag tag_abcd = MakeQuicTag('A', 'B', 'C', 'D');
+  EXPECT_EQ(ParseQuicTag("ABCD"), tag_abcd);
+  EXPECT_EQ(ParseQuicTag("ABCDE"), tag_abcd);
+  QuicTag tag_efgh = MakeQuicTag('E', 'F', 'G', 'H');
+  EXPECT_EQ(ParseQuicTag("EFGH"), tag_efgh);
+  QuicTag tag_ijk = MakeQuicTag('I', 'J', 'K', 0);
+  EXPECT_EQ(ParseQuicTag("IJK"), tag_ijk);
+  QuicTag tag_l = MakeQuicTag('L', 0, 0, 0);
+  EXPECT_EQ(ParseQuicTag("L"), tag_l);
+  QuicTag tag_hex = MakeQuicTag('M', 'N', 'O', static_cast<char>(255));
+  EXPECT_EQ(ParseQuicTag("4d4e4fff"), tag_hex);
+  EXPECT_EQ(ParseQuicTag("4D4E4FFF"), tag_hex);
+  QuicTag tag_with_numbers = MakeQuicTag('P', 'Q', '1', '2');
+  EXPECT_EQ(ParseQuicTag("PQ12"), tag_with_numbers);
+  QuicTag tag_with_custom_chars = MakeQuicTag('r', '$', '_', '7');
+  EXPECT_EQ(ParseQuicTag("r$_7"), tag_with_custom_chars);
+  QuicTag tag_zero = 0;
+  EXPECT_EQ(ParseQuicTag(""), tag_zero);
+  QuicTagVector tag_vector;
+  EXPECT_EQ(ParseQuicTagVector(""), tag_vector);
+  EXPECT_EQ(ParseQuicTagVector(" "), tag_vector);
+  tag_vector.push_back(tag_abcd);
+  EXPECT_EQ(ParseQuicTagVector("ABCD"), tag_vector);
+  tag_vector.push_back(tag_efgh);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH"), tag_vector);
+  tag_vector.push_back(tag_ijk);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK"), tag_vector);
+  tag_vector.push_back(tag_l);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L"), tag_vector);
+  tag_vector.push_back(tag_hex);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff"), tag_vector);
+  tag_vector.push_back(tag_with_numbers);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12"), tag_vector);
+  tag_vector.push_back(tag_with_custom_chars);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7"),
+            tag_vector);
+  tag_vector.push_back(tag_zero);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7,"),
+            tag_vector);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time.cc b/quiche/quic/core/quic_time.cc
new file mode 100644
index 0000000..8da46fe
--- /dev/null
+++ b/quiche/quic/core/quic_time.cc
@@ -0,0 +1,87 @@
+// 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 "quiche/quic/core/quic_time.h"
+
+#include <cinttypes>
+#include <cstdlib>
+#include <limits>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+
+namespace quic {
+
+std::string QuicTime::Delta::ToDebuggingValue() const {
+  constexpr int64_t kMillisecondInMicroseconds = 1000;
+  constexpr int64_t kSecondInMicroseconds = 1000 * kMillisecondInMicroseconds;
+
+  int64_t absolute_value = std::abs(time_offset_);
+
+  // For debugging purposes, always display the value with the highest precision
+  // available.
+  if (absolute_value >= kSecondInMicroseconds &&
+      absolute_value % kSecondInMicroseconds == 0) {
+    return absl::StrCat(time_offset_ / kSecondInMicroseconds, "s");
+  }
+  if (absolute_value >= kMillisecondInMicroseconds &&
+      absolute_value % kMillisecondInMicroseconds == 0) {
+    return absl::StrCat(time_offset_ / kMillisecondInMicroseconds, "ms");
+  }
+  return absl::StrCat(time_offset_, "us");
+}
+
+uint64_t QuicWallTime::ToUNIXSeconds() const {
+  return microseconds_ / 1000000;
+}
+
+uint64_t QuicWallTime::ToUNIXMicroseconds() const {
+  return microseconds_;
+}
+
+bool QuicWallTime::IsAfter(QuicWallTime other) const {
+  return microseconds_ > other.microseconds_;
+}
+
+bool QuicWallTime::IsBefore(QuicWallTime other) const {
+  return microseconds_ < other.microseconds_;
+}
+
+bool QuicWallTime::IsZero() const {
+  return microseconds_ == 0;
+}
+
+QuicTime::Delta QuicWallTime::AbsoluteDifference(QuicWallTime other) const {
+  uint64_t d;
+
+  if (microseconds_ > other.microseconds_) {
+    d = microseconds_ - other.microseconds_;
+  } else {
+    d = other.microseconds_ - microseconds_;
+  }
+
+  if (d > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
+    d = std::numeric_limits<int64_t>::max();
+  }
+  return QuicTime::Delta::FromMicroseconds(d);
+}
+
+QuicWallTime QuicWallTime::Add(QuicTime::Delta delta) const {
+  uint64_t microseconds = microseconds_ + delta.ToMicroseconds();
+  if (microseconds < microseconds_) {
+    microseconds = std::numeric_limits<uint64_t>::max();
+  }
+  return QuicWallTime(microseconds);
+}
+
+// TODO(ianswett) Test this.
+QuicWallTime QuicWallTime::Subtract(QuicTime::Delta delta) const {
+  uint64_t microseconds = microseconds_ - delta.ToMicroseconds();
+  if (microseconds > microseconds_) {
+    microseconds = 0;
+  }
+  return QuicWallTime(microseconds);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time.h b/quiche/quic/core/quic_time.h
new file mode 100644
index 0000000..74cfaf2
--- /dev/null
+++ b/quiche/quic/core/quic_time.h
@@ -0,0 +1,292 @@
+// 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.
+
+// QuicTime represents one point in time, stored in microsecond resolution.
+// QuicTime is monotonically increasing, even across system clock adjustments.
+// The epoch (time 0) of QuicTime is unspecified.
+//
+// This implementation wraps a int64_t of usec since the epoch.  While
+// the epoch is the Unix epoch, do not depend on this fact because other
+// implementations, like Chrome's, do NOT have the same epoch.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TIME_H_
+#define QUICHE_QUIC_CORE_QUIC_TIME_H_
+
+#include <cmath>
+#include <cstdint>
+#include <limits>
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+// TODO(vasilvv): replace with ABSL_MUST_USE_RESULT once we're using absl.
+#if defined(__clang__)
+#define QUIC_TIME_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define QUIC_TIME_WARN_UNUSED_RESULT
+#endif /* defined(__clang__) */
+
+namespace quic {
+
+class QuicClock;
+
+// A QuicTime is a purely relative time. QuicTime values from different clocks
+// cannot be compared to each other. If you need an absolute time, see
+// QuicWallTime, below.
+class QUIC_EXPORT_PRIVATE QuicTime {
+ public:
+  // A QuicTime::Delta represents the signed difference between two points in
+  // time, stored in microsecond resolution.
+  class QUIC_EXPORT_PRIVATE Delta {
+   public:
+    // Create a object with an offset of 0.
+    static constexpr Delta Zero() { return Delta(0); }
+
+    // Create a object with infinite offset time.
+    static constexpr Delta Infinite() { return Delta(kQuicInfiniteTimeUs); }
+
+    // Converts a number of seconds to a time offset.
+    static constexpr Delta FromSeconds(int64_t secs) {
+      return Delta(secs * 1000 * 1000);
+    }
+
+    // Converts a number of milliseconds to a time offset.
+    static constexpr Delta FromMilliseconds(int64_t ms) {
+      return Delta(ms * 1000);
+    }
+
+    // Converts a number of microseconds to a time offset.
+    static constexpr Delta FromMicroseconds(int64_t us) { return Delta(us); }
+
+    // Converts the time offset to a rounded number of seconds.
+    int64_t ToSeconds() const { return time_offset_ / 1000 / 1000; }
+
+    // Converts the time offset to a rounded number of milliseconds.
+    int64_t ToMilliseconds() const { return time_offset_ / 1000; }
+
+    // Converts the time offset to a rounded number of microseconds.
+    int64_t ToMicroseconds() const { return time_offset_; }
+
+    bool IsZero() const { return time_offset_ == 0; }
+
+    bool IsInfinite() const { return time_offset_ == kQuicInfiniteTimeUs; }
+
+    std::string ToDebuggingValue() const;
+
+   private:
+    friend inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs);
+    friend inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs);
+    friend inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs);
+
+    friend inline QuicTime::Delta operator+(QuicTime::Delta lhs,
+                                            QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator-(QuicTime::Delta lhs,
+                                            QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs);
+    friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs);
+
+    friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
+    friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
+
+    static const int64_t kQuicInfiniteTimeUs =
+        std::numeric_limits<int64_t>::max();
+
+    explicit constexpr Delta(int64_t time_offset) : time_offset_(time_offset) {}
+
+    int64_t time_offset_;
+    friend class QuicTime;
+  };
+
+  // Creates a new QuicTime with an internal value of 0.  IsInitialized()
+  // will return false for these times.
+  static constexpr QuicTime Zero() { return QuicTime(0); }
+
+  // Creates a new QuicTime with an infinite time.
+  static constexpr QuicTime Infinite() {
+    return QuicTime(Delta::kQuicInfiniteTimeUs);
+  }
+
+  QuicTime(const QuicTime& other) = default;
+
+  QuicTime& operator=(const QuicTime& other) {
+    time_ = other.time_;
+    return *this;
+  }
+
+  // Produce the internal value to be used when logging.  This value
+  // represents the number of microseconds since some epoch.  It may
+  // be the UNIX epoch on some platforms.  On others, it may
+  // be a CPU ticks based value.
+  int64_t ToDebuggingValue() const { return time_; }
+
+  bool IsInitialized() const { return 0 != time_; }
+
+ private:
+  friend class QuicClock;
+
+  friend inline bool operator==(QuicTime lhs, QuicTime rhs);
+  friend inline bool operator<(QuicTime lhs, QuicTime rhs);
+  friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
+  friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
+  friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
+
+  explicit constexpr QuicTime(int64_t time) : time_(time) {}
+
+  int64_t time_;
+};
+
+// A QuicWallTime represents an absolute time that is globally consistent. In
+// practice, clock-skew means that comparing values from different machines
+// requires some flexibility.
+class QUIC_EXPORT_PRIVATE QuicWallTime {
+ public:
+  // FromUNIXSeconds constructs a QuicWallTime from a count of the seconds
+  // since the UNIX epoch.
+  static constexpr QuicWallTime FromUNIXSeconds(uint64_t seconds) {
+    return QuicWallTime(seconds * 1000000);
+  }
+
+  static constexpr QuicWallTime FromUNIXMicroseconds(uint64_t microseconds) {
+    return QuicWallTime(microseconds);
+  }
+
+  // Zero returns a QuicWallTime set to zero. IsZero will return true for this
+  // value.
+  static constexpr QuicWallTime Zero() { return QuicWallTime(0); }
+
+  // Returns the number of seconds since the UNIX epoch.
+  uint64_t ToUNIXSeconds() const;
+  // Returns the number of microseconds since the UNIX epoch.
+  uint64_t ToUNIXMicroseconds() const;
+
+  bool IsAfter(QuicWallTime other) const;
+  bool IsBefore(QuicWallTime other) const;
+
+  // IsZero returns true if this object is the result of calling |Zero|.
+  bool IsZero() const;
+
+  // AbsoluteDifference returns the absolute value of the time difference
+  // between |this| and |other|.
+  QuicTime::Delta AbsoluteDifference(QuicWallTime other) const;
+
+  // Add returns a new QuicWallTime that represents the time of |this| plus
+  // |delta|.
+  QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime Add(QuicTime::Delta delta) const;
+
+  // Subtract returns a new QuicWallTime that represents the time of |this|
+  // minus |delta|.
+  QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime
+  Subtract(QuicTime::Delta delta) const;
+
+  bool operator==(const QuicWallTime& other) const {
+    return microseconds_ == other.microseconds_;
+  }
+
+  QuicTime::Delta operator-(const QuicWallTime& rhs) const {
+    return QuicTime::Delta::FromMicroseconds(microseconds_ - rhs.microseconds_);
+  }
+
+ private:
+  explicit constexpr QuicWallTime(uint64_t microseconds)
+      : microseconds_(microseconds) {}
+
+  uint64_t microseconds_;
+};
+
+// Non-member relational operators for QuicTime::Delta.
+inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return lhs.time_offset_ == rhs.time_offset_;
+}
+inline bool operator!=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return lhs.time_offset_ < rhs.time_offset_;
+}
+inline bool operator>(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(lhs < rhs);
+}
+inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs) {
+  return QuicTime::Delta(lhs.time_offset_ << rhs);
+}
+inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs) {
+  return QuicTime::Delta(lhs.time_offset_ >> rhs);
+}
+
+// Non-member relational operators for QuicTime.
+inline bool operator==(QuicTime lhs, QuicTime rhs) {
+  return lhs.time_ == rhs.time_;
+}
+inline bool operator!=(QuicTime lhs, QuicTime rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicTime lhs, QuicTime rhs) {
+  return lhs.time_ < rhs.time_;
+}
+inline bool operator>(QuicTime lhs, QuicTime rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicTime lhs, QuicTime rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicTime lhs, QuicTime rhs) {
+  return !(lhs < rhs);
+}
+
+// Override stream output operator for gtest or QUICHE_CHECK macros.
+inline std::ostream& operator<<(std::ostream& output, const QuicTime t) {
+  output << t.ToDebuggingValue();
+  return output;
+}
+
+// Non-member arithmetic operators for QuicTime::Delta.
+inline QuicTime::Delta operator+(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return QuicTime::Delta(lhs.time_offset_ + rhs.time_offset_);
+}
+inline QuicTime::Delta operator-(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return QuicTime::Delta(lhs.time_offset_ - rhs.time_offset_);
+}
+inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs) {
+  return QuicTime::Delta(lhs.time_offset_ * rhs);
+}
+inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs) {
+  return QuicTime::Delta(static_cast<int64_t>(
+      std::llround(static_cast<double>(lhs.time_offset_) * rhs)));
+}
+inline QuicTime::Delta operator*(int lhs, QuicTime::Delta rhs) {
+  return rhs * lhs;
+}
+inline QuicTime::Delta operator*(double lhs, QuicTime::Delta rhs) {
+  return rhs * lhs;
+}
+
+// Non-member arithmetic operators for QuicTime and QuicTime::Delta.
+inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs) {
+  return QuicTime(lhs.time_ + rhs.time_offset_);
+}
+inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs) {
+  return QuicTime(lhs.time_ - rhs.time_offset_);
+}
+inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs) {
+  return QuicTime::Delta(lhs.time_ - rhs.time_);
+}
+
+// Override stream output operator for gtest.
+inline std::ostream& operator<<(std::ostream& output,
+                                const QuicTime::Delta delta) {
+  output << delta.ToDebuggingValue();
+  return output;
+}
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TIME_H_
diff --git a/quiche/quic/core/quic_time_accumulator.h b/quiche/quic/core/quic_time_accumulator.h
new file mode 100644
index 0000000..480e797
--- /dev/null
+++ b/quiche/quic/core/quic_time_accumulator.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2019 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_TIME_ACCUMULATOR_H_
+#define QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// QuicTimeAccumulator accumulates elapsed times between Start(s) and Stop(s).
+class QUIC_EXPORT_PRIVATE QuicTimeAccumulator {
+  // TODO(wub): Switch to a data member called kNotRunningSentinel after c++17.
+  static constexpr QuicTime NotRunningSentinel() {
+    return QuicTime::Infinite();
+  }
+
+ public:
+  // True if Started and not Stopped.
+  bool IsRunning() const { return last_start_time_ != NotRunningSentinel(); }
+
+  void Start(QuicTime now) {
+    QUICHE_DCHECK(!IsRunning());
+    last_start_time_ = now;
+    QUICHE_DCHECK(IsRunning());
+  }
+
+  void Stop(QuicTime now) {
+    QUICHE_DCHECK(IsRunning());
+    if (now > last_start_time_) {
+      total_elapsed_ = total_elapsed_ + (now - last_start_time_);
+    }
+    last_start_time_ = NotRunningSentinel();
+    QUICHE_DCHECK(!IsRunning());
+  }
+
+  // Get total elapsed time between COMPLETED Start/Stop pairs.
+  QuicTime::Delta GetTotalElapsedTime() const { return total_elapsed_; }
+
+  // Get total elapsed time between COMPLETED Start/Stop pairs, plus, if it is
+  // running, the elapsed time between |last_start_time_| and |now|.
+  QuicTime::Delta GetTotalElapsedTime(QuicTime now) const {
+    if (!IsRunning()) {
+      return total_elapsed_;
+    }
+    if (now <= last_start_time_) {
+      return total_elapsed_;
+    }
+    return total_elapsed_ + (now - last_start_time_);
+  }
+
+ private:
+  //
+  //                                       |last_start_time_|
+  //                                         |
+  //                                         V
+  // Start => Stop  =>  Start => Stop  =>  Start
+  // |           |      |           |
+  // |___________|  +   |___________|  =   |total_elapsed_|
+  QuicTime::Delta total_elapsed_ = QuicTime::Delta::Zero();
+  QuicTime last_start_time_ = NotRunningSentinel();
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
diff --git a/quiche/quic/core/quic_time_accumulator_test.cc b/quiche/quic/core/quic_time_accumulator_test.cc
new file mode 100644
index 0000000..e431378
--- /dev/null
+++ b/quiche/quic/core/quic_time_accumulator_test.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 2019 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 "quiche/quic/core/quic_time_accumulator.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+TEST(QuicTimeAccumulator, DefaultConstruct) {
+  MockClock clock;
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicTimeAccumulator acc;
+  EXPECT_FALSE(acc.IsRunning());
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime(clock.Now()));
+}
+
+TEST(QuicTimeAccumulator, StartStop) {
+  MockClock clock;
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicTimeAccumulator acc;
+  acc.Start(clock.Now());
+  EXPECT_TRUE(acc.IsRunning());
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  acc.Stop(clock.Now());
+  EXPECT_FALSE(acc.IsRunning());
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+            acc.GetTotalElapsedTime(clock.Now()));
+
+  acc.Start(clock.Now());
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(15),
+            acc.GetTotalElapsedTime(clock.Now()));
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
+            acc.GetTotalElapsedTime(clock.Now()));
+
+  acc.Stop(clock.Now());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
+            acc.GetTotalElapsedTime(clock.Now()));
+}
+
+TEST(QuicTimeAccumulator, ClockStepBackwards) {
+  MockClock clock;
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+
+  QuicTimeAccumulator acc;
+  acc.Start(clock.Now());
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(-10));
+  acc.Stop(clock.Now());
+  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime(clock.Now()));
+
+  acc.Start(clock.Now());
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(50));
+  acc.Stop(clock.Now());
+
+  acc.Start(clock.Now());
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(-80));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
+            acc.GetTotalElapsedTime(clock.Now()));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time_test.cc b/quiche/quic/core/quic_time_test.cc
new file mode 100644
index 0000000..d2a8d91
--- /dev/null
+++ b/quiche/quic/core/quic_time_test.cc
@@ -0,0 +1,185 @@
+// 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 "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class QuicTimeDeltaTest : public QuicTest {};
+
+TEST_F(QuicTimeDeltaTest, Zero) {
+  EXPECT_TRUE(QuicTime::Delta::Zero().IsZero());
+  EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
+  EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsZero());
+}
+
+TEST_F(QuicTimeDeltaTest, Infinite) {
+  EXPECT_TRUE(QuicTime::Delta::Infinite().IsInfinite());
+  EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
+  EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsInfinite());
+}
+
+TEST_F(QuicTimeDeltaTest, FromTo) {
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
+            QuicTime::Delta::FromMicroseconds(1000));
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
+            QuicTime::Delta::FromMilliseconds(1000));
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
+            QuicTime::Delta::FromMicroseconds(1000000));
+
+  EXPECT_EQ(1, QuicTime::Delta::FromMicroseconds(1000).ToMilliseconds());
+  EXPECT_EQ(2, QuicTime::Delta::FromMilliseconds(2000).ToSeconds());
+  EXPECT_EQ(1000, QuicTime::Delta::FromMilliseconds(1).ToMicroseconds());
+  EXPECT_EQ(1, QuicTime::Delta::FromMicroseconds(1000).ToMilliseconds());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2000).ToMicroseconds(),
+            QuicTime::Delta::FromSeconds(2).ToMicroseconds());
+}
+
+TEST_F(QuicTimeDeltaTest, Add) {
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
+            QuicTime::Delta::Zero() + QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(QuicTimeDeltaTest, Subtract) {
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1000),
+            QuicTime::Delta::FromMilliseconds(2) -
+                QuicTime::Delta::FromMilliseconds(1));
+}
+
+TEST_F(QuicTimeDeltaTest, Multiply) {
+  int i = 2;
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
+            QuicTime::Delta::FromMilliseconds(2) * i);
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
+            i * QuicTime::Delta::FromMilliseconds(2));
+  double d = 2;
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
+            QuicTime::Delta::FromMilliseconds(2) * d);
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
+            d * QuicTime::Delta::FromMilliseconds(2));
+
+  // Ensure we are rounding correctly within a single-bit level of precision.
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(5),
+            QuicTime::Delta::FromMicroseconds(9) * 0.5);
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicTime::Delta::FromMicroseconds(12) * 0.2);
+}
+
+TEST_F(QuicTimeDeltaTest, Max) {
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
+            std::max(QuicTime::Delta::FromMicroseconds(1000),
+                     QuicTime::Delta::FromMicroseconds(2000)));
+}
+
+TEST_F(QuicTimeDeltaTest, NotEqual) {
+  EXPECT_TRUE(QuicTime::Delta::FromSeconds(0) !=
+              QuicTime::Delta::FromSeconds(1));
+  EXPECT_FALSE(QuicTime::Delta::FromSeconds(0) !=
+               QuicTime::Delta::FromSeconds(0));
+}
+
+TEST_F(QuicTimeDeltaTest, DebuggingValue) {
+  const QuicTime::Delta one_us = QuicTime::Delta::FromMicroseconds(1);
+  const QuicTime::Delta one_ms = QuicTime::Delta::FromMilliseconds(1);
+  const QuicTime::Delta one_s = QuicTime::Delta::FromSeconds(1);
+
+  EXPECT_EQ("1s", one_s.ToDebuggingValue());
+  EXPECT_EQ("3s", (3 * one_s).ToDebuggingValue());
+  EXPECT_EQ("1ms", one_ms.ToDebuggingValue());
+  EXPECT_EQ("3ms", (3 * one_ms).ToDebuggingValue());
+  EXPECT_EQ("1us", one_us.ToDebuggingValue());
+  EXPECT_EQ("3us", (3 * one_us).ToDebuggingValue());
+
+  EXPECT_EQ("3001us", (3 * one_ms + one_us).ToDebuggingValue());
+  EXPECT_EQ("3001ms", (3 * one_s + one_ms).ToDebuggingValue());
+  EXPECT_EQ("3000001us", (3 * one_s + one_us).ToDebuggingValue());
+}
+
+class QuicTimeTest : public QuicTest {
+ protected:
+  MockClock clock_;
+};
+
+TEST_F(QuicTimeTest, Initialized) {
+  EXPECT_FALSE(QuicTime::Zero().IsInitialized());
+  EXPECT_TRUE((QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1))
+                  .IsInitialized());
+}
+
+TEST_F(QuicTimeTest, CopyConstruct) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1234);
+  EXPECT_NE(time_1, QuicTime(QuicTime::Zero()));
+  EXPECT_EQ(time_1, QuicTime(time_1));
+}
+
+TEST_F(QuicTimeTest, CopyAssignment) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1234);
+  QuicTime time_2 = QuicTime::Zero();
+  EXPECT_NE(time_1, time_2);
+  time_2 = time_1;
+  EXPECT_EQ(time_1, time_2);
+}
+
+TEST_F(QuicTimeTest, Add) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
+  QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+
+  QuicTime::Delta diff = time_2 - time_1;
+
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), diff);
+  EXPECT_EQ(1000, diff.ToMicroseconds());
+  EXPECT_EQ(1, diff.ToMilliseconds());
+}
+
+TEST_F(QuicTimeTest, Subtract) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
+  QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), time_2 - time_1);
+}
+
+TEST_F(QuicTimeTest, SubtractDelta) {
+  QuicTime time = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+  EXPECT_EQ(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1),
+            time - QuicTime::Delta::FromMilliseconds(1));
+}
+
+TEST_F(QuicTimeTest, Max) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
+  QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+
+  EXPECT_EQ(time_2, std::max(time_1, time_2));
+}
+
+TEST_F(QuicTimeTest, MockClock) {
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicTime now = clock_.ApproximateNow();
+  QuicTime time = QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1000);
+
+  EXPECT_EQ(now, time);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  now = clock_.ApproximateNow();
+
+  EXPECT_NE(now, time);
+
+  time = time + QuicTime::Delta::FromMilliseconds(1);
+  EXPECT_EQ(now, time);
+}
+
+TEST_F(QuicTimeTest, LE) {
+  const QuicTime zero = QuicTime::Zero();
+  const QuicTime one = zero + QuicTime::Delta::FromSeconds(1);
+  EXPECT_TRUE(zero <= zero);
+  EXPECT_TRUE(zero <= one);
+  EXPECT_TRUE(one <= one);
+  EXPECT_FALSE(one <= zero);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time_wait_list_manager.cc b/quiche/quic/core/quic_time_wait_list_manager.cc
new file mode 100644
index 0000000..5aeff59
--- /dev/null
+++ b/quiche/quic/core/quic_time_wait_list_manager.cc
@@ -0,0 +1,503 @@
+// 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 "quiche/quic/core/quic_time_wait_list_manager.h"
+
+#include <errno.h>
+
+#include <memory>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+// A very simple alarm that just informs the QuicTimeWaitListManager to clean
+// up old connection_ids. This alarm should be cancelled and deleted before
+// the QuicTimeWaitListManager is deleted.
+class ConnectionIdCleanUpAlarm : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit ConnectionIdCleanUpAlarm(
+      QuicTimeWaitListManager* time_wait_list_manager)
+      : time_wait_list_manager_(time_wait_list_manager) {}
+  ConnectionIdCleanUpAlarm(const ConnectionIdCleanUpAlarm&) = delete;
+  ConnectionIdCleanUpAlarm& operator=(const ConnectionIdCleanUpAlarm&) = delete;
+
+  void OnAlarm() override {
+    time_wait_list_manager_->CleanUpOldConnectionIds();
+  }
+
+ private:
+  // Not owned.
+  QuicTimeWaitListManager* time_wait_list_manager_;
+};
+
+TimeWaitConnectionInfo::TimeWaitConnectionInfo(
+    bool ietf_quic,
+    std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
+    std::vector<QuicConnectionId> active_connection_ids)
+    : TimeWaitConnectionInfo(ietf_quic,
+                             termination_packets,
+                             std::move(active_connection_ids),
+                             QuicTime::Delta::Zero()) {}
+
+TimeWaitConnectionInfo::TimeWaitConnectionInfo(
+    bool ietf_quic,
+    std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
+    std::vector<QuicConnectionId> active_connection_ids,
+    QuicTime::Delta srtt)
+    : ietf_quic(ietf_quic),
+      active_connection_ids(std::move(active_connection_ids)),
+      srtt(srtt) {
+  if (termination_packets != nullptr) {
+    this->termination_packets.swap(*termination_packets);
+  }
+}
+
+QuicTimeWaitListManager::QuicTimeWaitListManager(
+    QuicPacketWriter* writer,
+    Visitor* visitor,
+    const QuicClock* clock,
+    QuicAlarmFactory* alarm_factory)
+    : time_wait_period_(QuicTime::Delta::FromSeconds(
+          GetQuicFlag(FLAGS_quic_time_wait_list_seconds))),
+      connection_id_clean_up_alarm_(
+          alarm_factory->CreateAlarm(new ConnectionIdCleanUpAlarm(this))),
+      clock_(clock),
+      writer_(writer),
+      visitor_(visitor) {
+  SetConnectionIdCleanUpAlarm();
+}
+
+QuicTimeWaitListManager::~QuicTimeWaitListManager() {
+  connection_id_clean_up_alarm_->Cancel();
+}
+
+QuicTimeWaitListManager::ConnectionIdMap::iterator
+QuicTimeWaitListManager::FindConnectionIdDataInMap(
+    const QuicConnectionId& connection_id) {
+  auto it = indirect_connection_id_map_.find(connection_id);
+  if (it == indirect_connection_id_map_.end()) {
+    return connection_id_map_.end();
+  }
+  return connection_id_map_.find(it->second);
+}
+
+void QuicTimeWaitListManager::AddConnectionIdDataToMap(
+    const QuicConnectionId& canonical_connection_id,
+    int num_packets,
+    TimeWaitAction action,
+    TimeWaitConnectionInfo info) {
+  for (const auto& cid : info.active_connection_ids) {
+    indirect_connection_id_map_[cid] = canonical_connection_id;
+  }
+  ConnectionIdData data(num_packets, clock_->ApproximateNow(), action,
+                        std::move(info));
+  connection_id_map_.emplace(
+      std::make_pair(canonical_connection_id, std::move(data)));
+}
+
+void QuicTimeWaitListManager::RemoveConnectionDataFromMap(
+    ConnectionIdMap::iterator it) {
+  for (const auto& cid : it->second.info.active_connection_ids) {
+    indirect_connection_id_map_.erase(cid);
+  }
+  connection_id_map_.erase(it);
+}
+
+void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
+    TimeWaitAction action,
+    TimeWaitConnectionInfo info) {
+  QUICHE_DCHECK(!info.active_connection_ids.empty());
+  const QuicConnectionId& canonical_connection_id =
+      info.active_connection_ids.front();
+  QUICHE_DCHECK(action != SEND_TERMINATION_PACKETS ||
+                !info.termination_packets.empty());
+  QUICHE_DCHECK(action != DO_NOTHING || info.ietf_quic);
+  int num_packets = 0;
+  auto it = FindConnectionIdDataInMap(canonical_connection_id);
+  const bool new_connection_id = it == connection_id_map_.end();
+  if (!new_connection_id) {  // Replace record if it is reinserted.
+    num_packets = it->second.num_packets;
+    RemoveConnectionDataFromMap(it);
+  }
+  TrimTimeWaitListIfNeeded();
+  int64_t max_connections =
+      GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
+  QUICHE_DCHECK(connection_id_map_.empty() ||
+                num_connections() < static_cast<size_t>(max_connections));
+  if (new_connection_id) {
+    for (const auto& cid : info.active_connection_ids) {
+      visitor_->OnConnectionAddedToTimeWaitList(cid);
+    }
+  }
+  AddConnectionIdDataToMap(canonical_connection_id, num_packets, action,
+                           std::move(info));
+}
+
+bool QuicTimeWaitListManager::IsConnectionIdInTimeWait(
+    QuicConnectionId connection_id) const {
+  return indirect_connection_id_map_.contains(connection_id);
+}
+
+void QuicTimeWaitListManager::OnBlockedWriterCanWrite() {
+  writer_->SetWritable();
+  while (!pending_packets_queue_.empty()) {
+    QueuedPacket* queued_packet = pending_packets_queue_.front().get();
+    if (!WriteToWire(queued_packet)) {
+      return;
+    }
+    pending_packets_queue_.pop_front();
+  }
+}
+
+void QuicTimeWaitListManager::ProcessPacket(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    QuicConnectionId connection_id,
+    PacketHeaderFormat header_format,
+    size_t received_packet_length,
+    std::unique_ptr<QuicPerPacketContext> packet_context) {
+  QUICHE_DCHECK(IsConnectionIdInTimeWait(connection_id));
+  // TODO(satyamshekhar): Think about handling packets from different peer
+  // addresses.
+  auto it = FindConnectionIdDataInMap(connection_id);
+  QUICHE_DCHECK(it != connection_id_map_.end());
+  // Increment the received packet count.
+  ConnectionIdData* connection_data = &it->second;
+  ++(connection_data->num_packets);
+  const QuicTime now = clock_->ApproximateNow();
+  QuicTime::Delta delta = QuicTime::Delta::Zero();
+  if (now > connection_data->time_added) {
+    delta = now - connection_data->time_added;
+  }
+  OnPacketReceivedForKnownConnection(connection_data->num_packets, delta,
+                                     connection_data->info.srtt);
+
+  if (!ShouldSendResponse(connection_data->num_packets)) {
+    QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state: "
+                    << "throttled";
+    return;
+  }
+
+  QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state: "
+                  << "header format=" << header_format
+                  << " ietf=" << connection_data->info.ietf_quic
+                  << ", action=" << connection_data->action
+                  << ", number termination packets="
+                  << connection_data->info.termination_packets.size();
+  switch (connection_data->action) {
+    case SEND_TERMINATION_PACKETS:
+      if (connection_data->info.termination_packets.empty()) {
+        QUIC_BUG(quic_bug_10608_1) << "There are no termination packets.";
+        return;
+      }
+      switch (header_format) {
+        case IETF_QUIC_LONG_HEADER_PACKET:
+          if (!connection_data->info.ietf_quic) {
+            QUIC_CODE_COUNT(quic_received_long_header_packet_for_gquic);
+          }
+          break;
+        case IETF_QUIC_SHORT_HEADER_PACKET:
+          if (!connection_data->info.ietf_quic) {
+            QUIC_CODE_COUNT(quic_received_short_header_packet_for_gquic);
+          }
+          // Send stateless reset in response to short header packets.
+          SendPublicReset(self_address, peer_address, connection_id,
+                          connection_data->info.ietf_quic,
+                          received_packet_length, std::move(packet_context));
+          return;
+        case GOOGLE_QUIC_PACKET:
+          if (connection_data->info.ietf_quic) {
+            QUIC_CODE_COUNT(quic_received_gquic_packet_for_ietf_quic);
+          }
+          break;
+      }
+
+      for (const auto& packet : connection_data->info.termination_packets) {
+        SendOrQueuePacket(std::make_unique<QueuedPacket>(
+                              self_address, peer_address, packet->Clone()),
+                          packet_context.get());
+      }
+      return;
+
+    case SEND_CONNECTION_CLOSE_PACKETS:
+      if (connection_data->info.termination_packets.empty()) {
+        QUIC_BUG(quic_bug_10608_2) << "There are no termination packets.";
+        return;
+      }
+      for (const auto& packet : connection_data->info.termination_packets) {
+        SendOrQueuePacket(std::make_unique<QueuedPacket>(
+                              self_address, peer_address, packet->Clone()),
+                          packet_context.get());
+      }
+      return;
+
+    case SEND_STATELESS_RESET:
+      if (header_format == IETF_QUIC_LONG_HEADER_PACKET) {
+        QUIC_CODE_COUNT(quic_stateless_reset_long_header_packet);
+      }
+      SendPublicReset(self_address, peer_address, connection_id,
+                      connection_data->info.ietf_quic, received_packet_length,
+                      std::move(packet_context));
+      return;
+    case DO_NOTHING:
+      QUIC_CODE_COUNT(quic_time_wait_list_do_nothing);
+      QUICHE_DCHECK(connection_data->info.ietf_quic);
+  }
+}
+
+void QuicTimeWaitListManager::SendVersionNegotiationPacket(
+    QuicConnectionId server_connection_id,
+    QuicConnectionId client_connection_id,
+    bool ietf_quic,
+    bool use_length_prefix,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    std::unique_ptr<QuicPerPacketContext> packet_context) {
+  std::unique_ptr<QuicEncryptedPacket> version_packet =
+      QuicFramer::BuildVersionNegotiationPacket(
+          server_connection_id, client_connection_id, ietf_quic,
+          use_length_prefix, supported_versions);
+  QUIC_DVLOG(2) << "Dispatcher sending version negotiation packet {"
+                << ParsedQuicVersionVectorToString(supported_versions) << "}, "
+                << (ietf_quic ? "" : "!") << "ietf_quic, "
+                << (use_length_prefix ? "" : "!")
+                << "use_length_prefix:" << std::endl
+                << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                       version_packet->data(), version_packet->length()));
+  SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
+                                                   std::move(version_packet)),
+                    packet_context.get());
+}
+
+// Returns true if the number of packets received for this connection_id is a
+// power of 2 to throttle the number of public reset packets we send to a peer.
+bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) {
+  return (received_packet_count & (received_packet_count - 1)) == 0;
+}
+
+void QuicTimeWaitListManager::SendPublicReset(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    QuicConnectionId connection_id,
+    bool ietf_quic,
+    size_t received_packet_length,
+    std::unique_ptr<QuicPerPacketContext> packet_context) {
+  if (ietf_quic) {
+    std::unique_ptr<QuicEncryptedPacket> ietf_reset_packet =
+        BuildIetfStatelessResetPacket(connection_id, received_packet_length);
+    if (ietf_reset_packet == nullptr) {
+      // This could happen when trying to reject a short header packet of
+      // a connection which is in the time wait list (and with no termination
+      // packet).
+      return;
+    }
+    QUIC_DVLOG(2) << "Dispatcher sending IETF reset packet for "
+                  << connection_id << std::endl
+                  << quiche::QuicheTextUtils::HexDump(
+                         absl::string_view(ietf_reset_packet->data(),
+                                           ietf_reset_packet->length()));
+    SendOrQueuePacket(
+        std::make_unique<QueuedPacket>(self_address, peer_address,
+                                       std::move(ietf_reset_packet)),
+        packet_context.get());
+    return;
+  }
+  // Google QUIC public resets donot elicit resets in response.
+  QuicPublicResetPacket packet;
+  packet.connection_id = connection_id;
+  // TODO(satyamshekhar): generate a valid nonce for this connection_id.
+  packet.nonce_proof = 1010101;
+  // TODO(wub): This is wrong for proxied sessions. Fix it.
+  packet.client_address = peer_address;
+  GetEndpointId(&packet.endpoint_id);
+  // Takes ownership of the packet.
+  std::unique_ptr<QuicEncryptedPacket> reset_packet = BuildPublicReset(packet);
+  QUIC_DVLOG(2) << "Dispatcher sending reset packet for " << connection_id
+                << std::endl
+                << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                       reset_packet->data(), reset_packet->length()));
+  SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
+                                                   std::move(reset_packet)),
+                    packet_context.get());
+}
+
+void QuicTimeWaitListManager::SendPacket(const QuicSocketAddress& self_address,
+                                         const QuicSocketAddress& peer_address,
+                                         const QuicEncryptedPacket& packet) {
+  SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
+                                                   packet.Clone()),
+                    nullptr);
+}
+
+std::unique_ptr<QuicEncryptedPacket> QuicTimeWaitListManager::BuildPublicReset(
+    const QuicPublicResetPacket& packet) {
+  return QuicFramer::BuildPublicResetPacket(packet);
+}
+
+std::unique_ptr<QuicEncryptedPacket>
+QuicTimeWaitListManager::BuildIetfStatelessResetPacket(
+    QuicConnectionId connection_id,
+    size_t received_packet_length) {
+  return QuicFramer::BuildIetfStatelessResetPacket(
+      connection_id, received_packet_length,
+      GetStatelessResetToken(connection_id));
+}
+
+// Either sends the packet and deletes it or makes pending queue the
+// owner of the packet.
+bool QuicTimeWaitListManager::SendOrQueuePacket(
+    std::unique_ptr<QueuedPacket> packet,
+    const QuicPerPacketContext* /*packet_context*/) {
+  if (packet == nullptr) {
+    QUIC_LOG(ERROR) << "Tried to send or queue a null packet";
+    return true;
+  }
+  if (pending_packets_queue_.size() >=
+      GetQuicFlag(FLAGS_quic_time_wait_list_max_pending_packets)) {
+    // There are too many pending packets.
+    QUIC_CODE_COUNT(quic_too_many_pending_packets_in_time_wait);
+    return true;
+  }
+  if (WriteToWire(packet.get())) {
+    // Allow the packet to be deleted upon leaving this function.
+    return true;
+  }
+  pending_packets_queue_.push_back(std::move(packet));
+  return false;
+}
+
+bool QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) {
+  if (writer_->IsWriteBlocked()) {
+    visitor_->OnWriteBlocked(this);
+    return false;
+  }
+  WriteResult result = writer_->WritePacket(
+      queued_packet->packet()->data(), queued_packet->packet()->length(),
+      queued_packet->self_address().host(), queued_packet->peer_address(),
+      nullptr);
+
+  // If using a batch writer and the packet is buffered, flush it.
+  if (writer_->IsBatchMode() && result.status == WRITE_STATUS_OK &&
+      result.bytes_written == 0) {
+    result = writer_->Flush();
+  }
+
+  if (IsWriteBlockedStatus(result.status)) {
+    // If blocked and unbuffered, return false to retry sending.
+    QUICHE_DCHECK(writer_->IsWriteBlocked());
+    visitor_->OnWriteBlocked(this);
+    return result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED;
+  } else if (IsWriteError(result.status)) {
+    QUIC_LOG_FIRST_N(WARNING, 1)
+        << "Received unknown error while sending termination packet to "
+        << queued_packet->peer_address().ToString() << ": "
+        << strerror(result.error_code);
+  }
+  return true;
+}
+
+void QuicTimeWaitListManager::SetConnectionIdCleanUpAlarm() {
+  QuicTime::Delta next_alarm_interval = QuicTime::Delta::Zero();
+  if (!connection_id_map_.empty()) {
+    QuicTime oldest_connection_id =
+        connection_id_map_.begin()->second.time_added;
+    QuicTime now = clock_->ApproximateNow();
+    if (now - oldest_connection_id < time_wait_period_) {
+      next_alarm_interval = oldest_connection_id + time_wait_period_ - now;
+    } else {
+      QUIC_LOG(ERROR)
+          << "ConnectionId lingered for longer than time_wait_period_";
+    }
+  } else {
+    // No connection_ids added so none will expire before time_wait_period_.
+    next_alarm_interval = time_wait_period_;
+  }
+
+  connection_id_clean_up_alarm_->Update(
+      clock_->ApproximateNow() + next_alarm_interval, QuicTime::Delta::Zero());
+}
+
+bool QuicTimeWaitListManager::MaybeExpireOldestConnection(
+    QuicTime expiration_time) {
+  if (connection_id_map_.empty()) {
+    return false;
+  }
+  auto it = connection_id_map_.begin();
+  QuicTime oldest_connection_id_time = it->second.time_added;
+  if (oldest_connection_id_time > expiration_time) {
+    // Too recent, don't retire.
+    return false;
+  }
+  // This connection_id has lived its age, retire it now.
+  QUIC_DLOG(INFO) << "Connection " << it->first
+                  << " expired from time wait list";
+  RemoveConnectionDataFromMap(it);
+  if (expiration_time == QuicTime::Infinite()) {
+    QUIC_CODE_COUNT(quic_time_wait_list_trim_full);
+  } else {
+    QUIC_CODE_COUNT(quic_time_wait_list_expire_connections);
+  }
+  return true;
+}
+
+void QuicTimeWaitListManager::CleanUpOldConnectionIds() {
+  QuicTime now = clock_->ApproximateNow();
+  QuicTime expiration = now - time_wait_period_;
+
+  while (MaybeExpireOldestConnection(expiration)) {
+  }
+
+  SetConnectionIdCleanUpAlarm();
+}
+
+void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() {
+  const int64_t kMaxConnections =
+      GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
+  if (kMaxConnections < 0) {
+    return;
+  }
+  while (!connection_id_map_.empty() &&
+         num_connections() >= static_cast<size_t>(kMaxConnections)) {
+    MaybeExpireOldestConnection(QuicTime::Infinite());
+  }
+}
+
+QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
+    int num_packets,
+    QuicTime time_added,
+    TimeWaitAction action,
+    TimeWaitConnectionInfo info)
+    : num_packets(num_packets),
+      time_added(time_added),
+      action(action),
+      info(std::move(info)) {}
+
+QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
+    ConnectionIdData&& other) = default;
+
+QuicTimeWaitListManager::ConnectionIdData::~ConnectionIdData() = default;
+
+StatelessResetToken QuicTimeWaitListManager::GetStatelessResetToken(
+    QuicConnectionId connection_id) const {
+  return QuicUtils::GenerateStatelessResetToken(connection_id);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time_wait_list_manager.h b/quiche/quic/core/quic_time_wait_list_manager.h
new file mode 100644
index 0000000..a40fa2f
--- /dev/null
+++ b/quiche/quic/core/quic_time_wait_list_manager.h
@@ -0,0 +1,343 @@
+// 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.
+
+// Handles packets for connection_ids in time wait state by discarding the
+// packet and sending the peers termination packets with exponential backoff.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/quic_blocked_writer_interface.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+namespace test {
+class QuicDispatcherPeer;
+class QuicTimeWaitListManagerPeer;
+}  // namespace test
+
+// TimeWaitConnectionInfo comprises information of a connection which is in the
+// time wait list.
+struct QUIC_NO_EXPORT TimeWaitConnectionInfo {
+  TimeWaitConnectionInfo(
+      bool ietf_quic,
+      std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
+      std::vector<QuicConnectionId> active_connection_ids);
+  TimeWaitConnectionInfo(
+      bool ietf_quic,
+      std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
+      std::vector<QuicConnectionId> active_connection_ids,
+      QuicTime::Delta srtt);
+
+  TimeWaitConnectionInfo(const TimeWaitConnectionInfo& other) = delete;
+  TimeWaitConnectionInfo(TimeWaitConnectionInfo&& other) = default;
+
+  ~TimeWaitConnectionInfo() = default;
+
+  bool ietf_quic;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  std::vector<QuicConnectionId> active_connection_ids;
+  QuicTime::Delta srtt;
+};
+
+// Maintains a list of all connection_ids that have been recently closed. A
+// connection_id lives in this state for time_wait_period_. All packets received
+// for connection_ids in this state are handed over to the
+// QuicTimeWaitListManager by the QuicDispatcher.  Decides whether to send a
+// public reset packet, a copy of the previously sent connection close packet,
+// or nothing to the peer which sent a packet with the connection_id in time
+// wait state.  After the connection_id expires its time wait period, a new
+// connection/session will be created if a packet is received for this
+// connection_id.
+class QUIC_NO_EXPORT QuicTimeWaitListManager
+    : public QuicBlockedWriterInterface {
+ public:
+  // Specifies what the time wait list manager should do when processing packets
+  // of a time wait connection.
+  enum TimeWaitAction : uint8_t {
+    // Send specified termination packets, error if termination packet is
+    // unavailable.
+    SEND_TERMINATION_PACKETS,
+    // The same as SEND_TERMINATION_PACKETS except that the corresponding
+    // termination packets are provided by the connection.
+    SEND_CONNECTION_CLOSE_PACKETS,
+    // Send stateless reset (public reset for GQUIC).
+    SEND_STATELESS_RESET,
+
+    DO_NOTHING,
+  };
+
+  class QUIC_NO_EXPORT Visitor : public QuicSession::Visitor {
+   public:
+    // Called after the given connection is added to the time-wait list.
+    virtual void OnConnectionAddedToTimeWaitList(
+        QuicConnectionId connection_id) = 0;
+  };
+
+  // writer - the entity that writes to the socket. (Owned by the caller)
+  // visitor - the entity that manages blocked writers. (Owned by the caller)
+  // clock - provide a clock (Owned by the caller)
+  // alarm_factory - used to run clean up alarms. (Owned by the caller)
+  QuicTimeWaitListManager(QuicPacketWriter* writer,
+                          Visitor* visitor,
+                          const QuicClock* clock,
+                          QuicAlarmFactory* alarm_factory);
+  QuicTimeWaitListManager(const QuicTimeWaitListManager&) = delete;
+  QuicTimeWaitListManager& operator=(const QuicTimeWaitListManager&) = delete;
+  ~QuicTimeWaitListManager() override;
+
+  // Adds the connection IDs in info to time wait state for time_wait_period_.
+  // If |info|.termination_packets are provided, copies of these packets will be
+  // sent when a packet with one of these connection IDs is processed. Any
+  // termination packets will be move from |info|.termination_packets and will
+  // become owned by the manager. |action| specifies what the time wait list
+  // manager should do when processing packets of the connection.
+  virtual void AddConnectionIdToTimeWait(TimeWaitAction action,
+                                         TimeWaitConnectionInfo info);
+
+  // Returns true if the connection_id is in time wait state, false otherwise.
+  // Packets received for this connection_id should not lead to creation of new
+  // QuicSessions.
+  bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) const;
+
+  // Called when a packet is received for a connection_id that is in time wait
+  // state. Sends a public reset packet to the peer which sent this
+  // connection_id. Sending of the public reset packet is throttled by using
+  // exponential back off. QUICHE_DCHECKs for the connection_id to be in time
+  // wait state. virtual to override in tests.
+  // TODO(fayang): change ProcessPacket and SendPublicReset to take
+  // ReceivedPacketInfo.
+  virtual void ProcessPacket(
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address,
+      QuicConnectionId connection_id,
+      PacketHeaderFormat header_format,
+      size_t received_packet_length,
+      std::unique_ptr<QuicPerPacketContext> packet_context);
+
+  // Called by the dispatcher when the underlying socket becomes writable again,
+  // since we might need to send pending public reset packets which we didn't
+  // send because the underlying socket was write blocked.
+  void OnBlockedWriterCanWrite() override;
+
+  bool IsWriterBlocked() const override {
+    return writer_ != nullptr && writer_->IsWriteBlocked();
+  }
+
+  // Used to delete connection_id entries that have outlived their time wait
+  // period.
+  void CleanUpOldConnectionIds();
+
+  // If necessary, trims the oldest connections from the time-wait list until
+  // the size is under the configured maximum.
+  void TrimTimeWaitListIfNeeded();
+
+  // The number of connections on the time-wait list.
+  size_t num_connections() const { return connection_id_map_.size(); }
+
+  // Sends a version negotiation packet for |server_connection_id| and
+  // |client_connection_id| announcing support for |supported_versions| to
+  // |peer_address| from |self_address|.
+  virtual void SendVersionNegotiationPacket(
+      QuicConnectionId server_connection_id,
+      QuicConnectionId client_connection_id,
+      bool ietf_quic,
+      bool use_length_prefix,
+      const ParsedQuicVersionVector& supported_versions,
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address,
+      std::unique_ptr<QuicPerPacketContext> packet_context);
+
+  // Creates a public reset packet and sends it or queues it to be sent later.
+  virtual void SendPublicReset(
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address,
+      QuicConnectionId connection_id,
+      bool ietf_quic,
+      size_t received_packet_length,
+      std::unique_ptr<QuicPerPacketContext> packet_context);
+
+  // Called to send |packet|.
+  virtual void SendPacket(const QuicSocketAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          const QuicEncryptedPacket& packet);
+
+  // Return a non-owning pointer to the packet writer.
+  QuicPacketWriter* writer() { return writer_; }
+
+ protected:
+  virtual std::unique_ptr<QuicEncryptedPacket> BuildPublicReset(
+      const QuicPublicResetPacket& packet);
+
+  virtual void GetEndpointId(std::string* /*endpoint_id*/) {}
+
+  // Returns a stateless reset token which will be included in the public reset
+  // packet.
+  virtual StatelessResetToken GetStatelessResetToken(
+      QuicConnectionId connection_id) const;
+
+  // Internal structure to store pending termination packets.
+  class QUIC_NO_EXPORT QueuedPacket {
+   public:
+    QueuedPacket(const QuicSocketAddress& self_address,
+                 const QuicSocketAddress& peer_address,
+                 std::unique_ptr<QuicEncryptedPacket> packet)
+        : self_address_(self_address),
+          peer_address_(peer_address),
+          packet_(std::move(packet)) {}
+    QueuedPacket(const QueuedPacket&) = delete;
+    QueuedPacket& operator=(const QueuedPacket&) = delete;
+
+    const QuicSocketAddress& self_address() const { return self_address_; }
+    const QuicSocketAddress& peer_address() const { return peer_address_; }
+    QuicEncryptedPacket* packet() { return packet_.get(); }
+
+   private:
+    // Server address on which a packet was received for a connection_id in
+    // time wait state.
+    const QuicSocketAddress self_address_;
+    // Address of the peer to send this packet to.
+    const QuicSocketAddress peer_address_;
+    // The pending termination packet that is to be sent to the peer.
+    std::unique_ptr<QuicEncryptedPacket> packet_;
+  };
+
+  // Called right after |packet| is serialized. Either sends the packet and
+  // deletes it or makes pending_packets_queue_ the owner of the packet.
+  // Subclasses overriding this method should call this class's base
+  // implementation at the end of the override.
+  // Return true if |packet| is sent, false if it is queued.
+  virtual bool SendOrQueuePacket(std::unique_ptr<QueuedPacket> packet,
+                                 const QuicPerPacketContext* packet_context);
+
+  const quiche::QuicheCircularDeque<std::unique_ptr<QueuedPacket>>&
+  pending_packets_queue() const {
+    return pending_packets_queue_;
+  }
+
+ private:
+  friend class test::QuicDispatcherPeer;
+  friend class test::QuicTimeWaitListManagerPeer;
+
+  // Decides if a packet should be sent for this connection_id based on the
+  // number of received packets.
+  bool ShouldSendResponse(int received_packet_count);
+
+  // Sends the packet out. Returns true if the packet was successfully consumed.
+  // If the writer got blocked and did not buffer the packet, we'll need to keep
+  // the packet and retry sending. In case of all other errors we drop the
+  // packet.
+  bool WriteToWire(QueuedPacket* packet);
+
+  // Register the alarm server to wake up at appropriate time.
+  void SetConnectionIdCleanUpAlarm();
+
+  // Removes the oldest connection from the time-wait list if it was added prior
+  // to "expiration_time".  To unconditionally remove the oldest connection, use
+  // a QuicTime::Delta:Infinity().  This function modifies the
+  // connection_id_map_.  If you plan to call this function in a loop, any
+  // iterators that you hold before the call to this function may be invalid
+  // afterward.  Returns true if the oldest connection was expired.  Returns
+  // false if the map is empty or the oldest connection has not expired.
+  bool MaybeExpireOldestConnection(QuicTime expiration_time);
+
+  // Called when a packet is received for a connection in this time wait list.
+  virtual void OnPacketReceivedForKnownConnection(
+      int /*num_packets*/,
+      QuicTime::Delta /*delta*/,
+      QuicTime::Delta /*srtt*/) const {}
+
+  std::unique_ptr<QuicEncryptedPacket> BuildIetfStatelessResetPacket(
+      QuicConnectionId connection_id,
+      size_t received_packet_length);
+
+  // A map from a recently closed connection_id to the number of packets
+  // received after the termination of the connection bound to the
+  // connection_id.
+  struct QUIC_NO_EXPORT ConnectionIdData {
+    ConnectionIdData(int num_packets,
+                     QuicTime time_added,
+                     TimeWaitAction action,
+                     TimeWaitConnectionInfo info);
+
+    ConnectionIdData(const ConnectionIdData& other) = delete;
+    ConnectionIdData(ConnectionIdData&& other);
+
+    ~ConnectionIdData();
+
+    int num_packets;
+    QuicTime time_added;
+    TimeWaitAction action;
+    TimeWaitConnectionInfo info;
+  };
+
+  // QuicheLinkedHashMap allows lookup by ConnectionId
+  // and traversal in add order.
+  using ConnectionIdMap = quiche::QuicheLinkedHashMap<QuicConnectionId,
+                                                      ConnectionIdData,
+                                                      QuicConnectionIdHash>;
+  // Do not use find/emplace/erase on this map directly. Use
+  // FindConnectionIdDataInMap, AddConnectionIdDateToMap,
+  // RemoveConnectionDataFromMap instead.
+  ConnectionIdMap connection_id_map_;
+
+  // TODO(haoyuewang) Consider making connection_id_map_ a map of shared pointer
+  // and remove the indirect map.
+  // A connection can have multiple unretired ConnectionIds when it is closed.
+  // These Ids have the same ConnectionIdData entry in connection_id_map_. To
+  // find the entry, look up the cannoical ConnectionId in
+  // indirect_connection_id_map_ first, and look up connection_id_map_ with the
+  // cannoical ConnectionId.
+  absl::flat_hash_map<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>
+      indirect_connection_id_map_;
+
+  // Find an iterator for the given connection_id. Returns
+  // connection_id_map_.end() if none found.
+  ConnectionIdMap::iterator FindConnectionIdDataInMap(
+      const QuicConnectionId& connection_id);
+  // Inserts a ConnectionIdData entry to connection_id_map_.
+  void AddConnectionIdDataToMap(const QuicConnectionId& canonical_connection_id,
+                                int num_packets,
+                                TimeWaitAction action,
+                                TimeWaitConnectionInfo info);
+  // Removes a ConnectionIdData entry in connection_id_map_.
+  void RemoveConnectionDataFromMap(ConnectionIdMap::iterator it);
+
+  // Pending termination packets that need to be sent out to the peer when we
+  // are given a chance to write by the dispatcher.
+  quiche::QuicheCircularDeque<std::unique_ptr<QueuedPacket>>
+      pending_packets_queue_;
+
+  // Time period for which connection_ids should remain in time wait state.
+  const QuicTime::Delta time_wait_period_;
+
+  // Alarm to clean up connection_ids that have out lived their duration in
+  // time wait state.
+  std::unique_ptr<QuicAlarm> connection_id_clean_up_alarm_;
+
+  // Clock to efficiently measure approximate time.
+  const QuicClock* clock_;
+
+  // Interface that writes given buffer to the socket.
+  QuicPacketWriter* writer_;
+
+  // Interface that manages blocked writers.
+  Visitor* visitor_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
diff --git a/quiche/quic/core/quic_time_wait_list_manager_test.cc b/quiche/quic/core/quic_time_wait_list_manager_test.cc
new file mode 100644
index 0000000..ee59fac
--- /dev/null
+++ b/quiche/quic/core/quic_time_wait_list_manager_test.cc
@@ -0,0 +1,788 @@
+// Copyright 2013 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 "quiche/quic/core/quic_time_wait_list_manager.h"
+
+#include <cerrno>
+#include <memory>
+#include <ostream>
+#include <utility>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_time_wait_list_manager_peer.h"
+
+using testing::_;
+using testing::Args;
+using testing::Assign;
+using testing::DoAll;
+using testing::Matcher;
+using testing::NiceMock;
+using testing::Return;
+using testing::ReturnPointee;
+using testing::StrictMock;
+using testing::Truly;
+
+namespace quic {
+namespace test {
+namespace {
+
+const size_t kTestPacketSize = 100;
+
+class FramerVisitorCapturingPublicReset : public NoOpFramerVisitor {
+ public:
+  FramerVisitorCapturingPublicReset(QuicConnectionId connection_id)
+      : connection_id_(connection_id) {}
+  ~FramerVisitorCapturingPublicReset() override = default;
+
+  void OnPublicResetPacket(const QuicPublicResetPacket& public_reset) override {
+    public_reset_packet_ = public_reset;
+  }
+
+  const QuicPublicResetPacket public_reset_packet() {
+    return public_reset_packet_;
+  }
+
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const override {
+    return token == QuicUtils::GenerateStatelessResetToken(connection_id_);
+  }
+
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& packet) override {
+    stateless_reset_packet_ = packet;
+  }
+
+  const QuicIetfStatelessResetPacket stateless_reset_packet() {
+    return stateless_reset_packet_;
+  }
+
+ private:
+  QuicPublicResetPacket public_reset_packet_;
+  QuicIetfStatelessResetPacket stateless_reset_packet_;
+  QuicConnectionId connection_id_;
+};
+
+class MockAlarmFactory;
+class MockAlarm : public QuicAlarm {
+ public:
+  explicit MockAlarm(QuicArenaScopedPtr<Delegate> delegate,
+                     int alarm_index,
+                     MockAlarmFactory* factory)
+      : QuicAlarm(std::move(delegate)),
+        alarm_index_(alarm_index),
+        factory_(factory) {}
+  virtual ~MockAlarm() {}
+
+  void SetImpl() override;
+  void CancelImpl() override;
+
+ private:
+  int alarm_index_;
+  MockAlarmFactory* factory_;
+};
+
+class MockAlarmFactory : public QuicAlarmFactory {
+ public:
+  ~MockAlarmFactory() override {}
+
+  // Creates a new platform-specific alarm which will be configured to notify
+  // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
+  // Caller takes ownership of the new alarm, which will not yet be "set" to
+  // fire.
+  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
+    return new MockAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate),
+                         alarm_index_++, this);
+  }
+  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+      QuicConnectionArena* arena) override {
+    if (arena != nullptr) {
+      return arena->New<MockAlarm>(std::move(delegate), alarm_index_++, this);
+    }
+    return QuicArenaScopedPtr<MockAlarm>(
+        new MockAlarm(std::move(delegate), alarm_index_++, this));
+  }
+  MOCK_METHOD(void, OnAlarmSet, (int, QuicTime), ());
+  MOCK_METHOD(void, OnAlarmCancelled, (int), ());
+
+ private:
+  int alarm_index_ = 0;
+};
+
+void MockAlarm::SetImpl() {
+  factory_->OnAlarmSet(alarm_index_, deadline());
+}
+
+void MockAlarm::CancelImpl() {
+  factory_->OnAlarmCancelled(alarm_index_);
+}
+
+class QuicTimeWaitListManagerTest : public QuicTest {
+ protected:
+  QuicTimeWaitListManagerTest()
+      : time_wait_list_manager_(&writer_, &visitor_, &clock_, &alarm_factory_),
+        connection_id_(TestConnectionId(45)),
+        peer_address_(TestPeerIPAddress(), kTestPort),
+        writer_is_blocked_(false) {}
+
+  ~QuicTimeWaitListManagerTest() override = default;
+
+  void SetUp() override {
+    EXPECT_CALL(writer_, IsWriteBlocked())
+        .WillRepeatedly(ReturnPointee(&writer_is_blocked_));
+  }
+
+  void AddConnectionId(QuicConnectionId connection_id,
+                       QuicTimeWaitListManager::TimeWaitAction action) {
+    AddConnectionId(connection_id, QuicVersionMax(), action, nullptr);
+  }
+
+  void AddStatelessConnectionId(QuicConnectionId connection_id) {
+    std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+    termination_packets.push_back(std::unique_ptr<QuicEncryptedPacket>(
+        new QuicEncryptedPacket(nullptr, 0, false)));
+    time_wait_list_manager_.AddConnectionIdToTimeWait(
+        QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+        TimeWaitConnectionInfo(false, &termination_packets, {connection_id}));
+  }
+
+  void AddConnectionId(
+      QuicConnectionId connection_id,
+      ParsedQuicVersion version,
+      QuicTimeWaitListManager::TimeWaitAction action,
+      std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) {
+    time_wait_list_manager_.AddConnectionIdToTimeWait(
+        action, TimeWaitConnectionInfo(version.HasIetfInvariantHeader(),
+                                       packets, {connection_id}));
+  }
+
+  bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
+    return time_wait_list_manager_.IsConnectionIdInTimeWait(connection_id);
+  }
+
+  void ProcessPacket(QuicConnectionId connection_id) {
+    time_wait_list_manager_.ProcessPacket(
+        self_address_, peer_address_, connection_id, GOOGLE_QUIC_PACKET,
+        kTestPacketSize, std::make_unique<QuicPerPacketContext>());
+  }
+
+  QuicEncryptedPacket* ConstructEncryptedPacket(
+      QuicConnectionId destination_connection_id,
+      QuicConnectionId source_connection_id,
+      uint64_t packet_number) {
+    return quic::test::ConstructEncryptedPacket(destination_connection_id,
+                                                source_connection_id, false,
+                                                false, packet_number, "data");
+  }
+
+  MockClock clock_;
+  MockAlarmFactory alarm_factory_;
+  NiceMock<MockPacketWriter> writer_;
+  StrictMock<MockQuicSessionVisitor> visitor_;
+  QuicTimeWaitListManager time_wait_list_manager_;
+  QuicConnectionId connection_id_;
+  QuicSocketAddress self_address_;
+  QuicSocketAddress peer_address_;
+  bool writer_is_blocked_;
+};
+
+bool ValidPublicResetPacketPredicate(
+    QuicConnectionId expected_connection_id,
+    const std::tuple<const char*, int>& packet_buffer) {
+  FramerVisitorCapturingPublicReset visitor(expected_connection_id);
+  QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(),
+                    Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+  framer.set_visitor(&visitor);
+  QuicEncryptedPacket encrypted(std::get<0>(packet_buffer),
+                                std::get<1>(packet_buffer));
+  framer.ProcessPacket(encrypted);
+  QuicPublicResetPacket packet = visitor.public_reset_packet();
+  bool public_reset_is_valid =
+      expected_connection_id == packet.connection_id &&
+      TestPeerIPAddress() == packet.client_address.host() &&
+      kTestPort == packet.client_address.port();
+
+  QuicIetfStatelessResetPacket stateless_reset =
+      visitor.stateless_reset_packet();
+
+  StatelessResetToken expected_stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(expected_connection_id);
+
+  bool stateless_reset_is_valid =
+      stateless_reset.stateless_reset_token == expected_stateless_reset_token;
+
+  return public_reset_is_valid || stateless_reset_is_valid;
+}
+
+Matcher<const std::tuple<const char*, int>> PublicResetPacketEq(
+    QuicConnectionId connection_id) {
+  return Truly(
+      [connection_id](const std::tuple<const char*, int> packet_buffer) {
+        return ValidPublicResetPacketPredicate(connection_id, packet_buffer);
+      });
+}
+
+TEST_F(QuicTimeWaitListManagerTest, CheckConnectionIdInTimeWait) {
+  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
+}
+
+TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
+  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddStatelessConnectionId(connection_id_);
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) {
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
+          /*use_length_prefix=*/false, AllSupportedVersions()));
+  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
+                                   peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  time_wait_list_manager_.SendVersionNegotiationPacket(
+      connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
+      /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
+      peer_address_, std::make_unique<QuicPerPacketContext>());
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       SendIetfVersionNegotiationPacketWithoutLengthPrefix) {
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
+          /*use_length_prefix=*/false, AllSupportedVersions()));
+  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
+                                   peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  time_wait_list_manager_.SendVersionNegotiationPacket(
+      connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
+      /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
+      peer_address_, std::make_unique<QuicPerPacketContext>());
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendIetfVersionNegotiationPacket) {
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
+          /*use_length_prefix=*/true, AllSupportedVersions()));
+  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
+                                   peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  time_wait_list_manager_.SendVersionNegotiationPacket(
+      connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
+      /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
+      peer_address_, std::make_unique<QuicPerPacketContext>());
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       SendIetfVersionNegotiationPacketWithClientConnectionId) {
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
+          /*use_length_prefix=*/true, AllSupportedVersions()));
+  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
+                                   peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  time_wait_list_manager_.SendVersionNegotiationPacket(
+      connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
+      /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
+      peer_address_, std::make_unique<QuicPerPacketContext>());
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) {
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  AddConnectionId(connection_id_, QuicVersionMax(),
+                  QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+                  &termination_packets);
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  ProcessPacket(connection_id_);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendTwoConnectionCloses) {
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  AddConnectionId(connection_id_, QuicVersionMax(),
+                  QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+                  &termination_packets);
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .Times(2)
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  ProcessPacket(connection_id_);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) {
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddConnectionId(connection_id_,
+                  QuicTimeWaitListManager::SEND_STATELESS_RESET);
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+  ProcessPacket(connection_id_);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) {
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddConnectionId(connection_id_,
+                  QuicTimeWaitListManager::SEND_STATELESS_RESET);
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+  for (int packet_number = 1; packet_number < 101; ++packet_number) {
+    if ((packet_number & (packet_number - 1)) == 0) {
+      EXPECT_CALL(writer_, WritePacket(_, _, _, _, _))
+          .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+    }
+    ProcessPacket(connection_id_);
+    // Send public reset with exponential back off.
+    if ((packet_number & (packet_number - 1)) == 0) {
+      EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
+          &time_wait_list_manager_, packet_number));
+    } else {
+      EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
+          &time_wait_list_manager_, packet_number));
+    }
+  }
+}
+
+TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) {
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddStatelessConnectionId(connection_id_);
+
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  ProcessPacket(connection_id_);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) {
+  const size_t kConnectionIdCount = 100;
+  const size_t kOldConnectionIdCount = 31;
+
+  // Add connection_ids such that their expiry time is time_wait_period_.
+  for (uint64_t conn_id = 1; conn_id <= kOldConnectionIdCount; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
+    AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
+  }
+  EXPECT_EQ(kOldConnectionIdCount, time_wait_list_manager_.num_connections());
+
+  // Add remaining connection_ids such that their add time is
+  // 2 * time_wait_period_.
+  const QuicTime::Delta time_wait_period =
+      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
+  clock_.AdvanceTime(time_wait_period);
+  for (uint64_t conn_id = kOldConnectionIdCount + 1;
+       conn_id <= kConnectionIdCount; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
+    AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
+  }
+  EXPECT_EQ(kConnectionIdCount, time_wait_list_manager_.num_connections());
+
+  QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
+  // Now set the current time as time_wait_period + offset usecs.
+  clock_.AdvanceTime(offset);
+  // After all the old connection_ids are cleaned up, check the next alarm
+  // interval.
+  QuicTime next_alarm_time = clock_.Now() + time_wait_period - offset;
+  EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
+
+  time_wait_list_manager_.CleanUpOldConnectionIds();
+  for (uint64_t conn_id = 1; conn_id <= kConnectionIdCount; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EXPECT_EQ(conn_id > kOldConnectionIdCount,
+              IsConnectionIdInTimeWait(connection_id))
+        << "kOldConnectionIdCount: " << kOldConnectionIdCount
+        << " connection_id: " << connection_id;
+  }
+  EXPECT_EQ(kConnectionIdCount - kOldConnectionIdCount,
+            time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       CleanUpOldConnectionIdsForMultipleConnectionIdsPerConnection) {
+  connection_id_ = TestConnectionId(7);
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+
+  // Add a CONNECTION_CLOSE termination packet.
+  std::vector<QuicConnectionId> active_connection_ids{connection_id_,
+                                                      TestConnectionId(8)};
+  time_wait_list_manager_.AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
+                             active_connection_ids, QuicTime::Delta::Zero()));
+
+  EXPECT_TRUE(
+      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
+  EXPECT_TRUE(
+      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
+
+  // Remove these IDs.
+  const QuicTime::Delta time_wait_period =
+      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
+  clock_.AdvanceTime(time_wait_period);
+  time_wait_list_manager_.CleanUpOldConnectionIds();
+
+  EXPECT_FALSE(
+      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
+  EXPECT_FALSE(
+      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
+  AddConnectionId(connection_id, QuicTimeWaitListManager::SEND_STATELESS_RESET);
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      connection_id, EmptyQuicConnectionId(), /*packet_number=*/234));
+  // Let first write through.
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
+  ProcessPacket(connection_id);
+
+  // write block for the next packet.
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
+      .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
+                      Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
+  EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
+  ProcessPacket(connection_id);
+  // 3rd packet. No public reset should be sent;
+  ProcessPacket(connection_id);
+
+  // write packet should not be called since we are write blocked but the
+  // should be queued.
+  QuicConnectionId other_connection_id = TestConnectionId(2);
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id));
+  AddConnectionId(other_connection_id,
+                  QuicTimeWaitListManager::SEND_STATELESS_RESET);
+  std::unique_ptr<QuicEncryptedPacket> other_packet(ConstructEncryptedPacket(
+      other_connection_id, EmptyQuicConnectionId(), /*packet_number=*/23423));
+  EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
+  ProcessPacket(other_connection_id);
+  EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
+
+  // Now expect all the write blocked public reset packets to be sent again.
+  writer_is_blocked_ = false;
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(other_connection_id)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
+  time_wait_list_manager_.OnBlockedWriterCanWrite();
+}
+
+TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) {
+  // Add connection_ids such that their expiry time is time_wait_period_.
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
+  const size_t kConnectionCloseLength = 100;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  AddConnectionId(connection_id_, QuicVersionMax(),
+                  QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+                  &termination_packets);
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  ProcessPacket(connection_id_);
+
+  const QuicTime::Delta time_wait_period =
+      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
+
+  QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
+  clock_.AdvanceTime(offset + time_wait_period);
+  // Now set the current time as time_wait_period + offset usecs.
+  QuicTime next_alarm_time = clock_.Now() + time_wait_period;
+  EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
+
+  time_wait_list_manager_.CleanUpOldConnectionIds();
+  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest, ConnectionIdsOrderedByTime) {
+  // Simple randomization: the values of connection_ids are randomly swapped.
+  // If the container is broken, the test will be 50% flaky.
+  const uint64_t conn_id1 = QuicRandom::GetInstance()->RandUint64() % 2;
+  const QuicConnectionId connection_id1 = TestConnectionId(conn_id1);
+  const QuicConnectionId connection_id2 = TestConnectionId(1 - conn_id1);
+
+  // 1 will hash lower than 2, but we add it later. They should come out in the
+  // add order, not hash order.
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id1));
+  AddConnectionId(connection_id1, QuicTimeWaitListManager::DO_NOTHING);
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(10));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id2));
+  AddConnectionId(connection_id2, QuicTimeWaitListManager::DO_NOTHING);
+  EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
+
+  const QuicTime::Delta time_wait_period =
+      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
+  clock_.AdvanceTime(time_wait_period - QuicTime::Delta::FromMicroseconds(9));
+
+  EXPECT_CALL(alarm_factory_, OnAlarmSet(_, _));
+
+  time_wait_list_manager_.CleanUpOldConnectionIds();
+  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id1));
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id2));
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest, MaxConnectionsTest) {
+  // Basically, shut off time-based eviction.
+  SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000000000);
+  SetQuicFlag(FLAGS_quic_time_wait_list_max_connections, 5);
+
+  uint64_t current_conn_id = 0;
+  const int64_t kMaxConnections =
+      GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
+  // Add exactly the maximum number of connections
+  for (int64_t i = 0; i < kMaxConnections; ++i) {
+    ++current_conn_id;
+    QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
+    EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
+    EXPECT_CALL(visitor_,
+                OnConnectionAddedToTimeWaitList(current_connection_id));
+    AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
+    EXPECT_EQ(current_conn_id, time_wait_list_manager_.num_connections());
+    EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
+  }
+
+  // Now keep adding.  Since we're already at the max, every new connection-id
+  // will evict the oldest one.
+  for (int64_t i = 0; i < kMaxConnections; ++i) {
+    ++current_conn_id;
+    QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
+    const QuicConnectionId id_to_evict =
+        TestConnectionId(current_conn_id - kMaxConnections);
+    EXPECT_TRUE(IsConnectionIdInTimeWait(id_to_evict));
+    EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
+    EXPECT_CALL(visitor_,
+                OnConnectionAddedToTimeWaitList(current_connection_id));
+    AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
+    EXPECT_EQ(static_cast<size_t>(kMaxConnections),
+              time_wait_list_manager_.num_connections());
+    EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict));
+    EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
+  }
+}
+
+TEST_F(QuicTimeWaitListManagerTest, ZeroMaxConnections) {
+  // Basically, shut off time-based eviction.
+  SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000000000);
+  // Keep time wait list empty.
+  SetQuicFlag(FLAGS_quic_time_wait_list_max_connections, 0);
+
+  uint64_t current_conn_id = 0;
+  // Add exactly the maximum number of connections
+  for (int64_t i = 0; i < 10; ++i) {
+    ++current_conn_id;
+    QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
+    EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
+    EXPECT_CALL(visitor_,
+                OnConnectionAddedToTimeWaitList(current_connection_id));
+    AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
+    // Verify time wait list always has 1 connection.
+    EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+    EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
+  }
+}
+
+// Regression test for b/116200989.
+TEST_F(QuicTimeWaitListManagerTest,
+       SendStatelessResetInResponseToShortHeaders) {
+  // This test mimics a scenario where an ENCRYPTION_INITIAL connection close is
+  // added as termination packet for an IETF connection ID. However, a short
+  // header packet is received later.
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  time_wait_list_manager_.AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
+                             {connection_id_}));
+
+  // Termination packet is not encrypted, instead, send stateless reset.
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  // Processes IETF short header packet.
+  time_wait_list_manager_.ProcessPacket(
+      self_address_, peer_address_, connection_id_,
+      IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
+      std::make_unique<QuicPerPacketContext>());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       SendConnectionClosePacketsInResponseToShortHeaders) {
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  // Add a CONNECTION_CLOSE termination packet.
+  time_wait_list_manager_.AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
+                             {connection_id_}));
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  // Processes IETF short header packet.
+  time_wait_list_manager_.ProcessPacket(
+      self_address_, peer_address_, connection_id_,
+      IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
+      std::make_unique<QuicPerPacketContext>());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       SendConnectionClosePacketsForMultipleConnectionIds) {
+  connection_id_ = TestConnectionId(7);
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+
+  // Add a CONNECTION_CLOSE termination packet.
+  std::vector<QuicConnectionId> active_connection_ids{connection_id_,
+                                                      TestConnectionId(8)};
+  time_wait_list_manager_.AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
+                             active_connection_ids, QuicTime::Delta::Zero()));
+
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .Times(2)
+      .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 1)));
+  // Processes IETF short header packet.
+  for (auto const& cid : active_connection_ids) {
+    time_wait_list_manager_.ProcessPacket(
+        self_address_, peer_address_, cid, IETF_QUIC_SHORT_HEADER_PACKET,
+        kTestPacketSize, std::make_unique<QuicPerPacketContext>());
+  }
+}
+
+// Regression test for b/184053898.
+TEST_F(QuicTimeWaitListManagerTest, DonotCrashOnNullStatelessReset) {
+  // Received a packet with length <
+  // QuicFramer::GetMinStatelessResetPacketLength(), and this will result in a
+  // null stateless reset.
+  time_wait_list_manager_.SendPublicReset(
+      self_address_, peer_address_, TestConnectionId(1),
+      /*ietf_quic=*/true,
+      /*received_packet_length=*/
+      QuicFramer::GetMinStatelessResetPacketLength() - 1,
+      /*packet_context=*/nullptr);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendOrQueueNullPacket) {
+  QuicTimeWaitListManagerPeer::SendOrQueuePacket(&time_wait_list_manager_,
+                                                 nullptr, nullptr);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, TooManyPendingPackets) {
+  SetQuicFlag(FLAGS_quic_time_wait_list_max_pending_packets, 5);
+  const size_t kNumOfUnProcessablePackets = 2048;
+  EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_))
+      .Times(testing::AnyNumber());
+  // Write block for the next packets.
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(TestConnectionId(1))))
+      .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
+                      Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
+  for (size_t i = 0; i < kNumOfUnProcessablePackets; ++i) {
+    time_wait_list_manager_.SendPublicReset(
+        self_address_, peer_address_, TestConnectionId(1),
+        /*ietf_quic=*/true,
+        /*received_packet_length=*/
+        QuicFramer::GetMinStatelessResetPacketLength() + 1,
+        /*packet_context=*/nullptr);
+  }
+  // Verify pending packet queue size is limited.
+  EXPECT_EQ(5u, QuicTimeWaitListManagerPeer::PendingPacketsQueueSize(
+                    &time_wait_list_manager_));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_trace_visitor.cc b/quiche/quic/core/quic_trace_visitor.cc
new file mode 100644
index 0000000..d7dd18b
--- /dev/null
+++ b/quiche/quic/core/quic_trace_visitor.cc
@@ -0,0 +1,348 @@
+// Copyright (c) 2018 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 "quiche/quic/core/quic_trace_visitor.h"
+
+#include <string>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+quic_trace::EncryptionLevel EncryptionLevelToProto(EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      return quic_trace::ENCRYPTION_INITIAL;
+    case ENCRYPTION_HANDSHAKE:
+      return quic_trace::ENCRYPTION_HANDSHAKE;
+    case ENCRYPTION_ZERO_RTT:
+      return quic_trace::ENCRYPTION_0RTT;
+    case ENCRYPTION_FORWARD_SECURE:
+      return quic_trace::ENCRYPTION_1RTT;
+    case NUM_ENCRYPTION_LEVELS:
+      QUIC_BUG(quic_bug_10284_1) << "Invalid encryption level specified";
+      return quic_trace::ENCRYPTION_UNKNOWN;
+  }
+}
+
+QuicTraceVisitor::QuicTraceVisitor(const QuicConnection* connection)
+    : connection_(connection),
+      start_time_(connection_->clock()->ApproximateNow()) {
+  std::string binary_connection_id(connection->connection_id().data(),
+                                   connection->connection_id().length());
+  // We assume that the connection ID in gQUIC is equivalent to the
+  // server-chosen client-selected ID.
+  switch (connection->perspective()) {
+    case Perspective::IS_CLIENT:
+      trace_.set_destination_connection_id(binary_connection_id);
+      break;
+    case Perspective::IS_SERVER:
+      trace_.set_source_connection_id(binary_connection_id);
+      break;
+  }
+}
+
+void QuicTraceVisitor::OnPacketSent(
+    QuicPacketNumber packet_number,
+    QuicPacketLength packet_length,
+    bool /*has_crypto_handshake*/,
+    TransmissionType /*transmission_type*/,
+    EncryptionLevel encryption_level,
+    const QuicFrames& retransmittable_frames,
+    const QuicFrames& /*nonretransmittable_frames*/,
+    QuicTime sent_time) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_event_type(quic_trace::PACKET_SENT);
+  event->set_time_us(ConvertTimestampToRecordedFormat(sent_time));
+  event->set_packet_number(packet_number.ToUint64());
+  event->set_packet_size(packet_length);
+  event->set_encryption_level(EncryptionLevelToProto(encryption_level));
+
+  for (const QuicFrame& frame : retransmittable_frames) {
+    switch (frame.type) {
+      case STREAM_FRAME:
+      case RST_STREAM_FRAME:
+      case CONNECTION_CLOSE_FRAME:
+      case WINDOW_UPDATE_FRAME:
+      case BLOCKED_FRAME:
+      case PING_FRAME:
+      case HANDSHAKE_DONE_FRAME:
+      case ACK_FREQUENCY_FRAME:
+        PopulateFrameInfo(frame, event->add_frames());
+        break;
+
+      case PADDING_FRAME:
+      case MTU_DISCOVERY_FRAME:
+      case STOP_WAITING_FRAME:
+      case ACK_FRAME:
+        QUIC_BUG(quic_bug_12732_1)
+            << "Frames of type are not retransmittable and are not supposed "
+               "to be in retransmittable_frames";
+        break;
+
+      // New IETF frames, not used in current gQUIC version.
+      case NEW_CONNECTION_ID_FRAME:
+      case RETIRE_CONNECTION_ID_FRAME:
+      case MAX_STREAMS_FRAME:
+      case STREAMS_BLOCKED_FRAME:
+      case PATH_RESPONSE_FRAME:
+      case PATH_CHALLENGE_FRAME:
+      case STOP_SENDING_FRAME:
+      case MESSAGE_FRAME:
+      case CRYPTO_FRAME:
+      case NEW_TOKEN_FRAME:
+        break;
+
+      // Ignore gQUIC-specific frames.
+      case GOAWAY_FRAME:
+        break;
+
+      case NUM_FRAME_TYPES:
+        QUIC_BUG(quic_bug_10284_2) << "Unknown frame type encountered";
+        break;
+    }
+  }
+
+  // Output PCC DebugState on packet sent for analysis.
+  if (connection_->sent_packet_manager()
+          .GetSendAlgorithm()
+          ->GetCongestionControlType() == kPCC) {
+    PopulateTransportState(event->mutable_transport_state());
+  }
+}
+
+void QuicTraceVisitor::PopulateFrameInfo(const QuicFrame& frame,
+                                         quic_trace::Frame* frame_record) {
+  switch (frame.type) {
+    case STREAM_FRAME: {
+      frame_record->set_frame_type(quic_trace::STREAM);
+
+      quic_trace::StreamFrameInfo* info =
+          frame_record->mutable_stream_frame_info();
+      info->set_stream_id(frame.stream_frame.stream_id);
+      info->set_fin(frame.stream_frame.fin);
+      info->set_offset(frame.stream_frame.offset);
+      info->set_length(frame.stream_frame.data_length);
+      break;
+    }
+
+    case ACK_FRAME: {
+      frame_record->set_frame_type(quic_trace::ACK);
+
+      quic_trace::AckInfo* info = frame_record->mutable_ack_info();
+      info->set_ack_delay_us(frame.ack_frame->ack_delay_time.ToMicroseconds());
+      for (const auto& interval : frame.ack_frame->packets) {
+        quic_trace::AckBlock* block = info->add_acked_packets();
+        // We record intervals as [a, b], whereas the in-memory representation
+        // we currently use is [a, b).
+        block->set_first_packet(interval.min().ToUint64());
+        block->set_last_packet(interval.max().ToUint64() - 1);
+      }
+      break;
+    }
+
+    case RST_STREAM_FRAME: {
+      frame_record->set_frame_type(quic_trace::RESET_STREAM);
+
+      quic_trace::ResetStreamInfo* info =
+          frame_record->mutable_reset_stream_info();
+      info->set_stream_id(frame.rst_stream_frame->stream_id);
+      info->set_final_offset(frame.rst_stream_frame->byte_offset);
+      info->set_application_error_code(frame.rst_stream_frame->error_code);
+      break;
+    }
+
+    case CONNECTION_CLOSE_FRAME: {
+      frame_record->set_frame_type(quic_trace::CONNECTION_CLOSE);
+
+      quic_trace::CloseInfo* info = frame_record->mutable_close_info();
+      info->set_error_code(frame.connection_close_frame->quic_error_code);
+      info->set_reason_phrase(frame.connection_close_frame->error_details);
+      info->set_close_type(static_cast<quic_trace::CloseType>(
+          frame.connection_close_frame->close_type));
+      info->set_transport_close_frame_type(
+          frame.connection_close_frame->transport_close_frame_type);
+      break;
+    }
+
+    case GOAWAY_FRAME:
+      // Do not bother logging this since the frame in question is
+      // gQUIC-specific.
+      break;
+
+    case WINDOW_UPDATE_FRAME: {
+      bool is_connection = frame.window_update_frame.stream_id == 0;
+      frame_record->set_frame_type(is_connection ? quic_trace::MAX_DATA
+                                                 : quic_trace::MAX_STREAM_DATA);
+
+      quic_trace::FlowControlInfo* info =
+          frame_record->mutable_flow_control_info();
+      info->set_max_data(frame.window_update_frame.max_data);
+      if (!is_connection) {
+        info->set_stream_id(frame.window_update_frame.stream_id);
+      }
+      break;
+    }
+
+    case BLOCKED_FRAME: {
+      bool is_connection = frame.blocked_frame.stream_id == 0;
+      frame_record->set_frame_type(is_connection ? quic_trace::BLOCKED
+                                                 : quic_trace::STREAM_BLOCKED);
+
+      quic_trace::FlowControlInfo* info =
+          frame_record->mutable_flow_control_info();
+      if (!is_connection) {
+        info->set_stream_id(frame.window_update_frame.stream_id);
+      }
+      break;
+    }
+
+    case PING_FRAME:
+    case MTU_DISCOVERY_FRAME:
+    case HANDSHAKE_DONE_FRAME:
+      frame_record->set_frame_type(quic_trace::PING);
+      break;
+
+    case PADDING_FRAME:
+      frame_record->set_frame_type(quic_trace::PADDING);
+      break;
+
+    case STOP_WAITING_FRAME:
+      // We're going to pretend those do not exist.
+      break;
+
+    // New IETF frames, not used in current gQUIC version.
+    case NEW_CONNECTION_ID_FRAME:
+    case RETIRE_CONNECTION_ID_FRAME:
+    case MAX_STREAMS_FRAME:
+    case STREAMS_BLOCKED_FRAME:
+    case PATH_RESPONSE_FRAME:
+    case PATH_CHALLENGE_FRAME:
+    case STOP_SENDING_FRAME:
+    case MESSAGE_FRAME:
+    case CRYPTO_FRAME:
+    case NEW_TOKEN_FRAME:
+    case ACK_FREQUENCY_FRAME:
+      break;
+
+    case NUM_FRAME_TYPES:
+      QUIC_BUG(quic_bug_10284_3) << "Unknown frame type encountered";
+      break;
+  }
+}
+
+void QuicTraceVisitor::OnIncomingAck(
+    QuicPacketNumber /*ack_packet_number*/,
+    EncryptionLevel ack_decrypted_level,
+    const QuicAckFrame& ack_frame,
+    QuicTime ack_receive_time,
+    QuicPacketNumber /*largest_observed*/,
+    bool /*rtt_updated*/,
+    QuicPacketNumber /*least_unacked_sent_packet*/) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(ConvertTimestampToRecordedFormat(ack_receive_time));
+  event->set_packet_number(connection_->GetLargestReceivedPacket().ToUint64());
+  event->set_event_type(quic_trace::PACKET_RECEIVED);
+  event->set_encryption_level(EncryptionLevelToProto(ack_decrypted_level));
+
+  // TODO(vasilvv): consider removing this copy.
+  QuicAckFrame copy_of_ack = ack_frame;
+  PopulateFrameInfo(QuicFrame(&copy_of_ack), event->add_frames());
+  PopulateTransportState(event->mutable_transport_state());
+}
+
+void QuicTraceVisitor::OnPacketLoss(QuicPacketNumber lost_packet_number,
+                                    EncryptionLevel encryption_level,
+                                    TransmissionType /*transmission_type*/,
+                                    QuicTime detection_time) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(ConvertTimestampToRecordedFormat(detection_time));
+  event->set_event_type(quic_trace::PACKET_LOST);
+  event->set_packet_number(lost_packet_number.ToUint64());
+  PopulateTransportState(event->mutable_transport_state());
+  event->set_encryption_level(EncryptionLevelToProto(encryption_level));
+}
+
+void QuicTraceVisitor::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
+                                           const QuicTime& receive_time) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(ConvertTimestampToRecordedFormat(receive_time));
+  event->set_event_type(quic_trace::PACKET_RECEIVED);
+  event->set_packet_number(connection_->GetLargestReceivedPacket().ToUint64());
+
+  PopulateFrameInfo(QuicFrame(frame), event->add_frames());
+}
+
+void QuicTraceVisitor::OnSuccessfulVersionNegotiation(
+    const ParsedQuicVersion& version) {
+  uint32_t tag =
+      quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version));
+  std::string binary_tag(reinterpret_cast<const char*>(&tag), sizeof(tag));
+  trace_.set_protocol_version(binary_tag);
+}
+
+void QuicTraceVisitor::OnApplicationLimited() {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(
+      ConvertTimestampToRecordedFormat(connection_->clock()->ApproximateNow()));
+  event->set_event_type(quic_trace::APPLICATION_LIMITED);
+}
+
+void QuicTraceVisitor::OnAdjustNetworkParameters(QuicBandwidth bandwidth,
+                                                 QuicTime::Delta rtt,
+                                                 QuicByteCount /*old_cwnd*/,
+                                                 QuicByteCount /*new_cwnd*/) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(
+      ConvertTimestampToRecordedFormat(connection_->clock()->ApproximateNow()));
+  event->set_event_type(quic_trace::EXTERNAL_PARAMETERS);
+
+  quic_trace::ExternalNetworkParameters* parameters =
+      event->mutable_external_network_parameters();
+  if (!bandwidth.IsZero()) {
+    parameters->set_bandwidth_bps(bandwidth.ToBitsPerSecond());
+  }
+  if (!rtt.IsZero()) {
+    parameters->set_rtt_us(rtt.ToMicroseconds());
+  }
+}
+
+uint64_t QuicTraceVisitor::ConvertTimestampToRecordedFormat(
+    QuicTime timestamp) {
+  if (timestamp < start_time_) {
+    QUIC_BUG(quic_bug_10284_4)
+        << "Timestamp went back in time while recording a trace";
+    return 0;
+  }
+
+  return (timestamp - start_time_).ToMicroseconds();
+}
+
+void QuicTraceVisitor::PopulateTransportState(
+    quic_trace::TransportState* state) {
+  const RttStats* rtt_stats = connection_->sent_packet_manager().GetRttStats();
+  state->set_min_rtt_us(rtt_stats->min_rtt().ToMicroseconds());
+  state->set_smoothed_rtt_us(rtt_stats->smoothed_rtt().ToMicroseconds());
+  state->set_last_rtt_us(rtt_stats->latest_rtt().ToMicroseconds());
+
+  state->set_cwnd_bytes(
+      connection_->sent_packet_manager().GetCongestionWindowInBytes());
+  QuicByteCount in_flight =
+      connection_->sent_packet_manager().GetBytesInFlight();
+  state->set_in_flight_bytes(in_flight);
+  state->set_pacing_rate_bps(connection_->sent_packet_manager()
+                                 .GetSendAlgorithm()
+                                 ->PacingRate(in_flight)
+                                 .ToBitsPerSecond());
+
+  if (connection_->sent_packet_manager()
+          .GetSendAlgorithm()
+          ->GetCongestionControlType() == kPCC) {
+    state->set_congestion_control_state(
+        connection_->sent_packet_manager().GetSendAlgorithm()->GetDebugState());
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_trace_visitor.h b/quiche/quic/core/quic_trace_visitor.h
new file mode 100644
index 0000000..ee76fff
--- /dev/null
+++ b/quiche/quic/core/quic_trace_visitor.h
@@ -0,0 +1,79 @@
+// Copyright (c) 2018 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_TRACE_VISITOR_H_
+#define QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
+
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_types.h"
+#include "third_party/quic_trace/lib/quic_trace.pb.h"
+
+namespace quic {
+
+// Records a QUIC trace protocol buffer for a QuicConnection.  It's the
+// responsibility of the user of this visitor to process or store the resulting
+// trace, which can be accessed via trace().
+class QUIC_NO_EXPORT QuicTraceVisitor : public QuicConnectionDebugVisitor {
+ public:
+  explicit QuicTraceVisitor(const QuicConnection* connection);
+
+  void OnPacketSent(QuicPacketNumber packet_number,
+                    QuicPacketLength packet_length,
+                    bool has_crypto_handshake,
+                    TransmissionType transmission_type,
+                    EncryptionLevel encryption_level,
+                    const QuicFrames& retransmittable_frames,
+                    const QuicFrames& nonretransmittable_frames,
+                    QuicTime sent_time) override;
+
+  void OnIncomingAck(QuicPacketNumber ack_packet_number,
+                     EncryptionLevel ack_decrypted_level,
+                     const QuicAckFrame& ack_frame,
+                     QuicTime ack_receive_time,
+                     QuicPacketNumber largest_observed,
+                     bool rtt_updated,
+                     QuicPacketNumber least_unacked_sent_packet) override;
+
+  void OnPacketLoss(QuicPacketNumber lost_packet_number,
+                    EncryptionLevel encryption_level,
+                    TransmissionType transmission_type,
+                    QuicTime detection_time) override;
+
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
+                           const QuicTime& receive_time) override;
+
+  void OnSuccessfulVersionNegotiation(
+      const ParsedQuicVersion& version) override;
+
+  void OnApplicationLimited() override;
+
+  void OnAdjustNetworkParameters(QuicBandwidth bandwidth,
+                                 QuicTime::Delta rtt,
+                                 QuicByteCount old_cwnd,
+                                 QuicByteCount new_cwnd) override;
+
+  // Returns a mutable pointer to the trace.  The trace is owned by the
+  // visitor, but can be moved using Swap() method after the connection is
+  // finished.
+  quic_trace::Trace* trace() { return &trace_; }
+
+ private:
+  // Converts QuicTime into a microsecond delta w.r.t. the beginning of the
+  // connection.
+  uint64_t ConvertTimestampToRecordedFormat(QuicTime timestamp);
+  // Populates a quic_trace::Frame message from |frame|.
+  void PopulateFrameInfo(const QuicFrame& frame,
+                         quic_trace::Frame* frame_record);
+  // Populates a quic_trace::TransportState message from the associated
+  // connection.
+  void PopulateTransportState(quic_trace::TransportState* state);
+
+  quic_trace::Trace trace_;
+  const QuicConnection* connection_;
+  const QuicTime start_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
diff --git a/quiche/quic/core/quic_trace_visitor_test.cc b/quiche/quic/core/quic_trace_visitor_test.cc
new file mode 100644
index 0000000..9e255b9
--- /dev/null
+++ b/quiche/quic/core/quic_trace_visitor_test.cc
@@ -0,0 +1,184 @@
+// Copyright (c) 2018 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 "quiche/quic/core/quic_trace_visitor.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+
+namespace quic {
+namespace {
+
+const QuicByteCount kTransferSize = 1000 * kMaxOutgoingPacketSize;
+const QuicByteCount kTestStreamNumber = 3;
+const QuicTime::Delta kDelay = QuicTime::Delta::FromMilliseconds(20);
+
+// The trace for this test is generated using a simulator transfer.
+class QuicTraceVisitorTest : public QuicTest {
+ public:
+  QuicTraceVisitorTest() {
+    QuicConnectionId connection_id = test::TestConnectionId();
+    simulator::Simulator simulator;
+    simulator::QuicEndpoint client(&simulator, "Client", "Server",
+                                   Perspective::IS_CLIENT, connection_id);
+    simulator::QuicEndpoint server(&simulator, "Server", "Client",
+                                   Perspective::IS_SERVER, connection_id);
+
+    const QuicBandwidth kBandwidth = QuicBandwidth::FromKBitsPerSecond(1000);
+    const QuicByteCount kBdp = kBandwidth * (2 * kDelay);
+
+    // Create parameters such that some loss is observed.
+    simulator::Switch network_switch(&simulator, "Switch", 8, 0.5 * kBdp);
+    simulator::SymmetricLink client_link(&client, network_switch.port(1),
+                                         2 * kBandwidth, kDelay);
+    simulator::SymmetricLink server_link(&server, network_switch.port(2),
+                                         kBandwidth, kDelay);
+
+    QuicTraceVisitor visitor(client.connection());
+    client.connection()->set_debug_visitor(&visitor);
+
+    // Transfer about a megabyte worth of data from client to server.
+    const QuicTime::Delta kDeadline =
+        3 * kBandwidth.TransferTime(kTransferSize);
+    client.AddBytesToTransfer(kTransferSize);
+    bool simulator_result = simulator.RunUntilOrTimeout(
+        [&]() { return server.bytes_received() >= kTransferSize; }, kDeadline);
+    QUICHE_CHECK(simulator_result);
+
+    // Save the trace and ensure some loss was observed.
+    trace_.Swap(visitor.trace());
+    QUICHE_CHECK_NE(0u, client.connection()->GetStats().packets_retransmitted);
+    packets_sent_ = client.connection()->GetStats().packets_sent;
+  }
+
+  std::vector<quic_trace::Event> AllEventsWithType(
+      quic_trace::EventType event_type) {
+    std::vector<quic_trace::Event> result;
+    for (const auto& event : trace_.events()) {
+      if (event.event_type() == event_type) {
+        result.push_back(event);
+      }
+    }
+    return result;
+  }
+
+ protected:
+  quic_trace::Trace trace_;
+  QuicPacketCount packets_sent_;
+};
+
+TEST_F(QuicTraceVisitorTest, ConnectionId) {
+  char expected_cid[] = {0, 0, 0, 0, 0, 0, 0, 42};
+  EXPECT_EQ(std::string(expected_cid, sizeof(expected_cid)),
+            trace_.destination_connection_id());
+}
+
+TEST_F(QuicTraceVisitorTest, Version) {
+  std::string version = trace_.protocol_version();
+  ASSERT_EQ(4u, version.size());
+  // Ensure version isn't all-zeroes.
+  EXPECT_TRUE(version[0] != 0 || version[1] != 0 || version[2] != 0 ||
+              version[3] != 0);
+}
+
+// Check that basic metadata about sent packets is recorded.
+TEST_F(QuicTraceVisitorTest, SentPacket) {
+  auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
+  EXPECT_EQ(packets_sent_, sent_packets.size());
+  ASSERT_GT(sent_packets.size(), 0u);
+
+  EXPECT_EQ(sent_packets[0].packet_size(), kDefaultMaxPacketSize);
+  EXPECT_EQ(sent_packets[0].packet_number(), 1u);
+}
+
+// Ensure that every stream frame that was sent is recorded.
+TEST_F(QuicTraceVisitorTest, SentStream) {
+  auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
+
+  QuicIntervalSet<QuicStreamOffset> offsets;
+  for (const quic_trace::Event& packet : sent_packets) {
+    for (const quic_trace::Frame& frame : packet.frames()) {
+      if (frame.frame_type() != quic_trace::STREAM) {
+        continue;
+      }
+
+      const quic_trace::StreamFrameInfo& info = frame.stream_frame_info();
+      if (info.stream_id() != kTestStreamNumber) {
+        continue;
+      }
+
+      ASSERT_GT(info.length(), 0u);
+      offsets.Add(info.offset(), info.offset() + info.length());
+    }
+  }
+
+  ASSERT_EQ(1u, offsets.Size());
+  EXPECT_EQ(0u, offsets.begin()->min());
+  EXPECT_EQ(kTransferSize, offsets.rbegin()->max());
+}
+
+// Ensure that all packets are either acknowledged or lost.
+TEST_F(QuicTraceVisitorTest, AckPackets) {
+  QuicIntervalSet<QuicPacketNumber> packets;
+  for (const quic_trace::Event& packet : trace_.events()) {
+    if (packet.event_type() == quic_trace::PACKET_RECEIVED) {
+      for (const quic_trace::Frame& frame : packet.frames()) {
+        if (frame.frame_type() != quic_trace::ACK) {
+          continue;
+        }
+
+        const quic_trace::AckInfo& info = frame.ack_info();
+        for (const auto& block : info.acked_packets()) {
+          packets.Add(QuicPacketNumber(block.first_packet()),
+                      QuicPacketNumber(block.last_packet()) + 1);
+        }
+      }
+    }
+    if (packet.event_type() == quic_trace::PACKET_LOST) {
+      packets.Add(QuicPacketNumber(packet.packet_number()),
+                  QuicPacketNumber(packet.packet_number()) + 1);
+    }
+  }
+
+  ASSERT_EQ(1u, packets.Size());
+  EXPECT_EQ(QuicPacketNumber(1u), packets.begin()->min());
+  // We leave some room (20 packets) for the packets which did not receive
+  // conclusive status at the end of simulation.
+  EXPECT_GT(packets.rbegin()->max(), QuicPacketNumber(packets_sent_ - 20));
+}
+
+TEST_F(QuicTraceVisitorTest, TransportState) {
+  auto acks = AllEventsWithType(quic_trace::PACKET_RECEIVED);
+  ASSERT_EQ(1, acks[0].frames_size());
+  ASSERT_EQ(quic_trace::ACK, acks[0].frames(0).frame_type());
+
+  // Check that min-RTT at the end is a reasonable approximation.
+  EXPECT_LE((4 * kDelay).ToMicroseconds() * 1.,
+            acks.rbegin()->transport_state().min_rtt_us());
+  EXPECT_GE((4 * kDelay).ToMicroseconds() * 1.25,
+            acks.rbegin()->transport_state().min_rtt_us());
+}
+
+TEST_F(QuicTraceVisitorTest, EncryptionLevels) {
+  for (const auto& event : trace_.events()) {
+    switch (event.event_type()) {
+      case quic_trace::PACKET_SENT:
+      case quic_trace::PACKET_RECEIVED:
+      case quic_trace::PACKET_LOST:
+        ASSERT_TRUE(event.has_encryption_level());
+        ASSERT_NE(event.encryption_level(), quic_trace::ENCRYPTION_UNKNOWN);
+        break;
+
+      default:
+        break;
+    }
+  }
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_transmission_info.cc b/quiche/quic/core/quic_transmission_info.cc
new file mode 100644
index 0000000..1f61dd5
--- /dev/null
+++ b/quiche/quic/core/quic_transmission_info.cc
@@ -0,0 +1,55 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_transmission_info.h"
+#include "absl/strings/str_cat.h"
+
+namespace quic {
+
+QuicTransmissionInfo::QuicTransmissionInfo()
+    : sent_time(QuicTime::Zero()),
+      bytes_sent(0),
+      encryption_level(ENCRYPTION_INITIAL),
+      transmission_type(NOT_RETRANSMISSION),
+      in_flight(false),
+      state(OUTSTANDING),
+      has_crypto_handshake(false),
+      has_ack_frequency(false) {}
+
+QuicTransmissionInfo::QuicTransmissionInfo(EncryptionLevel level,
+                                           TransmissionType transmission_type,
+                                           QuicTime sent_time,
+                                           QuicPacketLength bytes_sent,
+                                           bool has_crypto_handshake,
+                                           bool has_ack_frequency)
+    : sent_time(sent_time),
+      bytes_sent(bytes_sent),
+      encryption_level(level),
+      transmission_type(transmission_type),
+      in_flight(false),
+      state(OUTSTANDING),
+      has_crypto_handshake(has_crypto_handshake),
+      has_ack_frequency(has_ack_frequency) {}
+
+QuicTransmissionInfo::QuicTransmissionInfo(const QuicTransmissionInfo& other) =
+    default;
+
+QuicTransmissionInfo::~QuicTransmissionInfo() {}
+
+std::string QuicTransmissionInfo::DebugString() const {
+  return absl::StrCat(
+      "{sent_time: ", sent_time.ToDebuggingValue(),
+      ", bytes_sent: ", bytes_sent,
+      ", encryption_level: ", EncryptionLevelToString(encryption_level),
+      ", transmission_type: ", TransmissionTypeToString(transmission_type),
+      ", in_flight: ", in_flight, ", state: ", state,
+      ", has_crypto_handshake: ", has_crypto_handshake,
+      ", has_ack_frequency: ", has_ack_frequency,
+      ", first_sent_after_loss: ", first_sent_after_loss.ToString(),
+      ", largest_acked: ", largest_acked.ToString(),
+      ", retransmittable_frames: ", QuicFramesToString(retransmittable_frames),
+      "}");
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_transmission_info.h b/quiche/quic/core/quic_transmission_info.h
new file mode 100644
index 0000000..5a10c07
--- /dev/null
+++ b/quiche/quic/core/quic_transmission_info.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2016 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_TRANSMISSION_INFO_H_
+#define QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
+
+#include <list>
+
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_ack_listener_interface.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Stores details of a single sent packet.
+struct QUIC_EXPORT_PRIVATE QuicTransmissionInfo {
+  // Used by STL when assigning into a map.
+  QuicTransmissionInfo();
+
+  // Constructs a Transmission with a new all_transmissions set
+  // containing |packet_number|.
+  QuicTransmissionInfo(EncryptionLevel level,
+                       TransmissionType transmission_type,
+                       QuicTime sent_time,
+                       QuicPacketLength bytes_sent,
+                       bool has_crypto_handshake,
+                       bool has_ack_frequency);
+
+  QuicTransmissionInfo(const QuicTransmissionInfo& other);
+
+  ~QuicTransmissionInfo();
+
+  std::string DebugString() const;
+
+  QuicFrames retransmittable_frames;
+  QuicTime sent_time;
+  QuicPacketLength bytes_sent;
+  EncryptionLevel encryption_level;
+  // Reason why this packet was transmitted.
+  TransmissionType transmission_type;
+  // In flight packets have not been abandoned or lost.
+  bool in_flight;
+  // State of this packet.
+  SentPacketState state;
+  // True if the packet contains stream data from the crypto stream.
+  bool has_crypto_handshake;
+  // True if the packet contains ack frequency frame.
+  bool has_ack_frequency;
+  // Records the first sent packet after this packet was detected lost. Zero if
+  // this packet has not been detected lost. This is used to keep lost packet
+  // for another RTT (for potential spurious loss detection)
+  QuicPacketNumber first_sent_after_loss;
+  // The largest_acked in the ack frame, if the packet contains an ack.
+  QuicPacketNumber largest_acked;
+};
+// TODO(ianswett): Add static_assert when size of this struct is reduced below
+// 64 bytes.
+// NOTE(vlovich): Existing static_assert removed because padding differences on
+// 64-bit iOS resulted in an 88-byte struct that is greater than the 84-byte
+// limit on other platforms.  Removing per ianswett's request.
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
diff --git a/quiche/quic/core/quic_types.cc b/quiche/quic/core/quic_types.cc
new file mode 100644
index 0000000..389477b
--- /dev/null
+++ b/quiche/quic/core/quic_types.cc
@@ -0,0 +1,426 @@
+// 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 "quiche/quic/core/quic_types.h"
+
+#include <cstdint>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/common/print_elements.h"
+
+namespace quic {
+
+static_assert(sizeof(StatelessResetToken) == kStatelessResetTokenLength,
+              "bad size");
+
+std::ostream& operator<<(std::ostream& os, const QuicConsumedData& s) {
+  os << "bytes_consumed: " << s.bytes_consumed
+     << " fin_consumed: " << s.fin_consumed;
+  return os;
+}
+
+std::string PerspectiveToString(Perspective perspective) {
+  if (perspective == Perspective::IS_SERVER) {
+    return "IS_SERVER";
+  }
+  if (perspective == Perspective::IS_CLIENT) {
+    return "IS_CLIENT";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(perspective), ")");
+}
+
+std::ostream& operator<<(std::ostream& os, const Perspective& perspective) {
+  os << PerspectiveToString(perspective);
+  return os;
+}
+
+std::string ConnectionCloseSourceToString(
+    ConnectionCloseSource connection_close_source) {
+  if (connection_close_source == ConnectionCloseSource::FROM_PEER) {
+    return "FROM_PEER";
+  }
+  if (connection_close_source == ConnectionCloseSource::FROM_SELF) {
+    return "FROM_SELF";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(connection_close_source),
+                      ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ConnectionCloseSource& connection_close_source) {
+  os << ConnectionCloseSourceToString(connection_close_source);
+  return os;
+}
+
+std::string ConnectionCloseBehaviorToString(
+    ConnectionCloseBehavior connection_close_behavior) {
+  if (connection_close_behavior == ConnectionCloseBehavior::SILENT_CLOSE) {
+    return "SILENT_CLOSE";
+  }
+  if (connection_close_behavior ==
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET) {
+    return "SEND_CONNECTION_CLOSE_PACKET";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(connection_close_behavior),
+                      ")");
+}
+
+std::ostream& operator<<(
+    std::ostream& os,
+    const ConnectionCloseBehavior& connection_close_behavior) {
+  os << ConnectionCloseBehaviorToString(connection_close_behavior);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const AckedPacket& acked_packet) {
+  os << "{ packet_number: " << acked_packet.packet_number
+     << ", bytes_acked: " << acked_packet.bytes_acked << ", receive_timestamp: "
+     << acked_packet.receive_timestamp.ToDebuggingValue() << "} ";
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const LostPacket& lost_packet) {
+  os << "{ packet_number: " << lost_packet.packet_number
+     << ", bytes_lost: " << lost_packet.bytes_lost << "} ";
+  return os;
+}
+
+std::string HistogramEnumString(WriteStatus enum_value) {
+  switch (enum_value) {
+    case WRITE_STATUS_OK:
+      return "OK";
+    case WRITE_STATUS_BLOCKED:
+      return "BLOCKED";
+    case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
+      return "BLOCKED_DATA_BUFFERED";
+    case WRITE_STATUS_ERROR:
+      return "ERROR";
+    case WRITE_STATUS_MSG_TOO_BIG:
+      return "MSG_TOO_BIG";
+    case WRITE_STATUS_FAILED_TO_COALESCE_PACKET:
+      return "WRITE_STATUS_FAILED_TO_COALESCE_PACKET";
+    case WRITE_STATUS_NUM_VALUES:
+      return "NUM_VALUES";
+  }
+  QUIC_DLOG(ERROR) << "Invalid WriteStatus value: "
+                   << static_cast<int16_t>(enum_value);
+  return "<invalid>";
+}
+
+std::ostream& operator<<(std::ostream& os, const WriteStatus& status) {
+  os << HistogramEnumString(status);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const WriteResult& s) {
+  os << "{ status: " << s.status;
+  if (s.status == WRITE_STATUS_OK) {
+    os << ", bytes_written: " << s.bytes_written;
+  } else {
+    os << ", error_code: " << s.error_code;
+  }
+  os << " }";
+  return os;
+}
+
+MessageResult::MessageResult(MessageStatus status, QuicMessageId message_id)
+    : status(status), message_id(message_id) {}
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x;
+
+std::string QuicFrameTypeToString(QuicFrameType t) {
+  switch (t) {
+    RETURN_STRING_LITERAL(PADDING_FRAME)
+    RETURN_STRING_LITERAL(RST_STREAM_FRAME)
+    RETURN_STRING_LITERAL(CONNECTION_CLOSE_FRAME)
+    RETURN_STRING_LITERAL(GOAWAY_FRAME)
+    RETURN_STRING_LITERAL(WINDOW_UPDATE_FRAME)
+    RETURN_STRING_LITERAL(BLOCKED_FRAME)
+    RETURN_STRING_LITERAL(STOP_WAITING_FRAME)
+    RETURN_STRING_LITERAL(PING_FRAME)
+    RETURN_STRING_LITERAL(CRYPTO_FRAME)
+    RETURN_STRING_LITERAL(HANDSHAKE_DONE_FRAME)
+    RETURN_STRING_LITERAL(STREAM_FRAME)
+    RETURN_STRING_LITERAL(ACK_FRAME)
+    RETURN_STRING_LITERAL(MTU_DISCOVERY_FRAME)
+    RETURN_STRING_LITERAL(NEW_CONNECTION_ID_FRAME)
+    RETURN_STRING_LITERAL(MAX_STREAMS_FRAME)
+    RETURN_STRING_LITERAL(STREAMS_BLOCKED_FRAME)
+    RETURN_STRING_LITERAL(PATH_RESPONSE_FRAME)
+    RETURN_STRING_LITERAL(PATH_CHALLENGE_FRAME)
+    RETURN_STRING_LITERAL(STOP_SENDING_FRAME)
+    RETURN_STRING_LITERAL(MESSAGE_FRAME)
+    RETURN_STRING_LITERAL(NEW_TOKEN_FRAME)
+    RETURN_STRING_LITERAL(RETIRE_CONNECTION_ID_FRAME)
+    RETURN_STRING_LITERAL(ACK_FREQUENCY_FRAME)
+    RETURN_STRING_LITERAL(NUM_FRAME_TYPES)
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(t), ")");
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicFrameType& t) {
+  os << QuicFrameTypeToString(t);
+  return os;
+}
+
+std::string QuicIetfFrameTypeString(QuicIetfFrameType t) {
+  if (IS_IETF_STREAM_FRAME(t)) {
+    return "IETF_STREAM";
+  }
+
+  switch (t) {
+    RETURN_STRING_LITERAL(IETF_PADDING);
+    RETURN_STRING_LITERAL(IETF_PING);
+    RETURN_STRING_LITERAL(IETF_ACK);
+    RETURN_STRING_LITERAL(IETF_ACK_ECN);
+    RETURN_STRING_LITERAL(IETF_RST_STREAM);
+    RETURN_STRING_LITERAL(IETF_STOP_SENDING);
+    RETURN_STRING_LITERAL(IETF_CRYPTO);
+    RETURN_STRING_LITERAL(IETF_NEW_TOKEN);
+    RETURN_STRING_LITERAL(IETF_MAX_DATA);
+    RETURN_STRING_LITERAL(IETF_MAX_STREAM_DATA);
+    RETURN_STRING_LITERAL(IETF_MAX_STREAMS_BIDIRECTIONAL);
+    RETURN_STRING_LITERAL(IETF_MAX_STREAMS_UNIDIRECTIONAL);
+    RETURN_STRING_LITERAL(IETF_DATA_BLOCKED);
+    RETURN_STRING_LITERAL(IETF_STREAM_DATA_BLOCKED);
+    RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_BIDIRECTIONAL);
+    RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
+    RETURN_STRING_LITERAL(IETF_NEW_CONNECTION_ID);
+    RETURN_STRING_LITERAL(IETF_RETIRE_CONNECTION_ID);
+    RETURN_STRING_LITERAL(IETF_PATH_CHALLENGE);
+    RETURN_STRING_LITERAL(IETF_PATH_RESPONSE);
+    RETURN_STRING_LITERAL(IETF_CONNECTION_CLOSE);
+    RETURN_STRING_LITERAL(IETF_APPLICATION_CLOSE);
+    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH);
+    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE);
+    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99);
+    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_V99);
+    default:
+      return absl::StrCat("Private value (", t, ")");
+  }
+}
+std::ostream& operator<<(std::ostream& os, const QuicIetfFrameType& c) {
+  os << QuicIetfFrameTypeString(c);
+  return os;
+}
+
+std::string TransmissionTypeToString(TransmissionType transmission_type) {
+  switch (transmission_type) {
+    RETURN_STRING_LITERAL(NOT_RETRANSMISSION);
+    RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMISSION);
+    RETURN_STRING_LITERAL(ALL_ZERO_RTT_RETRANSMISSION);
+    RETURN_STRING_LITERAL(LOSS_RETRANSMISSION);
+    RETURN_STRING_LITERAL(RTO_RETRANSMISSION);
+    RETURN_STRING_LITERAL(TLP_RETRANSMISSION);
+    RETURN_STRING_LITERAL(PTO_RETRANSMISSION);
+    RETURN_STRING_LITERAL(PROBING_RETRANSMISSION);
+    RETURN_STRING_LITERAL(PATH_RETRANSMISSION);
+    RETURN_STRING_LITERAL(ALL_INITIAL_RETRANSMISSION);
+    default:
+      // Some varz rely on this behavior for statistic collection.
+      if (transmission_type == LAST_TRANSMISSION_TYPE + 1) {
+        return "INVALID_TRANSMISSION_TYPE";
+      }
+      return absl::StrCat("Unknown(", static_cast<int>(transmission_type), ")");
+  }
+}
+
+std::ostream& operator<<(std::ostream& os, TransmissionType transmission_type) {
+  os << TransmissionTypeToString(transmission_type);
+  return os;
+}
+
+std::string PacketHeaderFormatToString(PacketHeaderFormat format) {
+  switch (format) {
+    RETURN_STRING_LITERAL(IETF_QUIC_LONG_HEADER_PACKET);
+    RETURN_STRING_LITERAL(IETF_QUIC_SHORT_HEADER_PACKET);
+    RETURN_STRING_LITERAL(GOOGLE_QUIC_PACKET);
+    default:
+      return absl::StrCat("Unknown (", static_cast<int>(format), ")");
+  }
+}
+
+std::string QuicLongHeaderTypeToString(QuicLongHeaderType type) {
+  switch (type) {
+    RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
+    RETURN_STRING_LITERAL(INITIAL);
+    RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
+    RETURN_STRING_LITERAL(HANDSHAKE);
+    RETURN_STRING_LITERAL(RETRY);
+    RETURN_STRING_LITERAL(INVALID_PACKET_TYPE);
+    default:
+      return absl::StrCat("Unknown (", static_cast<int>(type), ")");
+  }
+}
+
+std::string MessageStatusToString(MessageStatus message_status) {
+  switch (message_status) {
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_SUCCESS);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_UNSUPPORTED);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_BLOCKED);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_TOO_LARGE);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_INTERNAL_ERROR);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(message_status), ")");
+  }
+}
+
+std::string MessageResultToString(MessageResult message_result) {
+  if (message_result.status != MESSAGE_STATUS_SUCCESS) {
+    return absl::StrCat("{", MessageStatusToString(message_result.status), "}");
+  }
+  return absl::StrCat("{MESSAGE_STATUS_SUCCESS,id=", message_result.message_id,
+                      "}");
+}
+
+std::ostream& operator<<(std::ostream& os, const MessageResult& mr) {
+  os << MessageResultToString(mr);
+  return os;
+}
+
+std::string PacketNumberSpaceToString(PacketNumberSpace packet_number_space) {
+  switch (packet_number_space) {
+    RETURN_STRING_LITERAL(INITIAL_DATA);
+    RETURN_STRING_LITERAL(HANDSHAKE_DATA);
+    RETURN_STRING_LITERAL(APPLICATION_DATA);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(packet_number_space),
+                          ")");
+  }
+}
+
+std::string SerializedPacketFateToString(SerializedPacketFate fate) {
+  switch (fate) {
+    RETURN_STRING_LITERAL(DISCARD);
+    RETURN_STRING_LITERAL(COALESCE);
+    RETURN_STRING_LITERAL(BUFFER);
+    RETURN_STRING_LITERAL(SEND_TO_WRITER);
+    RETURN_STRING_LITERAL(LEGACY_VERSION_ENCAPSULATE);
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(fate), ")");
+}
+
+std::ostream& operator<<(std::ostream& os, SerializedPacketFate fate) {
+  os << SerializedPacketFateToString(fate);
+  return os;
+}
+
+std::string EncryptionLevelToString(EncryptionLevel level) {
+  switch (level) {
+    RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
+    RETURN_STRING_LITERAL(ENCRYPTION_HANDSHAKE);
+    RETURN_STRING_LITERAL(ENCRYPTION_ZERO_RTT);
+    RETURN_STRING_LITERAL(ENCRYPTION_FORWARD_SECURE);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(level), ")");
+  }
+}
+
+std::ostream& operator<<(std::ostream& os, EncryptionLevel level) {
+  os << EncryptionLevelToString(level);
+  return os;
+}
+
+absl::string_view ClientCertModeToString(ClientCertMode mode) {
+#define RETURN_REASON_LITERAL(x) \
+  case ClientCertMode::x:        \
+    return #x
+  switch (mode) {
+    RETURN_REASON_LITERAL(kNone);
+    RETURN_REASON_LITERAL(kRequest);
+    RETURN_REASON_LITERAL(kRequire);
+    default:
+      return "<invalid>";
+  }
+#undef RETURN_REASON_LITERAL
+}
+
+std::ostream& operator<<(std::ostream& os, ClientCertMode mode) {
+  os << ClientCertModeToString(mode);
+  return os;
+}
+
+std::string QuicConnectionCloseTypeString(QuicConnectionCloseType type) {
+  switch (type) {
+    RETURN_STRING_LITERAL(GOOGLE_QUIC_CONNECTION_CLOSE);
+    RETURN_STRING_LITERAL(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE);
+    RETURN_STRING_LITERAL(IETF_QUIC_APPLICATION_CONNECTION_CLOSE);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(type), ")");
+  }
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicConnectionCloseType type) {
+  os << QuicConnectionCloseTypeString(type);
+  return os;
+}
+
+std::string AddressChangeTypeToString(AddressChangeType type) {
+  using IntType = typename std::underlying_type<AddressChangeType>::type;
+  switch (type) {
+    RETURN_STRING_LITERAL(NO_CHANGE);
+    RETURN_STRING_LITERAL(PORT_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
+    RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
+    RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
+    default:
+      return absl::StrCat("Unknown(", static_cast<IntType>(type), ")");
+  }
+}
+
+std::ostream& operator<<(std::ostream& os, AddressChangeType type) {
+  os << AddressChangeTypeToString(type);
+  return os;
+}
+
+std::string KeyUpdateReasonString(KeyUpdateReason reason) {
+#define RETURN_REASON_LITERAL(x) \
+  case KeyUpdateReason::x:       \
+    return #x
+  switch (reason) {
+    RETURN_REASON_LITERAL(kInvalid);
+    RETURN_REASON_LITERAL(kRemote);
+    RETURN_REASON_LITERAL(kLocalForTests);
+    RETURN_REASON_LITERAL(kLocalForInteropRunner);
+    RETURN_REASON_LITERAL(kLocalAeadConfidentialityLimit);
+    RETURN_REASON_LITERAL(kLocalKeyUpdateLimitOverride);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(reason), ")");
+  }
+#undef RETURN_REASON_LITERAL
+}
+
+std::ostream& operator<<(std::ostream& os, const KeyUpdateReason reason) {
+  os << KeyUpdateReasonString(reason);
+  return os;
+}
+
+bool operator==(const ParsedClientHello& a, const ParsedClientHello& b) {
+  return a.sni == b.sni && a.uaid == b.uaid && a.alpns == b.alpns &&
+         a.legacy_version_encapsulation_inner_packet ==
+             b.legacy_version_encapsulation_inner_packet &&
+         a.retry_token == b.retry_token &&
+         a.resumption_attempted == b.resumption_attempted &&
+         a.early_data_attempted == b.early_data_attempted;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ParsedClientHello& parsed_chlo) {
+  os << "{ sni:" << parsed_chlo.sni << ", uaid:" << parsed_chlo.uaid
+     << ", alpns:" << quiche::PrintElements(parsed_chlo.alpns)
+     << ", len(retry_token):" << parsed_chlo.retry_token.size()
+     << ", len(inner_packet):"
+     << parsed_chlo.legacy_version_encapsulation_inner_packet.size() << " }";
+  return os;
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_types.h b/quiche/quic/core/quic_types.h
new file mode 100644
index 0000000..b136708
--- /dev/null
+++ b/quiche/quic/core/quic_types.h
@@ -0,0 +1,891 @@
+// 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_CORE_QUIC_TYPES_H_
+#define QUICHE_QUIC_CORE_QUIC_TYPES_H_
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <ostream>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+using QuicPacketLength = uint16_t;
+using QuicControlFrameId = uint32_t;
+using QuicMessageId = uint32_t;
+
+// TODO(b/181256914) replace QuicDatagramStreamId with QuicStreamId once we
+// remove support for draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+using QuicDatagramStreamId = uint64_t;
+using QuicDatagramContextId = uint64_t;
+// Note that for draft-ietf-masque-h3-datagram-00, we represent the flow ID as a
+// QuicDatagramStreamId.
+
+// IMPORTANT: IETF QUIC defines stream IDs and stream counts as being unsigned
+// 62-bit numbers. However, we have decided to only support up to 2^32-1 streams
+// in order to reduce the size of data structures such as QuicStreamFrame
+// and QuicTransmissionInfo, as that allows them to fit in cache lines and has
+// visible perfomance impact.
+using QuicStreamId = uint32_t;
+
+// Count of stream IDs. Used in MAX_STREAMS and STREAMS_BLOCKED frames.
+using QuicStreamCount = QuicStreamId;
+
+using QuicByteCount = uint64_t;
+using QuicPacketCount = uint64_t;
+using QuicPublicResetNonceProof = uint64_t;
+using QuicStreamOffset = uint64_t;
+using DiversificationNonce = std::array<char, 32>;
+using PacketTimeVector = std::vector<std::pair<QuicPacketNumber, QuicTime>>;
+
+enum : size_t { kStatelessResetTokenLength = 16 };
+using StatelessResetToken = std::array<char, kStatelessResetTokenLength>;
+
+// WebTransport session IDs are stream IDs.
+using WebTransportSessionId = uint64_t;
+// WebTransport stream reset codes are 8-bit.
+using WebTransportStreamError = uint8_t;
+// WebTransport session error codes are 32-bit.
+using WebTransportSessionError = uint32_t;
+
+enum : size_t { kQuicPathFrameBufferSize = 8 };
+using QuicPathFrameBuffer = std::array<uint8_t, kQuicPathFrameBufferSize>;
+
+// The connection id sequence number specifies the order that connection
+// ids must be used in. This is also the sequence number carried in
+// the IETF QUIC NEW_CONNECTION_ID and RETIRE_CONNECTION_ID frames.
+using QuicConnectionIdSequenceNumber = uint64_t;
+
+// A custom data that represents application-specific settings.
+// In HTTP/3 for example, it includes the encoded SETTINGS.
+using ApplicationState = std::vector<uint8_t>;
+
+// A struct for functions which consume data payloads and fins.
+struct QUIC_EXPORT_PRIVATE QuicConsumedData {
+  constexpr QuicConsumedData(size_t bytes_consumed, bool fin_consumed)
+      : bytes_consumed(bytes_consumed), fin_consumed(fin_consumed) {}
+
+  // By default, gtest prints the raw bytes of an object. The bool data
+  // member causes this object to have padding bytes, which causes the
+  // default gtest object printer to read uninitialize memory. So we need
+  // to teach gtest how to print this object.
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os, const QuicConsumedData& s);
+
+  // How many bytes were consumed.
+  size_t bytes_consumed;
+
+  // True if an incoming fin was consumed.
+  bool fin_consumed;
+};
+
+// QuicAsyncStatus enumerates the possible results of an asynchronous
+// operation.
+enum QuicAsyncStatus {
+  QUIC_SUCCESS = 0,
+  QUIC_FAILURE = 1,
+  // QUIC_PENDING results from an operation that will occur asynchronously. When
+  // the operation is complete, a callback's |Run| method will be called.
+  QUIC_PENDING = 2,
+};
+
+// TODO(wtc): see if WriteStatus can be replaced by QuicAsyncStatus.
+enum WriteStatus : int16_t {
+  WRITE_STATUS_OK,
+  // Write is blocked, caller needs to retry.
+  WRITE_STATUS_BLOCKED,
+  // Write is blocked but the packet data is buffered, caller should not retry.
+  WRITE_STATUS_BLOCKED_DATA_BUFFERED,
+  // To make the IsWriteError(WriteStatus) function work properly:
+  // - Non-errors MUST be added before WRITE_STATUS_ERROR.
+  // - Errors MUST be added after WRITE_STATUS_ERROR.
+  WRITE_STATUS_ERROR,
+  WRITE_STATUS_MSG_TOO_BIG,
+  WRITE_STATUS_FAILED_TO_COALESCE_PACKET,
+  WRITE_STATUS_NUM_VALUES,
+};
+
+std::string HistogramEnumString(WriteStatus enum_value);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const WriteStatus& status);
+
+inline std::string HistogramEnumDescription(WriteStatus /*dummy*/) {
+  return "status";
+}
+
+inline bool IsWriteBlockedStatus(WriteStatus status) {
+  return status == WRITE_STATUS_BLOCKED ||
+         status == WRITE_STATUS_BLOCKED_DATA_BUFFERED;
+}
+
+inline bool IsWriteError(WriteStatus status) {
+  return status >= WRITE_STATUS_ERROR;
+}
+
+// A struct used to return the result of write calls including either the number
+// of bytes written or the error code, depending upon the status.
+struct QUIC_EXPORT_PRIVATE WriteResult {
+  constexpr WriteResult(WriteStatus status, int bytes_written_or_error_code)
+      : status(status), bytes_written(bytes_written_or_error_code) {}
+
+  constexpr WriteResult() : WriteResult(WRITE_STATUS_ERROR, 0) {}
+
+  bool operator==(const WriteResult& other) const {
+    if (status != other.status) {
+      return false;
+    }
+    switch (status) {
+      case WRITE_STATUS_OK:
+        return bytes_written == other.bytes_written;
+      case WRITE_STATUS_BLOCKED:
+      case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
+        return true;
+      default:
+        return error_code == other.error_code;
+    }
+  }
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+                                                      const WriteResult& s);
+
+  WriteStatus status;
+  // Number of packets dropped as a result of this write.
+  // Only used by batch writers. Otherwise always 0.
+  uint16_t dropped_packets = 0;
+  // The delta between a packet's ideal and actual send time:
+  //     actual_send_time = ideal_send_time + send_time_offset
+  //                      = (now + release_time_delay) + send_time_offset
+  // Only valid if |status| is WRITE_STATUS_OK.
+  QuicTime::Delta send_time_offset = QuicTime::Delta::Zero();
+  // TODO(wub): In some cases, WRITE_STATUS_ERROR may set an error_code and
+  // WRITE_STATUS_BLOCKED_DATA_BUFFERED may set bytes_written. This may need
+  // some cleaning up so that perhaps both values can be set and valid.
+  union {
+    int bytes_written;  // only valid when status is WRITE_STATUS_OK
+    int error_code;     // only valid when status is WRITE_STATUS_ERROR
+  };
+};
+
+enum TransmissionType : int8_t {
+  NOT_RETRANSMISSION,
+  FIRST_TRANSMISSION_TYPE = NOT_RETRANSMISSION,
+  HANDSHAKE_RETRANSMISSION,     // Retransmits due to handshake timeouts.
+  ALL_ZERO_RTT_RETRANSMISSION,  // Retransmits all packets encrypted with 0-RTT
+                                // key.
+  LOSS_RETRANSMISSION,          // Retransmits due to loss detection.
+  RTO_RETRANSMISSION,           // Retransmits due to retransmit time out.
+  TLP_RETRANSMISSION,           // Tail loss probes.
+  PTO_RETRANSMISSION,           // Retransmission due to probe timeout.
+  PROBING_RETRANSMISSION,       // Retransmission in order to probe bandwidth.
+  PATH_RETRANSMISSION,          // Retransmission proactively due to underlying
+                                // network change.
+  ALL_INITIAL_RETRANSMISSION,   // Retransmit all packets encrypted with INITIAL
+                                // key.
+  LAST_TRANSMISSION_TYPE = ALL_INITIAL_RETRANSMISSION,
+};
+
+QUIC_EXPORT_PRIVATE std::string TransmissionTypeToString(
+    TransmissionType transmission_type);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, TransmissionType transmission_type);
+
+enum HasRetransmittableData : uint8_t {
+  NO_RETRANSMITTABLE_DATA,
+  HAS_RETRANSMITTABLE_DATA,
+};
+
+enum IsHandshake : uint8_t { NOT_HANDSHAKE, IS_HANDSHAKE };
+
+enum class Perspective : uint8_t { IS_SERVER, IS_CLIENT };
+
+QUIC_EXPORT_PRIVATE std::string PerspectiveToString(Perspective perspective);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const Perspective& perspective);
+
+// Describes whether a ConnectionClose was originated by the peer.
+enum class ConnectionCloseSource { FROM_PEER, FROM_SELF };
+
+QUIC_EXPORT_PRIVATE std::string ConnectionCloseSourceToString(
+    ConnectionCloseSource connection_close_source);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ConnectionCloseSource& connection_close_source);
+
+// Should a connection be closed silently or not.
+enum class ConnectionCloseBehavior {
+  SILENT_CLOSE,
+  SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED,
+  SEND_CONNECTION_CLOSE_PACKET
+};
+
+QUIC_EXPORT_PRIVATE std::string ConnectionCloseBehaviorToString(
+    ConnectionCloseBehavior connection_close_behavior);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ConnectionCloseBehavior& connection_close_behavior);
+
+enum QuicFrameType : uint8_t {
+  // Regular frame types. The values set here cannot change without the
+  // introduction of a new QUIC version.
+  PADDING_FRAME = 0,
+  RST_STREAM_FRAME = 1,
+  CONNECTION_CLOSE_FRAME = 2,
+  GOAWAY_FRAME = 3,
+  WINDOW_UPDATE_FRAME = 4,
+  BLOCKED_FRAME = 5,
+  STOP_WAITING_FRAME = 6,
+  PING_FRAME = 7,
+  CRYPTO_FRAME = 8,
+  // TODO(b/157935330): stop hard coding this when deprecate T050.
+  HANDSHAKE_DONE_FRAME = 9,
+
+  // STREAM and ACK frames are special frames. They are encoded differently on
+  // the wire and their values do not need to be stable.
+  STREAM_FRAME,
+  ACK_FRAME,
+  // The path MTU discovery frame is encoded as a PING frame on the wire.
+  MTU_DISCOVERY_FRAME,
+
+  // These are for IETF-specific frames for which there is no mapping
+  // from Google QUIC frames. These are valid/allowed if and only if IETF-
+  // QUIC has been negotiated. Values are not important, they are not
+  // the values that are in the packets (see QuicIetfFrameType, below).
+  NEW_CONNECTION_ID_FRAME,
+  MAX_STREAMS_FRAME,
+  STREAMS_BLOCKED_FRAME,
+  PATH_RESPONSE_FRAME,
+  PATH_CHALLENGE_FRAME,
+  STOP_SENDING_FRAME,
+  MESSAGE_FRAME,
+  NEW_TOKEN_FRAME,
+  RETIRE_CONNECTION_ID_FRAME,
+  ACK_FREQUENCY_FRAME,
+
+  NUM_FRAME_TYPES
+};
+
+// Human-readable string suitable for logging.
+QUIC_EXPORT_PRIVATE std::string QuicFrameTypeToString(QuicFrameType t);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const QuicFrameType& t);
+
+// Ietf frame types. These are defined in the IETF QUIC Specification.
+// Explicit values are given in the enum so that we can be sure that
+// the symbol will map to the correct stream type.
+// All types are defined here, even if we have not yet implmented the
+// quic/core/stream/.... stuff needed.
+// Note: The protocol specifies that frame types are varint-62 encoded,
+// further stating that the shortest encoding must be used.  The current set of
+// frame types all have values less than 0x40 (64) so can be encoded in a single
+// byte, with the two most significant bits being 0. Thus, the following
+// enumerations are valid as both the numeric values of frame types AND their
+// encodings.
+enum QuicIetfFrameType : uint64_t {
+  IETF_PADDING = 0x00,
+  IETF_PING = 0x01,
+  IETF_ACK = 0x02,
+  IETF_ACK_ECN = 0x03,
+  IETF_RST_STREAM = 0x04,
+  IETF_STOP_SENDING = 0x05,
+  IETF_CRYPTO = 0x06,
+  IETF_NEW_TOKEN = 0x07,
+  // the low-3 bits of the stream frame type value are actually flags
+  // declaring what parts of the frame are/are-not present, as well as
+  // some other control information. The code would then do something
+  // along the lines of "if ((frame_type & 0xf8) == 0x08)" to determine
+  // whether the frame is a stream frame or not, and then examine each
+  // bit specifically when/as needed.
+  IETF_STREAM = 0x08,
+  // 0x09 through 0x0f are various flag settings of the IETF_STREAM frame.
+  IETF_MAX_DATA = 0x10,
+  IETF_MAX_STREAM_DATA = 0x11,
+  IETF_MAX_STREAMS_BIDIRECTIONAL = 0x12,
+  IETF_MAX_STREAMS_UNIDIRECTIONAL = 0x13,
+  IETF_DATA_BLOCKED = 0x14,
+  IETF_STREAM_DATA_BLOCKED = 0x15,
+  IETF_STREAMS_BLOCKED_BIDIRECTIONAL = 0x16,
+  IETF_STREAMS_BLOCKED_UNIDIRECTIONAL = 0x17,
+  IETF_NEW_CONNECTION_ID = 0x18,
+  IETF_RETIRE_CONNECTION_ID = 0x19,
+  IETF_PATH_CHALLENGE = 0x1a,
+  IETF_PATH_RESPONSE = 0x1b,
+  // Both of the following are "Connection Close" frames,
+  // the first signals transport-layer errors, the second application-layer
+  // errors.
+  IETF_CONNECTION_CLOSE = 0x1c,
+  IETF_APPLICATION_CLOSE = 0x1d,
+
+  IETF_HANDSHAKE_DONE = 0x1e,
+
+  // The MESSAGE frame type has not yet been fully standardized.
+  // QUIC versions starting with 46 and before 99 use 0x20-0x21.
+  // IETF QUIC (v99) uses 0x30-0x31, see draft-pauly-quic-datagram.
+  IETF_EXTENSION_MESSAGE_NO_LENGTH = 0x20,
+  IETF_EXTENSION_MESSAGE = 0x21,
+  IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 = 0x30,
+  IETF_EXTENSION_MESSAGE_V99 = 0x31,
+
+  // An QUIC extension frame for sender control of acknowledgement delays
+  IETF_ACK_FREQUENCY = 0xaf,
+
+  // A QUIC extension frame which augments the IETF_ACK frame definition with
+  // packet receive timestamps.
+  // TODO(ianswett): Determine a proper value to replace this temporary value.
+  IETF_ACK_RECEIVE_TIMESTAMPS = 0x22,
+};
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const QuicIetfFrameType& c);
+QUIC_EXPORT_PRIVATE std::string QuicIetfFrameTypeString(QuicIetfFrameType t);
+
+// Masks for the bits that indicate the frame is a Stream frame vs the
+// bits used as flags.
+#define IETF_STREAM_FRAME_TYPE_MASK 0xfffffffffffffff8
+#define IETF_STREAM_FRAME_FLAG_MASK 0x07
+#define IS_IETF_STREAM_FRAME(_stype_) \
+  (((_stype_)&IETF_STREAM_FRAME_TYPE_MASK) == IETF_STREAM)
+
+// These are the values encoded in the low-order 3 bits of the
+// IETF_STREAMx frame type.
+#define IETF_STREAM_FRAME_FIN_BIT 0x01
+#define IETF_STREAM_FRAME_LEN_BIT 0x02
+#define IETF_STREAM_FRAME_OFF_BIT 0x04
+
+enum QuicVariableLengthIntegerLength : uint8_t {
+  // Length zero means the variable length integer is not present.
+  VARIABLE_LENGTH_INTEGER_LENGTH_0 = 0,
+  VARIABLE_LENGTH_INTEGER_LENGTH_1 = 1,
+  VARIABLE_LENGTH_INTEGER_LENGTH_2 = 2,
+  VARIABLE_LENGTH_INTEGER_LENGTH_4 = 4,
+  VARIABLE_LENGTH_INTEGER_LENGTH_8 = 8,
+
+  // By default we write the IETF long header length using the 2-byte encoding
+  // of variable length integers, even when the length is below 64, which allows
+  // us to fill in the length before knowing what the length actually is.
+  kQuicDefaultLongHeaderLengthLength = VARIABLE_LENGTH_INTEGER_LENGTH_2,
+};
+
+enum QuicPacketNumberLength : uint8_t {
+  PACKET_1BYTE_PACKET_NUMBER = 1,
+  PACKET_2BYTE_PACKET_NUMBER = 2,
+  PACKET_3BYTE_PACKET_NUMBER = 3,  // Used in versions 45+.
+  PACKET_4BYTE_PACKET_NUMBER = 4,
+  IETF_MAX_PACKET_NUMBER_LENGTH = 4,
+  // TODO(b/145819870): Remove 6 and 8 when we remove Q043 since these values
+  // are not representable with later versions.
+  PACKET_6BYTE_PACKET_NUMBER = 6,
+  PACKET_8BYTE_PACKET_NUMBER = 8
+};
+
+// Used to indicate a QuicSequenceNumberLength using two flag bits.
+enum QuicPacketNumberLengthFlags {
+  PACKET_FLAGS_1BYTE_PACKET = 0,           // 00
+  PACKET_FLAGS_2BYTE_PACKET = 1,           // 01
+  PACKET_FLAGS_4BYTE_PACKET = 1 << 1,      // 10
+  PACKET_FLAGS_8BYTE_PACKET = 1 << 1 | 1,  // 11
+};
+
+// The public flags are specified in one byte.
+enum QuicPacketPublicFlags {
+  PACKET_PUBLIC_FLAGS_NONE = 0,
+
+  // Bit 0: Does the packet header contains version info?
+  PACKET_PUBLIC_FLAGS_VERSION = 1 << 0,
+
+  // Bit 1: Is this packet a public reset packet?
+  PACKET_PUBLIC_FLAGS_RST = 1 << 1,
+
+  // Bit 2: indicates the header includes a nonce.
+  PACKET_PUBLIC_FLAGS_NONCE = 1 << 2,
+
+  // Bit 3: indicates whether a ConnectionID is included.
+  PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID = 0,
+  PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID = 1 << 3,
+
+  // Deprecated version 32 and earlier used two bits to indicate an 8-byte
+  // connection ID. We send this from the client because of some broken
+  // middleboxes that are still checking this bit.
+  PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD = 1 << 3 | 1 << 2,
+
+  // Bits 4 and 5 describe the packet number length as follows:
+  // --00----: 1 byte
+  // --01----: 2 bytes
+  // --10----: 4 bytes
+  // --11----: 6 bytes
+  PACKET_PUBLIC_FLAGS_1BYTE_PACKET = PACKET_FLAGS_1BYTE_PACKET << 4,
+  PACKET_PUBLIC_FLAGS_2BYTE_PACKET = PACKET_FLAGS_2BYTE_PACKET << 4,
+  PACKET_PUBLIC_FLAGS_4BYTE_PACKET = PACKET_FLAGS_4BYTE_PACKET << 4,
+  PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_8BYTE_PACKET << 4,
+
+  // Reserved, unimplemented flags:
+
+  // Bit 7: indicates the presence of a second flags byte.
+  PACKET_PUBLIC_FLAGS_TWO_OR_MORE_BYTES = 1 << 7,
+
+  // All bits set (bits 6 and 7 are not currently used): 00111111
+  PACKET_PUBLIC_FLAGS_MAX = (1 << 6) - 1,
+};
+
+// The private flags are specified in one byte.
+enum QuicPacketPrivateFlags {
+  PACKET_PRIVATE_FLAGS_NONE = 0,
+
+  // Bit 0: Does this packet contain an entropy bit?
+  PACKET_PRIVATE_FLAGS_ENTROPY = 1 << 0,
+
+  // (bits 1-7 are not used): 00000001
+  PACKET_PRIVATE_FLAGS_MAX = (1 << 1) - 1
+};
+
+// Defines for all types of congestion control algorithms that can be used in
+// QUIC. Note that this is separate from the congestion feedback type -
+// some congestion control algorithms may use the same feedback type
+// (Reno and Cubic are the classic example for that).
+enum CongestionControlType {
+  kCubicBytes,
+  kRenoBytes,
+  kBBR,
+  kPCC,
+  kGoogCC,
+  kBBRv2,
+};
+
+// EncryptionLevel enumerates the stages of encryption that a QUIC connection
+// progresses through. When retransmitting a packet, the encryption level needs
+// to be specified so that it is retransmitted at a level which the peer can
+// understand.
+enum EncryptionLevel : int8_t {
+  ENCRYPTION_INITIAL = 0,
+  ENCRYPTION_HANDSHAKE = 1,
+  ENCRYPTION_ZERO_RTT = 2,
+  ENCRYPTION_FORWARD_SECURE = 3,
+
+  NUM_ENCRYPTION_LEVELS,
+};
+
+inline bool EncryptionLevelIsValid(EncryptionLevel level) {
+  return ENCRYPTION_INITIAL <= level && level < NUM_ENCRYPTION_LEVELS;
+}
+
+QUIC_EXPORT_PRIVATE std::string EncryptionLevelToString(EncryptionLevel level);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             EncryptionLevel level);
+
+// Enumeration of whether a server endpoint will request a client certificate,
+// and whether that endpoint requires a valid client certificate to establish a
+// connection.
+enum class ClientCertMode : uint8_t {
+  kNone,     // Do not request a client certificate.  Default server behavior.
+  kRequest,  // Request a certificate, but allow unauthenticated connections.
+  kRequire,  // Require clients to provide a valid certificate.
+};
+
+QUIC_EXPORT_PRIVATE absl::string_view ClientCertModeToString(
+    ClientCertMode mode);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             ClientCertMode mode);
+
+enum AddressChangeType : uint8_t {
+  // IP address and port remain unchanged.
+  NO_CHANGE,
+  // Port changed, but IP address remains unchanged.
+  PORT_CHANGE,
+  // IPv4 address changed, but within the /24 subnet (port may have changed.)
+  IPV4_SUBNET_CHANGE,
+  // IPv4 address changed, excluding /24 subnet change (port may have changed.)
+  IPV4_TO_IPV4_CHANGE,
+  // IP address change from an IPv4 to an IPv6 address (port may have changed.)
+  IPV4_TO_IPV6_CHANGE,
+  // IP address change from an IPv6 to an IPv4 address (port may have changed.)
+  IPV6_TO_IPV4_CHANGE,
+  // IP address change from an IPv6 to an IPv6 address (port may have changed.)
+  IPV6_TO_IPV6_CHANGE,
+};
+
+QUIC_EXPORT_PRIVATE std::string AddressChangeTypeToString(
+    AddressChangeType type);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             AddressChangeType type);
+
+enum StreamSendingState {
+  // Sender has more data to send on this stream.
+  NO_FIN,
+  // Sender is done sending on this stream.
+  FIN,
+  // Sender is done sending on this stream and random padding needs to be
+  // appended after all stream frames.
+  FIN_AND_PADDING,
+};
+
+enum SentPacketState : uint8_t {
+  // The packet is in flight and waiting to be acked.
+  OUTSTANDING,
+  FIRST_PACKET_STATE = OUTSTANDING,
+  // The packet was never sent.
+  NEVER_SENT,
+  // The packet has been acked.
+  ACKED,
+  // This packet is not expected to be acked.
+  UNACKABLE,
+  // This packet has been delivered or unneeded.
+  NEUTERED,
+
+  // States below are corresponding to retransmission types in TransmissionType.
+
+  // This packet has been retransmitted when retransmission timer fires in
+  // HANDSHAKE mode.
+  HANDSHAKE_RETRANSMITTED,
+  // This packet is considered as lost, this is used for LOST_RETRANSMISSION.
+  LOST,
+  // This packet has been retransmitted when TLP fires.
+  TLP_RETRANSMITTED,
+  // This packet has been retransmitted when RTO fires.
+  RTO_RETRANSMITTED,
+  // This packet has been retransmitted when PTO fires.
+  PTO_RETRANSMITTED,
+  // This packet has been retransmitted for probing purpose.
+  PROBE_RETRANSMITTED,
+  // This packet is sent on a different path or is a PING only packet.
+  // Do not update RTT stats and congestion control if the packet is the
+  // largest_acked of an incoming ACK.
+  NOT_CONTRIBUTING_RTT,
+  LAST_PACKET_STATE = NOT_CONTRIBUTING_RTT,
+};
+
+enum PacketHeaderFormat : uint8_t {
+  IETF_QUIC_LONG_HEADER_PACKET,
+  IETF_QUIC_SHORT_HEADER_PACKET,
+  GOOGLE_QUIC_PACKET,
+};
+
+QUIC_EXPORT_PRIVATE std::string PacketHeaderFormatToString(
+    PacketHeaderFormat format);
+
+// Information about a newly acknowledged packet.
+struct QUIC_EXPORT_PRIVATE AckedPacket {
+  constexpr AckedPacket(QuicPacketNumber packet_number,
+                        QuicPacketLength bytes_acked,
+                        QuicTime receive_timestamp)
+      : packet_number(packet_number),
+        bytes_acked(bytes_acked),
+        receive_timestamp(receive_timestamp) {}
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const AckedPacket& acked_packet);
+
+  QuicPacketNumber packet_number;
+  // Number of bytes sent in the packet that was acknowledged.
+  QuicPacketLength bytes_acked;
+  // The time |packet_number| was received by the peer, according to the
+  // optional timestamp the peer included in the ACK frame which acknowledged
+  // |packet_number|. Zero if no timestamp was available for this packet.
+  QuicTime receive_timestamp;
+};
+
+// A vector of acked packets.
+using AckedPacketVector = absl::InlinedVector<AckedPacket, 2>;
+
+// Information about a newly lost packet.
+struct QUIC_EXPORT_PRIVATE LostPacket {
+  LostPacket(QuicPacketNumber packet_number, QuicPacketLength bytes_lost)
+      : packet_number(packet_number), bytes_lost(bytes_lost) {}
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const LostPacket& lost_packet);
+
+  QuicPacketNumber packet_number;
+  // Number of bytes sent in the packet that was lost.
+  QuicPacketLength bytes_lost;
+};
+
+// A vector of lost packets.
+using LostPacketVector = absl::InlinedVector<LostPacket, 2>;
+
+// Please note, this value cannot used directly for packet serialization.
+enum QuicLongHeaderType : uint8_t {
+  VERSION_NEGOTIATION,
+  INITIAL,
+  ZERO_RTT_PROTECTED,
+  HANDSHAKE,
+  RETRY,
+
+  INVALID_PACKET_TYPE,
+};
+
+QUIC_EXPORT_PRIVATE std::string QuicLongHeaderTypeToString(
+    QuicLongHeaderType type);
+
+enum QuicPacketHeaderTypeFlags : uint8_t {
+  // Bit 2: Key phase bit for IETF QUIC short header packets.
+  FLAGS_KEY_PHASE_BIT = 1 << 2,
+  // Bit 3: Google QUIC Demultiplexing bit, the short header always sets this
+  // bit to 0, allowing to distinguish Google QUIC packets from short header
+  // packets.
+  FLAGS_DEMULTIPLEXING_BIT = 1 << 3,
+  // Bits 4 and 5: Reserved bits for short header.
+  FLAGS_SHORT_HEADER_RESERVED_1 = 1 << 4,
+  FLAGS_SHORT_HEADER_RESERVED_2 = 1 << 5,
+  // Bit 6: the 'QUIC' bit.
+  FLAGS_FIXED_BIT = 1 << 6,
+  // Bit 7: Indicates the header is long or short header.
+  FLAGS_LONG_HEADER = 1 << 7,
+};
+
+enum MessageStatus {
+  MESSAGE_STATUS_SUCCESS,
+  MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED,  // Failed to send message because
+                                              // encryption is not established
+                                              // yet.
+  MESSAGE_STATUS_UNSUPPORTED,  // Failed to send message because MESSAGE frame
+                               // is not supported by the connection.
+  MESSAGE_STATUS_BLOCKED,      // Failed to send message because connection is
+                           // congestion control blocked or underlying socket is
+                           // write blocked.
+  MESSAGE_STATUS_TOO_LARGE,  // Failed to send message because the message is
+                             // too large to fit into a single packet.
+  MESSAGE_STATUS_INTERNAL_ERROR,  // Failed to send message because connection
+                                  // reaches an invalid state.
+};
+
+QUIC_EXPORT_PRIVATE std::string MessageStatusToString(
+    MessageStatus message_status);
+
+// Used to return the result of SendMessage calls
+struct QUIC_EXPORT_PRIVATE MessageResult {
+  MessageResult(MessageStatus status, QuicMessageId message_id);
+
+  bool operator==(const MessageResult& other) const {
+    return status == other.status && message_id == other.message_id;
+  }
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+                                                      const MessageResult& mr);
+
+  MessageStatus status;
+  // Only valid when status is MESSAGE_STATUS_SUCCESS.
+  QuicMessageId message_id;
+};
+
+QUIC_EXPORT_PRIVATE std::string MessageResultToString(
+    MessageResult message_result);
+
+enum WriteStreamDataResult {
+  WRITE_SUCCESS,
+  STREAM_MISSING,  // Trying to write data of a nonexistent stream (e.g.
+                   // closed).
+  WRITE_FAILED,    // Trying to write nonexistent data of a stream
+};
+
+enum StreamType : uint8_t {
+  // Bidirectional streams allow for data to be sent in both directions.
+  BIDIRECTIONAL,
+
+  // Unidirectional streams carry data in one direction only.
+  WRITE_UNIDIRECTIONAL,
+  READ_UNIDIRECTIONAL,
+  // Not actually a stream type. Used only by QuicCryptoStream when it uses
+  // CRYPTO frames and isn't actually a QuicStream.
+  CRYPTO,
+};
+
+// A packet number space is the context in which a packet can be processed and
+// acknowledged.
+enum PacketNumberSpace : uint8_t {
+  INITIAL_DATA = 0,  // Only used in IETF QUIC.
+  HANDSHAKE_DATA = 1,
+  APPLICATION_DATA = 2,
+
+  NUM_PACKET_NUMBER_SPACES,
+};
+
+QUIC_EXPORT_PRIVATE std::string PacketNumberSpaceToString(
+    PacketNumberSpace packet_number_space);
+
+// Used to return the result of processing a received ACK frame.
+enum AckResult {
+  PACKETS_NEWLY_ACKED,
+  NO_PACKETS_NEWLY_ACKED,
+  UNSENT_PACKETS_ACKED,     // Peer acks unsent packets.
+  UNACKABLE_PACKETS_ACKED,  // Peer acks packets that are not expected to be
+                            // acked. For example, encryption is reestablished,
+                            // and all sent encrypted packets cannot be
+                            // decrypted by the peer. Version gets negotiated,
+                            // and all sent packets in the different version
+                            // cannot be processed by the peer.
+  PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
+};
+
+// Indicates the fate of a serialized packet in WritePacket().
+enum SerializedPacketFate : uint8_t {
+  DISCARD,                     // Discard the packet.
+  COALESCE,                    // Try to coalesce packet.
+  BUFFER,                      // Buffer packet in buffered_packets_.
+  SEND_TO_WRITER,              // Send packet to writer.
+  LEGACY_VERSION_ENCAPSULATE,  // Perform Legacy Version Encapsulation on this
+                               // packet.
+};
+
+QUIC_EXPORT_PRIVATE std::string SerializedPacketFateToString(
+    SerializedPacketFate fate);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const SerializedPacketFate fate);
+
+// There are three different forms of CONNECTION_CLOSE.
+enum QuicConnectionCloseType {
+  GOOGLE_QUIC_CONNECTION_CLOSE = 0,
+  IETF_QUIC_TRANSPORT_CONNECTION_CLOSE = 1,
+  IETF_QUIC_APPLICATION_CONNECTION_CLOSE = 2
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const QuicConnectionCloseType type);
+
+QUIC_EXPORT_PRIVATE std::string QuicConnectionCloseTypeString(
+    QuicConnectionCloseType type);
+
+// Indicate handshake state of a connection.
+enum HandshakeState {
+  // Initial state.
+  HANDSHAKE_START,
+  // Only used in IETF QUIC with TLS handshake. State proceeds to
+  // HANDSHAKE_PROCESSED after a packet of HANDSHAKE packet number space
+  // gets successfully processed, and the initial key can be dropped.
+  HANDSHAKE_PROCESSED,
+  // In QUIC crypto, state proceeds to HANDSHAKE_COMPLETE if client receives
+  // SHLO or server successfully processes an ENCRYPTION_FORWARD_SECURE
+  // packet, such that the handshake packets can be neutered. In IETF QUIC
+  // with TLS handshake, state proceeds to HANDSHAKE_COMPLETE once the client
+  // has both 1-RTT send and receive keys.
+  HANDSHAKE_COMPLETE,
+  // Only used in IETF QUIC with TLS handshake. State proceeds to
+  // HANDSHAKE_CONFIRMED if 1) a client receives HANDSHAKE_DONE frame or
+  // acknowledgment for 1-RTT packet or 2) server has
+  // 1-RTT send and receive keys.
+  HANDSHAKE_CONFIRMED,
+};
+
+struct QUIC_NO_EXPORT NextReleaseTimeResult {
+  // The ideal release time of the packet being sent.
+  QuicTime release_time;
+  // Whether it is allowed to send the packet before release_time.
+  bool allow_burst;
+};
+
+// QuicPacketBuffer bundles a buffer and a function that releases it. Note
+// it does not assume ownership of buffer, i.e. it doesn't release the buffer on
+// destruction.
+struct QUIC_NO_EXPORT QuicPacketBuffer {
+  QuicPacketBuffer() = default;
+
+  QuicPacketBuffer(char* buffer,
+                   std::function<void(const char*)> release_buffer)
+      : buffer(buffer), release_buffer(std::move(release_buffer)) {}
+
+  char* buffer = nullptr;
+  std::function<void(const char*)> release_buffer;
+};
+
+// QuicOwnedPacketBuffer is a QuicPacketBuffer that assumes buffer ownership.
+struct QUIC_NO_EXPORT QuicOwnedPacketBuffer : public QuicPacketBuffer {
+  QuicOwnedPacketBuffer(const QuicOwnedPacketBuffer&) = delete;
+  QuicOwnedPacketBuffer& operator=(const QuicOwnedPacketBuffer&) = delete;
+
+  QuicOwnedPacketBuffer(char* buffer,
+                        std::function<void(const char*)> release_buffer)
+      : QuicPacketBuffer(buffer, std::move(release_buffer)) {}
+
+  QuicOwnedPacketBuffer(QuicOwnedPacketBuffer&& owned_buffer)
+      : QuicPacketBuffer(std::move(owned_buffer)) {
+    // |owned_buffer| does not own a buffer any more.
+    owned_buffer.buffer = nullptr;
+  }
+
+  explicit QuicOwnedPacketBuffer(QuicPacketBuffer&& packet_buffer)
+      : QuicPacketBuffer(std::move(packet_buffer)) {}
+
+  ~QuicOwnedPacketBuffer() {
+    if (release_buffer != nullptr && buffer != nullptr) {
+      release_buffer(buffer);
+    }
+  }
+};
+
+// These values must remain stable as they are uploaded to UMA histograms.
+enum class KeyUpdateReason {
+  kInvalid = 0,
+  kRemote = 1,
+  kLocalForTests = 2,
+  kLocalForInteropRunner = 3,
+  kLocalAeadConfidentialityLimit = 4,
+  kLocalKeyUpdateLimitOverride = 5,
+  kMaxValue = kLocalKeyUpdateLimitOverride,
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const KeyUpdateReason reason);
+
+QUIC_EXPORT_PRIVATE std::string KeyUpdateReasonString(KeyUpdateReason reason);
+
+// QuicSSLConfig contains configurations to be applied on a SSL object, which
+// overrides the configurations in SSL_CTX.
+struct QUIC_NO_EXPORT QuicSSLConfig {
+  // Whether TLS early data should be enabled. If not set, default to enabled.
+  absl::optional<bool> early_data_enabled;
+  // Whether TLS session tickets are supported. If not set, default to
+  // supported.
+  absl::optional<bool> disable_ticket_support;
+  // If set, used to configure the SSL object with
+  // SSL_set_signing_algorithm_prefs.
+  absl::optional<absl::InlinedVector<uint16_t, 8>> signing_algorithm_prefs;
+  // Client certificate mode for mTLS support. Only used at server side.
+  ClientCertMode client_cert_mode = ClientCertMode::kNone;
+};
+
+// QuicDelayedSSLConfig contains a subset of SSL config that can be applied
+// after BoringSSL's early select certificate callback. This overwrites all SSL
+// configs applied before cert selection.
+struct QUIC_NO_EXPORT QuicDelayedSSLConfig {
+  // Client certificate mode for mTLS support. Only used at server side.
+  // absl::nullopt means do not change client certificate mode.
+  absl::optional<ClientCertMode> client_cert_mode;
+};
+
+// ParsedClientHello contains client hello information extracted from a fully
+// received client hello.
+struct QUIC_NO_EXPORT ParsedClientHello {
+  std::string sni;                 // QUIC crypto and TLS.
+  std::string uaid;                // QUIC crypto only.
+  std::vector<std::string> alpns;  // QUIC crypto and TLS.
+  std::string legacy_version_encapsulation_inner_packet;  // QUIC crypto only.
+  // The unvalidated retry token from the last received packet of a potentially
+  // multi-packet client hello. TLS only.
+  std::string retry_token;
+  bool resumption_attempted = false;  // TLS only.
+  bool early_data_attempted = false;  // TLS only.
+};
+
+QUIC_EXPORT_PRIVATE bool operator==(const ParsedClientHello& a,
+                                    const ParsedClientHello& b);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ParsedClientHello& parsed_chlo);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TYPES_H_
diff --git a/quiche/quic/core/quic_udp_socket.h b/quiche/quic/core/quic_udp_socket.h
new file mode 100644
index 0000000..fcfdcac
--- /dev/null
+++ b/quiche/quic/core/quic_udp_socket.h
@@ -0,0 +1,253 @@
+// Copyright 2019 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_UDP_SOCKET_H_
+#define QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include <type_traits>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+#if defined(_WIN32)
+using QuicUdpSocketFd = SOCKET;
+const QuicUdpSocketFd kQuicInvalidSocketFd = INVALID_SOCKET;
+#else
+using QuicUdpSocketFd = int;
+const QuicUdpSocketFd kQuicInvalidSocketFd = -1;
+#endif
+
+const size_t kDefaultUdpPacketControlBufferSize = 512;
+
+enum class QuicUdpPacketInfoBit : uint8_t {
+  DROPPED_PACKETS = 0,   // Read
+  V4_SELF_IP,            // Read
+  V6_SELF_IP,            // Read
+  PEER_ADDRESS,          // Read & Write
+  RECV_TIMESTAMP,        // Read
+  TTL,                   // Read & Write
+  GOOGLE_PACKET_HEADER,  // Read
+  NUM_BITS,
+};
+static_assert(static_cast<size_t>(QuicUdpPacketInfoBit::NUM_BITS) <=
+                  BitMask64::NumBits(),
+              "BitMask64 not wide enough to hold all bits.");
+
+// BufferSpan points to an unowned buffer, copying this structure only copies
+// the pointer and length, not the buffer itself.
+struct QUIC_EXPORT_PRIVATE BufferSpan {
+  BufferSpan(char* buffer, size_t buffer_len)
+      : buffer(buffer), buffer_len(buffer_len) {}
+
+  BufferSpan() = default;
+  BufferSpan(const BufferSpan& other) = default;
+  BufferSpan& operator=(const BufferSpan& other) = default;
+
+  char* buffer = nullptr;
+  size_t buffer_len = 0;
+};
+
+// QuicUdpPacketInfo contains per-packet information used for sending and
+// receiving.
+class QUIC_EXPORT_PRIVATE QuicUdpPacketInfo {
+ public:
+  BitMask64 bitmask() const { return bitmask_; }
+
+  void Reset() { bitmask_.ClearAll(); }
+
+  bool HasValue(QuicUdpPacketInfoBit bit) const { return bitmask_.IsSet(bit); }
+
+  QuicPacketCount dropped_packets() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::DROPPED_PACKETS));
+    return dropped_packets_;
+  }
+
+  void SetDroppedPackets(QuicPacketCount dropped_packets) {
+    dropped_packets_ = dropped_packets;
+    bitmask_.Set(QuicUdpPacketInfoBit::DROPPED_PACKETS);
+  }
+
+  const QuicIpAddress& self_v4_ip() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V4_SELF_IP));
+    return self_v4_ip_;
+  }
+
+  void SetSelfV4Ip(QuicIpAddress self_v4_ip) {
+    self_v4_ip_ = self_v4_ip;
+    bitmask_.Set(QuicUdpPacketInfoBit::V4_SELF_IP);
+  }
+
+  const QuicIpAddress& self_v6_ip() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V6_SELF_IP));
+    return self_v6_ip_;
+  }
+
+  void SetSelfV6Ip(QuicIpAddress self_v6_ip) {
+    self_v6_ip_ = self_v6_ip;
+    bitmask_.Set(QuicUdpPacketInfoBit::V6_SELF_IP);
+  }
+
+  void SetSelfIp(QuicIpAddress self_ip) {
+    if (self_ip.IsIPv4()) {
+      SetSelfV4Ip(self_ip);
+    } else {
+      SetSelfV6Ip(self_ip);
+    }
+  }
+
+  const QuicSocketAddress& peer_address() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
+    return peer_address_;
+  }
+
+  void SetPeerAddress(QuicSocketAddress peer_address) {
+    peer_address_ = peer_address;
+    bitmask_.Set(QuicUdpPacketInfoBit::PEER_ADDRESS);
+  }
+
+  QuicWallTime receive_timestamp() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::RECV_TIMESTAMP));
+    return receive_timestamp_;
+  }
+
+  void SetReceiveTimestamp(QuicWallTime receive_timestamp) {
+    receive_timestamp_ = receive_timestamp;
+    bitmask_.Set(QuicUdpPacketInfoBit::RECV_TIMESTAMP);
+  }
+
+  int ttl() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::TTL));
+    return ttl_;
+  }
+
+  void SetTtl(int ttl) {
+    ttl_ = ttl;
+    bitmask_.Set(QuicUdpPacketInfoBit::TTL);
+  }
+
+  BufferSpan google_packet_headers() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER));
+    return google_packet_headers_;
+  }
+
+  void SetGooglePacketHeaders(BufferSpan google_packet_headers) {
+    google_packet_headers_ = google_packet_headers;
+    bitmask_.Set(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER);
+  }
+
+ private:
+  BitMask64 bitmask_;
+  QuicPacketCount dropped_packets_;
+  QuicIpAddress self_v4_ip_;
+  QuicIpAddress self_v6_ip_;
+  QuicSocketAddress peer_address_;
+  QuicWallTime receive_timestamp_ = QuicWallTime::Zero();
+  int ttl_;
+  BufferSpan google_packet_headers_;
+};
+
+// QuicUdpSocketApi provides a minimal set of apis for sending and receiving
+// udp packets. The low level udp socket apis differ between kernels and kernel
+// versions, the goal of QuicUdpSocketApi is to hide such differences.
+// We use non-static functions because it is easier to be mocked in tests when
+// needed.
+class QUIC_EXPORT_PRIVATE QuicUdpSocketApi {
+ public:
+  // Creates a non-blocking udp socket, sets the receive/send buffer and enable
+  // receiving of self ip addresses on read.
+  // If address_family == AF_INET6 and ipv6_only is true, receiving of IPv4 self
+  // addresses is disabled. This is only necessary for IPv6 sockets on iOS - all
+  // other platforms can ignore this parameter. Return kQuicInvalidSocketFd if
+  // failed.
+  QuicUdpSocketFd Create(int address_family,
+                         int receive_buffer_size,
+                         int send_buffer_size,
+                         bool ipv6_only = false);
+
+  // Closes |fd|. No-op if |fd| equals to kQuicInvalidSocketFd.
+  void Destroy(QuicUdpSocketFd fd);
+
+  // Bind |fd| to |address|. If |address|'s port number is 0, kernel will choose
+  // a random port to bind to. Caller can use QuicSocketAddress::FromSocket(fd)
+  // to get the bound random port.
+  bool Bind(QuicUdpSocketFd fd, QuicSocketAddress address);
+
+  // Enable receiving of various per-packet information. Return true if the
+  // corresponding information can be received on read.
+  bool EnableDroppedPacketCount(QuicUdpSocketFd fd);
+  bool EnableReceiveTimestamp(QuicUdpSocketFd fd);
+  bool EnableReceiveTtlForV4(QuicUdpSocketFd fd);
+  bool EnableReceiveTtlForV6(QuicUdpSocketFd fd);
+
+  // Wait for |fd| to become readable, up to |timeout|.
+  // Return true if |fd| is readable upon return.
+  bool WaitUntilReadable(QuicUdpSocketFd fd, QuicTime::Delta timeout);
+
+  struct QUIC_EXPORT_PRIVATE ReadPacketResult {
+    bool ok = false;
+    QuicUdpPacketInfo packet_info;
+    BufferSpan packet_buffer;
+    BufferSpan control_buffer;
+
+    void Reset(size_t packet_buffer_length) {
+      ok = false;
+      packet_info.Reset();
+      packet_buffer.buffer_len = packet_buffer_length;
+    }
+  };
+  // Read a packet from |fd|:
+  // packet_info_interested: Bitmask indicating what information caller wants to
+  //                         receive into |result->packet_info|.
+  // result->packet_info:    Received per packet information.
+  // result->packet_buffer:  The packet buffer, to be filled with packet data.
+  //                         |result->packet_buffer.buffer_len| is set to the
+  //                         packet length on a successful return.
+  // result->control_buffer: The control buffer, used by ReadPacket internally.
+  //                         It is recommended to be
+  //                         |kDefaultUdpPacketControlBufferSize| bytes.
+  // result->ok:             True iff a packet is successfully received.
+  //
+  // If |*result| is reused for subsequent ReadPacket() calls, caller needs to
+  // call result->Reset() before each ReadPacket().
+  void ReadPacket(QuicUdpSocketFd fd,
+                  BitMask64 packet_info_interested,
+                  ReadPacketResult* result);
+
+  using ReadPacketResults = std::vector<ReadPacketResult>;
+  // Read up to |results->size()| packets from |fd|. The meaning of each element
+  // in |*results| has been documented on top of |ReadPacket|.
+  // Return the number of elements populated into |*results|, note it is
+  // possible for some of the populated elements to have ok=false.
+  size_t ReadMultiplePackets(QuicUdpSocketFd fd,
+                             BitMask64 packet_info_interested,
+                             ReadPacketResults* results);
+
+  // Write a packet to |fd|.
+  // packet_buffer, packet_buffer_len:  The packet buffer to write.
+  // packet_info:                       The per packet information to set.
+  WriteResult WritePacket(QuicUdpSocketFd fd,
+                          const char* packet_buffer,
+                          size_t packet_buffer_len,
+                          const QuicUdpPacketInfo& packet_info);
+
+ protected:
+  bool SetupSocket(QuicUdpSocketFd fd,
+                   int address_family,
+                   int receive_buffer_size,
+                   int send_buffer_size,
+                   bool ipv6_only);
+  bool EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd);
+  bool EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
diff --git a/quiche/quic/core/quic_udp_socket_posix.cc b/quiche/quic/core/quic_udp_socket_posix.cc
new file mode 100644
index 0000000..5851bea
--- /dev/null
+++ b/quiche/quic/core/quic_udp_socket_posix.cc
@@ -0,0 +1,639 @@
+// Copyright 2019 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 "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_udp_socket_platform_api.h"
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#if defined(__APPLE__) && !defined(__APPLE_USE_RFC_3542)
+#error "__APPLE_USE_RFC_3542 needs to be defined."
+#endif
+
+#if defined(__linux__)
+#include <alloca.h>
+// For SO_TIMESTAMPING.
+#include <linux/net_tstamp.h>
+#endif
+
+#if defined(__linux__) && !defined(__ANDROID__)
+#define QUIC_UDP_SOCKET_SUPPORT_TTL 1
+#endif
+
+namespace quic {
+namespace {
+
+#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
+#define QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING 1
+// This is the structure that SO_TIMESTAMPING fills into the cmsg header.
+// It is well-defined, but does not have a definition in a public header.
+// See https://www.kernel.org/doc/Documentation/networking/timestamping.txt
+// for more information.
+struct LinuxSoTimestamping {
+  // The converted system time of the timestamp.
+  struct timespec systime;
+  // Deprecated; serves only as padding.
+  struct timespec hwtimetrans;
+  // The raw hardware timestamp.
+  struct timespec hwtimeraw;
+};
+const size_t kCmsgSpaceForRecvTimestamp =
+    CMSG_SPACE(sizeof(LinuxSoTimestamping));
+#else
+const size_t kCmsgSpaceForRecvTimestamp = 0;
+#endif
+
+const size_t kMinCmsgSpaceForRead =
+    CMSG_SPACE(sizeof(uint32_t))       // Dropped packet count
+    + CMSG_SPACE(sizeof(in_pktinfo))   // V4 Self IP
+    + CMSG_SPACE(sizeof(in6_pktinfo))  // V6 Self IP
+    + kCmsgSpaceForRecvTimestamp + CMSG_SPACE(sizeof(int))  // TTL
+    + kCmsgSpaceForGooglePacketHeader;
+
+QuicUdpSocketFd CreateNonblockingSocket(int address_family) {
+#if defined(__linux__) && defined(SOCK_NONBLOCK)
+
+  // Create a nonblocking socket directly.
+  int fd = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
+  if (fd < 0) {
+    QUIC_LOG_FIRST_N(ERROR, 100)
+        << "socket() failed with address_family=" << address_family << ": "
+        << strerror(errno);
+    return kQuicInvalidSocketFd;
+  }
+#else
+  // Create a socket and use fcntl to set it to nonblocking.
+  // This implementation is used when building for iOS, OSX and old versions of
+  // Linux (< 2.6.27) and old versions of Android (< API 21).
+  int fd = socket(address_family, SOCK_DGRAM, IPPROTO_UDP);
+  if (fd < 0) {
+    QUIC_LOG_FIRST_N(ERROR, 100)
+        << "socket() failed with address_family=" << address_family << ": "
+        << strerror(errno);
+    return kQuicInvalidSocketFd;
+  }
+  int current_flags = fcntl(fd, F_GETFL, 0);
+  if (current_flags == -1) {
+    QUIC_LOG_FIRST_N(ERROR, 100)
+        << "failed to get current socket flags: " << strerror(errno);
+    close(fd);
+    return kQuicInvalidSocketFd;
+  }
+
+  int rc = fcntl(fd, F_SETFL, current_flags | O_NONBLOCK);
+  if (rc == -1) {
+    QUIC_LOG_FIRST_N(ERROR, 100)
+        << "failed to set socket to non-blocking: " << strerror(errno);
+    close(fd);
+    return kQuicInvalidSocketFd;
+  }
+#endif
+
+  SetGoogleSocketOptions(fd);
+  return fd;
+}  // End CreateNonblockingSocket
+
+void SetV4SelfIpInControlMessage(const QuicIpAddress& self_address,
+                                 cmsghdr* cmsg) {
+  QUICHE_DCHECK(self_address.IsIPv4());
+  in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+  memset(pktinfo, 0, sizeof(in_pktinfo));
+  pktinfo->ipi_ifindex = 0;
+  std::string address_string = self_address.ToPackedString();
+  memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
+         address_string.length());
+}
+
+void SetV6SelfIpInControlMessage(const QuicIpAddress& self_address,
+                                 cmsghdr* cmsg) {
+  QUICHE_DCHECK(self_address.IsIPv6());
+  in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+  memset(pktinfo, 0, sizeof(in6_pktinfo));
+  std::string address_string = self_address.ToPackedString();
+  memcpy(&pktinfo->ipi6_addr, address_string.c_str(), address_string.length());
+}
+
+void PopulatePacketInfoFromControlMessage(struct cmsghdr* cmsg,
+                                          QuicUdpPacketInfo* packet_info,
+                                          BitMask64 packet_info_interested) {
+#if defined(__linux__) && defined(SO_RXQ_OVFL)
+  if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::DROPPED_PACKETS)) {
+      packet_info->SetDroppedPackets(
+          *(reinterpret_cast<uint32_t*> CMSG_DATA(cmsg)));
+    }
+    return;
+  }
+#endif
+
+#if defined(QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING)
+  if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPING) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::RECV_TIMESTAMP)) {
+      LinuxSoTimestamping* linux_ts =
+          reinterpret_cast<LinuxSoTimestamping*>(CMSG_DATA(cmsg));
+      timespec* ts = &linux_ts->systime;
+      int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) +
+                     (static_cast<int64_t>(ts->tv_nsec) / 1000);
+      packet_info->SetReceiveTimestamp(
+          QuicWallTime::FromUNIXMicroseconds(usec));
+    }
+    return;
+  }
+#endif
+
+  if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V6_SELF_IP)) {
+      const in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+      const char* addr_data = reinterpret_cast<const char*>(&info->ipi6_addr);
+      int addr_len = sizeof(in6_addr);
+      QuicIpAddress self_v6_ip;
+      if (self_v6_ip.FromPackedString(addr_data, addr_len)) {
+        packet_info->SetSelfV6Ip(self_v6_ip);
+      } else {
+        QUIC_BUG(quic_bug_10751_1) << "QuicIpAddress::FromPackedString failed";
+      }
+    }
+    return;
+  }
+
+  if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V4_SELF_IP)) {
+      const in_pktinfo* info = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+      const char* addr_data = reinterpret_cast<const char*>(&info->ipi_addr);
+      int addr_len = sizeof(in_addr);
+      QuicIpAddress self_v4_ip;
+      if (self_v4_ip.FromPackedString(addr_data, addr_len)) {
+        packet_info->SetSelfV4Ip(self_v4_ip);
+      } else {
+        QUIC_BUG(quic_bug_10751_2) << "QuicIpAddress::FromPackedString failed";
+      }
+    }
+    return;
+  }
+
+  if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
+      (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_HOPLIMIT)) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::TTL)) {
+      packet_info->SetTtl(*(reinterpret_cast<int*>(CMSG_DATA(cmsg))));
+    }
+    return;
+  }
+
+  if (packet_info_interested.IsSet(
+          QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
+    BufferSpan google_packet_headers;
+    if (GetGooglePacketHeadersFromControlMessage(
+            cmsg, &google_packet_headers.buffer,
+            &google_packet_headers.buffer_len)) {
+      packet_info->SetGooglePacketHeaders(google_packet_headers);
+    }
+  }
+}
+
+bool NextCmsg(msghdr* hdr,
+              char* control_buffer,
+              size_t control_buffer_len,
+              int cmsg_level,
+              int cmsg_type,
+              size_t data_size,
+              cmsghdr** cmsg /*in, out*/) {
+  // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
+  // return nullptr.
+  hdr->msg_controllen += CMSG_SPACE(data_size);
+  if (hdr->msg_controllen > control_buffer_len) {
+    return false;
+  }
+
+  if ((*cmsg) == nullptr) {
+    QUICHE_DCHECK_EQ(nullptr, hdr->msg_control);
+    memset(control_buffer, 0, control_buffer_len);
+    hdr->msg_control = control_buffer;
+    (*cmsg) = CMSG_FIRSTHDR(hdr);
+  } else {
+    QUICHE_DCHECK_NE(nullptr, hdr->msg_control);
+    (*cmsg) = CMSG_NXTHDR(hdr, (*cmsg));
+  }
+
+  if (nullptr == (*cmsg)) {
+    return false;
+  }
+
+  (*cmsg)->cmsg_len = CMSG_LEN(data_size);
+  (*cmsg)->cmsg_level = cmsg_level;
+  (*cmsg)->cmsg_type = cmsg_type;
+
+  return true;
+}
+}  // namespace
+
+QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
+                                         int receive_buffer_size,
+                                         int send_buffer_size,
+                                         bool ipv6_only) {
+  // QUICHE_DCHECK here so the program exits early(before reading packets) in
+  // debug mode. This should have been a static_assert, however it can't be done
+  // on ios/osx because CMSG_SPACE isn't a constant expression there.
+  QUICHE_DCHECK_GE(kDefaultUdpPacketControlBufferSize, kMinCmsgSpaceForRead);
+  QuicUdpSocketFd fd = CreateNonblockingSocket(address_family);
+
+  if (fd == kQuicInvalidSocketFd) {
+    return kQuicInvalidSocketFd;
+  }
+
+  if (!SetupSocket(fd, address_family, receive_buffer_size, send_buffer_size,
+                   ipv6_only)) {
+    Destroy(fd);
+    return kQuicInvalidSocketFd;
+  }
+
+  return fd;
+}
+
+bool QuicUdpSocketApi::SetupSocket(QuicUdpSocketFd fd,
+                                   int address_family,
+                                   int receive_buffer_size,
+                                   int send_buffer_size,
+                                   bool ipv6_only) {
+  // Receive buffer size.
+  if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &receive_buffer_size,
+                 sizeof(receive_buffer_size)) != 0) {
+    QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket recv size";
+    return false;
+  }
+
+  // Send buffer size.
+  if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &send_buffer_size,
+                 sizeof(send_buffer_size)) != 0) {
+    QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket send size";
+    return false;
+  }
+
+  if (!(address_family == AF_INET6 && ipv6_only)) {
+    if (!EnableReceiveSelfIpAddressForV4(fd)) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Failed to enable receiving of self v4 ip";
+      return false;
+    }
+  }
+
+  if (address_family == AF_INET6) {
+    if (!EnableReceiveSelfIpAddressForV6(fd)) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Failed to enable receiving of self v6 ip";
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void QuicUdpSocketApi::Destroy(QuicUdpSocketFd fd) {
+  if (fd != kQuicInvalidSocketFd) {
+    close(fd);
+  }
+}
+
+bool QuicUdpSocketApi::Bind(QuicUdpSocketFd fd, QuicSocketAddress address) {
+  sockaddr_storage addr = address.generic_address();
+  int addr_len =
+      address.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
+  return 0 == bind(fd, reinterpret_cast<sockaddr*>(&addr), addr_len);
+}
+
+bool QuicUdpSocketApi::EnableDroppedPacketCount(QuicUdpSocketFd fd) {
+#if defined(__linux__) && defined(SO_RXQ_OVFL)
+  int get_overflow = 1;
+  return 0 == setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow,
+                         sizeof(get_overflow));
+#else
+  (void)fd;
+  return false;
+#endif
+}
+
+bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd) {
+  int get_self_ip = 1;
+  return 0 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_self_ip,
+                         sizeof(get_self_ip));
+}
+
+bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd) {
+  int get_self_ip = 1;
+  return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_self_ip,
+                         sizeof(get_self_ip));
+}
+
+bool QuicUdpSocketApi::EnableReceiveTimestamp(QuicUdpSocketFd fd) {
+#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
+  int timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
+  return 0 == setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &timestamping,
+                         sizeof(timestamping));
+#else
+  (void)fd;
+  return false;
+#endif
+}
+
+bool QuicUdpSocketApi::EnableReceiveTtlForV4(QuicUdpSocketFd fd) {
+#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
+  int get_ttl = 1;
+  return 0 == setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &get_ttl, sizeof(get_ttl));
+#else
+  (void)fd;
+  return false;
+#endif
+}
+
+bool QuicUdpSocketApi::EnableReceiveTtlForV6(QuicUdpSocketFd fd) {
+#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
+  int get_ttl = 1;
+  return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &get_ttl,
+                         sizeof(get_ttl));
+#else
+  (void)fd;
+  return false;
+#endif
+}
+
+bool QuicUdpSocketApi::WaitUntilReadable(QuicUdpSocketFd fd,
+                                         QuicTime::Delta timeout) {
+  fd_set read_fds;
+  FD_ZERO(&read_fds);
+  FD_SET(fd, &read_fds);
+
+  timeval select_timeout;
+  select_timeout.tv_sec = timeout.ToSeconds();
+  select_timeout.tv_usec = timeout.ToMicroseconds() % 1000000;
+
+  return 1 == select(1 + fd, &read_fds, nullptr, nullptr, &select_timeout);
+}
+
+void QuicUdpSocketApi::ReadPacket(QuicUdpSocketFd fd,
+                                  BitMask64 packet_info_interested,
+                                  ReadPacketResult* result) {
+  result->ok = false;
+  BufferSpan& packet_buffer = result->packet_buffer;
+  BufferSpan& control_buffer = result->control_buffer;
+  QuicUdpPacketInfo* packet_info = &result->packet_info;
+
+  QUICHE_DCHECK_GE(control_buffer.buffer_len, kMinCmsgSpaceForRead);
+
+  struct iovec iov = {packet_buffer.buffer, packet_buffer.buffer_len};
+  struct sockaddr_storage raw_peer_address;
+
+  if (control_buffer.buffer_len > 0) {
+    reinterpret_cast<struct cmsghdr*>(control_buffer.buffer)->cmsg_len =
+        control_buffer.buffer_len;
+  }
+
+  msghdr hdr;
+  hdr.msg_name = &raw_peer_address;
+  hdr.msg_namelen = sizeof(raw_peer_address);
+  hdr.msg_iov = &iov;
+  hdr.msg_iovlen = 1;
+  hdr.msg_flags = 0;
+  hdr.msg_control = control_buffer.buffer;
+  hdr.msg_controllen = control_buffer.buffer_len;
+
+#if defined(__linux__)
+  // If MSG_TRUNC is set on Linux, recvmsg will return the real packet size even
+  // if |packet_buffer| is too small to receive it.
+  int flags = MSG_TRUNC;
+#else
+  int flags = 0;
+#endif
+
+  int bytes_read = recvmsg(fd, &hdr, flags);
+  if (bytes_read < 0) {
+    const int error_num = errno;
+    if (error_num != EAGAIN) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Error reading packet: " << strerror(error_num);
+    }
+    return;
+  }
+
+  if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
+    QUIC_BUG(quic_bug_10751_3)
+        << "Control buffer too small. size:" << control_buffer.buffer_len;
+    return;
+  }
+
+  if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC) ||
+      // Normally "bytes_read > packet_buffer.buffer_len" implies the MSG_TRUNC
+      // bit is set, but it is not the case if tested with config=android_arm64.
+      static_cast<size_t>(bytes_read) > packet_buffer.buffer_len) {
+    QUIC_LOG_FIRST_N(WARNING, 100)
+        << "Received truncated QUIC packet: buffer size:"
+        << packet_buffer.buffer_len << " packet size:" << bytes_read;
+    return;
+  }
+
+  packet_buffer.buffer_len = bytes_read;
+  if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
+    packet_info->SetPeerAddress(QuicSocketAddress(raw_peer_address));
+  }
+
+  if (hdr.msg_controllen > 0) {
+    for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
+         cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
+      BitMask64 prior_bitmask = packet_info->bitmask();
+      PopulatePacketInfoFromControlMessage(cmsg, packet_info,
+                                           packet_info_interested);
+      if (packet_info->bitmask() == prior_bitmask) {
+        QUIC_DLOG(INFO) << "Ignored cmsg_level:" << cmsg->cmsg_level
+                        << ", cmsg_type:" << cmsg->cmsg_type;
+      }
+    }
+  }
+
+  result->ok = true;
+}
+
+size_t QuicUdpSocketApi::ReadMultiplePackets(QuicUdpSocketFd fd,
+                                             BitMask64 packet_info_interested,
+                                             ReadPacketResults* results) {
+#if defined(__linux__) && !defined(__ANDROID__)
+  // Use recvmmsg.
+  size_t hdrs_size = sizeof(mmsghdr) * results->size();
+  mmsghdr* hdrs = static_cast<mmsghdr*>(alloca(hdrs_size));
+  memset(hdrs, 0, hdrs_size);
+
+  struct TempPerPacketData {
+    iovec iov;
+    sockaddr_storage raw_peer_address;
+  };
+  TempPerPacketData* packet_data_array = static_cast<TempPerPacketData*>(
+      alloca(sizeof(TempPerPacketData) * results->size()));
+
+  for (size_t i = 0; i < results->size(); ++i) {
+    (*results)[i].ok = false;
+
+    msghdr* hdr = &hdrs[i].msg_hdr;
+    TempPerPacketData* packet_data = &packet_data_array[i];
+    packet_data->iov.iov_base = (*results)[i].packet_buffer.buffer;
+    packet_data->iov.iov_len = (*results)[i].packet_buffer.buffer_len;
+
+    hdr->msg_name = &packet_data->raw_peer_address;
+    hdr->msg_namelen = sizeof(sockaddr_storage);
+    hdr->msg_iov = &packet_data->iov;
+    hdr->msg_iovlen = 1;
+    hdr->msg_flags = 0;
+    hdr->msg_control = (*results)[i].control_buffer.buffer;
+    hdr->msg_controllen = (*results)[i].control_buffer.buffer_len;
+
+    QUICHE_DCHECK_GE(hdr->msg_controllen, kMinCmsgSpaceForRead);
+  }
+  // If MSG_TRUNC is set on Linux, recvmmsg will return the real packet size in
+  // |hdrs[i].msg_len| even if packet buffer is too small to receive it.
+  int packets_read = recvmmsg(fd, hdrs, results->size(), MSG_TRUNC, nullptr);
+  if (packets_read <= 0) {
+    const int error_num = errno;
+    if (error_num != EAGAIN) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Error reading packets: " << strerror(error_num);
+    }
+    return 0;
+  }
+
+  for (int i = 0; i < packets_read; ++i) {
+    if (hdrs[i].msg_len == 0) {
+      continue;
+    }
+
+    msghdr& hdr = hdrs[i].msg_hdr;
+    if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
+      QUIC_BUG(quic_bug_10751_4) << "Control buffer too small. size:"
+                                 << (*results)[i].control_buffer.buffer_len
+                                 << ", need:" << hdr.msg_controllen;
+      continue;
+    }
+
+    if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC)) {
+      QUIC_LOG_FIRST_N(WARNING, 100)
+          << "Received truncated QUIC packet: buffer size:"
+          << (*results)[i].packet_buffer.buffer_len
+          << " packet size:" << hdrs[i].msg_len;
+      continue;
+    }
+
+    (*results)[i].ok = true;
+    (*results)[i].packet_buffer.buffer_len = hdrs[i].msg_len;
+
+    QuicUdpPacketInfo* packet_info = &(*results)[i].packet_info;
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
+      packet_info->SetPeerAddress(
+          QuicSocketAddress(packet_data_array[i].raw_peer_address));
+    }
+
+    if (hdr.msg_controllen > 0) {
+      for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
+           cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
+        PopulatePacketInfoFromControlMessage(cmsg, packet_info,
+                                             packet_info_interested);
+      }
+    }
+  }
+  return packets_read;
+#else
+  size_t num_packets = 0;
+  for (ReadPacketResult& result : *results) {
+    result.ok = false;
+  }
+  for (ReadPacketResult& result : *results) {
+    errno = 0;
+    ReadPacket(fd, packet_info_interested, &result);
+    if (!result.ok && errno == EAGAIN) {
+      break;
+    }
+    ++num_packets;
+  }
+  return num_packets;
+#endif
+}
+
+WriteResult QuicUdpSocketApi::WritePacket(
+    QuicUdpSocketFd fd,
+    const char* packet_buffer,
+    size_t packet_buffer_len,
+    const QuicUdpPacketInfo& packet_info) {
+  if (!packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
+    return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+  }
+
+  char control_buffer[512];
+  sockaddr_storage raw_peer_address =
+      packet_info.peer_address().generic_address();
+  iovec iov = {const_cast<char*>(packet_buffer), packet_buffer_len};
+
+  msghdr hdr;
+  hdr.msg_name = &raw_peer_address;
+  hdr.msg_namelen = packet_info.peer_address().host().IsIPv4()
+                        ? sizeof(sockaddr_in)
+                        : sizeof(sockaddr_in6);
+  hdr.msg_iov = &iov;
+  hdr.msg_iovlen = 1;
+  hdr.msg_flags = 0;
+  hdr.msg_control = nullptr;
+  hdr.msg_controllen = 0;
+
+  cmsghdr* cmsg = nullptr;
+
+  // Set self IP.
+  if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP) &&
+      packet_info.self_v4_ip().IsInitialized()) {
+    if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IP,
+                  IP_PKTINFO, sizeof(in_pktinfo), &cmsg)) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Not enough buffer to set self v4 ip address.";
+      return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+    }
+    SetV4SelfIpInControlMessage(packet_info.self_v4_ip(), cmsg);
+  } else if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP) &&
+             packet_info.self_v6_ip().IsInitialized()) {
+    if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IPV6,
+                  IPV6_PKTINFO, sizeof(in6_pktinfo), &cmsg)) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Not enough buffer to set self v6 ip address.";
+      return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+    }
+    SetV6SelfIpInControlMessage(packet_info.self_v6_ip(), cmsg);
+  }
+
+#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
+  // Set ttl.
+  if (packet_info.HasValue(QuicUdpPacketInfoBit::TTL)) {
+    int cmsg_level =
+        packet_info.peer_address().host().IsIPv4() ? IPPROTO_IP : IPPROTO_IPV6;
+    int cmsg_type =
+        packet_info.peer_address().host().IsIPv4() ? IP_TTL : IPV6_HOPLIMIT;
+    if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), cmsg_level,
+                  cmsg_type, sizeof(int), &cmsg)) {
+      QUIC_LOG_FIRST_N(ERROR, 100) << "Not enough buffer to set ttl.";
+      return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+    }
+    *reinterpret_cast<int*>(CMSG_DATA(cmsg)) = packet_info.ttl();
+  }
+#endif
+
+  int rc;
+  do {
+    rc = sendmsg(fd, &hdr, 0);
+  } while (rc < 0 && errno == EINTR);
+  if (rc >= 0) {
+    return WriteResult(WRITE_STATUS_OK, rc);
+  }
+  return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
+                         ? WRITE_STATUS_BLOCKED
+                         : WRITE_STATUS_ERROR,
+                     errno);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_unacked_packet_map.cc b/quiche/quic/core/quic_unacked_packet_map.cc
new file mode 100644
index 0000000..63c345e
--- /dev/null
+++ b/quiche/quic/core/quic_unacked_packet_map.cc
@@ -0,0 +1,658 @@
+// 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 "quiche/quic/core/quic_unacked_packet_map.h"
+
+#include <cstddef>
+#include <limits>
+#include <type_traits>
+
+#include "absl/container/inlined_vector.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+namespace {
+bool WillStreamFrameLengthSumWrapAround(QuicPacketLength lhs,
+                                        QuicPacketLength rhs) {
+  static_assert(
+      std::is_unsigned<QuicPacketLength>::value,
+      "This function assumes QuicPacketLength is an unsigned integer type.");
+  return std::numeric_limits<QuicPacketLength>::max() - lhs < rhs;
+}
+
+enum QuicFrameTypeBitfield : uint32_t {
+  kInvalidFrameBitfield = 0,
+  kPaddingFrameBitfield = 1,
+  kRstStreamFrameBitfield = 1 << 1,
+  kConnectionCloseFrameBitfield = 1 << 2,
+  kGoawayFrameBitfield = 1 << 3,
+  kWindowUpdateFrameBitfield = 1 << 4,
+  kBlockedFrameBitfield = 1 << 5,
+  kStopWaitingFrameBitfield = 1 << 6,
+  kPingFrameBitfield = 1 << 7,
+  kCryptoFrameBitfield = 1 << 8,
+  kHandshakeDoneFrameBitfield = 1 << 9,
+  kStreamFrameBitfield = 1 << 10,
+  kAckFrameBitfield = 1 << 11,
+  kMtuDiscoveryFrameBitfield = 1 << 12,
+  kNewConnectionIdFrameBitfield = 1 << 13,
+  kMaxStreamsFrameBitfield = 1 << 14,
+  kStreamsBlockedFrameBitfield = 1 << 15,
+  kPathResponseFrameBitfield = 1 << 16,
+  kPathChallengeFrameBitfield = 1 << 17,
+  kStopSendingFrameBitfield = 1 << 18,
+  kMessageFrameBitfield = 1 << 19,
+  kNewTokenFrameBitfield = 1 << 20,
+  kRetireConnectionIdFrameBitfield = 1 << 21,
+  kAckFrequencyFrameBitfield = 1 << 22,
+};
+
+QuicFrameTypeBitfield GetFrameTypeBitfield(QuicFrameType type) {
+  switch (type) {
+    case PADDING_FRAME:
+      return kPaddingFrameBitfield;
+    case RST_STREAM_FRAME:
+      return kRstStreamFrameBitfield;
+    case CONNECTION_CLOSE_FRAME:
+      return kConnectionCloseFrameBitfield;
+    case GOAWAY_FRAME:
+      return kGoawayFrameBitfield;
+    case WINDOW_UPDATE_FRAME:
+      return kWindowUpdateFrameBitfield;
+    case BLOCKED_FRAME:
+      return kBlockedFrameBitfield;
+    case STOP_WAITING_FRAME:
+      return kStopWaitingFrameBitfield;
+    case PING_FRAME:
+      return kPingFrameBitfield;
+    case CRYPTO_FRAME:
+      return kCryptoFrameBitfield;
+    case HANDSHAKE_DONE_FRAME:
+      return kHandshakeDoneFrameBitfield;
+    case STREAM_FRAME:
+      return kStreamFrameBitfield;
+    case ACK_FRAME:
+      return kAckFrameBitfield;
+    case MTU_DISCOVERY_FRAME:
+      return kMtuDiscoveryFrameBitfield;
+    case NEW_CONNECTION_ID_FRAME:
+      return kNewConnectionIdFrameBitfield;
+    case MAX_STREAMS_FRAME:
+      return kMaxStreamsFrameBitfield;
+    case STREAMS_BLOCKED_FRAME:
+      return kStreamsBlockedFrameBitfield;
+    case PATH_RESPONSE_FRAME:
+      return kPathResponseFrameBitfield;
+    case PATH_CHALLENGE_FRAME:
+      return kPathChallengeFrameBitfield;
+    case STOP_SENDING_FRAME:
+      return kStopSendingFrameBitfield;
+    case MESSAGE_FRAME:
+      return kMessageFrameBitfield;
+    case NEW_TOKEN_FRAME:
+      return kNewTokenFrameBitfield;
+    case RETIRE_CONNECTION_ID_FRAME:
+      return kRetireConnectionIdFrameBitfield;
+    case ACK_FREQUENCY_FRAME:
+      return kAckFrequencyFrameBitfield;
+    case NUM_FRAME_TYPES:
+      QUIC_BUG(quic_bug_10518_1) << "Unexpected frame type";
+      return kInvalidFrameBitfield;
+  }
+  QUIC_BUG(quic_bug_10518_2) << "Unexpected frame type";
+  return kInvalidFrameBitfield;
+}
+
+}  // namespace
+
+QuicUnackedPacketMap::QuicUnackedPacketMap(Perspective perspective)
+    : perspective_(perspective),
+      least_unacked_(FirstSendingPacketNumber()),
+      bytes_in_flight_(0),
+      bytes_in_flight_per_packet_number_space_{0, 0, 0},
+      packets_in_flight_(0),
+      last_inflight_packet_sent_time_(QuicTime::Zero()),
+      last_inflight_packets_sent_time_{{QuicTime::Zero()},
+                                       {QuicTime::Zero()},
+                                       {QuicTime::Zero()}},
+      last_crypto_packet_sent_time_(QuicTime::Zero()),
+      session_notifier_(nullptr),
+      supports_multiple_packet_number_spaces_(false) {
+}
+
+QuicUnackedPacketMap::~QuicUnackedPacketMap() {
+  for (QuicTransmissionInfo& transmission_info : unacked_packets_) {
+    DeleteFrames(&(transmission_info.retransmittable_frames));
+  }
+}
+
+void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* mutable_packet,
+                                         TransmissionType transmission_type,
+                                         QuicTime sent_time,
+                                         bool set_in_flight,
+                                         bool measure_rtt) {
+  const SerializedPacket& packet = *mutable_packet;
+  QuicPacketNumber packet_number = packet.packet_number;
+  QuicPacketLength bytes_sent = packet.encrypted_length;
+  QUIC_BUG_IF(quic_bug_12645_1, largest_sent_packet_.IsInitialized() &&
+                                    largest_sent_packet_ >= packet_number)
+      << "largest_sent_packet_: " << largest_sent_packet_
+      << ", packet_number: " << packet_number;
+  QUICHE_DCHECK_GE(packet_number, least_unacked_ + unacked_packets_.size());
+  while (least_unacked_ + unacked_packets_.size() < packet_number) {
+    unacked_packets_.push_back(QuicTransmissionInfo());
+    unacked_packets_.back().state = NEVER_SENT;
+  }
+
+  const bool has_crypto_handshake = packet.has_crypto_handshake == IS_HANDSHAKE;
+  QuicTransmissionInfo info(packet.encryption_level, transmission_type,
+                            sent_time, bytes_sent, has_crypto_handshake,
+                            packet.has_ack_frequency);
+  info.largest_acked = packet.largest_acked;
+  largest_sent_largest_acked_.UpdateMax(packet.largest_acked);
+
+  if (!measure_rtt) {
+    QUIC_BUG_IF(quic_bug_12645_2, set_in_flight)
+        << "Packet " << mutable_packet->packet_number << ", transmission type "
+        << TransmissionTypeToString(mutable_packet->transmission_type)
+        << ", retransmittable frames: "
+        << QuicFramesToString(mutable_packet->retransmittable_frames)
+        << ", nonretransmittable_frames: "
+        << QuicFramesToString(mutable_packet->nonretransmittable_frames);
+    info.state = NOT_CONTRIBUTING_RTT;
+  }
+
+  largest_sent_packet_ = packet_number;
+  if (set_in_flight) {
+    const PacketNumberSpace packet_number_space =
+        GetPacketNumberSpace(info.encryption_level);
+    bytes_in_flight_ += bytes_sent;
+    bytes_in_flight_per_packet_number_space_[packet_number_space] += bytes_sent;
+    ++packets_in_flight_;
+    info.in_flight = true;
+    largest_sent_retransmittable_packets_[packet_number_space] = packet_number;
+    last_inflight_packet_sent_time_ = sent_time;
+    last_inflight_packets_sent_time_[packet_number_space] = sent_time;
+  }
+  unacked_packets_.push_back(std::move(info));
+  // Swap the retransmittable frames to avoid allocations.
+  // TODO(ianswett): Could use emplace_back when Chromium can.
+  if (has_crypto_handshake) {
+    last_crypto_packet_sent_time_ = sent_time;
+  }
+
+  mutable_packet->retransmittable_frames.swap(
+      unacked_packets_.back().retransmittable_frames);
+}
+
+void QuicUnackedPacketMap::RemoveObsoletePackets() {
+  while (!unacked_packets_.empty()) {
+    if (!IsPacketUseless(least_unacked_, unacked_packets_.front())) {
+      break;
+    }
+    DeleteFrames(&unacked_packets_.front().retransmittable_frames);
+    unacked_packets_.pop_front();
+    ++least_unacked_;
+  }
+}
+
+bool QuicUnackedPacketMap::HasRetransmittableFrames(
+    QuicPacketNumber packet_number) const {
+  QUICHE_DCHECK_GE(packet_number, least_unacked_);
+  QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
+  return HasRetransmittableFrames(
+      unacked_packets_[packet_number - least_unacked_]);
+}
+
+bool QuicUnackedPacketMap::HasRetransmittableFrames(
+    const QuicTransmissionInfo& info) const {
+  if (!QuicUtils::IsAckable(info.state)) {
+    return false;
+  }
+
+  for (const auto& frame : info.retransmittable_frames) {
+    if (session_notifier_->IsFrameOutstanding(frame)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicUnackedPacketMap::RemoveRetransmittability(
+    QuicTransmissionInfo* info) {
+  DeleteFrames(&info->retransmittable_frames);
+  info->first_sent_after_loss.Clear();
+}
+
+void QuicUnackedPacketMap::RemoveRetransmittability(
+    QuicPacketNumber packet_number) {
+  QUICHE_DCHECK_GE(packet_number, least_unacked_);
+  QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
+  QuicTransmissionInfo* info =
+      &unacked_packets_[packet_number - least_unacked_];
+  RemoveRetransmittability(info);
+}
+
+void QuicUnackedPacketMap::IncreaseLargestAcked(
+    QuicPacketNumber largest_acked) {
+  QUICHE_DCHECK(!largest_acked_.IsInitialized() ||
+                largest_acked_ <= largest_acked);
+  largest_acked_ = largest_acked;
+}
+
+void QuicUnackedPacketMap::MaybeUpdateLargestAckedOfPacketNumberSpace(
+    PacketNumberSpace packet_number_space,
+    QuicPacketNumber packet_number) {
+  largest_acked_packets_[packet_number_space].UpdateMax(packet_number);
+}
+
+bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt(
+    QuicPacketNumber packet_number,
+    const QuicTransmissionInfo& info) const {
+  // Packet can be used for RTT measurement if it may yet be acked as the
+  // largest observed packet by the receiver.
+  return QuicUtils::IsAckable(info.state) &&
+         (!largest_acked_.IsInitialized() || packet_number > largest_acked_) &&
+         info.state != NOT_CONTRIBUTING_RTT;
+}
+
+bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl(
+    const QuicTransmissionInfo& info) const {
+  // Packet contributes to congestion control if it is considered inflight.
+  return info.in_flight;
+}
+
+bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData(
+    const QuicTransmissionInfo& info) const {
+  // Wait for 1 RTT before giving up on the lost packet.
+  return info.first_sent_after_loss.IsInitialized() &&
+         (!largest_acked_.IsInitialized() ||
+          info.first_sent_after_loss > largest_acked_);
+}
+
+bool QuicUnackedPacketMap::IsPacketUseless(
+    QuicPacketNumber packet_number,
+    const QuicTransmissionInfo& info) const {
+  return !IsPacketUsefulForMeasuringRtt(packet_number, info) &&
+         !IsPacketUsefulForCongestionControl(info) &&
+         !IsPacketUsefulForRetransmittableData(info);
+}
+
+bool QuicUnackedPacketMap::IsUnacked(QuicPacketNumber packet_number) const {
+  if (packet_number < least_unacked_ ||
+      packet_number >= least_unacked_ + unacked_packets_.size()) {
+    return false;
+  }
+  return !IsPacketUseless(packet_number,
+                          unacked_packets_[packet_number - least_unacked_]);
+}
+
+void QuicUnackedPacketMap::RemoveFromInFlight(QuicTransmissionInfo* info) {
+  if (info->in_flight) {
+    QUIC_BUG_IF(quic_bug_12645_3, bytes_in_flight_ < info->bytes_sent);
+    QUIC_BUG_IF(quic_bug_12645_4, packets_in_flight_ == 0);
+    bytes_in_flight_ -= info->bytes_sent;
+    --packets_in_flight_;
+
+    const PacketNumberSpace packet_number_space =
+        GetPacketNumberSpace(info->encryption_level);
+    if (bytes_in_flight_per_packet_number_space_[packet_number_space] <
+        info->bytes_sent) {
+      QUIC_BUG(quic_bug_10518_3)
+          << "bytes_in_flight: "
+          << bytes_in_flight_per_packet_number_space_[packet_number_space]
+          << " is smaller than bytes_sent: " << info->bytes_sent
+          << " for packet number space: "
+          << PacketNumberSpaceToString(packet_number_space);
+      bytes_in_flight_per_packet_number_space_[packet_number_space] = 0;
+    } else {
+      bytes_in_flight_per_packet_number_space_[packet_number_space] -=
+          info->bytes_sent;
+    }
+    if (bytes_in_flight_per_packet_number_space_[packet_number_space] == 0) {
+      last_inflight_packets_sent_time_[packet_number_space] = QuicTime::Zero();
+    }
+
+    info->in_flight = false;
+  }
+}
+
+void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) {
+  QUICHE_DCHECK_GE(packet_number, least_unacked_);
+  QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
+  QuicTransmissionInfo* info =
+      &unacked_packets_[packet_number - least_unacked_];
+  RemoveFromInFlight(info);
+}
+
+absl::InlinedVector<QuicPacketNumber, 2>
+QuicUnackedPacketMap::NeuterUnencryptedPackets() {
+  absl::InlinedVector<QuicPacketNumber, 2> neutered_packets;
+  QuicPacketNumber packet_number = GetLeastUnacked();
+  for (QuicUnackedPacketMap::iterator it = begin(); it != end();
+       ++it, ++packet_number) {
+    if (!it->retransmittable_frames.empty() &&
+        it->encryption_level == ENCRYPTION_INITIAL) {
+      QUIC_DVLOG(2) << "Neutering unencrypted packet " << packet_number;
+      // Once the connection swithes to forward secure, no unencrypted packets
+      // will be sent. The data has been abandoned in the cryto stream. Remove
+      // it from in flight.
+      RemoveFromInFlight(packet_number);
+      it->state = NEUTERED;
+      neutered_packets.push_back(packet_number);
+      // Notify session that the data has been delivered (but do not notify
+      // send algorithm).
+      // TODO(b/148868195): use NotifyFramesNeutered.
+      NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
+      QUICHE_DCHECK(!HasRetransmittableFrames(*it));
+    }
+  }
+  QUICHE_DCHECK(!supports_multiple_packet_number_spaces_ ||
+                last_inflight_packets_sent_time_[INITIAL_DATA] ==
+                    QuicTime::Zero());
+  return neutered_packets;
+}
+
+absl::InlinedVector<QuicPacketNumber, 2>
+QuicUnackedPacketMap::NeuterHandshakePackets() {
+  absl::InlinedVector<QuicPacketNumber, 2> neutered_packets;
+  QuicPacketNumber packet_number = GetLeastUnacked();
+  for (QuicUnackedPacketMap::iterator it = begin(); it != end();
+       ++it, ++packet_number) {
+    if (!it->retransmittable_frames.empty() &&
+        GetPacketNumberSpace(it->encryption_level) == HANDSHAKE_DATA) {
+      QUIC_DVLOG(2) << "Neutering handshake packet " << packet_number;
+      RemoveFromInFlight(packet_number);
+      // Notify session that the data has been delivered (but do not notify
+      // send algorithm).
+      it->state = NEUTERED;
+      neutered_packets.push_back(packet_number);
+      // TODO(b/148868195): use NotifyFramesNeutered.
+      NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
+    }
+  }
+  QUICHE_DCHECK(!supports_multiple_packet_number_spaces() ||
+                last_inflight_packets_sent_time_[HANDSHAKE_DATA] ==
+                    QuicTime::Zero());
+  return neutered_packets;
+}
+
+bool QuicUnackedPacketMap::HasInFlightPackets() const {
+  return bytes_in_flight_ > 0;
+}
+
+const QuicTransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
+    QuicPacketNumber packet_number) const {
+  return unacked_packets_[packet_number - least_unacked_];
+}
+
+QuicTransmissionInfo* QuicUnackedPacketMap::GetMutableTransmissionInfo(
+    QuicPacketNumber packet_number) {
+  return &unacked_packets_[packet_number - least_unacked_];
+}
+
+QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime() const {
+  return last_inflight_packet_sent_time_;
+}
+
+QuicTime QuicUnackedPacketMap::GetLastCryptoPacketSentTime() const {
+  return last_crypto_packet_sent_time_;
+}
+
+size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
+  size_t unacked_packet_count = 0;
+  QuicPacketNumber packet_number = least_unacked_;
+  for (auto it = begin(); it != end(); ++it, ++packet_number) {
+    if (!IsPacketUseless(packet_number, *it)) {
+      ++unacked_packet_count;
+    }
+  }
+  return unacked_packet_count;
+}
+
+bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
+  if (bytes_in_flight_ > kDefaultTCPMSS) {
+    return true;
+  }
+  size_t num_in_flight = 0;
+  for (auto it = rbegin(); it != rend(); ++it) {
+    if (it->in_flight) {
+      ++num_in_flight;
+    }
+    if (num_in_flight > 1) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
+  return session_notifier_->HasUnackedCryptoData();
+}
+
+bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
+  for (auto it = rbegin(); it != rend(); ++it) {
+    if (it->in_flight && HasRetransmittableFrames(*it)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const {
+  return least_unacked_;
+}
+
+void QuicUnackedPacketMap::SetSessionNotifier(
+    SessionNotifierInterface* session_notifier) {
+  session_notifier_ = session_notifier;
+}
+
+bool QuicUnackedPacketMap::NotifyFramesAcked(const QuicTransmissionInfo& info,
+                                             QuicTime::Delta ack_delay,
+                                             QuicTime receive_timestamp) {
+  if (session_notifier_ == nullptr) {
+    return false;
+  }
+  bool new_data_acked = false;
+  for (const QuicFrame& frame : info.retransmittable_frames) {
+    if (session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp)) {
+      new_data_acked = true;
+    }
+  }
+  return new_data_acked;
+}
+
+void QuicUnackedPacketMap::NotifyFramesLost(const QuicTransmissionInfo& info,
+                                            TransmissionType /*type*/) {
+  for (const QuicFrame& frame : info.retransmittable_frames) {
+    session_notifier_->OnFrameLost(frame);
+  }
+}
+
+bool QuicUnackedPacketMap::RetransmitFrames(const QuicFrames& frames,
+                                            TransmissionType type) {
+  return session_notifier_->RetransmitFrames(frames, type);
+}
+
+void QuicUnackedPacketMap::MaybeAggregateAckedStreamFrame(
+    const QuicTransmissionInfo& info,
+    QuicTime::Delta ack_delay,
+    QuicTime receive_timestamp) {
+  if (session_notifier_ == nullptr) {
+    return;
+  }
+  for (const auto& frame : info.retransmittable_frames) {
+    // Determine whether acked stream frame can be aggregated.
+    const bool can_aggregate =
+        frame.type == STREAM_FRAME &&
+        frame.stream_frame.stream_id == aggregated_stream_frame_.stream_id &&
+        frame.stream_frame.offset == aggregated_stream_frame_.offset +
+                                         aggregated_stream_frame_.data_length &&
+        // We would like to increment aggregated_stream_frame_.data_length by
+        // frame.stream_frame.data_length, so we need to make sure their sum is
+        // representable by QuicPacketLength, which is the type of the former.
+        !WillStreamFrameLengthSumWrapAround(
+            aggregated_stream_frame_.data_length,
+            frame.stream_frame.data_length);
+
+    if (can_aggregate) {
+      // Aggregate stream frame.
+      aggregated_stream_frame_.data_length += frame.stream_frame.data_length;
+      aggregated_stream_frame_.fin = frame.stream_frame.fin;
+      if (aggregated_stream_frame_.fin) {
+        // Notify session notifier aggregated stream frame gets acked if fin is
+        // acked.
+        NotifyAggregatedStreamFrameAcked(ack_delay);
+      }
+      continue;
+    }
+
+    NotifyAggregatedStreamFrameAcked(ack_delay);
+    if (frame.type != STREAM_FRAME || frame.stream_frame.fin) {
+      session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp);
+      continue;
+    }
+
+    // Delay notifying session notifier stream frame gets acked in case it can
+    // be aggregated with following acked ones.
+    aggregated_stream_frame_.stream_id = frame.stream_frame.stream_id;
+    aggregated_stream_frame_.offset = frame.stream_frame.offset;
+    aggregated_stream_frame_.data_length = frame.stream_frame.data_length;
+    aggregated_stream_frame_.fin = frame.stream_frame.fin;
+  }
+}
+
+void QuicUnackedPacketMap::NotifyAggregatedStreamFrameAcked(
+    QuicTime::Delta ack_delay) {
+  if (aggregated_stream_frame_.stream_id == static_cast<QuicStreamId>(-1) ||
+      session_notifier_ == nullptr) {
+    // Aggregated stream frame is empty.
+    return;
+  }
+  // Note: there is no receive_timestamp for an aggregated stream frame.  The
+  // frames that are aggregated may not have been received at the same time.
+  session_notifier_->OnFrameAcked(QuicFrame(aggregated_stream_frame_),
+                                  ack_delay,
+                                  /*receive_timestamp=*/QuicTime::Zero());
+  // Clear aggregated stream frame.
+  aggregated_stream_frame_.stream_id = -1;
+}
+
+PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
+    QuicPacketNumber packet_number) const {
+  return GetPacketNumberSpace(
+      GetTransmissionInfo(packet_number).encryption_level);
+}
+
+PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
+    EncryptionLevel encryption_level) const {
+  if (supports_multiple_packet_number_spaces_) {
+    return QuicUtils::GetPacketNumberSpace(encryption_level);
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    return encryption_level == ENCRYPTION_INITIAL ? HANDSHAKE_DATA
+                                                  : APPLICATION_DATA;
+  }
+  return encryption_level == ENCRYPTION_FORWARD_SECURE ? APPLICATION_DATA
+                                                       : HANDSHAKE_DATA;
+}
+
+QuicPacketNumber QuicUnackedPacketMap::GetLargestAckedOfPacketNumberSpace(
+    PacketNumberSpace packet_number_space) const {
+  if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10518_4)
+        << "Invalid packet number space: " << packet_number_space;
+    return QuicPacketNumber();
+  }
+  return largest_acked_packets_[packet_number_space];
+}
+
+QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime(
+    PacketNumberSpace packet_number_space) const {
+  if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10518_5)
+        << "Invalid packet number space: " << packet_number_space;
+    return QuicTime::Zero();
+  }
+  return last_inflight_packets_sent_time_[packet_number_space];
+}
+
+QuicPacketNumber
+QuicUnackedPacketMap::GetLargestSentRetransmittableOfPacketNumberSpace(
+    PacketNumberSpace packet_number_space) const {
+  if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10518_6)
+        << "Invalid packet number space: " << packet_number_space;
+    return QuicPacketNumber();
+  }
+  return largest_sent_retransmittable_packets_[packet_number_space];
+}
+
+const QuicTransmissionInfo*
+QuicUnackedPacketMap::GetFirstInFlightTransmissionInfo() const {
+  QUICHE_DCHECK(HasInFlightPackets());
+  for (auto it = begin(); it != end(); ++it) {
+    if (it->in_flight) {
+      return &(*it);
+    }
+  }
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+const QuicTransmissionInfo*
+QuicUnackedPacketMap::GetFirstInFlightTransmissionInfoOfSpace(
+    PacketNumberSpace packet_number_space) const {
+  // TODO(fayang): Optimize this part if arm 1st PTO with first in flight sent
+  // time works.
+  for (auto it = begin(); it != end(); ++it) {
+    if (it->in_flight &&
+        GetPacketNumberSpace(it->encryption_level) == packet_number_space) {
+      return &(*it);
+    }
+  }
+  return nullptr;
+}
+
+void QuicUnackedPacketMap::EnableMultiplePacketNumberSpacesSupport() {
+  if (supports_multiple_packet_number_spaces_) {
+    QUIC_BUG(quic_bug_10518_7)
+        << "Multiple packet number spaces has already been enabled";
+    return;
+  }
+  if (largest_sent_packet_.IsInitialized()) {
+    QUIC_BUG(quic_bug_10518_8)
+        << "Try to enable multiple packet number spaces support after any "
+           "packet has been sent.";
+    return;
+  }
+
+  supports_multiple_packet_number_spaces_ = true;
+}
+
+int32_t QuicUnackedPacketMap::GetLastPacketContent() const {
+  if (empty()) {
+    // Use -1 to distinguish with packets with no retransmittable frames nor
+    // acks.
+    return -1;
+  }
+  int32_t content = 0;
+  const QuicTransmissionInfo& last_packet = unacked_packets_.back();
+  for (const auto& frame : last_packet.retransmittable_frames) {
+    content |= GetFrameTypeBitfield(frame.type);
+  }
+  if (last_packet.largest_acked.IsInitialized()) {
+    content |= GetFrameTypeBitfield(ACK_FRAME);
+  }
+  return content;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_unacked_packet_map.h b/quiche/quic/core/quic_unacked_packet_map.h
new file mode 100644
index 0000000..ebbabe8
--- /dev/null
+++ b/quiche/quic/core/quic_unacked_packet_map.h
@@ -0,0 +1,339 @@
+// 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_CORE_QUIC_UNACKED_PACKET_MAP_H_
+#define QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_transmission_info.h"
+#include "quiche/quic/core/session_notifier_interface.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class QuicUnackedPacketMapPeer;
+}  // namespace test
+
+// Class which tracks unacked packets for three purposes:
+// 1) Track retransmittable data, including multiple transmissions of frames.
+// 2) Track packets and bytes in flight for congestion control.
+// 3) Track sent time of packets to provide RTT measurements from acks.
+class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
+ public:
+  QuicUnackedPacketMap(Perspective perspective);
+  QuicUnackedPacketMap(const QuicUnackedPacketMap&) = delete;
+  QuicUnackedPacketMap& operator=(const QuicUnackedPacketMap&) = delete;
+  ~QuicUnackedPacketMap();
+
+  // Adds |mutable_packet| to the map and marks it as sent at |sent_time|.
+  // Marks the packet as in flight if |set_in_flight| is true.
+  // Packets marked as in flight are expected to be marked as missing when they
+  // don't arrive, indicating the need for retransmission.
+  // Any retransmittible_frames in |mutable_packet| are swapped from
+  // |mutable_packet| into the QuicTransmissionInfo.
+  void AddSentPacket(SerializedPacket* mutable_packet,
+                     TransmissionType transmission_type,
+                     QuicTime sent_time,
+                     bool set_in_flight,
+                     bool measure_rtt);
+
+  // Returns true if the packet |packet_number| is unacked.
+  bool IsUnacked(QuicPacketNumber packet_number) const;
+
+  // Notifies session_notifier that frames have been acked. Returns true if any
+  // new data gets acked, returns false otherwise.
+  bool NotifyFramesAcked(const QuicTransmissionInfo& info,
+                         QuicTime::Delta ack_delay,
+                         QuicTime receive_timestamp);
+
+  // Notifies session_notifier that frames in |info| are considered as lost.
+  void NotifyFramesLost(const QuicTransmissionInfo& info,
+                        TransmissionType type);
+
+  // Notifies session_notifier to retransmit frames with |transmission_type|.
+  // Returns true if all data gets retransmitted.
+  bool RetransmitFrames(const QuicFrames& frames, TransmissionType type);
+
+  // Marks |info| as no longer in flight.
+  void RemoveFromInFlight(QuicTransmissionInfo* info);
+
+  // Marks |packet_number| as no longer in flight.
+  void RemoveFromInFlight(QuicPacketNumber packet_number);
+
+  // Called to neuter all unencrypted packets to ensure they do not get
+  // retransmitted. Returns a vector of neutered packet numbers.
+  absl::InlinedVector<QuicPacketNumber, 2> NeuterUnencryptedPackets();
+
+  // Called to neuter packets in handshake packet number space to ensure they do
+  // not get retransmitted. Returns a vector of neutered packet numbers.
+  // TODO(fayang): Consider to combine this with NeuterUnencryptedPackets.
+  absl::InlinedVector<QuicPacketNumber, 2> NeuterHandshakePackets();
+
+  // Returns true if |packet_number| has retransmittable frames. This will
+  // return false if all frames of this packet are either non-retransmittable or
+  // have been acked.
+  bool HasRetransmittableFrames(QuicPacketNumber packet_number) const;
+
+  // Returns true if |info| has retransmittable frames. This will return false
+  // if all frames of this packet are either non-retransmittable or have been
+  // acked.
+  bool HasRetransmittableFrames(const QuicTransmissionInfo& info) const;
+
+  // Returns true if there are any unacked packets which have retransmittable
+  // frames.
+  bool HasUnackedRetransmittableFrames() const;
+
+  // Returns true if there are no packets present in the unacked packet map.
+  bool empty() const { return unacked_packets_.empty(); }
+
+  // Returns the largest packet number that has been sent.
+  QuicPacketNumber largest_sent_packet() const { return largest_sent_packet_; }
+
+  QuicPacketNumber largest_sent_largest_acked() const {
+    return largest_sent_largest_acked_;
+  }
+
+  // Returns the largest packet number that has been acked.
+  QuicPacketNumber largest_acked() const { return largest_acked_; }
+
+  // Returns the sum of bytes from all packets in flight.
+  QuicByteCount bytes_in_flight() const { return bytes_in_flight_; }
+  QuicPacketCount packets_in_flight() const { return packets_in_flight_; }
+
+  // Returns the smallest packet number of a serialized packet which has not
+  // been acked by the peer.  If there are no unacked packets, returns 0.
+  QuicPacketNumber GetLeastUnacked() const;
+
+  using const_iterator =
+      quiche::QuicheCircularDeque<QuicTransmissionInfo>::const_iterator;
+  using const_reverse_iterator =
+      quiche::QuicheCircularDeque<QuicTransmissionInfo>::const_reverse_iterator;
+  using iterator = quiche::QuicheCircularDeque<QuicTransmissionInfo>::iterator;
+
+  const_iterator begin() const { return unacked_packets_.begin(); }
+  const_iterator end() const { return unacked_packets_.end(); }
+  const_reverse_iterator rbegin() const { return unacked_packets_.rbegin(); }
+  const_reverse_iterator rend() const { return unacked_packets_.rend(); }
+  iterator begin() { return unacked_packets_.begin(); }
+  iterator end() { return unacked_packets_.end(); }
+
+  // Returns true if there are unacked packets that are in flight.
+  bool HasInFlightPackets() const;
+
+  // Returns the QuicTransmissionInfo associated with |packet_number|, which
+  // must be unacked.
+  const QuicTransmissionInfo& GetTransmissionInfo(
+      QuicPacketNumber packet_number) const;
+
+  // Returns mutable QuicTransmissionInfo associated with |packet_number|, which
+  // must be unacked.
+  QuicTransmissionInfo* GetMutableTransmissionInfo(
+      QuicPacketNumber packet_number);
+
+  // Returns the time that the last unacked packet was sent.
+  QuicTime GetLastInFlightPacketSentTime() const;
+
+  // Returns the time that the last unacked crypto packet was sent.
+  QuicTime GetLastCryptoPacketSentTime() const;
+
+  // Returns the number of unacked packets.
+  size_t GetNumUnackedPacketsDebugOnly() const;
+
+  // Returns true if there are multiple packets in flight.
+  // TODO(fayang): Remove this method and use packets_in_flight_ instead.
+  bool HasMultipleInFlightPackets() const;
+
+  // Returns true if there are any pending crypto packets.
+  bool HasPendingCryptoPackets() const;
+
+  // Returns true if there is any unacked non-crypto stream data.
+  bool HasUnackedStreamData() const {
+    return session_notifier_->HasUnackedStreamData();
+  }
+
+  // Removes any retransmittable frames from this transmission or an associated
+  // transmission.  It removes now useless transmissions, and disconnects any
+  // other packets from other transmissions.
+  void RemoveRetransmittability(QuicTransmissionInfo* info);
+
+  // Looks up the QuicTransmissionInfo by |packet_number| and calls
+  // RemoveRetransmittability.
+  void RemoveRetransmittability(QuicPacketNumber packet_number);
+
+  // Increases the largest acked.  Any packets less or equal to
+  // |largest_acked| are discarded if they are only for the RTT purposes.
+  void IncreaseLargestAcked(QuicPacketNumber largest_acked);
+
+  // Called when |packet_number| gets acked. Maybe increase the largest acked of
+  // |packet_number_space|.
+  void MaybeUpdateLargestAckedOfPacketNumberSpace(
+      PacketNumberSpace packet_number_space,
+      QuicPacketNumber packet_number);
+
+  // Remove any packets no longer needed for retransmission, congestion, or
+  // RTT measurement purposes.
+  void RemoveObsoletePackets();
+
+  // Try to aggregate acked contiguous stream frames. For noncontiguous stream
+  // frames or control frames, notify the session notifier they get acked
+  // immediately.
+  void MaybeAggregateAckedStreamFrame(const QuicTransmissionInfo& info,
+                                      QuicTime::Delta ack_delay,
+                                      QuicTime receive_timestamp);
+
+  // Notify the session notifier of any stream data aggregated in
+  // aggregated_stream_frame_.  No effect if the stream frame has an invalid
+  // stream id.
+  void NotifyAggregatedStreamFrameAcked(QuicTime::Delta ack_delay);
+
+  // Returns packet number space that |packet_number| belongs to. Please use
+  // GetPacketNumberSpace(EncryptionLevel) whenever encryption level is
+  // available.
+  PacketNumberSpace GetPacketNumberSpace(QuicPacketNumber packet_number) const;
+
+  // Returns packet number space of |encryption_level|.
+  PacketNumberSpace GetPacketNumberSpace(
+      EncryptionLevel encryption_level) const;
+
+  // Returns largest acked packet number of |packet_number_space|.
+  QuicPacketNumber GetLargestAckedOfPacketNumberSpace(
+      PacketNumberSpace packet_number_space) const;
+
+  // Returns largest sent retransmittable packet number of
+  // |packet_number_space|.
+  QuicPacketNumber GetLargestSentRetransmittableOfPacketNumberSpace(
+      PacketNumberSpace packet_number_space) const;
+
+  // Returns largest sent packet number of |encryption_level|.
+  QuicPacketNumber GetLargestSentPacketOfPacketNumberSpace(
+      EncryptionLevel encryption_level) const;
+
+  // Returns last in flight packet sent time of |packet_number_space|.
+  QuicTime GetLastInFlightPacketSentTime(
+      PacketNumberSpace packet_number_space) const;
+
+  // Returns TransmissionInfo of the first in flight packet.
+  const QuicTransmissionInfo* GetFirstInFlightTransmissionInfo() const;
+
+  // Returns TransmissionInfo of first in flight packet in
+  // |packet_number_space|.
+  const QuicTransmissionInfo* GetFirstInFlightTransmissionInfoOfSpace(
+      PacketNumberSpace packet_number_space) const;
+
+  void SetSessionNotifier(SessionNotifierInterface* session_notifier);
+
+  void EnableMultiplePacketNumberSpacesSupport();
+
+  // Returns a bitfield of retransmittable frames of last packet in
+  // unacked_packets_. For example, if the packet contains STREAM_FRAME, content
+  // & (1 << STREAM_FRAME) would be set. Returns max uint32_t if
+  // unacked_packets_ is empty.
+  int32_t GetLastPacketContent() const;
+
+  Perspective perspective() const { return perspective_; }
+
+  bool supports_multiple_packet_number_spaces() const {
+    return supports_multiple_packet_number_spaces_;
+  }
+
+  void ReserveInitialCapacity(size_t initial_capacity) {
+    unacked_packets_.reserve(initial_capacity);
+  }
+
+  std::string DebugString() const {
+    return absl::StrCat(
+        "{size: ", unacked_packets_.size(),
+        ", least_unacked: ", least_unacked_.ToString(),
+        ", largest_sent_packet: ", largest_sent_packet_.ToString(),
+        ", largest_acked: ", largest_acked_.ToString(),
+        ", bytes_in_flight: ", bytes_in_flight_,
+        ", packets_in_flight: ", packets_in_flight_, "}");
+  }
+
+ private:
+  friend class test::QuicUnackedPacketMapPeer;
+
+  // Returns true if packet may be useful for an RTT measurement.
+  bool IsPacketUsefulForMeasuringRtt(QuicPacketNumber packet_number,
+                                     const QuicTransmissionInfo& info) const;
+
+  // Returns true if packet may be useful for congestion control purposes.
+  bool IsPacketUsefulForCongestionControl(
+      const QuicTransmissionInfo& info) const;
+
+  // Returns true if packet may be associated with retransmittable data
+  // directly or through retransmissions.
+  bool IsPacketUsefulForRetransmittableData(
+      const QuicTransmissionInfo& info) const;
+
+  // Returns true if the packet no longer has a purpose in the map.
+  bool IsPacketUseless(QuicPacketNumber packet_number,
+                       const QuicTransmissionInfo& info) const;
+
+  const Perspective perspective_;
+
+  QuicPacketNumber largest_sent_packet_;
+  // The largest sent packet we expect to receive an ack for per packet number
+  // space.
+  QuicPacketNumber
+      largest_sent_retransmittable_packets_[NUM_PACKET_NUMBER_SPACES];
+  // The largest sent largest_acked in an ACK frame.
+  QuicPacketNumber largest_sent_largest_acked_;
+  // The largest received largest_acked from an ACK frame.
+  QuicPacketNumber largest_acked_;
+  // The largest received largest_acked from ACK frame per packet number space.
+  QuicPacketNumber largest_acked_packets_[NUM_PACKET_NUMBER_SPACES];
+
+  // Newly serialized retransmittable packets are added to this map, which
+  // contains owning pointers to any contained frames.  If a packet is
+  // retransmitted, this map will contain entries for both the old and the new
+  // packet. The old packet's retransmittable frames entry will be nullptr,
+  // while the new packet's entry will contain the frames to retransmit.
+  // If the old packet is acked before the new packet, then the old entry will
+  // be removed from the map and the new entry's retransmittable frames will be
+  // set to nullptr.
+  quiche::QuicheCircularDeque<QuicTransmissionInfo> unacked_packets_;
+
+  // The packet at the 0th index of unacked_packets_.
+  QuicPacketNumber least_unacked_;
+
+  QuicByteCount bytes_in_flight_;
+  // Bytes in flight per packet number space.
+  QuicByteCount
+      bytes_in_flight_per_packet_number_space_[NUM_PACKET_NUMBER_SPACES];
+  QuicPacketCount packets_in_flight_;
+
+  // Time that the last inflight packet was sent.
+  QuicTime last_inflight_packet_sent_time_;
+  // Time that the last in flight packet was sent per packet number space.
+  QuicTime last_inflight_packets_sent_time_[NUM_PACKET_NUMBER_SPACES];
+
+  // Time that the last unacked crypto packet was sent.
+  QuicTime last_crypto_packet_sent_time_;
+
+  // Aggregates acked stream data across multiple acked sent packets to save CPU
+  // by reducing the number of calls to the session notifier.
+  QuicStreamFrame aggregated_stream_frame_;
+
+  // Receives notifications of frames being retransmitted or acknowledged.
+  SessionNotifierInterface* session_notifier_;
+
+  // If true, supports multiple packet number spaces.
+  bool supports_multiple_packet_number_spaces_;
+
+  // Latched value of the quic_simple_inflight_time flag.
+  bool simple_inflight_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
diff --git a/quiche/quic/core/quic_unacked_packet_map_test.cc b/quiche/quic/core/quic_unacked_packet_map_test.cc
new file mode 100644
index 0000000..02102fd
--- /dev/null
+++ b/quiche/quic/core/quic_unacked_packet_map_test.cc
@@ -0,0 +1,699 @@
+// 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 "quiche/quic/core/quic_unacked_packet_map.h"
+#include <cstddef>
+#include <limits>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_transmission_info.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_unacked_packet_map_peer.h"
+
+using testing::_;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+class QuicUnackedPacketMapTest : public QuicTestWithParam<Perspective> {
+ protected:
+  QuicUnackedPacketMapTest()
+      : unacked_packets_(GetParam()),
+        now_(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1000)) {
+    unacked_packets_.SetSessionNotifier(&notifier_);
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+    EXPECT_CALL(notifier_, OnStreamFrameRetransmitted(_))
+        .Times(testing::AnyNumber());
+  }
+
+  ~QuicUnackedPacketMapTest() override {}
+
+  SerializedPacket CreateRetransmittablePacket(uint64_t packet_number) {
+    return CreateRetransmittablePacketForStream(
+        packet_number, QuicUtils::GetFirstBidirectionalStreamId(
+                           CurrentSupportedVersions()[0].transport_version,
+                           Perspective::IS_CLIENT));
+  }
+
+  SerializedPacket CreateRetransmittablePacketForStream(
+      uint64_t packet_number,
+      QuicStreamId stream_id) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+    QuicStreamFrame frame;
+    frame.stream_id = stream_id;
+    packet.retransmittable_frames.push_back(QuicFrame(frame));
+    return packet;
+  }
+
+  SerializedPacket CreateNonRetransmittablePacket(uint64_t packet_number) {
+    return SerializedPacket(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+  }
+
+  void VerifyInFlightPackets(uint64_t* packets, size_t num_packets) {
+    unacked_packets_.RemoveObsoletePackets();
+    if (num_packets == 0) {
+      EXPECT_FALSE(unacked_packets_.HasInFlightPackets());
+      EXPECT_FALSE(unacked_packets_.HasMultipleInFlightPackets());
+      return;
+    }
+    if (num_packets == 1) {
+      EXPECT_TRUE(unacked_packets_.HasInFlightPackets());
+      EXPECT_FALSE(unacked_packets_.HasMultipleInFlightPackets());
+      ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[0])));
+      EXPECT_TRUE(
+          unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[0]))
+              .in_flight);
+    }
+    for (size_t i = 0; i < num_packets; ++i) {
+      ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])));
+      EXPECT_TRUE(
+          unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[i]))
+              .in_flight);
+    }
+    size_t in_flight_count = 0;
+    for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
+         ++it) {
+      if (it->in_flight) {
+        ++in_flight_count;
+      }
+    }
+    EXPECT_EQ(num_packets, in_flight_count);
+  }
+
+  void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
+    unacked_packets_.RemoveObsoletePackets();
+    if (num_packets == 0) {
+      EXPECT_TRUE(unacked_packets_.empty());
+      EXPECT_FALSE(unacked_packets_.HasUnackedRetransmittableFrames());
+      return;
+    }
+    EXPECT_FALSE(unacked_packets_.empty());
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])))
+          << packets[i];
+    }
+    EXPECT_EQ(num_packets, unacked_packets_.GetNumUnackedPacketsDebugOnly());
+  }
+
+  void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
+    unacked_packets_.RemoveObsoletePackets();
+    size_t num_retransmittable_packets = 0;
+    for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
+         ++it) {
+      if (unacked_packets_.HasRetransmittableFrames(*it)) {
+        ++num_retransmittable_packets;
+      }
+    }
+    EXPECT_EQ(num_packets, num_retransmittable_packets);
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(unacked_packets_.HasRetransmittableFrames(
+          QuicPacketNumber(packets[i])))
+          << " packets[" << i << "]:" << packets[i];
+    }
+  }
+
+  void UpdatePacketState(uint64_t packet_number, SentPacketState state) {
+    unacked_packets_
+        .GetMutableTransmissionInfo(QuicPacketNumber(packet_number))
+        ->state = state;
+  }
+
+  void RetransmitAndSendPacket(uint64_t old_packet_number,
+                               uint64_t new_packet_number,
+                               TransmissionType transmission_type) {
+    QUICHE_DCHECK(unacked_packets_.HasRetransmittableFrames(
+        QuicPacketNumber(old_packet_number)));
+    QuicTransmissionInfo* info = unacked_packets_.GetMutableTransmissionInfo(
+        QuicPacketNumber(old_packet_number));
+    QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        CurrentSupportedVersions()[0].transport_version,
+        Perspective::IS_CLIENT);
+    for (const auto& frame : info->retransmittable_frames) {
+      if (frame.type == STREAM_FRAME) {
+        stream_id = frame.stream_frame.stream_id;
+        break;
+      }
+    }
+    UpdatePacketState(
+        old_packet_number,
+        QuicUtils::RetransmissionTypeToPacketState(transmission_type));
+    info->first_sent_after_loss = QuicPacketNumber(new_packet_number);
+    SerializedPacket packet(
+        CreateRetransmittablePacketForStream(new_packet_number, stream_id));
+    unacked_packets_.AddSentPacket(&packet, transmission_type, now_, true,
+                                   true);
+  }
+  QuicUnackedPacketMap unacked_packets_;
+  QuicTime now_;
+  StrictMock<MockSessionNotifier> notifier_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicUnackedPacketMapTest,
+                         ::testing::ValuesIn({Perspective::IS_CLIENT,
+                                              Perspective::IS_SERVER}),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicUnackedPacketMapTest, RttOnly) {
+  // Acks are only tracked for RTT measurement purposes.
+  SerializedPacket packet(CreateNonRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, false,
+                                 true);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
+  VerifyUnackedPackets(nullptr, 0);
+  VerifyInFlightPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, RetransmittableInflightAndRtt) {
+  // Simulate a retransmittable packet being sent and acked.
+  SerializedPacket packet(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(unacked, ABSL_ARRAYSIZE(unacked));
+
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  VerifyUnackedPackets(nullptr, 0);
+  VerifyInFlightPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, StopRetransmission) {
+  const QuicStreamId stream_id = 2;
+  SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
+  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, StopRetransmissionOnOtherStream) {
+  const QuicStreamId stream_id = 2;
+  SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
+  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+}
+
+TEST_P(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) {
+  const QuicStreamId stream_id = 2;
+  SerializedPacket packet1(CreateRetransmittablePacketForStream(1, stream_id));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
+
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  std::vector<uint64_t> retransmittable = {1, 2};
+  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, RetransmittedPacket) {
+  // Simulate a retransmittable packet being sent, retransmitted, and the first
+  // transmission being acked.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
+
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  std::vector<uint64_t> retransmittable = {1, 2};
+  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  uint64_t unacked2[] = {1};
+  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  VerifyInFlightPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  VerifyUnackedPackets(nullptr, 0);
+  VerifyInFlightPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
+  // Simulate a retransmittable packet being sent and retransmitted twice.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  SerializedPacket packet2(CreateRetransmittablePacket(2));
+  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1, 2};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+
+  // Early retransmit 1 as 3 and send new data as 4.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
+  SerializedPacket packet4(CreateRetransmittablePacket(4));
+  unacked_packets_.AddSentPacket(&packet4, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  uint64_t unacked2[] = {1, 3, 4};
+  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  uint64_t pending2[] = {3, 4};
+  VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2));
+  std::vector<uint64_t> retransmittable2 = {1, 3, 4};
+  VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size());
+
+  // Early retransmit 3 (formerly 1) as 5, and remove 1 from unacked.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(4));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(4));
+  RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
+  SerializedPacket packet6(CreateRetransmittablePacket(6));
+  unacked_packets_.AddSentPacket(&packet6, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  std::vector<uint64_t> unacked3 = {3, 5, 6};
+  std::vector<uint64_t> retransmittable3 = {3, 5, 6};
+  VerifyUnackedPackets(&unacked3[0], unacked3.size());
+  VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
+  uint64_t pending3[] = {3, 5, 6};
+  VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3));
+
+  // Early retransmit 5 as 7 and ensure in flight packet 3 is not removed.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(6));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(6));
+  RetransmitAndSendPacket(5, 7, LOSS_RETRANSMISSION);
+
+  std::vector<uint64_t> unacked4 = {3, 5, 7};
+  std::vector<uint64_t> retransmittable4 = {3, 5, 7};
+  VerifyUnackedPackets(&unacked4[0], unacked4.size());
+  VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size());
+  uint64_t pending4[] = {3, 5, 7};
+  VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4));
+
+  // Remove the older two transmissions from in flight.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  uint64_t pending5[] = {7};
+  VerifyInFlightPackets(pending5, ABSL_ARRAYSIZE(pending5));
+}
+
+TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) {
+  // Simulate a retransmittable packet being sent and retransmitted twice.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  SerializedPacket packet2(CreateRetransmittablePacket(2));
+  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1, 2};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+
+  // Early retransmit 1 as 3.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
+
+  uint64_t unacked2[] = {1, 3};
+  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  uint64_t pending2[] = {3};
+  VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2));
+  std::vector<uint64_t> retransmittable2 = {1, 3};
+  VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size());
+
+  // TLP 3 (formerly 1) as 4, and don't remove 1 from unacked.
+  RetransmitAndSendPacket(3, 4, TLP_RETRANSMISSION);
+  SerializedPacket packet5(CreateRetransmittablePacket(5));
+  unacked_packets_.AddSentPacket(&packet5, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  uint64_t unacked3[] = {1, 3, 4, 5};
+  VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3));
+  uint64_t pending3[] = {3, 4, 5};
+  VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3));
+  std::vector<uint64_t> retransmittable3 = {1, 3, 4, 5};
+  VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
+
+  // Early retransmit 4 as 6 and ensure in flight packet 3 is removed.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(5));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(5));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  RetransmitAndSendPacket(4, 6, LOSS_RETRANSMISSION);
+
+  std::vector<uint64_t> unacked4 = {4, 6};
+  VerifyUnackedPackets(&unacked4[0], unacked4.size());
+  uint64_t pending4[] = {6};
+  VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4));
+  std::vector<uint64_t> retransmittable4 = {4, 6};
+  VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size());
+}
+
+TEST_P(QuicUnackedPacketMapTest, SendWithGap) {
+  // Simulate a retransmittable packet being sent, retransmitted, and the first
+  // transmission being acked.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  SerializedPacket packet3(CreateRetransmittablePacket(3));
+  unacked_packets_.AddSentPacket(&packet3, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
+
+  EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.GetLeastUnacked());
+  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(1)));
+  EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(2)));
+  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(3)));
+  EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(4)));
+  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(5)));
+  EXPECT_EQ(QuicPacketNumber(5u), unacked_packets_.largest_sent_packet());
+}
+
+TEST_P(QuicUnackedPacketMapTest, AggregateContiguousAckedStreamFrames) {
+  testing::InSequence s;
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.NotifyAggregatedStreamFrameAcked(QuicTime::Delta::Zero());
+
+  QuicTransmissionInfo info1;
+  QuicStreamFrame stream_frame1(3, false, 0, 100);
+  info1.retransmittable_frames.push_back(QuicFrame(stream_frame1));
+
+  QuicTransmissionInfo info2;
+  QuicStreamFrame stream_frame2(3, false, 100, 100);
+  info2.retransmittable_frames.push_back(QuicFrame(stream_frame2));
+
+  QuicTransmissionInfo info3;
+  QuicStreamFrame stream_frame3(3, false, 200, 100);
+  info3.retransmittable_frames.push_back(QuicFrame(stream_frame3));
+
+  QuicTransmissionInfo info4;
+  QuicStreamFrame stream_frame4(3, true, 300, 0);
+  info4.retransmittable_frames.push_back(QuicFrame(stream_frame4));
+
+  // Verify stream frames are aggregated.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info1, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info2, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info3, QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  // Verify aggregated stream frame gets acked since fin is acked.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info4, QuicTime::Delta::Zero(), QuicTime::Zero());
+}
+
+// Regression test for b/112930090.
+TEST_P(QuicUnackedPacketMapTest, CannotAggregateIfDataLengthOverflow) {
+  QuicByteCount kMaxAggregatedDataLength =
+      std::numeric_limits<decltype(QuicStreamFrame().data_length)>::max();
+  QuicStreamId stream_id = 2;
+
+  // acked_stream_length=512 covers the case where a frame will cause the
+  // aggregated frame length to be exactly 64K.
+  // acked_stream_length=1300 covers the case where a frame will cause the
+  // aggregated frame length to exceed 64K.
+  for (const QuicPacketLength acked_stream_length : {512, 1300}) {
+    ++stream_id;
+    QuicStreamOffset offset = 0;
+    // Expected length of the aggregated stream frame.
+    QuicByteCount aggregated_data_length = 0;
+
+    while (offset < 1e6) {
+      QuicTransmissionInfo info;
+      QuicStreamFrame stream_frame(stream_id, false, offset,
+                                   acked_stream_length);
+      info.retransmittable_frames.push_back(QuicFrame(stream_frame));
+
+      const QuicStreamFrame& aggregated_stream_frame =
+          QuicUnackedPacketMapPeer::GetAggregatedStreamFrame(unacked_packets_);
+      if (aggregated_stream_frame.data_length + acked_stream_length <=
+          kMaxAggregatedDataLength) {
+        // Verify the acked stream frame can be aggregated.
+        EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+        unacked_packets_.MaybeAggregateAckedStreamFrame(
+            info, QuicTime::Delta::Zero(), QuicTime::Zero());
+        aggregated_data_length += acked_stream_length;
+        testing::Mock::VerifyAndClearExpectations(&notifier_);
+      } else {
+        // Verify the acked stream frame cannot be aggregated because
+        // data_length is overflow.
+        EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+        unacked_packets_.MaybeAggregateAckedStreamFrame(
+            info, QuicTime::Delta::Zero(), QuicTime::Zero());
+        aggregated_data_length = acked_stream_length;
+        testing::Mock::VerifyAndClearExpectations(&notifier_);
+      }
+
+      EXPECT_EQ(aggregated_data_length, aggregated_stream_frame.data_length);
+      offset += acked_stream_length;
+    }
+
+    // Ack the last frame of the stream.
+    QuicTransmissionInfo info;
+    QuicStreamFrame stream_frame(stream_id, true, offset, acked_stream_length);
+    info.retransmittable_frames.push_back(QuicFrame(stream_frame));
+    EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+    unacked_packets_.MaybeAggregateAckedStreamFrame(
+        info, QuicTime::Delta::Zero(), QuicTime::Zero());
+    testing::Mock::VerifyAndClearExpectations(&notifier_);
+  }
+}
+
+TEST_P(QuicUnackedPacketMapTest, CannotAggregateAckedControlFrames) {
+  testing::InSequence s;
+  QuicWindowUpdateFrame window_update(1, 5, 100);
+  QuicStreamFrame stream_frame1(3, false, 0, 100);
+  QuicStreamFrame stream_frame2(3, false, 100, 100);
+  QuicBlockedFrame blocked(2, 5);
+  QuicGoAwayFrame go_away(3, QUIC_PEER_GOING_AWAY, 5, "Going away.");
+
+  QuicTransmissionInfo info1;
+  info1.retransmittable_frames.push_back(QuicFrame(window_update));
+  info1.retransmittable_frames.push_back(QuicFrame(stream_frame1));
+  info1.retransmittable_frames.push_back(QuicFrame(stream_frame2));
+
+  QuicTransmissionInfo info2;
+  info2.retransmittable_frames.push_back(QuicFrame(blocked));
+  info2.retransmittable_frames.push_back(QuicFrame(&go_away));
+
+  // Verify 2 contiguous stream frames are aggregated.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info1, QuicTime::Delta::Zero(), QuicTime::Zero());
+  // Verify aggregated stream frame gets acked.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(3);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info2, QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.NotifyAggregatedStreamFrameAcked(QuicTime::Delta::Zero());
+}
+
+TEST_P(QuicUnackedPacketMapTest, LargestSentPacketMultiplePacketNumberSpaces) {
+  unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_FALSE(
+      unacked_packets_
+          .GetLargestSentRetransmittableOfPacketNumberSpace(INITIAL_DATA)
+          .IsInitialized());
+  // Send packet 1.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  packet1.encryption_level = ENCRYPTION_INITIAL;
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.largest_sent_packet());
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_FALSE(
+      unacked_packets_
+          .GetLargestSentRetransmittableOfPacketNumberSpace(HANDSHAKE_DATA)
+          .IsInitialized());
+  // Send packet 2.
+  SerializedPacket packet2(CreateRetransmittablePacket(2));
+  packet2.encryption_level = ENCRYPTION_HANDSHAKE;
+  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(QuicPacketNumber(2u), unacked_packets_.largest_sent_packet());
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(2),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_FALSE(
+      unacked_packets_
+          .GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
+          .IsInitialized());
+  // Send packet 3.
+  SerializedPacket packet3(CreateRetransmittablePacket(3));
+  packet3.encryption_level = ENCRYPTION_ZERO_RTT;
+  unacked_packets_.AddSentPacket(&packet3, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(QuicPacketNumber(3u), unacked_packets_.largest_sent_packet());
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(2),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  // Verify forward secure belongs to the same packet number space as encryption
+  // zero rtt.
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+
+  // Send packet 4.
+  SerializedPacket packet4(CreateRetransmittablePacket(4));
+  packet4.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  unacked_packets_.AddSentPacket(&packet4, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(QuicPacketNumber(4u), unacked_packets_.largest_sent_packet());
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(2),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_EQ(QuicPacketNumber(4),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  // Verify forward secure belongs to the same packet number space as encryption
+  // zero rtt.
+  EXPECT_EQ(QuicPacketNumber(4),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  EXPECT_TRUE(unacked_packets_.GetLastPacketContent() & (1 << STREAM_FRAME));
+  EXPECT_FALSE(unacked_packets_.GetLastPacketContent() & (1 << ACK_FRAME));
+}
+
+TEST_P(QuicUnackedPacketMapTest, ReserveInitialCapacityTest) {
+  QuicUnackedPacketMap unacked_packets(GetParam());
+  ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 0u);
+  unacked_packets.ReserveInitialCapacity(16);
+  QuicStreamId stream_id(1);
+  SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
+  unacked_packets.AddSentPacket(&packet, TransmissionType::NOT_RETRANSMISSION,
+                                now_, true, true);
+  ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 16u);
+}
+
+TEST_P(QuicUnackedPacketMapTest, DebugString) {
+  EXPECT_EQ(unacked_packets_.DebugString(),
+            "{size: 0, least_unacked: 1, largest_sent_packet: uninitialized, "
+            "largest_acked: uninitialized, bytes_in_flight: 0, "
+            "packets_in_flight: 0}");
+
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(
+      unacked_packets_.DebugString(),
+      "{size: 1, least_unacked: 1, largest_sent_packet: 1, largest_acked: "
+      "uninitialized, bytes_in_flight: 1000, packets_in_flight: 1}");
+
+  SerializedPacket packet2(CreateRetransmittablePacket(2));
+  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
+  unacked_packets_.RemoveObsoletePackets();
+  EXPECT_EQ(
+      unacked_packets_.DebugString(),
+      "{size: 1, least_unacked: 2, largest_sent_packet: 2, largest_acked: 1, "
+      "bytes_in_flight: 1000, packets_in_flight: 1}");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_utils.cc b/quiche/quic/core/quic_utils.cc
new file mode 100644
index 0000000..fb37efc
--- /dev/null
+++ b/quiche/quic/core/quic_utils.cc
@@ -0,0 +1,690 @@
+// 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 "quiche/quic/core/quic_utils.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <cstring>
+#include <limits>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/base/optimization.h"
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+namespace {
+
+// We know that >= GCC 4.8 and Clang have a __uint128_t intrinsic. Other
+// compilers don't necessarily, notably MSVC.
+#if defined(__x86_64__) &&                                         \
+    ((defined(__GNUC__) &&                                         \
+      (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \
+     defined(__clang__))
+#define QUIC_UTIL_HAS_UINT128 1
+#endif
+
+#ifdef QUIC_UTIL_HAS_UINT128
+absl::uint128 IncrementalHashFast(absl::uint128 uhash, absl::string_view data) {
+  // This code ends up faster than the naive implementation for 2 reasons:
+  // 1. absl::uint128 is sufficiently complicated that the compiler
+  //    cannot transform the multiplication by kPrime into a shift-multiply-add;
+  //    it has go through all of the instructions for a 128-bit multiply.
+  // 2. Because there are so fewer instructions (around 13), the hot loop fits
+  //    nicely in the instruction queue of many Intel CPUs.
+  // kPrime = 309485009821345068724781371
+  static const absl::uint128 kPrime =
+      (static_cast<absl::uint128>(16777216) << 64) + 315;
+  auto hi = absl::Uint128High64(uhash);
+  auto lo = absl::Uint128Low64(uhash);
+  absl::uint128 xhash = (static_cast<absl::uint128>(hi) << 64) + lo;
+  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
+  for (size_t i = 0; i < data.length(); ++i) {
+    xhash = (xhash ^ static_cast<uint32_t>(octets[i])) * kPrime;
+  }
+  return absl::MakeUint128(absl::Uint128High64(xhash),
+                           absl::Uint128Low64(xhash));
+}
+#endif
+
+#ifndef QUIC_UTIL_HAS_UINT128
+// Slow implementation of IncrementalHash. In practice, only used by Chromium.
+absl::uint128 IncrementalHashSlow(absl::uint128 hash, absl::string_view data) {
+  // kPrime = 309485009821345068724781371
+  static const absl::uint128 kPrime = absl::MakeUint128(16777216, 315);
+  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
+  for (size_t i = 0; i < data.length(); ++i) {
+    hash = hash ^ absl::MakeUint128(0, octets[i]);
+    hash = hash * kPrime;
+  }
+  return hash;
+}
+#endif
+
+absl::uint128 IncrementalHash(absl::uint128 hash, absl::string_view data) {
+#ifdef QUIC_UTIL_HAS_UINT128
+  return IncrementalHashFast(hash, data);
+#else
+  return IncrementalHashSlow(hash, data);
+#endif
+}
+
+}  // namespace
+
+// static
+uint64_t QuicUtils::FNV1a_64_Hash(absl::string_view data) {
+  static const uint64_t kOffset = UINT64_C(14695981039346656037);
+  static const uint64_t kPrime = UINT64_C(1099511628211);
+
+  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
+
+  uint64_t hash = kOffset;
+
+  for (size_t i = 0; i < data.length(); ++i) {
+    hash = hash ^ octets[i];
+    hash = hash * kPrime;
+  }
+
+  return hash;
+}
+
+// static
+absl::uint128 QuicUtils::FNV1a_128_Hash(absl::string_view data) {
+  return FNV1a_128_Hash_Three(data, absl::string_view(), absl::string_view());
+}
+
+// static
+absl::uint128 QuicUtils::FNV1a_128_Hash_Two(absl::string_view data1,
+                                            absl::string_view data2) {
+  return FNV1a_128_Hash_Three(data1, data2, absl::string_view());
+}
+
+// static
+absl::uint128 QuicUtils::FNV1a_128_Hash_Three(absl::string_view data1,
+                                              absl::string_view data2,
+                                              absl::string_view data3) {
+  // The two constants are defined as part of the hash algorithm.
+  // see http://www.isthe.com/chongo/tech/comp/fnv/
+  // kOffset = 144066263297769815596495629667062367629
+  const absl::uint128 kOffset = absl::MakeUint128(
+      UINT64_C(7809847782465536322), UINT64_C(7113472399480571277));
+
+  absl::uint128 hash = IncrementalHash(kOffset, data1);
+  if (data2.empty()) {
+    return hash;
+  }
+
+  hash = IncrementalHash(hash, data2);
+  if (data3.empty()) {
+    return hash;
+  }
+  return IncrementalHash(hash, data3);
+}
+
+// static
+void QuicUtils::SerializeUint128Short(absl::uint128 v, uint8_t* out) {
+  const uint64_t lo = absl::Uint128Low64(v);
+  const uint64_t hi = absl::Uint128High64(v);
+  // This assumes that the system is little-endian.
+  memcpy(out, &lo, sizeof(lo));
+  memcpy(out + sizeof(lo), &hi, sizeof(hi) / 2);
+}
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x;
+
+std::string QuicUtils::AddressChangeTypeToString(AddressChangeType type) {
+  switch (type) {
+    RETURN_STRING_LITERAL(NO_CHANGE);
+    RETURN_STRING_LITERAL(PORT_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
+    RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
+    RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
+  }
+  return "INVALID_ADDRESS_CHANGE_TYPE";
+}
+
+const char* QuicUtils::SentPacketStateToString(SentPacketState state) {
+  switch (state) {
+    RETURN_STRING_LITERAL(OUTSTANDING);
+    RETURN_STRING_LITERAL(NEVER_SENT);
+    RETURN_STRING_LITERAL(ACKED);
+    RETURN_STRING_LITERAL(UNACKABLE);
+    RETURN_STRING_LITERAL(NEUTERED);
+    RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMITTED);
+    RETURN_STRING_LITERAL(LOST);
+    RETURN_STRING_LITERAL(TLP_RETRANSMITTED);
+    RETURN_STRING_LITERAL(RTO_RETRANSMITTED);
+    RETURN_STRING_LITERAL(PTO_RETRANSMITTED);
+    RETURN_STRING_LITERAL(PROBE_RETRANSMITTED);
+    RETURN_STRING_LITERAL(NOT_CONTRIBUTING_RTT);
+  }
+  return "INVALID_SENT_PACKET_STATE";
+}
+
+// static
+const char* QuicUtils::QuicLongHeaderTypetoString(QuicLongHeaderType type) {
+  switch (type) {
+    RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
+    RETURN_STRING_LITERAL(INITIAL);
+    RETURN_STRING_LITERAL(RETRY);
+    RETURN_STRING_LITERAL(HANDSHAKE);
+    RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
+    default:
+      return "INVALID_PACKET_TYPE";
+  }
+}
+
+// static
+const char* QuicUtils::AckResultToString(AckResult result) {
+  switch (result) {
+    RETURN_STRING_LITERAL(PACKETS_NEWLY_ACKED);
+    RETURN_STRING_LITERAL(NO_PACKETS_NEWLY_ACKED);
+    RETURN_STRING_LITERAL(UNSENT_PACKETS_ACKED);
+    RETURN_STRING_LITERAL(UNACKABLE_PACKETS_ACKED);
+    RETURN_STRING_LITERAL(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE);
+  }
+  return "INVALID_ACK_RESULT";
+}
+
+// static
+AddressChangeType QuicUtils::DetermineAddressChangeType(
+    const QuicSocketAddress& old_address,
+    const QuicSocketAddress& new_address) {
+  if (!old_address.IsInitialized() || !new_address.IsInitialized() ||
+      old_address == new_address) {
+    return NO_CHANGE;
+  }
+
+  if (old_address.host() == new_address.host()) {
+    return PORT_CHANGE;
+  }
+
+  bool old_ip_is_ipv4 = old_address.host().IsIPv4() ? true : false;
+  bool migrating_ip_is_ipv4 = new_address.host().IsIPv4() ? true : false;
+  if (old_ip_is_ipv4 && !migrating_ip_is_ipv4) {
+    return IPV4_TO_IPV6_CHANGE;
+  }
+
+  if (!old_ip_is_ipv4) {
+    return migrating_ip_is_ipv4 ? IPV6_TO_IPV4_CHANGE : IPV6_TO_IPV6_CHANGE;
+  }
+
+  const int kSubnetMaskLength = 24;
+  if (old_address.host().InSameSubnet(new_address.host(), kSubnetMaskLength)) {
+    // Subnet part does not change (here, we use /24), which is considered to be
+    // caused by NATs.
+    return IPV4_SUBNET_CHANGE;
+  }
+
+  return IPV4_TO_IPV4_CHANGE;
+}
+
+// static
+bool QuicUtils::IsAckable(SentPacketState state) {
+  return state != NEVER_SENT && state != ACKED && state != UNACKABLE;
+}
+
+// static
+bool QuicUtils::IsRetransmittableFrame(QuicFrameType type) {
+  switch (type) {
+    case ACK_FRAME:
+    case PADDING_FRAME:
+    case STOP_WAITING_FRAME:
+    case MTU_DISCOVERY_FRAME:
+    case PATH_CHALLENGE_FRAME:
+    case PATH_RESPONSE_FRAME:
+      return false;
+    default:
+      return true;
+  }
+}
+
+// static
+bool QuicUtils::IsHandshakeFrame(const QuicFrame& frame,
+                                 QuicTransportVersion transport_version) {
+  if (!QuicVersionUsesCryptoFrames(transport_version)) {
+    return frame.type == STREAM_FRAME &&
+           frame.stream_frame.stream_id == GetCryptoStreamId(transport_version);
+  } else {
+    return frame.type == CRYPTO_FRAME;
+  }
+}
+
+// static
+bool QuicUtils::ContainsFrameType(const QuicFrames& frames,
+                                  QuicFrameType type) {
+  for (const QuicFrame& frame : frames) {
+    if (frame.type == type) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// static
+SentPacketState QuicUtils::RetransmissionTypeToPacketState(
+    TransmissionType retransmission_type) {
+  switch (retransmission_type) {
+    case ALL_ZERO_RTT_RETRANSMISSION:
+      return UNACKABLE;
+    case HANDSHAKE_RETRANSMISSION:
+      return HANDSHAKE_RETRANSMITTED;
+    case LOSS_RETRANSMISSION:
+      return LOST;
+    case TLP_RETRANSMISSION:
+      return TLP_RETRANSMITTED;
+    case RTO_RETRANSMISSION:
+      return RTO_RETRANSMITTED;
+    case PTO_RETRANSMISSION:
+      return PTO_RETRANSMITTED;
+    case PROBING_RETRANSMISSION:
+      return PROBE_RETRANSMITTED;
+    case PATH_RETRANSMISSION:
+      return NOT_CONTRIBUTING_RTT;
+    case ALL_INITIAL_RETRANSMISSION:
+      return UNACKABLE;
+    default:
+      QUIC_BUG(quic_bug_10839_2)
+          << retransmission_type << " is not a retransmission_type";
+      return UNACKABLE;
+  }
+}
+
+// static
+bool QuicUtils::IsIetfPacketHeader(uint8_t first_byte) {
+  return (first_byte & FLAGS_LONG_HEADER) || (first_byte & FLAGS_FIXED_BIT) ||
+         !(first_byte & FLAGS_DEMULTIPLEXING_BIT);
+}
+
+// static
+bool QuicUtils::IsIetfPacketShortHeader(uint8_t first_byte) {
+  return IsIetfPacketHeader(first_byte) && !(first_byte & FLAGS_LONG_HEADER);
+}
+
+// static
+QuicStreamId QuicUtils::GetInvalidStreamId(QuicTransportVersion version) {
+  return VersionHasIetfQuicFrames(version)
+             ? std::numeric_limits<QuicStreamId>::max()
+             : 0;
+}
+
+// static
+QuicStreamId QuicUtils::GetCryptoStreamId(QuicTransportVersion version) {
+  QUIC_BUG_IF(quic_bug_12982_1, QuicVersionUsesCryptoFrames(version))
+      << "CRYPTO data aren't in stream frames; they have no stream ID.";
+  return QuicVersionUsesCryptoFrames(version) ? GetInvalidStreamId(version) : 1;
+}
+
+// static
+bool QuicUtils::IsCryptoStreamId(QuicTransportVersion version,
+                                 QuicStreamId stream_id) {
+  if (QuicVersionUsesCryptoFrames(version)) {
+    return false;
+  }
+  return stream_id == GetCryptoStreamId(version);
+}
+
+// static
+QuicStreamId QuicUtils::GetHeadersStreamId(QuicTransportVersion version) {
+  QUICHE_DCHECK(!VersionUsesHttp3(version));
+  return GetFirstBidirectionalStreamId(version, Perspective::IS_CLIENT);
+}
+
+// static
+bool QuicUtils::IsClientInitiatedStreamId(QuicTransportVersion version,
+                                          QuicStreamId id) {
+  if (id == GetInvalidStreamId(version)) {
+    return false;
+  }
+  return VersionHasIetfQuicFrames(version) ? id % 2 == 0 : id % 2 != 0;
+}
+
+// static
+bool QuicUtils::IsServerInitiatedStreamId(QuicTransportVersion version,
+                                          QuicStreamId id) {
+  if (id == GetInvalidStreamId(version)) {
+    return false;
+  }
+  return VersionHasIetfQuicFrames(version) ? id % 2 != 0 : id % 2 == 0;
+}
+
+// static
+bool QuicUtils::IsOutgoingStreamId(ParsedQuicVersion version,
+                                   QuicStreamId id,
+                                   Perspective perspective) {
+  // Streams are outgoing streams, iff:
+  // - we are the server and the stream is server-initiated
+  // - we are the client and the stream is client-initiated.
+  const bool perspective_is_server = perspective == Perspective::IS_SERVER;
+  const bool stream_is_server =
+      QuicUtils::IsServerInitiatedStreamId(version.transport_version, id);
+  return perspective_is_server == stream_is_server;
+}
+
+// static
+bool QuicUtils::IsBidirectionalStreamId(QuicStreamId id,
+                                        ParsedQuicVersion version) {
+  QUICHE_DCHECK(version.HasIetfQuicFrames());
+  return id % 4 < 2;
+}
+
+// static
+StreamType QuicUtils::GetStreamType(QuicStreamId id,
+                                    Perspective perspective,
+                                    bool peer_initiated,
+                                    ParsedQuicVersion version) {
+  QUICHE_DCHECK(version.HasIetfQuicFrames());
+  if (IsBidirectionalStreamId(id, version)) {
+    return BIDIRECTIONAL;
+  }
+
+  if (peer_initiated) {
+    if (perspective == Perspective::IS_SERVER) {
+      QUICHE_DCHECK_EQ(2u, id % 4);
+    } else {
+      QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective);
+      QUICHE_DCHECK_EQ(3u, id % 4);
+    }
+    return READ_UNIDIRECTIONAL;
+  }
+
+  if (perspective == Perspective::IS_SERVER) {
+    QUICHE_DCHECK_EQ(3u, id % 4);
+  } else {
+    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective);
+    QUICHE_DCHECK_EQ(2u, id % 4);
+  }
+  return WRITE_UNIDIRECTIONAL;
+}
+
+// static
+QuicStreamId QuicUtils::StreamIdDelta(QuicTransportVersion version) {
+  return VersionHasIetfQuicFrames(version) ? 4 : 2;
+}
+
+// static
+QuicStreamId QuicUtils::GetFirstBidirectionalStreamId(
+    QuicTransportVersion version,
+    Perspective perspective) {
+  if (VersionHasIetfQuicFrames(version)) {
+    return perspective == Perspective::IS_CLIENT ? 0 : 1;
+  } else if (QuicVersionUsesCryptoFrames(version)) {
+    return perspective == Perspective::IS_CLIENT ? 1 : 2;
+  }
+  return perspective == Perspective::IS_CLIENT ? 3 : 2;
+}
+
+// static
+QuicStreamId QuicUtils::GetFirstUnidirectionalStreamId(
+    QuicTransportVersion version,
+    Perspective perspective) {
+  if (VersionHasIetfQuicFrames(version)) {
+    return perspective == Perspective::IS_CLIENT ? 2 : 3;
+  } else if (QuicVersionUsesCryptoFrames(version)) {
+    return perspective == Perspective::IS_CLIENT ? 1 : 2;
+  }
+  return perspective == Perspective::IS_CLIENT ? 3 : 2;
+}
+
+// static
+QuicStreamId QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
+    QuicTransportVersion version) {
+  if (VersionHasIetfQuicFrames(version)) {
+    // Client initiated bidirectional streams have stream IDs divisible by 4.
+    return std::numeric_limits<QuicStreamId>::max() - 3;
+  }
+
+  // Client initiated bidirectional streams have odd stream IDs.
+  return std::numeric_limits<QuicStreamId>::max();
+}
+
+// static
+QuicConnectionId QuicUtils::CreateReplacementConnectionId(
+    const QuicConnectionId& connection_id) {
+  return CreateReplacementConnectionId(connection_id,
+                                       kQuicDefaultConnectionIdLength);
+}
+
+// static
+QuicConnectionId QuicUtils::CreateReplacementConnectionId(
+    const QuicConnectionId& connection_id,
+    uint8_t expected_connection_id_length) {
+  if (expected_connection_id_length == 0) {
+    return EmptyQuicConnectionId();
+  }
+  const uint64_t connection_id_hash64 = FNV1a_64_Hash(
+      absl::string_view(connection_id.data(), connection_id.length()));
+  if (expected_connection_id_length <= sizeof(uint64_t)) {
+    return QuicConnectionId(
+        reinterpret_cast<const char*>(&connection_id_hash64),
+        expected_connection_id_length);
+  }
+  char new_connection_id_data[255] = {};
+  const absl::uint128 connection_id_hash128 = FNV1a_128_Hash(
+      absl::string_view(connection_id.data(), connection_id.length()));
+  static_assert(sizeof(connection_id_hash64) + sizeof(connection_id_hash128) <=
+                    sizeof(new_connection_id_data),
+                "bad size");
+  memcpy(new_connection_id_data, &connection_id_hash64,
+         sizeof(connection_id_hash64));
+  memcpy(new_connection_id_data + sizeof(connection_id_hash64),
+         &connection_id_hash128, sizeof(connection_id_hash128));
+  return QuicConnectionId(new_connection_id_data,
+                          expected_connection_id_length);
+}
+
+// static
+QuicConnectionId QuicUtils::CreateRandomConnectionId() {
+  return CreateRandomConnectionId(kQuicDefaultConnectionIdLength,
+                                  QuicRandom::GetInstance());
+}
+
+// static
+QuicConnectionId QuicUtils::CreateRandomConnectionId(QuicRandom* random) {
+  return CreateRandomConnectionId(kQuicDefaultConnectionIdLength, random);
+}
+// static
+QuicConnectionId QuicUtils::CreateRandomConnectionId(
+    uint8_t connection_id_length) {
+  return CreateRandomConnectionId(connection_id_length,
+                                  QuicRandom::GetInstance());
+}
+
+// static
+QuicConnectionId QuicUtils::CreateRandomConnectionId(
+    uint8_t connection_id_length,
+    QuicRandom* random) {
+  QuicConnectionId connection_id;
+  connection_id.set_length(connection_id_length);
+  if (connection_id.length() > 0) {
+    random->RandBytes(connection_id.mutable_data(), connection_id.length());
+  }
+  return connection_id;
+}
+
+// static
+QuicConnectionId QuicUtils::CreateZeroConnectionId(
+    QuicTransportVersion version) {
+  if (!VersionAllowsVariableLengthConnectionIds(version)) {
+    char connection_id_bytes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    return QuicConnectionId(static_cast<char*>(connection_id_bytes),
+                            ABSL_ARRAYSIZE(connection_id_bytes));
+  }
+  return EmptyQuicConnectionId();
+}
+
+// static
+bool QuicUtils::IsConnectionIdLengthValidForVersion(
+    size_t connection_id_length,
+    QuicTransportVersion transport_version) {
+  // No version of QUIC can support lengths that do not fit in an uint8_t.
+  if (connection_id_length >
+      static_cast<size_t>(std::numeric_limits<uint8_t>::max())) {
+    return false;
+  }
+
+  if (transport_version == QUIC_VERSION_UNSUPPORTED ||
+      transport_version == QUIC_VERSION_RESERVED_FOR_NEGOTIATION) {
+    // Unknown versions could allow connection ID lengths up to 255.
+    return true;
+  }
+
+  const uint8_t connection_id_length8 =
+      static_cast<uint8_t>(connection_id_length);
+  // Versions that do not support variable lengths only support length 8.
+  if (!VersionAllowsVariableLengthConnectionIds(transport_version)) {
+    return connection_id_length8 == kQuicDefaultConnectionIdLength;
+  }
+  // Versions that do support variable length but do not have length-prefixed
+  // connection IDs use the 4-bit connection ID length encoding which can
+  // only encode values 0 and 4-18.
+  if (!VersionHasLengthPrefixedConnectionIds(transport_version)) {
+    return connection_id_length8 == 0 ||
+           (connection_id_length8 >= 4 &&
+            connection_id_length8 <= kQuicMaxConnectionId4BitLength);
+  }
+  return connection_id_length8 <= kQuicMaxConnectionIdWithLengthPrefixLength;
+}
+
+// static
+bool QuicUtils::IsConnectionIdValidForVersion(
+    QuicConnectionId connection_id,
+    QuicTransportVersion transport_version) {
+  return IsConnectionIdLengthValidForVersion(connection_id.length(),
+                                             transport_version);
+}
+
+StatelessResetToken QuicUtils::GenerateStatelessResetToken(
+    QuicConnectionId connection_id) {
+  static_assert(sizeof(absl::uint128) == sizeof(StatelessResetToken),
+                "bad size");
+  static_assert(alignof(absl::uint128) >= alignof(StatelessResetToken),
+                "bad alignment");
+  absl::uint128 hash = FNV1a_128_Hash(
+      absl::string_view(connection_id.data(), connection_id.length()));
+  return *reinterpret_cast<StatelessResetToken*>(&hash);
+}
+
+// static
+QuicStreamCount QuicUtils::GetMaxStreamCount() {
+  return (kMaxQuicStreamCount >> 2) + 1;
+}
+
+// static
+PacketNumberSpace QuicUtils::GetPacketNumberSpace(
+    EncryptionLevel encryption_level) {
+  switch (encryption_level) {
+    case ENCRYPTION_INITIAL:
+      return INITIAL_DATA;
+    case ENCRYPTION_HANDSHAKE:
+      return HANDSHAKE_DATA;
+    case ENCRYPTION_ZERO_RTT:
+    case ENCRYPTION_FORWARD_SECURE:
+      return APPLICATION_DATA;
+    default:
+      QUIC_BUG(quic_bug_10839_3)
+          << "Try to get packet number space of encryption level: "
+          << encryption_level;
+      return NUM_PACKET_NUMBER_SPACES;
+  }
+}
+
+// static
+EncryptionLevel QuicUtils::GetEncryptionLevel(
+    PacketNumberSpace packet_number_space) {
+  switch (packet_number_space) {
+    case INITIAL_DATA:
+      return ENCRYPTION_INITIAL;
+    case HANDSHAKE_DATA:
+      return ENCRYPTION_HANDSHAKE;
+    case APPLICATION_DATA:
+      return ENCRYPTION_FORWARD_SECURE;
+    default:
+      QUICHE_DCHECK(false);
+      return NUM_ENCRYPTION_LEVELS;
+  }
+}
+
+// static
+bool QuicUtils::IsProbingFrame(QuicFrameType type) {
+  switch (type) {
+    case PATH_CHALLENGE_FRAME:
+    case PATH_RESPONSE_FRAME:
+    case NEW_CONNECTION_ID_FRAME:
+    case PADDING_FRAME:
+      return true;
+    default:
+      return false;
+  }
+}
+
+// static
+bool QuicUtils::IsAckElicitingFrame(QuicFrameType type) {
+  switch (type) {
+    case PADDING_FRAME:
+    case STOP_WAITING_FRAME:
+    case ACK_FRAME:
+    case CONNECTION_CLOSE_FRAME:
+      return false;
+    default:
+      return true;
+  }
+}
+
+// static
+bool QuicUtils::AreStatelessResetTokensEqual(
+    const StatelessResetToken& token1,
+    const StatelessResetToken& token2) {
+  char byte = 0;
+  for (size_t i = 0; i < kStatelessResetTokenLength; i++) {
+    // This avoids compiler optimizations that could make us stop comparing
+    // after we find a byte that doesn't match.
+    byte |= (token1[i] ^ token2[i]);
+  }
+  return byte == 0;
+}
+
+bool IsValidWebTransportSessionId(WebTransportSessionId id,
+                                  ParsedQuicVersion version) {
+  QUICHE_DCHECK(version.UsesHttp3());
+  return (id <= std::numeric_limits<QuicStreamId>::max()) &&
+         QuicUtils::IsBidirectionalStreamId(id, version) &&
+         QuicUtils::IsClientInitiatedStreamId(version.transport_version, id);
+}
+
+QuicByteCount MemSliceSpanTotalSize(absl::Span<quiche::QuicheMemSlice> span) {
+  QuicByteCount total = 0;
+  for (const quiche::QuicheMemSlice& slice : span) {
+    total += slice.length();
+  }
+  return total;
+}
+
+std::string RawSha256(absl::string_view input) {
+  std::string raw_hash;
+  raw_hash.resize(SHA256_DIGEST_LENGTH);
+  SHA256(reinterpret_cast<const uint8_t*>(input.data()), input.size(),
+         reinterpret_cast<uint8_t*>(&raw_hash[0]));
+  return raw_hash;
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_utils.h b/quiche/quic/core/quic_utils.h
new file mode 100644
index 0000000..6c2197b
--- /dev/null
+++ b/quiche/quic/core/quic_utils.h
@@ -0,0 +1,310 @@
+// 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_UTILS_H_
+#define QUICHE_QUIC_CORE_QUIC_UTILS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <sstream>
+#include <string>
+#include <type_traits>
+
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicUtils {
+ public:
+  QuicUtils() = delete;
+
+  // Returns the 64 bit FNV1a hash of the data.  See
+  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
+  static uint64_t FNV1a_64_Hash(absl::string_view data);
+
+  // Returns the 128 bit FNV1a hash of the data.  See
+  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
+  static absl::uint128 FNV1a_128_Hash(absl::string_view data);
+
+  // Returns the 128 bit FNV1a hash of the two sequences of data.  See
+  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
+  static absl::uint128 FNV1a_128_Hash_Two(absl::string_view data1,
+                                          absl::string_view data2);
+
+  // Returns the 128 bit FNV1a hash of the three sequences of data.  See
+  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
+  static absl::uint128 FNV1a_128_Hash_Three(absl::string_view data1,
+                                            absl::string_view data2,
+                                            absl::string_view data3);
+
+  // SerializeUint128 writes the first 96 bits of |v| in little-endian form
+  // to |out|.
+  static void SerializeUint128Short(absl::uint128 v, uint8_t* out);
+
+  // Returns AddressChangeType as a string.
+  static std::string AddressChangeTypeToString(AddressChangeType type);
+
+  // Returns SentPacketState as a char*.
+  static const char* SentPacketStateToString(SentPacketState state);
+
+  // Returns QuicLongHeaderType as a char*.
+  static const char* QuicLongHeaderTypetoString(QuicLongHeaderType type);
+
+  // Returns AckResult as a char*.
+  static const char* AckResultToString(AckResult result);
+
+  // Determines and returns change type of address change from |old_address| to
+  // |new_address|.
+  static AddressChangeType DetermineAddressChangeType(
+      const QuicSocketAddress& old_address,
+      const QuicSocketAddress& new_address);
+
+  // Returns the opposite Perspective of the |perspective| passed in.
+  static constexpr Perspective InvertPerspective(Perspective perspective) {
+    return perspective == Perspective::IS_CLIENT ? Perspective::IS_SERVER
+                                                 : Perspective::IS_CLIENT;
+  }
+
+  // Returns true if a packet is ackable. A packet is unackable if it can never
+  // be acked. Occurs when a packet is never sent, after it is acknowledged
+  // once, or if it's a crypto packet we never expect to receive an ack for.
+  static bool IsAckable(SentPacketState state);
+
+  // Returns true if frame with |type| is retransmittable. A retransmittable
+  // frame should be retransmitted if it is detected as lost.
+  static bool IsRetransmittableFrame(QuicFrameType type);
+
+  // Returns true if |frame| is a handshake frame in version |version|.
+  static bool IsHandshakeFrame(const QuicFrame& frame,
+                               QuicTransportVersion transport_version);
+
+  // Return true if any frame in |frames| is of |type|.
+  static bool ContainsFrameType(const QuicFrames& frames, QuicFrameType type);
+
+  // Returns packet state corresponding to |retransmission_type|.
+  static SentPacketState RetransmissionTypeToPacketState(
+      TransmissionType retransmission_type);
+
+  // Returns true if header with |first_byte| is considered as an IETF QUIC
+  // packet header. This only works on the server.
+  static bool IsIetfPacketHeader(uint8_t first_byte);
+
+  // Returns true if header with |first_byte| is considered as an IETF QUIC
+  // short packet header.
+  static bool IsIetfPacketShortHeader(uint8_t first_byte);
+
+  // Returns ID to denote an invalid stream of |version|.
+  static QuicStreamId GetInvalidStreamId(QuicTransportVersion version);
+
+  // Returns crypto stream ID of |version|.
+  static QuicStreamId GetCryptoStreamId(QuicTransportVersion version);
+
+  // Returns whether |id| is the stream ID for the crypto stream. If |version|
+  // is a version where crypto data doesn't go over stream frames, this function
+  // will always return false.
+  static bool IsCryptoStreamId(QuicTransportVersion version, QuicStreamId id);
+
+  // Returns headers stream ID of |version|.
+  static QuicStreamId GetHeadersStreamId(QuicTransportVersion version);
+
+  // Returns true if |id| is considered as client initiated stream ID.
+  static bool IsClientInitiatedStreamId(QuicTransportVersion version,
+                                        QuicStreamId id);
+
+  // Returns true if |id| is considered as server initiated stream ID.
+  static bool IsServerInitiatedStreamId(QuicTransportVersion version,
+                                        QuicStreamId id);
+
+  // Returns true if the stream ID represents a stream initiated by the
+  // provided perspective.
+  static bool IsOutgoingStreamId(ParsedQuicVersion version,
+                                 QuicStreamId id,
+                                 Perspective perspective);
+
+  // Returns true if |id| is considered as bidirectional stream ID. Only used in
+  // v99.
+  static bool IsBidirectionalStreamId(QuicStreamId id,
+                                      ParsedQuicVersion version);
+
+  // Returns stream type.  Either |perspective| or |peer_initiated| would be
+  // enough together with |id|.  This method enforces that the three parameters
+  // are consistent.  Only used in v99.
+  static StreamType GetStreamType(QuicStreamId id,
+                                  Perspective perspective,
+                                  bool peer_initiated,
+                                  ParsedQuicVersion version);
+
+  // Returns the delta between consecutive stream IDs of the same type.
+  static QuicStreamId StreamIdDelta(QuicTransportVersion version);
+
+  // Returns the first initiated bidirectional stream ID of |perspective|.
+  static QuicStreamId GetFirstBidirectionalStreamId(
+      QuicTransportVersion version,
+      Perspective perspective);
+
+  // Returns the first initiated unidirectional stream ID of |perspective|.
+  static QuicStreamId GetFirstUnidirectionalStreamId(
+      QuicTransportVersion version,
+      Perspective perspective);
+
+  // Returns the largest possible client initiated bidirectional stream ID.
+  static QuicStreamId GetMaxClientInitiatedBidirectionalStreamId(
+      QuicTransportVersion version);
+
+  // Generates a connection ID of length |expected_connection_id_length|
+  // derived from |connection_id|.
+  // This is guaranteed to be deterministic (calling this method with two
+  // connection IDs that are equal is guaranteed to produce the same result).
+  static QuicConnectionId CreateReplacementConnectionId(
+      const QuicConnectionId& connection_id,
+      uint8_t expected_connection_id_length);
+
+  // Generates a 64bit connection ID derived from |connection_id|.
+  // This is guaranteed to be deterministic (calling this method with two
+  // connection IDs that are equal is guaranteed to produce the same result).
+  static QuicConnectionId CreateReplacementConnectionId(
+      const QuicConnectionId& connection_id);
+
+  // Generates a random 64bit connection ID.
+  static QuicConnectionId CreateRandomConnectionId();
+
+  // Generates a random 64bit connection ID using the provided QuicRandom.
+  static QuicConnectionId CreateRandomConnectionId(QuicRandom* random);
+
+  // Generates a random connection ID of the given length.
+  static QuicConnectionId CreateRandomConnectionId(
+      uint8_t connection_id_length);
+
+  // Generates a random connection ID of the given length using the provided
+  // QuicRandom.
+  static QuicConnectionId CreateRandomConnectionId(uint8_t connection_id_length,
+                                                   QuicRandom* random);
+
+  // Returns true if the connection ID length is valid for this QUIC version.
+  static bool IsConnectionIdLengthValidForVersion(
+      size_t connection_id_length,
+      QuicTransportVersion transport_version);
+
+  // Returns true if the connection ID is valid for this QUIC version.
+  static bool IsConnectionIdValidForVersion(
+      QuicConnectionId connection_id,
+      QuicTransportVersion transport_version);
+
+  // Returns a connection ID suitable for QUIC use-cases that do not need the
+  // connection ID for multiplexing. If the version allows variable lengths,
+  // a connection of length zero is returned, otherwise 64bits set to zero.
+  static QuicConnectionId CreateZeroConnectionId(QuicTransportVersion version);
+
+  // Generates a 128bit stateless reset token based on a connection ID.
+  static StatelessResetToken GenerateStatelessResetToken(
+      QuicConnectionId connection_id);
+
+  // Determines packet number space from |encryption_level|.
+  static PacketNumberSpace GetPacketNumberSpace(
+      EncryptionLevel encryption_level);
+
+  // Determines encryption level to send packets in |packet_number_space|.
+  static EncryptionLevel GetEncryptionLevel(
+      PacketNumberSpace packet_number_space);
+
+  // Get the maximum value for a V99/IETF QUIC stream count. If a count
+  // exceeds this value, it will result in a stream ID that exceeds the
+  // implementation limit on stream ID size.
+  static QuicStreamCount GetMaxStreamCount();
+
+  // Return true if this frame is an IETF probing frame.
+  static bool IsProbingFrame(QuicFrameType type);
+
+  // Return true if the two stateless reset tokens are equal. Performs the
+  // comparison in constant time.
+  static bool AreStatelessResetTokensEqual(const StatelessResetToken& token1,
+                                           const StatelessResetToken& token2);
+
+  // Return ture if this frame is an ack-eliciting frame.
+  static bool IsAckElicitingFrame(QuicFrameType type);
+};
+
+// Returns true if the specific ID is a valid WebTransport session ID that our
+// implementation can process.
+bool IsValidWebTransportSessionId(WebTransportSessionId id,
+                                  ParsedQuicVersion transport_version);
+
+QuicByteCount MemSliceSpanTotalSize(absl::Span<quiche::QuicheMemSlice> span);
+
+// Computes a SHA-256 hash and returns the raw bytes of the hash.
+QUIC_EXPORT_PRIVATE std::string RawSha256(absl::string_view input);
+
+template <typename Mask>
+class QUIC_EXPORT_PRIVATE BitMask {
+ public:
+  // explicit to prevent (incorrect) usage like "BitMask bitmask = 0;".
+  template <typename... Bits>
+  explicit BitMask(Bits... bits) {
+    mask_ = MakeMask(bits...);
+  }
+
+  BitMask() = default;
+  BitMask(const BitMask& other) = default;
+  BitMask& operator=(const BitMask& other) = default;
+
+  template <typename... Bits>
+  void Set(Bits... bits) {
+    mask_ |= MakeMask(bits...);
+  }
+
+  template <typename Bit>
+  bool IsSet(Bit bit) const {
+    return (MakeMask(bit) & mask_) != 0;
+  }
+
+  void ClearAll() { mask_ = 0; }
+
+  static constexpr size_t NumBits() { return 8 * sizeof(Mask); }
+
+  friend bool operator==(const BitMask& lhs, const BitMask& rhs) {
+    return lhs.mask_ == rhs.mask_;
+  }
+
+  std::string DebugString() const {
+    std::ostringstream oss;
+    oss << "0x" << std::hex << mask_;
+    return oss.str();
+  }
+
+ private:
+  template <typename Bit>
+  static std::enable_if_t<std::is_enum<Bit>::value, Mask> MakeMask(Bit bit) {
+    using IntType = typename std::underlying_type<Bit>::type;
+    return Mask(1) << static_cast<IntType>(bit);
+  }
+
+  template <typename Bit>
+  static std::enable_if_t<!std::is_enum<Bit>::value, Mask> MakeMask(Bit bit) {
+    return Mask(1) << bit;
+  }
+
+  template <typename Bit, typename... Bits>
+  static Mask MakeMask(Bit first_bit, Bits... other_bits) {
+    return MakeMask(first_bit) | MakeMask(other_bits...);
+  }
+
+  Mask mask_ = 0;
+};
+
+using BitMask64 = BitMask<uint64_t>;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_UTILS_H_
diff --git a/quiche/quic/core/quic_utils_test.cc b/quiche/quic/core/quic_utils_test.cc
new file mode 100644
index 0000000..19ce446
--- /dev/null
+++ b/quiche/quic/core/quic_utils_test.cc
@@ -0,0 +1,404 @@
+// Copyright (c) 2013 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 "quiche/quic/core/quic_utils.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicUtilsTest : public QuicTest {};
+
+TEST_F(QuicUtilsTest, DetermineAddressChangeType) {
+  const std::string kIPv4String1 = "1.2.3.4";
+  const std::string kIPv4String2 = "1.2.3.5";
+  const std::string kIPv4String3 = "1.1.3.5";
+  const std::string kIPv6String1 = "2001:700:300:1800::f";
+  const std::string kIPv6String2 = "2001:700:300:1800:1:1:1:f";
+  QuicSocketAddress old_address;
+  QuicSocketAddress new_address;
+  QuicIpAddress address;
+
+  EXPECT_EQ(NO_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+  ASSERT_TRUE(address.FromString(kIPv4String1));
+  old_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(NO_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(NO_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  new_address = QuicSocketAddress(address, 5678);
+  EXPECT_EQ(PORT_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+  ASSERT_TRUE(address.FromString(kIPv6String1));
+  old_address = QuicSocketAddress(address, 1234);
+  new_address = QuicSocketAddress(address, 5678);
+  EXPECT_EQ(PORT_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  ASSERT_TRUE(address.FromString(kIPv4String1));
+  old_address = QuicSocketAddress(address, 1234);
+  ASSERT_TRUE(address.FromString(kIPv6String1));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV4_TO_IPV6_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  old_address = QuicSocketAddress(address, 1234);
+  ASSERT_TRUE(address.FromString(kIPv4String1));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  ASSERT_TRUE(address.FromString(kIPv6String2));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV6_TO_IPV6_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  ASSERT_TRUE(address.FromString(kIPv4String1));
+  old_address = QuicSocketAddress(address, 1234);
+  ASSERT_TRUE(address.FromString(kIPv4String2));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV4_SUBNET_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+  ASSERT_TRUE(address.FromString(kIPv4String3));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV4_TO_IPV4_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+}
+
+absl::uint128 IncrementalHashReference(const void* data, size_t len) {
+  // The two constants are defined as part of the hash algorithm.
+  // see http://www.isthe.com/chongo/tech/comp/fnv/
+  // hash = 144066263297769815596495629667062367629
+  absl::uint128 hash = absl::MakeUint128(UINT64_C(7809847782465536322),
+                                         UINT64_C(7113472399480571277));
+  // kPrime = 309485009821345068724781371
+  const absl::uint128 kPrime = absl::MakeUint128(16777216, 315);
+  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data);
+  for (size_t i = 0; i < len; ++i) {
+    hash = hash ^ absl::MakeUint128(0, octets[i]);
+    hash = hash * kPrime;
+  }
+  return hash;
+}
+
+TEST_F(QuicUtilsTest, ReferenceTest) {
+  std::vector<uint8_t> data(32);
+  for (size_t i = 0; i < data.size(); ++i) {
+    data[i] = i % 255;
+  }
+  EXPECT_EQ(IncrementalHashReference(data.data(), data.size()),
+            QuicUtils::FNV1a_128_Hash(absl::string_view(
+                reinterpret_cast<const char*>(data.data()), data.size())));
+}
+
+TEST_F(QuicUtilsTest, IsUnackable) {
+  for (size_t i = FIRST_PACKET_STATE; i <= LAST_PACKET_STATE; ++i) {
+    if (i == NEVER_SENT || i == ACKED || i == UNACKABLE) {
+      EXPECT_FALSE(QuicUtils::IsAckable(static_cast<SentPacketState>(i)));
+    } else {
+      EXPECT_TRUE(QuicUtils::IsAckable(static_cast<SentPacketState>(i)));
+    }
+  }
+}
+
+TEST_F(QuicUtilsTest, RetransmissionTypeToPacketState) {
+  for (size_t i = FIRST_TRANSMISSION_TYPE; i <= LAST_TRANSMISSION_TYPE; ++i) {
+    if (i == NOT_RETRANSMISSION) {
+      continue;
+    }
+    SentPacketState state = QuicUtils::RetransmissionTypeToPacketState(
+        static_cast<TransmissionType>(i));
+    if (i == HANDSHAKE_RETRANSMISSION) {
+      EXPECT_EQ(HANDSHAKE_RETRANSMITTED, state);
+    } else if (i == LOSS_RETRANSMISSION) {
+      EXPECT_EQ(LOST, state);
+    } else if (i == ALL_ZERO_RTT_RETRANSMISSION) {
+      EXPECT_EQ(UNACKABLE, state);
+    } else if (i == TLP_RETRANSMISSION) {
+      EXPECT_EQ(TLP_RETRANSMITTED, state);
+    } else if (i == RTO_RETRANSMISSION) {
+      EXPECT_EQ(RTO_RETRANSMITTED, state);
+    } else if (i == PTO_RETRANSMISSION) {
+      EXPECT_EQ(PTO_RETRANSMITTED, state);
+    } else if (i == PROBING_RETRANSMISSION) {
+      EXPECT_EQ(PROBE_RETRANSMITTED, state);
+    } else if (i == PATH_RETRANSMISSION) {
+      EXPECT_EQ(NOT_CONTRIBUTING_RTT, state);
+    } else if (i == ALL_INITIAL_RETRANSMISSION) {
+      EXPECT_EQ(UNACKABLE, state);
+    } else {
+      QUICHE_DCHECK(false)
+          << "No corresponding packet state according to transmission type: "
+          << i;
+    }
+  }
+}
+
+TEST_F(QuicUtilsTest, IsIetfPacketHeader) {
+  // IETF QUIC short header
+  uint8_t first_byte = 0;
+  EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
+  EXPECT_TRUE(QuicUtils::IsIetfPacketShortHeader(first_byte));
+
+  // IETF QUIC long header
+  first_byte |= (FLAGS_LONG_HEADER | FLAGS_DEMULTIPLEXING_BIT);
+  EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
+  EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
+
+  // IETF QUIC long header, version negotiation.
+  first_byte = 0;
+  first_byte |= FLAGS_LONG_HEADER;
+  EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
+  EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
+
+  // GQUIC
+  first_byte = 0;
+  first_byte |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
+  EXPECT_FALSE(QuicUtils::IsIetfPacketHeader(first_byte));
+  EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
+}
+
+TEST_F(QuicUtilsTest, ReplacementConnectionIdIsDeterministic) {
+  // Verify that two equal connection IDs get the same replacement.
+  QuicConnectionId connection_id64a = TestConnectionId(33);
+  QuicConnectionId connection_id64b = TestConnectionId(33);
+  EXPECT_EQ(connection_id64a, connection_id64b);
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a),
+            QuicUtils::CreateReplacementConnectionId(connection_id64b));
+  QuicConnectionId connection_id72a = TestConnectionIdNineBytesLong(42);
+  QuicConnectionId connection_id72b = TestConnectionIdNineBytesLong(42);
+  EXPECT_EQ(connection_id72a, connection_id72b);
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b));
+  // Test variant with custom length.
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 7),
+            QuicUtils::CreateReplacementConnectionId(connection_id64b, 7));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 9),
+            QuicUtils::CreateReplacementConnectionId(connection_id64b, 9));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 16),
+            QuicUtils::CreateReplacementConnectionId(connection_id64b, 16));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 7),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 7));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 9),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 9));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 16),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 16));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 32),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 32));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 255),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 255));
+}
+
+TEST_F(QuicUtilsTest, ReplacementConnectionIdLengthIsCorrect) {
+  // Verify that all lengths get replaced by kQuicDefaultConnectionIdLength.
+  const char connection_id_bytes[255] = {};
+  for (uint8_t i = 0; i < sizeof(connection_id_bytes) - 1; ++i) {
+    QuicConnectionId connection_id(connection_id_bytes, i);
+    QuicConnectionId replacement_connection_id =
+        QuicUtils::CreateReplacementConnectionId(connection_id);
+    EXPECT_EQ(kQuicDefaultConnectionIdLength,
+              replacement_connection_id.length());
+    // Test variant with custom length.
+    QuicConnectionId replacement_connection_id7 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 7);
+    EXPECT_EQ(7, replacement_connection_id7.length());
+    QuicConnectionId replacement_connection_id9 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 9);
+    EXPECT_EQ(9, replacement_connection_id9.length());
+    QuicConnectionId replacement_connection_id16 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 16);
+    EXPECT_EQ(16, replacement_connection_id16.length());
+    QuicConnectionId replacement_connection_id32 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 32);
+    EXPECT_EQ(32, replacement_connection_id32.length());
+    QuicConnectionId replacement_connection_id255 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 255);
+    EXPECT_EQ(255, replacement_connection_id255.length());
+  }
+}
+
+TEST_F(QuicUtilsTest, ReplacementConnectionIdHasEntropy) {
+  // Make sure all these test connection IDs have different replacements.
+  for (uint64_t i = 0; i < 256; ++i) {
+    QuicConnectionId connection_id_i = TestConnectionId(i);
+    EXPECT_NE(connection_id_i,
+              QuicUtils::CreateReplacementConnectionId(connection_id_i));
+    for (uint64_t j = i + 1; j <= 256; ++j) {
+      QuicConnectionId connection_id_j = TestConnectionId(j);
+      EXPECT_NE(connection_id_i, connection_id_j);
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j));
+      // Test variant with custom length.
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 7),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 7));
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 9),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 9));
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 16),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 16));
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 32),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 32));
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 255),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 255));
+    }
+  }
+}
+
+TEST_F(QuicUtilsTest, RandomConnectionId) {
+  MockRandom random(33);
+  QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(&random);
+  EXPECT_EQ(connection_id.length(), sizeof(uint64_t));
+  char connection_id_bytes[sizeof(uint64_t)];
+  random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes));
+  EXPECT_EQ(connection_id,
+            QuicConnectionId(static_cast<char*>(connection_id_bytes),
+                             ABSL_ARRAYSIZE(connection_id_bytes)));
+  EXPECT_NE(connection_id, EmptyQuicConnectionId());
+  EXPECT_NE(connection_id, TestConnectionId());
+  EXPECT_NE(connection_id, TestConnectionId(1));
+  EXPECT_NE(connection_id, TestConnectionIdNineBytesLong(1));
+  EXPECT_EQ(QuicUtils::CreateRandomConnectionId().length(),
+            kQuicDefaultConnectionIdLength);
+}
+
+TEST_F(QuicUtilsTest, RandomConnectionIdVariableLength) {
+  MockRandom random(1337);
+  const uint8_t connection_id_length = 9;
+  QuicConnectionId connection_id =
+      QuicUtils::CreateRandomConnectionId(connection_id_length, &random);
+  EXPECT_EQ(connection_id.length(), connection_id_length);
+  char connection_id_bytes[connection_id_length];
+  random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes));
+  EXPECT_EQ(connection_id,
+            QuicConnectionId(static_cast<char*>(connection_id_bytes),
+                             ABSL_ARRAYSIZE(connection_id_bytes)));
+  EXPECT_NE(connection_id, EmptyQuicConnectionId());
+  EXPECT_NE(connection_id, TestConnectionId());
+  EXPECT_NE(connection_id, TestConnectionId(1));
+  EXPECT_NE(connection_id, TestConnectionIdNineBytesLong(1));
+  EXPECT_EQ(QuicUtils::CreateRandomConnectionId(connection_id_length).length(),
+            connection_id_length);
+}
+
+TEST_F(QuicUtilsTest, VariableLengthConnectionId) {
+  EXPECT_FALSE(VersionAllowsVariableLengthConnectionIds(QUIC_VERSION_43));
+  EXPECT_TRUE(QuicUtils::IsConnectionIdValidForVersion(
+      QuicUtils::CreateZeroConnectionId(QUIC_VERSION_43), QUIC_VERSION_43));
+  EXPECT_TRUE(QuicUtils::IsConnectionIdValidForVersion(
+      QuicUtils::CreateZeroConnectionId(QUIC_VERSION_50), QUIC_VERSION_50));
+  EXPECT_NE(QuicUtils::CreateZeroConnectionId(QUIC_VERSION_43),
+            EmptyQuicConnectionId());
+  EXPECT_EQ(QuicUtils::CreateZeroConnectionId(QUIC_VERSION_50),
+            EmptyQuicConnectionId());
+  EXPECT_FALSE(QuicUtils::IsConnectionIdValidForVersion(EmptyQuicConnectionId(),
+                                                        QUIC_VERSION_43));
+}
+
+TEST_F(QuicUtilsTest, StatelessResetToken) {
+  QuicConnectionId connection_id1a = test::TestConnectionId(1);
+  QuicConnectionId connection_id1b = test::TestConnectionId(1);
+  QuicConnectionId connection_id2 = test::TestConnectionId(2);
+  StatelessResetToken token1a =
+      QuicUtils::GenerateStatelessResetToken(connection_id1a);
+  StatelessResetToken token1b =
+      QuicUtils::GenerateStatelessResetToken(connection_id1b);
+  StatelessResetToken token2 =
+      QuicUtils::GenerateStatelessResetToken(connection_id2);
+  EXPECT_EQ(token1a, token1b);
+  EXPECT_NE(token1a, token2);
+  EXPECT_TRUE(QuicUtils::AreStatelessResetTokensEqual(token1a, token1b));
+  EXPECT_FALSE(QuicUtils::AreStatelessResetTokensEqual(token1a, token2));
+}
+
+enum class TestEnumClassBit : uint8_t {
+  BIT_ZERO = 0,
+  BIT_ONE,
+  BIT_TWO,
+};
+
+enum TestEnumBit {
+  TEST_BIT_0 = 0,
+  TEST_BIT_1,
+  TEST_BIT_2,
+};
+
+TEST(QuicBitMaskTest, EnumClass) {
+  BitMask64 mask(TestEnumClassBit::BIT_ZERO, TestEnumClassBit::BIT_TWO);
+  EXPECT_TRUE(mask.IsSet(TestEnumClassBit::BIT_ZERO));
+  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ONE));
+  EXPECT_TRUE(mask.IsSet(TestEnumClassBit::BIT_TWO));
+
+  mask.ClearAll();
+  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ZERO));
+  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ONE));
+  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_TWO));
+}
+
+TEST(QuicBitMaskTest, Enum) {
+  BitMask64 mask(TEST_BIT_1, TEST_BIT_2);
+  EXPECT_FALSE(mask.IsSet(TEST_BIT_0));
+  EXPECT_TRUE(mask.IsSet(TEST_BIT_1));
+  EXPECT_TRUE(mask.IsSet(TEST_BIT_2));
+
+  mask.ClearAll();
+  EXPECT_FALSE(mask.IsSet(TEST_BIT_0));
+  EXPECT_FALSE(mask.IsSet(TEST_BIT_1));
+  EXPECT_FALSE(mask.IsSet(TEST_BIT_2));
+}
+
+TEST(QuicBitMaskTest, Integer) {
+  BitMask64 mask(1, 3);
+  mask.Set(3);
+  mask.Set(5, 7, 9);
+  EXPECT_FALSE(mask.IsSet(0));
+  EXPECT_TRUE(mask.IsSet(1));
+  EXPECT_FALSE(mask.IsSet(2));
+  EXPECT_TRUE(mask.IsSet(3));
+  EXPECT_FALSE(mask.IsSet(4));
+  EXPECT_TRUE(mask.IsSet(5));
+  EXPECT_FALSE(mask.IsSet(6));
+  EXPECT_TRUE(mask.IsSet(7));
+  EXPECT_FALSE(mask.IsSet(8));
+  EXPECT_TRUE(mask.IsSet(9));
+}
+
+TEST(QuicBitMaskTest, NumBits) {
+  EXPECT_EQ(64u, BitMask64::NumBits());
+  EXPECT_EQ(32u, BitMask<uint32_t>::NumBits());
+}
+
+TEST(QuicBitMaskTest, Constructor) {
+  BitMask64 empty_mask;
+  for (size_t bit = 0; bit < empty_mask.NumBits(); ++bit) {
+    EXPECT_FALSE(empty_mask.IsSet(bit));
+  }
+
+  BitMask64 mask(1, 3);
+  BitMask64 mask2 = mask;
+  BitMask64 mask3(mask2);
+
+  for (size_t bit = 0; bit < mask.NumBits(); ++bit) {
+    EXPECT_EQ(mask.IsSet(bit), mask2.IsSet(bit));
+    EXPECT_EQ(mask.IsSet(bit), mask3.IsSet(bit));
+  }
+
+  EXPECT_TRUE(std::is_trivially_copyable<BitMask64>::value);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_version_manager.cc b/quiche/quic/core/quic_version_manager.cc
new file mode 100644
index 0000000..2c88477
--- /dev/null
+++ b/quiche/quic/core/quic_version_manager.cc
@@ -0,0 +1,94 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_version_manager.h"
+
+#include <algorithm>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicVersionManager::QuicVersionManager(
+    ParsedQuicVersionVector supported_versions)
+    : allowed_supported_versions_(std::move(supported_versions)) {}
+
+QuicVersionManager::~QuicVersionManager() {}
+
+const ParsedQuicVersionVector& QuicVersionManager::GetSupportedVersions() {
+  MaybeRefilterSupportedVersions();
+  return filtered_supported_versions_;
+}
+
+const ParsedQuicVersionVector&
+QuicVersionManager::GetSupportedVersionsWithOnlyHttp3() {
+  MaybeRefilterSupportedVersions();
+  return filtered_supported_versions_with_http3_;
+}
+
+const std::vector<std::string>& QuicVersionManager::GetSupportedAlpns() {
+  MaybeRefilterSupportedVersions();
+  return filtered_supported_alpns_;
+}
+
+void QuicVersionManager::MaybeRefilterSupportedVersions() {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  if (enable_version_2_draft_01_ !=
+          GetQuicReloadableFlag(quic_enable_version_2_draft_01) ||
+      disable_version_rfcv1_ !=
+          GetQuicReloadableFlag(quic_disable_version_rfcv1) ||
+      disable_version_draft_29_ !=
+          GetQuicReloadableFlag(quic_disable_version_draft_29) ||
+      disable_version_q050_ !=
+          GetQuicReloadableFlag(quic_disable_version_q050) ||
+      disable_version_q046_ !=
+          GetQuicReloadableFlag(quic_disable_version_q046) ||
+      disable_version_q043_ !=
+          GetQuicReloadableFlag(quic_disable_version_q043)) {
+    enable_version_2_draft_01_ =
+        GetQuicReloadableFlag(quic_enable_version_2_draft_01);
+    disable_version_rfcv1_ = GetQuicReloadableFlag(quic_disable_version_rfcv1);
+    disable_version_draft_29_ =
+        GetQuicReloadableFlag(quic_disable_version_draft_29);
+    disable_version_q050_ = GetQuicReloadableFlag(quic_disable_version_q050);
+    disable_version_q046_ = GetQuicReloadableFlag(quic_disable_version_q046);
+    disable_version_q043_ = GetQuicReloadableFlag(quic_disable_version_q043);
+
+    RefilterSupportedVersions();
+  }
+}
+
+void QuicVersionManager::RefilterSupportedVersions() {
+  filtered_supported_versions_ =
+      FilterSupportedVersions(allowed_supported_versions_);
+  filtered_supported_versions_with_http3_.clear();
+  filtered_transport_versions_.clear();
+  filtered_supported_alpns_.clear();
+  for (const ParsedQuicVersion& version : filtered_supported_versions_) {
+    auto transport_version = version.transport_version;
+    if (std::find(filtered_transport_versions_.begin(),
+                  filtered_transport_versions_.end(),
+                  transport_version) == filtered_transport_versions_.end()) {
+      filtered_transport_versions_.push_back(transport_version);
+    }
+    if (version.UsesHttp3()) {
+      filtered_supported_versions_with_http3_.push_back(version);
+    }
+    if (std::find(filtered_supported_alpns_.begin(),
+                  filtered_supported_alpns_.end(),
+                  AlpnForVersion(version)) == filtered_supported_alpns_.end()) {
+      filtered_supported_alpns_.emplace_back(AlpnForVersion(version));
+    }
+  }
+}
+
+void QuicVersionManager::AddCustomAlpn(const std::string& alpn) {
+  filtered_supported_alpns_.push_back(alpn);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_version_manager.h b/quiche/quic/core/quic_version_manager.h
new file mode 100644
index 0000000..ddabd1c
--- /dev/null
+++ b/quiche/quic/core/quic_version_manager.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2016 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_VERSION_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
+
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Used to generate filtered supported versions based on flags.
+class QUIC_EXPORT_PRIVATE QuicVersionManager {
+ public:
+  // |supported_versions| should be sorted in the order of preference (typically
+  // highest supported version to the lowest supported version).
+  explicit QuicVersionManager(ParsedQuicVersionVector supported_versions);
+  virtual ~QuicVersionManager();
+
+  // Returns currently supported QUIC versions. This vector has the same order
+  // as the versions passed to the constructor.
+  const ParsedQuicVersionVector& GetSupportedVersions();
+
+  // Returns currently supported versions using HTTP/3.
+  const ParsedQuicVersionVector& GetSupportedVersionsWithOnlyHttp3();
+
+  // Returns the list of supported ALPNs, based on the current supported
+  // versions and any custom additions by subclasses.
+  const std::vector<std::string>& GetSupportedAlpns();
+
+ protected:
+  // If the value of any reloadable flag is different from the cached value,
+  // re-filter |filtered_supported_versions_| and update the cached flag values.
+  // Otherwise, does nothing.
+  // TODO(dschinazi): Make private when deprecating
+  // FLAGS_gfe2_restart_flag_quic_disable_old_alt_svc_format.
+  void MaybeRefilterSupportedVersions();
+
+  // Refilters filtered_supported_versions_.
+  virtual void RefilterSupportedVersions();
+
+  // RefilterSupportedVersions() must be called before calling this method.
+  // TODO(dschinazi): Remove when deprecating
+  // FLAGS_gfe2_restart_flag_quic_disable_old_alt_svc_format.
+  const QuicTransportVersionVector& filtered_transport_versions() const {
+    return filtered_transport_versions_;
+  }
+
+  // Subclasses may add custom ALPNs to the supported list by overriding
+  // RefilterSupportedVersions() to first call
+  // QuicVersionManager::RefilterSupportedVersions() then AddCustomAlpn().
+  // Must not be called elsewhere.
+  void AddCustomAlpn(const std::string& alpn);
+
+ private:
+  // Cached value of reloadable flags.
+  // quic_enable_version_2_draft_01 flag
+  bool enable_version_2_draft_01_ = false;
+  // quic_disable_version_rfcv1 flag
+  bool disable_version_rfcv1_ = true;
+  // quic_disable_version_draft_29 flag
+  bool disable_version_draft_29_ = true;
+  // quic_disable_version_q050 flag
+  bool disable_version_q050_ = true;
+  // quic_disable_version_q046 flag
+  bool disable_version_q046_ = true;
+  // quic_disable_version_q043 flag
+  bool disable_version_q043_ = true;
+
+  // The list of versions that may be supported.
+  const ParsedQuicVersionVector allowed_supported_versions_;
+
+  // The following vectors are calculated from reloadable flags by
+  // RefilterSupportedVersions().  It is performed lazily when first needed, and
+  // after that, since the calculation is relatively expensive, only if the flag
+  // values change.
+
+  // This vector contains QUIC versions which are currently supported based on
+  // flags.
+  ParsedQuicVersionVector filtered_supported_versions_;
+  // Currently supported versions using HTTP/3.
+  ParsedQuicVersionVector filtered_supported_versions_with_http3_;
+  // This vector contains the transport versions from
+  // |filtered_supported_versions_|. No guarantees are made that the same
+  // transport version isn't repeated.
+  QuicTransportVersionVector filtered_transport_versions_;
+  // Contains the list of ALPNs corresponding to filtered_supported_versions_
+  // with custom ALPNs added.
+  std::vector<std::string> filtered_supported_alpns_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
diff --git a/quiche/quic/core/quic_version_manager_test.cc b/quiche/quic/core/quic_version_manager_test.cc
new file mode 100644
index 0000000..8ef018a
--- /dev/null
+++ b/quiche/quic/core/quic_version_manager_test.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2016 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 "quiche/quic/core/quic_version_manager.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using ::testing::ElementsAre;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicVersionManagerTest : public QuicTest {};
+
+TEST_F(QuicVersionManagerTest, QuicVersionManager) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicEnableVersion(version);
+  }
+  QuicDisableVersion(ParsedQuicVersion::V2Draft01());
+  QuicDisableVersion(ParsedQuicVersion::RFCv1());
+  QuicDisableVersion(ParsedQuicVersion::Draft29());
+  QuicVersionManager manager(AllSupportedVersions());
+
+  ParsedQuicVersionVector expected_parsed_versions;
+  expected_parsed_versions.push_back(ParsedQuicVersion::Q050());
+  expected_parsed_versions.push_back(ParsedQuicVersion::Q046());
+  expected_parsed_versions.push_back(ParsedQuicVersion::Q043());
+
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+  EXPECT_TRUE(manager.GetSupportedVersionsWithOnlyHttp3().empty());
+  EXPECT_THAT(manager.GetSupportedAlpns(),
+              ElementsAre("h3-Q050", "h3-Q046", "h3-Q043"));
+
+  QuicEnableVersion(ParsedQuicVersion::Draft29());
+  expected_parsed_versions.insert(expected_parsed_versions.begin(),
+                                  ParsedQuicVersion::Draft29());
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+  EXPECT_EQ(1u, manager.GetSupportedVersionsWithOnlyHttp3().size());
+  EXPECT_EQ(CurrentSupportedHttp3Versions(),
+            manager.GetSupportedVersionsWithOnlyHttp3());
+  EXPECT_THAT(manager.GetSupportedAlpns(),
+              ElementsAre("h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
+
+  QuicEnableVersion(ParsedQuicVersion::RFCv1());
+  expected_parsed_versions.insert(expected_parsed_versions.begin(),
+                                  ParsedQuicVersion::RFCv1());
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+  EXPECT_EQ(2u, manager.GetSupportedVersionsWithOnlyHttp3().size());
+  EXPECT_EQ(CurrentSupportedHttp3Versions(),
+            manager.GetSupportedVersionsWithOnlyHttp3());
+  EXPECT_THAT(manager.GetSupportedAlpns(),
+              ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
+
+  QuicEnableVersion(ParsedQuicVersion::V2Draft01());
+  expected_parsed_versions.insert(expected_parsed_versions.begin(),
+                                  ParsedQuicVersion::V2Draft01());
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+  EXPECT_EQ(3u, manager.GetSupportedVersionsWithOnlyHttp3().size());
+  EXPECT_EQ(CurrentSupportedHttp3Versions(),
+            manager.GetSupportedVersionsWithOnlyHttp3());
+  EXPECT_THAT(
+      manager.GetSupportedAlpns(),
+      ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_versions.cc b/quiche/quic/core/quic_versions.cc
new file mode 100644
index 0000000..df43ce7
--- /dev/null
+++ b/quiche/quic/core/quic_versions.cc
@@ -0,0 +1,667 @@
+// 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 "quiche/quic/core/quic_versions.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace {
+
+QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
+  QuicVersionLabel result;
+  if (!GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness)) {
+    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
+  } else {
+    result = MakeVersionLabel(0xd1, 0x57, 0x38, 0x3f);
+  }
+  result &= 0xf0f0f0f0;
+  result |= 0x0a0a0a0a;
+  return result;
+}
+
+void SetVersionFlag(const ParsedQuicVersion& version, bool should_enable) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  const bool enable = should_enable;
+  const bool disable = !should_enable;
+  if (version == ParsedQuicVersion::V2Draft01()) {
+    SetQuicReloadableFlag(quic_enable_version_2_draft_01, enable);
+  } else if (version == ParsedQuicVersion::RFCv1()) {
+    SetQuicReloadableFlag(quic_disable_version_rfcv1, disable);
+  } else if (version == ParsedQuicVersion::Draft29()) {
+    SetQuicReloadableFlag(quic_disable_version_draft_29, disable);
+  } else if (version == ParsedQuicVersion::Q050()) {
+    SetQuicReloadableFlag(quic_disable_version_q050, disable);
+  } else if (version == ParsedQuicVersion::Q046()) {
+    SetQuicReloadableFlag(quic_disable_version_q046, disable);
+  } else if (version == ParsedQuicVersion::Q043()) {
+    SetQuicReloadableFlag(quic_disable_version_q043, disable);
+  } else {
+    QUIC_BUG(quic_bug_10589_1)
+        << "Cannot " << (enable ? "en" : "dis") << "able version " << version;
+  }
+}
+
+}  // namespace
+
+bool ParsedQuicVersion::IsKnown() const {
+  QUICHE_DCHECK(ParsedQuicVersionIsValid(handshake_protocol, transport_version))
+      << QuicVersionToString(transport_version) << " "
+      << HandshakeProtocolToString(handshake_protocol);
+  return transport_version != QUIC_VERSION_UNSUPPORTED;
+}
+
+bool ParsedQuicVersion::KnowsWhichDecrypterToUse() const {
+  QUICHE_DCHECK(IsKnown());
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::UsesInitialObfuscators() const {
+  QUICHE_DCHECK(IsKnown());
+  // Initial obfuscators were added in version 50.
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::AllowsLowFlowControlLimits() const {
+  QUICHE_DCHECK(IsKnown());
+  // Low flow-control limits are used for all IETF versions.
+  return UsesHttp3();
+}
+
+bool ParsedQuicVersion::HasHeaderProtection() const {
+  QUICHE_DCHECK(IsKnown());
+  // Header protection was added in version 50.
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::SupportsRetry() const {
+  QUICHE_DCHECK(IsKnown());
+  // Retry was added in version 47.
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::SendsVariableLengthPacketNumberInLongHeader() const {
+  QUICHE_DCHECK(IsKnown());
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::AllowsVariableLengthConnectionIds() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionAllowsVariableLengthConnectionIds(transport_version);
+}
+
+bool ParsedQuicVersion::SupportsClientConnectionIds() const {
+  QUICHE_DCHECK(IsKnown());
+  // Client connection IDs were added in version 49.
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::HasLengthPrefixedConnectionIds() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionHasLengthPrefixedConnectionIds(transport_version);
+}
+
+bool ParsedQuicVersion::SupportsAntiAmplificationLimit() const {
+  QUICHE_DCHECK(IsKnown());
+  // The anti-amplification limit is used for all IETF versions.
+  return UsesHttp3();
+}
+
+bool ParsedQuicVersion::CanSendCoalescedPackets() const {
+  QUICHE_DCHECK(IsKnown());
+  return HasLongHeaderLengths() && UsesTls();
+}
+
+bool ParsedQuicVersion::SupportsGoogleAltSvcFormat() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionSupportsGoogleAltSvcFormat(transport_version);
+}
+
+bool ParsedQuicVersion::HasIetfInvariantHeader() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionHasIetfInvariantHeader(transport_version);
+}
+
+bool ParsedQuicVersion::SupportsMessageFrames() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionSupportsMessageFrames(transport_version);
+}
+
+bool ParsedQuicVersion::UsesHttp3() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionUsesHttp3(transport_version);
+}
+
+bool ParsedQuicVersion::HasLongHeaderLengths() const {
+  QUICHE_DCHECK(IsKnown());
+  return QuicVersionHasLongHeaderLengths(transport_version);
+}
+
+bool ParsedQuicVersion::UsesCryptoFrames() const {
+  QUICHE_DCHECK(IsKnown());
+  return QuicVersionUsesCryptoFrames(transport_version);
+}
+
+bool ParsedQuicVersion::HasIetfQuicFrames() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionHasIetfQuicFrames(transport_version);
+}
+
+bool ParsedQuicVersion::UsesLegacyTlsExtension() const {
+  QUICHE_DCHECK(IsKnown());
+  return UsesTls() && transport_version <= QUIC_VERSION_IETF_DRAFT_29;
+}
+
+bool ParsedQuicVersion::UsesTls() const {
+  QUICHE_DCHECK(IsKnown());
+  return handshake_protocol == PROTOCOL_TLS1_3;
+}
+
+bool ParsedQuicVersion::UsesQuicCrypto() const {
+  QUICHE_DCHECK(IsKnown());
+  return handshake_protocol == PROTOCOL_QUIC_CRYPTO;
+}
+
+bool ParsedQuicVersion::UsesV2PacketTypes() const {
+  QUICHE_DCHECK(IsKnown());
+  return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
+}
+
+bool ParsedQuicVersion::AlpnDeferToRFCv1() const {
+  QUICHE_DCHECK(IsKnown());
+  return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
+}
+
+bool VersionHasLengthPrefixedConnectionIds(
+    QuicTransportVersion transport_version) {
+  QUICHE_DCHECK(transport_version != QUIC_VERSION_UNSUPPORTED);
+  // Length-prefixed connection IDs were added in version 49.
+  return transport_version > QUIC_VERSION_46;
+}
+
+std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
+  os << ParsedQuicVersionToString(version);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ParsedQuicVersionVector& versions) {
+  os << ParsedQuicVersionVectorToString(versions);
+  return os;
+}
+
+QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+  return MakeQuicTag(d, c, b, a);
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicVersionLabelVector& version_labels) {
+  os << QuicVersionLabelVectorToString(version_labels);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicTransportVersionVector& transport_versions) {
+  os << QuicTransportVersionVectorToString(transport_versions);
+  return os;
+}
+
+QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  if (parsed_version == ParsedQuicVersion::V2Draft01()) {
+    return MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4);
+  } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
+    return MakeVersionLabel(0x00, 0x00, 0x00, 0x01);
+  } else if (parsed_version == ParsedQuicVersion::Draft29()) {
+    return MakeVersionLabel(0xff, 0x00, 0x00, 29);
+  } else if (parsed_version == ParsedQuicVersion::Q050()) {
+    return MakeVersionLabel('Q', '0', '5', '0');
+  } else if (parsed_version == ParsedQuicVersion::Q046()) {
+    return MakeVersionLabel('Q', '0', '4', '6');
+  } else if (parsed_version == ParsedQuicVersion::Q043()) {
+    return MakeVersionLabel('Q', '0', '4', '3');
+  } else if (parsed_version == ParsedQuicVersion::ReservedForNegotiation()) {
+    return CreateRandomVersionLabelForNegotiation();
+  }
+  QUIC_BUG(quic_bug_10589_2)
+      << "Unsupported version "
+      << QuicVersionToString(parsed_version.transport_version) << " "
+      << HandshakeProtocolToString(parsed_version.handshake_protocol);
+  return 0;
+}
+
+QuicVersionLabelVector CreateQuicVersionLabelVector(
+    const ParsedQuicVersionVector& versions) {
+  QuicVersionLabelVector out;
+  out.reserve(versions.size());
+  for (const auto& version : versions) {
+    out.push_back(CreateQuicVersionLabel(version));
+  }
+  return out;
+}
+
+ParsedQuicVersionVector AllSupportedVersionsWithQuicCrypto() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(quic_bug_10589_3, versions.empty())
+      << "No version with QUIC crypto found.";
+  return versions;
+}
+
+ParsedQuicVersionVector CurrentSupportedVersionsWithQuicCrypto() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
+    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(quic_bug_10589_4, versions.empty())
+      << "No version with QUIC crypto found.";
+  return versions;
+}
+
+ParsedQuicVersionVector AllSupportedVersionsWithTls() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.UsesTls()) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(quic_bug_10589_5, versions.empty())
+      << "No version with TLS handshake found.";
+  return versions;
+}
+
+ParsedQuicVersionVector CurrentSupportedVersionsWithTls() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
+    if (version.UsesTls()) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(quic_bug_10589_6, versions.empty())
+      << "No version with TLS handshake found.";
+  return versions;
+}
+
+ParsedQuicVersionVector CurrentSupportedHttp3Versions() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
+    if (version.UsesHttp3()) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(no_version_uses_http3, versions.empty())
+      << "No version speaking Http3 found.";
+  return versions;
+}
+
+ParsedQuicVersion ParseQuicVersionLabel(QuicVersionLabel version_label) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version_label == CreateQuicVersionLabel(version)) {
+      return version;
+    }
+  }
+  // Reading from the client so this should not be considered an ERROR.
+  QUIC_DLOG(INFO) << "Unsupported QuicVersionLabel version: "
+                  << QuicVersionLabelToString(version_label);
+  return UnsupportedQuicVersion();
+}
+
+ParsedQuicVersionVector ParseQuicVersionLabelVector(
+    const QuicVersionLabelVector& version_labels) {
+  ParsedQuicVersionVector parsed_versions;
+  for (const QuicVersionLabel& version_label : version_labels) {
+    ParsedQuicVersion parsed_version = ParseQuicVersionLabel(version_label);
+    if (parsed_version.IsKnown()) {
+      parsed_versions.push_back(parsed_version);
+    }
+  }
+  return parsed_versions;
+}
+
+ParsedQuicVersion ParseQuicVersionString(absl::string_view version_string) {
+  if (version_string.empty()) {
+    return UnsupportedQuicVersion();
+  }
+  const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  for (const ParsedQuicVersion& version : supported_versions) {
+    if (version_string == ParsedQuicVersionToString(version) ||
+        (version_string == AlpnForVersion(version) &&
+         !version.AlpnDeferToRFCv1()) ||
+        (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
+         version_string == QuicVersionToString(version.transport_version))) {
+      return version;
+    }
+  }
+  for (const ParsedQuicVersion& version : supported_versions) {
+    if (version.UsesHttp3() &&
+        version_string ==
+            QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
+      return version;
+    }
+  }
+  int quic_version_number = 0;
+  if (absl::SimpleAtoi(version_string, &quic_version_number) &&
+      quic_version_number > 0) {
+    QuicTransportVersion transport_version =
+        static_cast<QuicTransportVersion>(quic_version_number);
+    if (!ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO, transport_version)) {
+      return UnsupportedQuicVersion();
+    }
+    ParsedQuicVersion version(PROTOCOL_QUIC_CRYPTO, transport_version);
+    if (std::find(supported_versions.begin(), supported_versions.end(),
+                  version) != supported_versions.end()) {
+      return version;
+    }
+    return UnsupportedQuicVersion();
+  }
+  // Reading from the client so this should not be considered an ERROR.
+  QUIC_DLOG(INFO) << "Unsupported QUIC version string: \"" << version_string
+                  << "\".";
+  return UnsupportedQuicVersion();
+}
+
+ParsedQuicVersionVector ParseQuicVersionVectorString(
+    absl::string_view versions_string) {
+  ParsedQuicVersionVector versions;
+  std::vector<absl::string_view> version_strings =
+      absl::StrSplit(versions_string, ',');
+  for (absl::string_view version_string : version_strings) {
+    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
+        &version_string);
+    ParsedQuicVersion version = ParseQuicVersionString(version_string);
+    if (!version.IsKnown() || std::find(versions.begin(), versions.end(),
+                                        version) != versions.end()) {
+      continue;
+    }
+    versions.push_back(version);
+  }
+  return versions;
+}
+
+QuicTransportVersionVector AllSupportedTransportVersions() {
+  QuicTransportVersionVector transport_versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (std::find(transport_versions.begin(), transport_versions.end(),
+                  version.transport_version) == transport_versions.end()) {
+      transport_versions.push_back(version.transport_version);
+    }
+  }
+  return transport_versions;
+}
+
+ParsedQuicVersionVector AllSupportedVersions() {
+  constexpr auto supported_versions = SupportedVersions();
+  return ParsedQuicVersionVector(supported_versions.begin(),
+                                 supported_versions.end());
+}
+
+ParsedQuicVersionVector CurrentSupportedVersions() {
+  return FilterSupportedVersions(AllSupportedVersions());
+}
+
+ParsedQuicVersionVector FilterSupportedVersions(
+    ParsedQuicVersionVector versions) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  ParsedQuicVersionVector filtered_versions;
+  filtered_versions.reserve(versions.size());
+  for (const ParsedQuicVersion& version : versions) {
+    if (version == ParsedQuicVersion::V2Draft01()) {
+      if (GetQuicReloadableFlag(quic_enable_version_2_draft_01)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::RFCv1()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_rfcv1)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::Draft29()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_draft_29)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::Q050()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_q050)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::Q046()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_q046)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::Q043()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_q043)) {
+        filtered_versions.push_back(version);
+      }
+    } else {
+      QUIC_BUG(quic_bug_10589_7)
+          << "QUIC version " << version << " has no flag protection";
+      filtered_versions.push_back(version);
+    }
+  }
+  return filtered_versions;
+}
+
+ParsedQuicVersionVector ParsedVersionOfIndex(
+    const ParsedQuicVersionVector& versions, int index) {
+  ParsedQuicVersionVector version;
+  int version_count = versions.size();
+  if (index >= 0 && index < version_count) {
+    version.push_back(versions[index]);
+  } else {
+    version.push_back(UnsupportedQuicVersion());
+  }
+  return version;
+}
+
+std::string QuicVersionLabelToString(QuicVersionLabel version_label) {
+  return QuicTagToString(quiche::QuicheEndian::HostToNet32(version_label));
+}
+
+ParsedQuicVersion ParseQuicVersionLabelString(
+    absl::string_view version_label_string) {
+  const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  for (const ParsedQuicVersion& version : supported_versions) {
+    if (version_label_string ==
+        QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
+      return version;
+    }
+  }
+  return UnsupportedQuicVersion();
+}
+
+std::string QuicVersionLabelVectorToString(
+    const QuicVersionLabelVector& version_labels, const std::string& separator,
+    size_t skip_after_nth_version) {
+  std::string result;
+  for (size_t i = 0; i < version_labels.size(); ++i) {
+    if (i != 0) {
+      result.append(separator);
+    }
+
+    if (i > skip_after_nth_version) {
+      result.append("...");
+      break;
+    }
+    result.append(QuicVersionLabelToString(version_labels[i]));
+  }
+  return result;
+}
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x
+
+std::string QuicVersionToString(QuicTransportVersion transport_version) {
+  switch (transport_version) {
+    RETURN_STRING_LITERAL(QUIC_VERSION_43);
+    RETURN_STRING_LITERAL(QUIC_VERSION_46);
+    RETURN_STRING_LITERAL(QUIC_VERSION_50);
+    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
+    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_RFC_V1);
+    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_2_DRAFT_01);
+    RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
+    RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
+  }
+  return absl::StrCat("QUIC_VERSION_UNKNOWN(",
+                      static_cast<int>(transport_version), ")");
+}
+
+std::string HandshakeProtocolToString(HandshakeProtocol handshake_protocol) {
+  switch (handshake_protocol) {
+    RETURN_STRING_LITERAL(PROTOCOL_UNSUPPORTED);
+    RETURN_STRING_LITERAL(PROTOCOL_QUIC_CRYPTO);
+    RETURN_STRING_LITERAL(PROTOCOL_TLS1_3);
+  }
+  return absl::StrCat("PROTOCOL_UNKNOWN(", static_cast<int>(handshake_protocol),
+                      ")");
+}
+
+std::string ParsedQuicVersionToString(ParsedQuicVersion version) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  if (version == UnsupportedQuicVersion()) {
+    return "0";
+  } else if (version == ParsedQuicVersion::V2Draft01()) {
+    QUICHE_DCHECK(version.UsesHttp3());
+    return "v2draft01";
+  } else if (version == ParsedQuicVersion::RFCv1()) {
+    QUICHE_DCHECK(version.UsesHttp3());
+    return "RFCv1";
+  } else if (version == ParsedQuicVersion::Draft29()) {
+    QUICHE_DCHECK(version.UsesHttp3());
+    return "draft29";
+  }
+
+  return QuicVersionLabelToString(CreateQuicVersionLabel(version));
+}
+
+std::string QuicTransportVersionVectorToString(
+    const QuicTransportVersionVector& versions) {
+  std::string result = "";
+  for (size_t i = 0; i < versions.size(); ++i) {
+    if (i != 0) {
+      result.append(",");
+    }
+    result.append(QuicVersionToString(versions[i]));
+  }
+  return result;
+}
+
+std::string ParsedQuicVersionVectorToString(
+    const ParsedQuicVersionVector& versions, const std::string& separator,
+    size_t skip_after_nth_version) {
+  std::string result;
+  for (size_t i = 0; i < versions.size(); ++i) {
+    if (i != 0) {
+      result.append(separator);
+    }
+    if (i > skip_after_nth_version) {
+      result.append("...");
+      break;
+    }
+    result.append(ParsedQuicVersionToString(versions[i]));
+  }
+  return result;
+}
+
+bool VersionSupportsGoogleAltSvcFormat(QuicTransportVersion transport_version) {
+  return transport_version <= QUIC_VERSION_46;
+}
+
+bool VersionAllowsVariableLengthConnectionIds(
+    QuicTransportVersion transport_version) {
+  QUICHE_DCHECK_NE(transport_version, QUIC_VERSION_UNSUPPORTED);
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool QuicVersionLabelUses4BitConnectionIdLength(
+    QuicVersionLabel version_label) {
+  // As we deprecate old versions, we still need the ability to send valid
+  // version negotiation packets for those versions. This function keeps track
+  // of the versions that ever supported the 4bit connection ID length encoding
+  // that we know about. Google QUIC 43 and earlier used a different encoding,
+  // and Google QUIC 49 and later use the new length prefixed encoding.
+  // Similarly, only IETF drafts 11 to 21 used this encoding.
+
+  // Check Q044, Q045, Q046, Q047 and Q048.
+  for (uint8_t c = '4'; c <= '8'; ++c) {
+    if (version_label == MakeVersionLabel('Q', '0', '4', c)) {
+      return true;
+    }
+  }
+  // Check T048.
+  if (version_label == MakeVersionLabel('T', '0', '4', '8')) {
+    return true;
+  }
+  // Check IETF draft versions in [11,21].
+  for (uint8_t draft_number = 11; draft_number <= 21; ++draft_number) {
+    if (version_label == MakeVersionLabel(0xff, 0x00, 0x00, draft_number)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+ParsedQuicVersion UnsupportedQuicVersion() {
+  return ParsedQuicVersion::Unsupported();
+}
+
+ParsedQuicVersion QuicVersionReservedForNegotiation() {
+  return ParsedQuicVersion::ReservedForNegotiation();
+}
+
+ParsedQuicVersion LegacyVersionForEncapsulation() {
+  return ParsedQuicVersion::Q043();
+}
+
+std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
+  if (parsed_version == ParsedQuicVersion::V2Draft01()) {
+    return "h3";
+  } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
+    return "h3";
+  } else if (parsed_version == ParsedQuicVersion::Draft29()) {
+    return "h3-29";
+  }
+  return "h3-" + ParsedQuicVersionToString(parsed_version);
+}
+
+void QuicVersionInitializeSupportForIetfDraft() {
+  // Enable necessary flags.
+}
+
+void QuicEnableVersion(const ParsedQuicVersion& version) {
+  SetVersionFlag(version, /*should_enable=*/true);
+}
+
+void QuicDisableVersion(const ParsedQuicVersion& version) {
+  SetVersionFlag(version, /*should_enable=*/false);
+}
+
+bool QuicVersionIsEnabled(const ParsedQuicVersion& version) {
+  ParsedQuicVersionVector current = CurrentSupportedVersions();
+  return std::find(current.begin(), current.end(), version) != current.end();
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_versions.h b/quiche/quic/core/quic_versions.h
new file mode 100644
index 0000000..39f8642
--- /dev/null
+++ b/quiche/quic/core/quic_versions.h
@@ -0,0 +1,652 @@
+// 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.
+
+// Definitions and utility functions related to handling of QUIC versions.
+//
+// QUIC versions are encoded over the wire as an opaque 32bit field. The wire
+// encoding is represented in memory as a QuicVersionLabel type (which is an
+// alias to uint32_t). Conceptual versions are represented in memory as
+// ParsedQuicVersion.
+//
+// We currently support two kinds of QUIC versions, GoogleQUIC and IETF QUIC.
+//
+// All GoogleQUIC versions use a wire encoding that matches the following regex
+// when converted to ASCII: "[QT]0\d\d" (e.g. Q050). Q or T distinguishes the
+// type of handshake used (Q for the QUIC_CRYPTO handshake, T for the QUIC+TLS
+// handshake), and the two digits at the end contain the numeric value of
+// the transport version used.
+//
+// All IETF QUIC versions use the wire encoding described in:
+// https://tools.ietf.org/html/draft-ietf-quic-transport
+
+#ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
+#define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// The list of existing QUIC transport versions. Note that QUIC versions are
+// sent over the wire as an encoding of ParsedQuicVersion, which requires a
+// QUIC transport version and handshake protocol. For transport versions of the
+// form QUIC_VERSION_XX where XX is decimal, the enum numeric value is
+// guaranteed to match the name. Older deprecated transport versions are
+// documented in comments below.
+enum QuicTransportVersion {
+  // Special case to indicate unknown/unsupported QUIC version.
+  QUIC_VERSION_UNSUPPORTED = 0,
+
+  // Version 1 was the first version of QUIC that supported versioning.
+  // Version 2 decoupled versioning of non-cryptographic parameters from the
+  //           SCFG.
+  // Version 3 moved public flags into the beginning of the packet.
+  // Version 4 added support for variable-length connection IDs.
+  // Version 5 made specifying FEC groups optional.
+  // Version 6 introduced variable-length packet numbers.
+  // Version 7 introduced a lower-overhead encoding for stream frames.
+  // Version 8 made salt length equal to digest length for the RSA-PSS
+  //           signatures.
+  // Version 9 added stream priority.
+  // Version 10 redid the frame type numbering.
+  // Version 11 reduced the length of null encryption authentication tag
+  //            from 16 to 12 bytes.
+  // Version 12 made the sequence numbers in the ACK frames variable-sized.
+  // Version 13 added the dedicated header stream.
+  // Version 14 added byte_offset to RST_STREAM frame.
+  // Version 15 added a list of packets recovered using FEC to the ACK frame.
+  // Version 16 added STOP_WAITING frame.
+  // Version 17 added per-stream flow control.
+  // Version 18 added PING frame.
+  // Version 19 added connection-level flow control
+  // Version 20 allowed to set stream- and connection-level flow control windows
+  //            to different values.
+  // Version 21 made header and crypto streams flow-controlled.
+  // Version 22 added support for SCUP (server config update) messages.
+  // Version 23 added timestamps into the ACK frame.
+  // Version 24 added SPDY/4 header compression.
+  // Version 25 added support for SPDY/4 header keys and removed error_details
+  //            from RST_STREAM frame.
+  // Version 26 added XLCT (expected leaf certificate) tag into CHLO.
+  // Version 27 added a nonce into SHLO.
+  // Version 28 allowed receiver to refuse creating a requested stream.
+  // Version 29 added support for QUIC_STREAM_NO_ERROR.
+  // Version 30 added server-side support for certificate transparency.
+  // Version 31 incorporated the hash of CHLO into the crypto proof supplied by
+  //            the server.
+  // Version 32 removed FEC-related fields from wire format.
+  // Version 33 added diversification nonces.
+  // Version 34 removed entropy bits from packets and ACK frames, removed
+  //            private flag from packet header and changed the ACK format to
+  //            specify ranges of packets acknowledged rather than missing
+  //            ranges.
+  // Version 35 allows endpoints to independently set stream limit.
+  // Version 36 added support for forced head-of-line blocking experiments.
+  // Version 37 added perspective into null encryption.
+  // Version 38 switched to IETF padding frame format and support for NSTP (no
+  //            stop waiting frame) connection option.
+
+  // Version 39 writes integers and floating numbers in big endian, stops acking
+  // acks, sends a connection level WINDOW_UPDATE every 20 sent packets which do
+  // not contain retransmittable frames.
+
+  // Version 40 was an attempt to convert QUIC to IETF frame format; it was
+  //            never shipped due to a bug.
+  // Version 41 was a bugfix for version 40.  The working group changed the wire
+  //            format before it shipped, which caused it to be never shipped
+  //            and all the changes from it to be reverted.  No changes from v40
+  //            or v41 are present in subsequent versions.
+  // Version 42 allowed receiving overlapping stream data.
+
+  QUIC_VERSION_43 = 43,  // PRIORITY frames are sent by client and accepted by
+                         // server.
+  // Version 44 used IETF header format from draft-ietf-quic-invariants-05.
+
+  // Version 45 added MESSAGE frame.
+
+  QUIC_VERSION_46 = 46,  // Use IETF draft-17 header format with demultiplexing
+                         // bit.
+  // Version 47 added variable-length QUIC server connection IDs.
+  // Version 48 added CRYPTO frames for the handshake.
+  // Version 49 added client connection IDs, long header lengths, and the IETF
+  // header format from draft-ietf-quic-invariants-06
+  QUIC_VERSION_50 = 50,  // Header protection and initial obfuscators.
+  // Number 51 was T051 which used draft-29 features but with GoogleQUIC frames.
+  // Number 70 used to represent draft-ietf-quic-transport-25.
+  // Number 71 used to represent draft-ietf-quic-transport-27.
+  // Number 72 used to represent draft-ietf-quic-transport-28.
+  QUIC_VERSION_IETF_DRAFT_29 = 73,    // draft-ietf-quic-transport-29.
+  QUIC_VERSION_IETF_RFC_V1 = 80,      // RFC 9000.
+  QUIC_VERSION_IETF_2_DRAFT_01 = 81,  // draft-ietf-quic-v2-01.
+  // Version 99 was a dumping ground for IETF QUIC changes which were not yet
+  // ready for production between 2018-02 and 2020-02.
+
+  // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a
+  // which is part of a range reserved by the IETF for version negotiation
+  // testing (see the "Versions" section of draft-ietf-quic-transport).
+  // This version is intentionally meant to never be supported to trigger
+  // version negotiation when proposed by clients and to prevent client
+  // ossification when sent by servers.
+  QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999,
+};
+
+// Helper function which translates from a QuicTransportVersion to a string.
+// Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
+QUIC_EXPORT_PRIVATE std::string QuicVersionToString(
+    QuicTransportVersion transport_version);
+
+// The crypto handshake protocols that can be used with QUIC.
+// We are planning on eventually deprecating PROTOCOL_QUIC_CRYPTO in favor of
+// PROTOCOL_TLS1_3.
+enum HandshakeProtocol {
+  PROTOCOL_UNSUPPORTED,
+  PROTOCOL_QUIC_CRYPTO,
+  PROTOCOL_TLS1_3,
+};
+
+// Helper function which translates from a HandshakeProtocol to a string.
+QUIC_EXPORT_PRIVATE std::string HandshakeProtocolToString(
+    HandshakeProtocol handshake_protocol);
+
+// Returns whether |transport_version| uses CRYPTO frames for the handshake
+// instead of stream 1.
+QUIC_EXPORT_PRIVATE constexpr bool QuicVersionUsesCryptoFrames(
+    QuicTransportVersion transport_version) {
+  // CRYPTO frames were added in version 48.
+  return transport_version > QUIC_VERSION_46;
+}
+
+// Returns whether this combination of handshake protocol and transport
+// version is allowed. For example, {PROTOCOL_TLS1_3, QUIC_VERSION_43} is NOT
+// allowed as TLS requires crypto frames which v43 does not support. Note that
+// UnsupportedQuicVersion is a valid version.
+QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
+    HandshakeProtocol handshake_protocol,
+    QuicTransportVersion transport_version) {
+  bool transport_version_is_valid = false;
+  constexpr QuicTransportVersion valid_transport_versions[] = {
+      QUIC_VERSION_IETF_2_DRAFT_01,
+      QUIC_VERSION_IETF_RFC_V1,
+      QUIC_VERSION_IETF_DRAFT_29,
+      QUIC_VERSION_50,
+      QUIC_VERSION_46,
+      QUIC_VERSION_43,
+      QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
+      QUIC_VERSION_UNSUPPORTED,
+  };
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(valid_transport_versions); ++i) {
+    if (transport_version == valid_transport_versions[i]) {
+      transport_version_is_valid = true;
+      break;
+    }
+  }
+  if (!transport_version_is_valid) {
+    return false;
+  }
+  switch (handshake_protocol) {
+    case PROTOCOL_UNSUPPORTED:
+      return transport_version == QUIC_VERSION_UNSUPPORTED;
+    case PROTOCOL_QUIC_CRYPTO:
+      return transport_version != QUIC_VERSION_UNSUPPORTED &&
+             transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION &&
+             transport_version != QUIC_VERSION_IETF_DRAFT_29 &&
+             transport_version != QUIC_VERSION_IETF_RFC_V1 &&
+             transport_version != QUIC_VERSION_IETF_2_DRAFT_01;
+    case PROTOCOL_TLS1_3:
+      return transport_version != QUIC_VERSION_UNSUPPORTED &&
+             transport_version != QUIC_VERSION_50 &&
+             QuicVersionUsesCryptoFrames(transport_version);
+  }
+  return false;
+}
+
+// A parsed QUIC version label which determines that handshake protocol
+// and the transport version.
+struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
+  HandshakeProtocol handshake_protocol;
+  QuicTransportVersion transport_version;
+
+  constexpr ParsedQuicVersion(HandshakeProtocol handshake_protocol,
+                              QuicTransportVersion transport_version)
+      : handshake_protocol(handshake_protocol),
+        transport_version(transport_version) {
+    QUICHE_DCHECK(
+        ParsedQuicVersionIsValid(handshake_protocol, transport_version))
+        << QuicVersionToString(transport_version) << " "
+        << HandshakeProtocolToString(handshake_protocol);
+  }
+
+  constexpr ParsedQuicVersion(const ParsedQuicVersion& other)
+      : ParsedQuicVersion(other.handshake_protocol, other.transport_version) {}
+
+  ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
+    QUICHE_DCHECK(ParsedQuicVersionIsValid(other.handshake_protocol,
+                                           other.transport_version))
+        << QuicVersionToString(other.transport_version) << " "
+        << HandshakeProtocolToString(other.handshake_protocol);
+    if (this != &other) {
+      handshake_protocol = other.handshake_protocol;
+      transport_version = other.transport_version;
+    }
+    return *this;
+  }
+
+  bool operator==(const ParsedQuicVersion& other) const {
+    return handshake_protocol == other.handshake_protocol &&
+           transport_version == other.transport_version;
+  }
+
+  bool operator!=(const ParsedQuicVersion& other) const {
+    return handshake_protocol != other.handshake_protocol ||
+           transport_version != other.transport_version;
+  }
+
+  static constexpr ParsedQuicVersion V2Draft01() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_2_DRAFT_01);
+  }
+
+  static constexpr ParsedQuicVersion RFCv1() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1);
+  }
+
+  static constexpr ParsedQuicVersion Draft29() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29);
+  }
+
+  static constexpr ParsedQuicVersion Q050() {
+    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
+  }
+
+  static constexpr ParsedQuicVersion Q046() {
+    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46);
+  }
+
+  static constexpr ParsedQuicVersion Q043() {
+    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
+  }
+
+  static constexpr ParsedQuicVersion Unsupported() {
+    return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
+  }
+
+  static constexpr ParsedQuicVersion ReservedForNegotiation() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3,
+                             QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
+  }
+
+  // Returns whether our codebase understands this version. This should only be
+  // called on valid versions, see ParsedQuicVersionIsValid. Assuming the
+  // version is valid, IsKnown returns whether the version is not
+  // UnsupportedQuicVersion.
+  bool IsKnown() const;
+
+  bool KnowsWhichDecrypterToUse() const;
+
+  // Returns whether this version uses keys derived from the Connection ID for
+  // ENCRYPTION_INITIAL keys (instead of NullEncrypter/NullDecrypter).
+  bool UsesInitialObfuscators() const;
+
+  // Indicates that this QUIC version does not have an enforced minimum value
+  // for flow control values negotiated during the handshake.
+  bool AllowsLowFlowControlLimits() const;
+
+  // Returns whether header protection is used in this version of QUIC.
+  bool HasHeaderProtection() const;
+
+  // Returns whether this version supports IETF RETRY packets.
+  bool SupportsRetry() const;
+
+  // Returns true if this version sends variable length packet number in long
+  // header.
+  bool SendsVariableLengthPacketNumberInLongHeader() const;
+
+  // Returns whether this version allows server connection ID lengths
+  // that are not 64 bits.
+  bool AllowsVariableLengthConnectionIds() const;
+
+  // Returns whether this version supports client connection ID.
+  bool SupportsClientConnectionIds() const;
+
+  // Returns whether this version supports long header 8-bit encoded
+  // connection ID lengths as described in draft-ietf-quic-invariants-06 and
+  // draft-ietf-quic-transport-22.
+  bool HasLengthPrefixedConnectionIds() const;
+
+  // Returns whether this version supports IETF style anti-amplification limit,
+  // i.e., server will send no more than FLAGS_quic_anti_amplification_factor
+  // times received bytes until address can be validated.
+  bool SupportsAntiAmplificationLimit() const;
+
+  // Returns true if this version can send coalesced packets.
+  bool CanSendCoalescedPackets() const;
+
+  // Returns true if this version supports the old Google-style Alt-Svc
+  // advertisement format.
+  bool SupportsGoogleAltSvcFormat() const;
+
+  // Returns true if |transport_version| uses IETF invariant headers.
+  bool HasIetfInvariantHeader() const;
+
+  // Returns true if |transport_version| supports MESSAGE frames.
+  bool SupportsMessageFrames() const;
+
+  // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
+  // Notable changes are:
+  // * Headers stream no longer exists.
+  // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
+  // * PUSH_PROMISE is moved to request stream.
+  // * Unidirectional streams will have their first byte as a stream type.
+  // * HEADERS frames are compressed using QPACK.
+  // * DATA frame has frame headers.
+  // * GOAWAY is moved to HTTP layer.
+  bool UsesHttp3() const;
+
+  // Returns whether the transport_version supports the variable length integer
+  // length field as defined by IETF QUIC draft-13 and later.
+  bool HasLongHeaderLengths() const;
+
+  // Returns whether |transport_version| uses CRYPTO frames for the handshake
+  // instead of stream 1.
+  bool UsesCryptoFrames() const;
+
+  // Returns whether |transport_version| makes use of IETF QUIC
+  // frames or not.
+  bool HasIetfQuicFrames() const;
+
+  // Returns whether this version uses the legacy TLS extension codepoint.
+  bool UsesLegacyTlsExtension() const;
+
+  // Returns whether this version uses PROTOCOL_TLS1_3.
+  bool UsesTls() const;
+
+  // Returns whether this version uses PROTOCOL_QUIC_CRYPTO.
+  bool UsesQuicCrypto() const;
+
+  // Returns whether this version uses the QUICv2 Long Header Packet Types.
+  bool UsesV2PacketTypes() const;
+
+  // Returns true if this shares ALPN codes with RFCv1, and endpoints should
+  // choose RFCv1 when presented with a v1 ALPN. Note that this is false for
+  // RFCv1.
+  bool AlpnDeferToRFCv1() const;
+};
+
+QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
+
+QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation();
+
+// Outer version used when encapsulating other packets using the Legacy Version
+// Encapsulation feature.
+QUIC_EXPORT_PRIVATE ParsedQuicVersion LegacyVersionForEncapsulation();
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const ParsedQuicVersion& version);
+
+using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ParsedQuicVersionVector& versions);
+
+// Representation of the on-the-wire QUIC version number. Will be written/read
+// to the wire in network-byte-order.
+using QuicVersionLabel = uint32_t;
+using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
+
+// Constructs a version label from the 4 bytes such that the on-the-wire
+// order will be: d, c, b, a.
+QUIC_EXPORT_PRIVATE QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b,
+                                                      uint8_t c, uint8_t d);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const QuicVersionLabelVector& version_labels);
+
+// This vector contains all crypto handshake protocols that are supported.
+constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
+  return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
+}
+
+constexpr std::array<ParsedQuicVersion, 6> SupportedVersions() {
+  return {
+      ParsedQuicVersion::V2Draft01(), ParsedQuicVersion::RFCv1(),
+      ParsedQuicVersion::Draft29(),   ParsedQuicVersion::Q050(),
+      ParsedQuicVersion::Q046(),      ParsedQuicVersion::Q043(),
+  };
+}
+
+using QuicTransportVersionVector = std::vector<QuicTransportVersion>;
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const QuicTransportVersionVector& transport_versions);
+
+// Returns a vector of supported QUIC versions.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
+
+// Returns a vector of supported QUIC versions, with any versions disabled by
+// flags excluded.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions();
+
+// Returns a vector of QUIC versions from |versions| which exclude any versions
+// which are disabled by flags.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+FilterSupportedVersions(ParsedQuicVersionVector versions);
+
+// Returns a subset of AllSupportedVersions() with
+// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
+// Deprecated; only to be used in components that do not yet support
+// PROTOCOL_TLS1_3.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+AllSupportedVersionsWithQuicCrypto();
+
+// Returns a subset of CurrentSupportedVersions() with
+// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+CurrentSupportedVersionsWithQuicCrypto();
+
+// Returns a subset of AllSupportedVersions() with
+// handshake_protocol == PROTOCOL_TLS1_3, in the same order.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersionsWithTls();
+
+// Returns a subset of CurrentSupportedVersions() with handshake_protocol ==
+// PROTOCOL_TLS1_3.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersionsWithTls();
+
+// Returns a subset of CurrentSupportedVersions() using HTTP/3 at the HTTP
+// layer.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedHttp3Versions();
+
+// Returns QUIC version of |index| in result of |versions|. Returns
+// UnsupportedQuicVersion() if |index| is out of bounds.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index);
+
+// QuicVersionLabel is written to and read from the wire, but we prefer to use
+// the more readable ParsedQuicVersion at other levels.
+// Helper function which translates from a QuicVersionLabel to a
+// ParsedQuicVersion.
+QUIC_EXPORT_PRIVATE ParsedQuicVersion
+ParseQuicVersionLabel(QuicVersionLabel version_label);
+
+// Helper function that translates from a QuicVersionLabelVector to a
+// ParsedQuicVersionVector.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+ParseQuicVersionLabelVector(const QuicVersionLabelVector& version_labels);
+
+// Parses a QUIC version string such as "Q043" or "T051". Also supports parsing
+// ALPN such as "h3-29" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also
+// supports parsing numbers such as "46".
+QUIC_EXPORT_PRIVATE ParsedQuicVersion
+ParseQuicVersionString(absl::string_view version_string);
+
+// Parses a comma-separated list of QUIC version strings. Supports parsing by
+// label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions.
+// For example: "h3-29,Q050,46".
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+ParseQuicVersionVectorString(absl::string_view versions_string);
+
+// Constructs a QuicVersionLabel from the provided ParsedQuicVersion.
+// QuicVersionLabel is written to and read from the wire, but we prefer to use
+// the more readable ParsedQuicVersion at other levels.
+// Helper function which translates from a ParsedQuicVersion to a
+// QuicVersionLabel. Returns 0 if |parsed_version| is unsupported.
+QUIC_EXPORT_PRIVATE QuicVersionLabel
+CreateQuicVersionLabel(ParsedQuicVersion parsed_version);
+
+// Constructs a QuicVersionLabelVector from the provided
+// ParsedQuicVersionVector.
+QUIC_EXPORT_PRIVATE QuicVersionLabelVector
+CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);
+
+// Helper function which translates from a QuicVersionLabel to a string.
+QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString(
+    QuicVersionLabel version_label);
+
+// Helper function which translates from a QuicVersionLabel string to a
+// ParsedQuicVersion. The version label string must be of the form returned
+// by QuicVersionLabelToString, for example, "00000001" or "Q046", but not
+// "51303433" (the hex encoding of the Q064 version label). Returns
+// the ParsedQuicVersion which matches the label or UnsupportedQuicVersion()
+// otherwise.
+QUIC_EXPORT_PRIVATE ParsedQuicVersion
+ParseQuicVersionLabelString(absl::string_view version_label_string);
+
+// Returns |separator|-separated list of string representations of
+// QuicVersionLabel values in the supplied |version_labels| vector. The values
+// after the (0-based) |skip_after_nth_version|'th are skipped.
+QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString(
+    const QuicVersionLabelVector& version_labels, const std::string& separator,
+    size_t skip_after_nth_version);
+
+// Returns comma separated list of string representations of QuicVersionLabel
+// values in the supplied |version_labels| vector.
+QUIC_EXPORT_PRIVATE inline std::string QuicVersionLabelVectorToString(
+    const QuicVersionLabelVector& version_labels) {
+  return QuicVersionLabelVectorToString(version_labels, ",",
+                                        std::numeric_limits<size_t>::max());
+}
+
+// Helper function which translates from a ParsedQuicVersion to a string.
+// Returns strings corresponding to the on-the-wire tag.
+QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString(
+    ParsedQuicVersion version);
+
+// Returns a vector of supported QUIC transport versions. DEPRECATED, use
+// AllSupportedVersions instead.
+QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions();
+
+// Returns comma separated list of string representations of
+// QuicTransportVersion enum values in the supplied |versions| vector.
+QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString(
+    const QuicTransportVersionVector& versions);
+
+// Returns comma separated list of string representations of ParsedQuicVersion
+// values in the supplied |versions| vector.
+QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
+    const ParsedQuicVersionVector& versions);
+
+// Returns |separator|-separated list of string representations of
+// ParsedQuicVersion values in the supplied |versions| vector. The values after
+// the (0-based) |skip_after_nth_version|'th are skipped.
+QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
+    const ParsedQuicVersionVector& versions, const std::string& separator,
+    size_t skip_after_nth_version);
+
+// Returns comma separated list of string representations of ParsedQuicVersion
+// values in the supplied |versions| vector.
+QUIC_EXPORT_PRIVATE inline std::string ParsedQuicVersionVectorToString(
+    const ParsedQuicVersionVector& versions) {
+  return ParsedQuicVersionVectorToString(versions, ",",
+                                         std::numeric_limits<size_t>::max());
+}
+
+// Returns true if |transport_version| uses IETF invariant headers.
+QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfInvariantHeader(
+    QuicTransportVersion transport_version) {
+  return transport_version > QUIC_VERSION_43;
+}
+
+// Returns true if |transport_version| supports MESSAGE frames.
+QUIC_EXPORT_PRIVATE constexpr bool VersionSupportsMessageFrames(
+    QuicTransportVersion transport_version) {
+  // MESSAGE frames were added in version 45.
+  return transport_version > QUIC_VERSION_43;
+}
+
+// If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
+// Notable changes are:
+// * Headers stream no longer exists.
+// * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
+// * PUSH_PROMISE is moved to request stream.
+// * Unidirectional streams will have their first byte as a stream type.
+// * HEADERS frames are compressed using QPACK.
+// * DATA frame has frame headers.
+// * GOAWAY is moved to HTTP layer.
+QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3(
+    QuicTransportVersion transport_version) {
+  return transport_version >= QUIC_VERSION_IETF_DRAFT_29;
+}
+
+// Returns whether the transport_version supports the variable length integer
+// length field as defined by IETF QUIC draft-13 and later.
+QUIC_EXPORT_PRIVATE constexpr bool QuicVersionHasLongHeaderLengths(
+    QuicTransportVersion transport_version) {
+  // Long header lengths were added in version 49.
+  return transport_version > QUIC_VERSION_46;
+}
+
+// Returns whether |transport_version| makes use of IETF QUIC
+// frames or not.
+QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfQuicFrames(
+    QuicTransportVersion transport_version) {
+  return VersionUsesHttp3(transport_version);
+}
+
+// Returns whether this version supports long header 8-bit encoded
+// connection ID lengths as described in draft-ietf-quic-invariants-06 and
+// draft-ietf-quic-transport-22.
+QUIC_EXPORT_PRIVATE bool VersionHasLengthPrefixedConnectionIds(
+    QuicTransportVersion transport_version);
+
+// Returns true if this version supports the old Google-style Alt-Svc
+// advertisement format.
+QUIC_EXPORT_PRIVATE bool VersionSupportsGoogleAltSvcFormat(
+    QuicTransportVersion transport_version);
+
+// Returns whether this version allows server connection ID lengths that are
+// not 64 bits.
+QUIC_EXPORT_PRIVATE bool VersionAllowsVariableLengthConnectionIds(
+    QuicTransportVersion transport_version);
+
+// Returns whether this version label supports long header 4-bit encoded
+// connection ID lengths as described in draft-ietf-quic-invariants-05 and
+// draft-ietf-quic-transport-21.
+QUIC_EXPORT_PRIVATE bool QuicVersionLabelUses4BitConnectionIdLength(
+    QuicVersionLabel version_label);
+
+// Returns the ALPN string to use in TLS for this version of QUIC.
+QUIC_EXPORT_PRIVATE std::string AlpnForVersion(
+    ParsedQuicVersion parsed_version);
+
+// Initializes support for the provided IETF draft version by setting the
+// correct flags.
+QUIC_EXPORT_PRIVATE void QuicVersionInitializeSupportForIetfDraft();
+
+// Configures the flags required to enable support for this version of QUIC.
+QUIC_EXPORT_PRIVATE void QuicEnableVersion(const ParsedQuicVersion& version);
+
+// Configures the flags required to disable support for this version of QUIC.
+QUIC_EXPORT_PRIVATE void QuicDisableVersion(const ParsedQuicVersion& version);
+
+// Returns whether support for this version of QUIC is currently enabled.
+QUIC_EXPORT_PRIVATE bool QuicVersionIsEnabled(const ParsedQuicVersion& version);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
diff --git a/quiche/quic/core/quic_versions_test.cc b/quiche/quic/core/quic_versions_test.cc
new file mode 100644
index 0000000..5dbfdd0
--- /dev/null
+++ b/quiche/quic/core/quic_versions_test.cc
@@ -0,0 +1,524 @@
+// 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 "quiche/quic/core/quic_versions.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_mock_log.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+
+TEST(QuicVersionsTest, CreateQuicVersionLabelUnsupported) {
+  EXPECT_QUIC_BUG(
+      CreateQuicVersionLabel(UnsupportedQuicVersion()),
+      "Unsupported version QUIC_VERSION_UNSUPPORTED PROTOCOL_UNSUPPORTED");
+}
+
+TEST(QuicVersionsTest, KnownAndValid) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_TRUE(version.IsKnown());
+    EXPECT_TRUE(ParsedQuicVersionIsValid(version.handshake_protocol,
+                                         version.transport_version));
+  }
+  ParsedQuicVersion unsupported = UnsupportedQuicVersion();
+  EXPECT_FALSE(unsupported.IsKnown());
+  EXPECT_TRUE(ParsedQuicVersionIsValid(unsupported.handshake_protocol,
+                                       unsupported.transport_version));
+  ParsedQuicVersion reserved = QuicVersionReservedForNegotiation();
+  EXPECT_TRUE(reserved.IsKnown());
+  EXPECT_TRUE(ParsedQuicVersionIsValid(reserved.handshake_protocol,
+                                       reserved.transport_version));
+  // Check that invalid combinations are not valid.
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3, QUIC_VERSION_43));
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
+                                        QUIC_VERSION_IETF_DRAFT_29));
+  // Check that deprecated versions are not valid.
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
+                                        static_cast<QuicTransportVersion>(33)));
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
+                                        static_cast<QuicTransportVersion>(99)));
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3,
+                                        static_cast<QuicTransportVersion>(99)));
+}
+
+TEST(QuicVersionsTest, Features) {
+  ParsedQuicVersion parsed_version_q043 = ParsedQuicVersion::Q043();
+  ParsedQuicVersion parsed_version_draft_29 = ParsedQuicVersion::Draft29();
+
+  EXPECT_TRUE(parsed_version_q043.IsKnown());
+  EXPECT_FALSE(parsed_version_q043.KnowsWhichDecrypterToUse());
+  EXPECT_FALSE(parsed_version_q043.UsesInitialObfuscators());
+  EXPECT_FALSE(parsed_version_q043.AllowsLowFlowControlLimits());
+  EXPECT_FALSE(parsed_version_q043.HasHeaderProtection());
+  EXPECT_FALSE(parsed_version_q043.SupportsRetry());
+  EXPECT_FALSE(
+      parsed_version_q043.SendsVariableLengthPacketNumberInLongHeader());
+  EXPECT_FALSE(parsed_version_q043.AllowsVariableLengthConnectionIds());
+  EXPECT_FALSE(parsed_version_q043.SupportsClientConnectionIds());
+  EXPECT_FALSE(parsed_version_q043.HasLengthPrefixedConnectionIds());
+  EXPECT_FALSE(parsed_version_q043.SupportsAntiAmplificationLimit());
+  EXPECT_FALSE(parsed_version_q043.CanSendCoalescedPackets());
+  EXPECT_TRUE(parsed_version_q043.SupportsGoogleAltSvcFormat());
+  EXPECT_FALSE(parsed_version_q043.HasIetfInvariantHeader());
+  EXPECT_FALSE(parsed_version_q043.SupportsMessageFrames());
+  EXPECT_FALSE(parsed_version_q043.UsesHttp3());
+  EXPECT_FALSE(parsed_version_q043.HasLongHeaderLengths());
+  EXPECT_FALSE(parsed_version_q043.UsesCryptoFrames());
+  EXPECT_FALSE(parsed_version_q043.HasIetfQuicFrames());
+  EXPECT_FALSE(parsed_version_q043.UsesTls());
+  EXPECT_TRUE(parsed_version_q043.UsesQuicCrypto());
+
+  EXPECT_TRUE(parsed_version_draft_29.IsKnown());
+  EXPECT_TRUE(parsed_version_draft_29.KnowsWhichDecrypterToUse());
+  EXPECT_TRUE(parsed_version_draft_29.UsesInitialObfuscators());
+  EXPECT_TRUE(parsed_version_draft_29.AllowsLowFlowControlLimits());
+  EXPECT_TRUE(parsed_version_draft_29.HasHeaderProtection());
+  EXPECT_TRUE(parsed_version_draft_29.SupportsRetry());
+  EXPECT_TRUE(
+      parsed_version_draft_29.SendsVariableLengthPacketNumberInLongHeader());
+  EXPECT_TRUE(parsed_version_draft_29.AllowsVariableLengthConnectionIds());
+  EXPECT_TRUE(parsed_version_draft_29.SupportsClientConnectionIds());
+  EXPECT_TRUE(parsed_version_draft_29.HasLengthPrefixedConnectionIds());
+  EXPECT_TRUE(parsed_version_draft_29.SupportsAntiAmplificationLimit());
+  EXPECT_TRUE(parsed_version_draft_29.CanSendCoalescedPackets());
+  EXPECT_FALSE(parsed_version_draft_29.SupportsGoogleAltSvcFormat());
+  EXPECT_TRUE(parsed_version_draft_29.HasIetfInvariantHeader());
+  EXPECT_TRUE(parsed_version_draft_29.SupportsMessageFrames());
+  EXPECT_TRUE(parsed_version_draft_29.UsesHttp3());
+  EXPECT_TRUE(parsed_version_draft_29.HasLongHeaderLengths());
+  EXPECT_TRUE(parsed_version_draft_29.UsesCryptoFrames());
+  EXPECT_TRUE(parsed_version_draft_29.HasIetfQuicFrames());
+  EXPECT_TRUE(parsed_version_draft_29.UsesTls());
+  EXPECT_FALSE(parsed_version_draft_29.UsesQuicCrypto());
+}
+
+TEST(QuicVersionsTest, ParseQuicVersionLabel) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ(ParsedQuicVersion::Q043(),
+            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '3')));
+  EXPECT_EQ(ParsedQuicVersion::Q046(),
+            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '6')));
+  EXPECT_EQ(ParsedQuicVersion::Q050(),
+            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '5', '0')));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(),
+            ParseQuicVersionLabel(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)));
+  EXPECT_EQ(ParsedQuicVersion::RFCv1(),
+            ParseQuicVersionLabel(MakeVersionLabel(0x00, 0x00, 0x00, 0x01)));
+  EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
+            ParseQuicVersionLabel(MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4)));
+  EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::V2Draft01(),
+                                     ParsedQuicVersion::RFCv1(),
+                                     ParsedQuicVersion::Draft29()}),
+            ParseQuicVersionLabelVector(QuicVersionLabelVector{
+                MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4),
+                MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
+                MakeVersionLabel(0xaa, 0xaa, 0xaa, 0xaa),
+                MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)}));
+
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_EQ(version, ParseQuicVersionLabel(CreateQuicVersionLabel(version)));
+  }
+}
+
+TEST(QuicVersionsTest, ParseQuicVersionString) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionString("Q043"));
+  EXPECT_EQ(ParsedQuicVersion::Q046(),
+            ParseQuicVersionString("QUIC_VERSION_46"));
+  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("46"));
+  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("Q046"));
+  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("Q050"));
+  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("50"));
+  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("h3-Q050"));
+
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString(""));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q 46"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q046 "));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("99"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("70"));
+
+  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("draft29"));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
+
+  EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("00000001"));
+  EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("h3"));
+
+  // QUICv2 will never be the result for "h3".
+
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_EQ(version,
+              ParseQuicVersionString(ParsedQuicVersionToString(version)));
+    EXPECT_EQ(version, ParseQuicVersionString(QuicVersionLabelToString(
+                           CreateQuicVersionLabel(version))));
+    if (!version.AlpnDeferToRFCv1()) {
+      EXPECT_EQ(version, ParseQuicVersionString(AlpnForVersion(version)));
+    }
+  }
+}
+
+TEST(QuicVersionsTest, ParseQuicVersionVectorString) {
+  ParsedQuicVersion version_q046 = ParsedQuicVersion::Q046();
+  ParsedQuicVersion version_q050 = ParsedQuicVersion::Q050();
+  ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
+
+  EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());
+
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-29"),
+              ElementsAre(version_q050, version_draft_29));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050,h3-29"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050, h3-29"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29, h3-Q050"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,h3-29"),
+              ElementsAre(version_q050, version_draft_29));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,QUIC_VERSION_50"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29"),
+              ElementsAre(version_q050, version_draft_29));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29, QUIC_VERSION_50"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,QUIC_VERSION_46"),
+              ElementsAre(version_q050, version_q046));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_46,QUIC_VERSION_50"),
+              ElementsAre(version_q046, version_q050));
+
+  // Regression test for https://crbug.com/1044952.
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, QUIC_VERSION_50"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-Q050"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, QUIC_VERSION_50"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString(
+                  "QUIC_VERSION_50, h3-Q050, QUIC_VERSION_50, h3-Q050"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29, h3-Q050"),
+              ElementsAre(version_q050, version_draft_29));
+
+  EXPECT_THAT(ParseQuicVersionVectorString("99"), IsEmpty());
+  EXPECT_THAT(ParseQuicVersionVectorString("70"), IsEmpty());
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-01"), IsEmpty());
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-01,h3-29"),
+              ElementsAre(version_draft_29));
+}
+
+// Do not use MakeVersionLabel() to generate expectations, because
+// CreateQuicVersionLabel() uses MakeVersionLabel() internally,
+// in case it has a bug.
+TEST(QuicVersionsTest, CreateQuicVersionLabel) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ(0x51303433u, CreateQuicVersionLabel(ParsedQuicVersion::Q043()));
+  EXPECT_EQ(0x51303436u, CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
+  EXPECT_EQ(0x51303530u, CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
+  EXPECT_EQ(0xff00001du, CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
+  EXPECT_EQ(0x00000001u, CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
+  EXPECT_EQ(0x709a50c4u,
+            CreateQuicVersionLabel(ParsedQuicVersion::V2Draft01()));
+
+  // Make sure the negotiation reserved version is in the IETF reserved space.
+  EXPECT_EQ(
+      0xda5a3a3au & 0x0f0f0f0f,
+      CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()) &
+          0x0f0f0f0f);
+
+  // Make sure that disabling randomness works.
+  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
+  EXPECT_EQ(0xda5a3a3au, CreateQuicVersionLabel(
+                             ParsedQuicVersion::ReservedForNegotiation()));
+}
+
+TEST(QuicVersionsTest, QuicVersionLabelToString) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ("Q043", QuicVersionLabelToString(
+                        CreateQuicVersionLabel(ParsedQuicVersion::Q043())));
+  EXPECT_EQ("Q046", QuicVersionLabelToString(
+                        CreateQuicVersionLabel(ParsedQuicVersion::Q046())));
+  EXPECT_EQ("Q050", QuicVersionLabelToString(
+                        CreateQuicVersionLabel(ParsedQuicVersion::Q050())));
+  EXPECT_EQ("ff00001d", QuicVersionLabelToString(CreateQuicVersionLabel(
+                            ParsedQuicVersion::Draft29())));
+  EXPECT_EQ("00000001", QuicVersionLabelToString(CreateQuicVersionLabel(
+                            ParsedQuicVersion::RFCv1())));
+  EXPECT_EQ("709a50c4", QuicVersionLabelToString(CreateQuicVersionLabel(
+                            ParsedQuicVersion::V2Draft01())));
+
+  QuicVersionLabelVector version_labels = {
+      MakeVersionLabel('Q', '0', '3', '5'),
+      MakeVersionLabel('T', '0', '3', '8'),
+      MakeVersionLabel(0xff, 0, 0, 7),
+  };
+
+  EXPECT_EQ("Q035", QuicVersionLabelToString(version_labels[0]));
+  EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[1]));
+  EXPECT_EQ("ff000007", QuicVersionLabelToString(version_labels[2]));
+
+  EXPECT_EQ("Q035,T038,ff000007",
+            QuicVersionLabelVectorToString(version_labels));
+  EXPECT_EQ("Q035:T038:ff000007",
+            QuicVersionLabelVectorToString(version_labels, ":", 2));
+  EXPECT_EQ("Q035|T038|...",
+            QuicVersionLabelVectorToString(version_labels, "|", 1));
+
+  std::ostringstream os;
+  os << version_labels;
+  EXPECT_EQ("Q035,T038,ff000007", os.str());
+}
+
+TEST(QuicVersionsTest, ParseQuicVersionLabelString) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  // Explicitly test known QUIC version label strings.
+  EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionLabelString("Q043"));
+  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionLabelString("Q046"));
+  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionLabelString("Q050"));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(),
+            ParseQuicVersionLabelString("ff00001d"));
+  EXPECT_EQ(ParsedQuicVersion::RFCv1(),
+            ParseQuicVersionLabelString("00000001"));
+  EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
+            ParseQuicVersionLabelString("709a50c4"));
+
+  // Sanity check that a variety of other serialization formats are ignored.
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("1"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("46"));
+  EXPECT_EQ(UnsupportedQuicVersion(),
+            ParseQuicVersionLabelString("QUIC_VERSION_46"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3-29"));
+
+  // Test round-trips between QuicVersionLabelToString and
+  // ParseQuicVersionLabelString.
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_EQ(version, ParseQuicVersionLabelString(QuicVersionLabelToString(
+                           CreateQuicVersionLabel(version))));
+  }
+}
+
+TEST(QuicVersionsTest, QuicVersionToString) {
+  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED",
+            QuicVersionToString(QUIC_VERSION_UNSUPPORTED));
+
+  QuicTransportVersion single_version[] = {QUIC_VERSION_43};
+  QuicTransportVersionVector versions_vector;
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(single_version); ++i) {
+    versions_vector.push_back(single_version[i]);
+  }
+  EXPECT_EQ("QUIC_VERSION_43",
+            QuicTransportVersionVectorToString(versions_vector));
+
+  QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED,
+                                              QUIC_VERSION_43};
+  versions_vector.clear();
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(multiple_versions); ++i) {
+    versions_vector.push_back(multiple_versions[i]);
+  }
+  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43",
+            QuicTransportVersionVectorToString(versions_vector));
+
+  // Make sure that all supported versions are present in QuicVersionToString.
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_NE("QUIC_VERSION_UNSUPPORTED",
+              QuicVersionToString(version.transport_version));
+  }
+
+  std::ostringstream os;
+  os << versions_vector;
+  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43", os.str());
+}
+
+TEST(QuicVersionsTest, ParsedQuicVersionToString) {
+  EXPECT_EQ("0", ParsedQuicVersionToString(ParsedQuicVersion::Unsupported()));
+  EXPECT_EQ("Q043", ParsedQuicVersionToString(ParsedQuicVersion::Q043()));
+  EXPECT_EQ("Q046", ParsedQuicVersionToString(ParsedQuicVersion::Q046()));
+  EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
+  EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
+  EXPECT_EQ("RFCv1", ParsedQuicVersionToString(ParsedQuicVersion::RFCv1()));
+  EXPECT_EQ("v2draft01",
+            ParsedQuicVersionToString(ParsedQuicVersion::V2Draft01()));
+
+  ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q043()};
+  EXPECT_EQ("Q043", ParsedQuicVersionVectorToString(versions_vector));
+
+  versions_vector = {ParsedQuicVersion::Unsupported(),
+                     ParsedQuicVersion::Q043()};
+  EXPECT_EQ("0,Q043", ParsedQuicVersionVectorToString(versions_vector));
+  EXPECT_EQ("0:Q043", ParsedQuicVersionVectorToString(versions_vector, ":",
+                                                      versions_vector.size()));
+  EXPECT_EQ("0|...", ParsedQuicVersionVectorToString(versions_vector, "|", 0));
+
+  // Make sure that all supported versions are present in
+  // ParsedQuicVersionToString.
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_NE("0", ParsedQuicVersionToString(version));
+  }
+
+  std::ostringstream os;
+  os << versions_vector;
+  EXPECT_EQ("0,Q043", os.str());
+}
+
+TEST(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicEnableVersion(version);
+  }
+  ParsedQuicVersionVector expected_parsed_versions;
+  for (const ParsedQuicVersion& version : SupportedVersions()) {
+    expected_parsed_versions.push_back(version);
+  }
+  EXPECT_EQ(expected_parsed_versions,
+            FilterSupportedVersions(AllSupportedVersions()));
+  EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
+}
+
+TEST(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicEnableVersion(version);
+  }
+  QuicDisableVersion(AllSupportedVersions().front());
+  ParsedQuicVersionVector expected_parsed_versions;
+  for (const ParsedQuicVersion& version : SupportedVersions()) {
+    expected_parsed_versions.push_back(version);
+  }
+  expected_parsed_versions.erase(expected_parsed_versions.begin());
+  EXPECT_EQ(expected_parsed_versions,
+            FilterSupportedVersions(AllSupportedVersions()));
+}
+
+TEST(QuicVersionsTest, LookUpParsedVersionByIndex) {
+  ParsedQuicVersionVector all_versions = AllSupportedVersions();
+  int version_count = all_versions.size();
+  for (int i = -5; i <= version_count + 1; ++i) {
+    ParsedQuicVersionVector index = ParsedVersionOfIndex(all_versions, i);
+    if (i >= 0 && i < version_count) {
+      EXPECT_EQ(all_versions[i], index[0]);
+    } else {
+      EXPECT_EQ(UnsupportedQuicVersion(), index[0]);
+    }
+  }
+}
+
+// This test may appear to be so simplistic as to be unnecessary,
+// yet a typo was made in doing the #defines and it was caught
+// only in some test far removed from here... Better safe than sorry.
+TEST(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ(QUIC_VERSION_43, 43);
+  EXPECT_EQ(QUIC_VERSION_46, 46);
+  EXPECT_EQ(QUIC_VERSION_50, 50);
+  EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
+  EXPECT_EQ(QUIC_VERSION_IETF_RFC_V1, 80);
+  EXPECT_EQ(QUIC_VERSION_IETF_2_DRAFT_01, 81);
+}
+
+TEST(QuicVersionsTest, AlpnForVersion) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ("h3-Q043", AlpnForVersion(ParsedQuicVersion::Q043()));
+  EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
+  EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
+  EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
+  EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv1()));
+  EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::V2Draft01()));
+}
+
+TEST(QuicVersionsTest, QuicVersionEnabling) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicFlagSaver flag_saver;
+    QuicDisableVersion(version);
+    EXPECT_FALSE(QuicVersionIsEnabled(version));
+    QuicEnableVersion(version);
+    EXPECT_TRUE(QuicVersionIsEnabled(version));
+  }
+}
+
+TEST(QuicVersionsTest, ReservedForNegotiation) {
+  EXPECT_EQ(QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
+            QuicVersionReservedForNegotiation().transport_version);
+  // QUIC_VERSION_RESERVED_FOR_NEGOTIATION MUST NOT be supported.
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_NE(QUIC_VERSION_RESERVED_FOR_NEGOTIATION, version.transport_version);
+  }
+}
+
+TEST(QuicVersionsTest, SupportedVersionsHasCorrectList) {
+  size_t index = 0;
+  for (HandshakeProtocol handshake_protocol : SupportedHandshakeProtocols()) {
+    for (int trans_vers = 255; trans_vers > 0; trans_vers--) {
+      QuicTransportVersion transport_version =
+          static_cast<QuicTransportVersion>(trans_vers);
+      SCOPED_TRACE(index);
+      if (ParsedQuicVersionIsValid(handshake_protocol, transport_version)) {
+        ParsedQuicVersion version = SupportedVersions()[index];
+        EXPECT_EQ(version,
+                  ParsedQuicVersion(handshake_protocol, transport_version));
+        index++;
+      }
+    }
+  }
+  EXPECT_EQ(SupportedVersions().size(), index);
+}
+
+TEST(QuicVersionsTest, SupportedVersionsAllDistinct) {
+  for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
+    ParsedQuicVersion version1 = SupportedVersions()[index1];
+    for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
+         ++index2) {
+      ParsedQuicVersion version2 = SupportedVersions()[index2];
+      EXPECT_NE(version1, version2) << version1 << " " << version2;
+      EXPECT_NE(CreateQuicVersionLabel(version1),
+                CreateQuicVersionLabel(version2))
+          << version1 << " " << version2;
+      // The one pair where ALPNs are the same.
+      if ((version1 != ParsedQuicVersion::V2Draft01()) &&
+          (version2 != ParsedQuicVersion::RFCv1())) {
+        EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
+            << version1 << " " << version2;
+      }
+    }
+  }
+}
+
+TEST(QuicVersionsTest, CurrentSupportedHttp3Versions) {
+  ParsedQuicVersionVector h3_versions = CurrentSupportedHttp3Versions();
+  ParsedQuicVersionVector all_current_supported_versions =
+      CurrentSupportedVersions();
+  for (auto& version : all_current_supported_versions) {
+    bool version_is_h3 = false;
+    for (auto& h3_version : h3_versions) {
+      if (version == h3_version) {
+        EXPECT_TRUE(version.UsesHttp3());
+        version_is_h3 = true;
+        break;
+      }
+    }
+    if (!version_is_h3) {
+      EXPECT_FALSE(version.UsesHttp3());
+    }
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_write_blocked_list.cc b/quiche/quic/core/quic_write_blocked_list.cc
new file mode 100644
index 0000000..231259b
--- /dev/null
+++ b/quiche/quic/core/quic_write_blocked_list.cc
@@ -0,0 +1,182 @@
+// 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 "quiche/quic/core/quic_write_blocked_list.h"
+
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicWriteBlockedList::QuicWriteBlockedList(QuicTransportVersion version)
+    : priority_write_scheduler_(QuicVersionUsesCryptoFrames(version)
+                                    ? std::numeric_limits<QuicStreamId>::max()
+                                    : 0),
+      last_priority_popped_(0) {
+  memset(batch_write_stream_id_, 0, sizeof(batch_write_stream_id_));
+  memset(bytes_left_for_batch_write_, 0, sizeof(bytes_left_for_batch_write_));
+}
+
+QuicWriteBlockedList::~QuicWriteBlockedList() {}
+
+bool QuicWriteBlockedList::ShouldYield(QuicStreamId id) const {
+  for (const auto& stream : static_stream_collection_) {
+    if (stream.id == id) {
+      // Static streams should never yield to data streams, or to lower
+      // priority static stream.
+      return false;
+    }
+    if (stream.is_blocked) {
+      return true;  // All data streams yield to static streams.
+    }
+  }
+
+  return priority_write_scheduler_.ShouldYield(id);
+}
+
+QuicStreamId QuicWriteBlockedList::PopFront() {
+  QuicStreamId static_stream_id;
+  if (static_stream_collection_.UnblockFirstBlocked(&static_stream_id)) {
+    return static_stream_id;
+  }
+
+  const auto id_and_precedence =
+      priority_write_scheduler_.PopNextReadyStreamAndPrecedence();
+  const QuicStreamId id = std::get<0>(id_and_precedence);
+  const spdy::SpdyPriority priority =
+      std::get<1>(id_and_precedence).spdy3_priority();
+
+  if (!priority_write_scheduler_.HasReadyStreams()) {
+    // If no streams are blocked, don't bother latching.  This stream will be
+    // the first popped for its priority anyway.
+    batch_write_stream_id_[priority] = 0;
+    last_priority_popped_ = priority;
+  } else if (batch_write_stream_id_[priority] != id) {
+    // If newly latching this batch write stream, let it write 16k.
+    batch_write_stream_id_[priority] = id;
+    bytes_left_for_batch_write_[priority] = 16000;
+    last_priority_popped_ = priority;
+  }
+
+  return id;
+}
+
+void QuicWriteBlockedList::RegisterStream(
+    QuicStreamId stream_id,
+    bool is_static_stream,
+    const spdy::SpdyStreamPrecedence& precedence) {
+  QUICHE_DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id))
+      << "stream " << stream_id << " already registered";
+  QUICHE_DCHECK(precedence.is_spdy3_priority());
+  if (is_static_stream) {
+    static_stream_collection_.Register(stream_id);
+    return;
+  }
+
+  priority_write_scheduler_.RegisterStream(stream_id, precedence);
+}
+
+void QuicWriteBlockedList::UnregisterStream(QuicStreamId stream_id,
+                                            bool is_static) {
+  if (is_static) {
+    static_stream_collection_.Unregister(stream_id);
+    return;
+  }
+  priority_write_scheduler_.UnregisterStream(stream_id);
+}
+
+void QuicWriteBlockedList::UpdateStreamPriority(
+    QuicStreamId stream_id,
+    const spdy::SpdyStreamPrecedence& new_precedence) {
+  QUICHE_DCHECK(!static_stream_collection_.IsRegistered(stream_id));
+  QUICHE_DCHECK(new_precedence.is_spdy3_priority());
+  priority_write_scheduler_.UpdateStreamPrecedence(stream_id, new_precedence);
+}
+
+void QuicWriteBlockedList::UpdateBytesForStream(QuicStreamId stream_id,
+                                                size_t bytes) {
+  if (batch_write_stream_id_[last_priority_popped_] == stream_id) {
+    // If this was the last data stream popped by PopFront, update the
+    // bytes remaining in its batch write.
+    bytes_left_for_batch_write_[last_priority_popped_] -=
+        std::min(bytes_left_for_batch_write_[last_priority_popped_], bytes);
+  }
+}
+
+void QuicWriteBlockedList::AddStream(QuicStreamId stream_id) {
+  if (static_stream_collection_.SetBlocked(stream_id)) {
+    return;
+  }
+
+  bool push_front =
+      stream_id == batch_write_stream_id_[last_priority_popped_] &&
+      bytes_left_for_batch_write_[last_priority_popped_] > 0;
+  priority_write_scheduler_.MarkStreamReady(stream_id, push_front);
+}
+
+bool QuicWriteBlockedList::IsStreamBlocked(QuicStreamId stream_id) const {
+  for (const auto& stream : static_stream_collection_) {
+    if (stream.id == stream_id) {
+      return stream.is_blocked;
+    }
+  }
+
+  return priority_write_scheduler_.IsStreamReady(stream_id);
+}
+
+void QuicWriteBlockedList::StaticStreamCollection::Register(QuicStreamId id) {
+  QUICHE_DCHECK(!IsRegistered(id));
+  streams_.push_back({id, false});
+}
+
+bool QuicWriteBlockedList::StaticStreamCollection::IsRegistered(
+    QuicStreamId id) const {
+  for (const auto& stream : streams_) {
+    if (stream.id == id) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicWriteBlockedList::StaticStreamCollection::Unregister(QuicStreamId id) {
+  for (auto it = streams_.begin(); it != streams_.end(); ++it) {
+    if (it->id == id) {
+      if (it->is_blocked) {
+        --num_blocked_;
+      }
+      streams_.erase(it);
+      return;
+    }
+  }
+  QUICHE_DCHECK(false) << "Erasing a non-exist stream with id " << id;
+}
+
+bool QuicWriteBlockedList::StaticStreamCollection::SetBlocked(QuicStreamId id) {
+  for (auto& stream : streams_) {
+    if (stream.id == id) {
+      if (!stream.is_blocked) {
+        stream.is_blocked = true;
+        ++num_blocked_;
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicWriteBlockedList::StaticStreamCollection::UnblockFirstBlocked(
+    QuicStreamId* id) {
+  for (auto& stream : streams_) {
+    if (stream.is_blocked) {
+      --num_blocked_;
+      stream.is_blocked = false;
+      *id = stream.id;
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_write_blocked_list.h b/quiche/quic/core/quic_write_blocked_list.h
new file mode 100644
index 0000000..f8bf603
--- /dev/null
+++ b/quiche/quic/core/quic_write_blocked_list.h
@@ -0,0 +1,143 @@
+// 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_CORE_QUIC_WRITE_BLOCKED_LIST_H_
+#define QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <utility>
+
+#include "absl/container/inlined_vector.h"
+#include "quiche/http2/core/priority_write_scheduler.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+// Keeps tracks of the QUIC streams that have data to write, sorted by
+// priority.  QUIC stream priority order is:
+// Crypto stream > Headers stream > Data streams by requested priority.
+class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
+ public:
+  explicit QuicWriteBlockedList(QuicTransportVersion version);
+  QuicWriteBlockedList(const QuicWriteBlockedList&) = delete;
+  QuicWriteBlockedList& operator=(const QuicWriteBlockedList&) = delete;
+  ~QuicWriteBlockedList();
+
+  bool HasWriteBlockedDataStreams() const {
+    return priority_write_scheduler_.HasReadyStreams();
+  }
+
+  bool HasWriteBlockedSpecialStream() const {
+    return static_stream_collection_.num_blocked() > 0;
+  }
+
+  size_t NumBlockedSpecialStreams() const {
+    return static_stream_collection_.num_blocked();
+  }
+
+  size_t NumBlockedStreams() const {
+    return NumBlockedSpecialStreams() +
+           priority_write_scheduler_.NumReadyStreams();
+  }
+
+  bool ShouldYield(QuicStreamId id) const;
+
+  spdy::SpdyPriority GetSpdyPriorityofStream(QuicStreamId id) const {
+    return priority_write_scheduler_.GetStreamPrecedence(id).spdy3_priority();
+  }
+
+  // Pops the highest priority stream, special casing crypto and headers
+  // streams. Latches the most recently popped data stream for batch writing
+  // purposes.
+  QuicStreamId PopFront();
+
+  void RegisterStream(QuicStreamId stream_id,
+                      bool is_static_stream,
+                      const spdy::SpdyStreamPrecedence& precedence);
+
+  void UnregisterStream(QuicStreamId stream_id, bool is_static);
+
+  void UpdateStreamPriority(QuicStreamId stream_id,
+                            const spdy::SpdyStreamPrecedence& new_precedence);
+
+  void UpdateBytesForStream(QuicStreamId stream_id, size_t bytes);
+
+  // Pushes a stream to the back of the list for its priority level *unless* it
+  // is latched for doing batched writes in which case it goes to the front of
+  // the list for its priority level.
+  // Headers and crypto streams are special cased to always resume first.
+  void AddStream(QuicStreamId stream_id);
+
+  // Returns true if stream with |stream_id| is write blocked.
+  bool IsStreamBlocked(QuicStreamId stream_id) const;
+
+ private:
+  http2::PriorityWriteScheduler<QuicStreamId> priority_write_scheduler_;
+
+  // If performing batch writes, this will be the stream ID of the stream doing
+  // batch writes for this priority level.  We will allow this stream to write
+  // until it has written kBatchWriteSize bytes, it has no more data to write,
+  // or a higher priority stream preempts.
+  QuicStreamId batch_write_stream_id_[spdy::kV3LowestPriority + 1];
+  // Set to kBatchWriteSize when we set a new batch_write_stream_id_ for a given
+  // priority.  This is decremented with each write the stream does until it is
+  // done with its batch write.
+  size_t bytes_left_for_batch_write_[spdy::kV3LowestPriority + 1];
+  // Tracks the last priority popped for UpdateBytesForStream.
+  spdy::SpdyPriority last_priority_popped_;
+
+  // A StaticStreamCollection is a vector of <QuicStreamId, bool> pairs plus a
+  // eagerly-computed number of blocked static streams.
+  class QUIC_EXPORT_PRIVATE StaticStreamCollection {
+   public:
+    struct QUIC_EXPORT_PRIVATE StreamIdBlockedPair {
+      QuicStreamId id;
+      bool is_blocked;
+    };
+
+    // Optimized for the typical case of 2 static streams per session.
+    using StreamsVector = absl::InlinedVector<StreamIdBlockedPair, 2>;
+
+    StreamsVector::const_iterator begin() const { return streams_.cbegin(); }
+
+    StreamsVector::const_iterator end() const { return streams_.cend(); }
+
+    size_t num_blocked() const { return num_blocked_; }
+
+    // Add |id| to the collection in unblocked state.
+    void Register(QuicStreamId id);
+
+    // True if |id| is in the collection, regardless of its state.
+    bool IsRegistered(QuicStreamId id) const;
+
+    // Remove |id| from the collection, if it is in the blocked state, reduce
+    // |num_blocked_| by 1.
+    void Unregister(QuicStreamId id);
+
+    // Set |id| to be blocked. If |id| is not already blocked, increase
+    // |num_blocked_| by 1.
+    // Return true if |id| is in the collection.
+    bool SetBlocked(QuicStreamId id);
+
+    // Unblock the first blocked stream in the collection.
+    // If no stream is blocked, return false. Otherwise return true, set *id to
+    // the unblocked stream id and reduce |num_blocked_| by 1.
+    bool UnblockFirstBlocked(QuicStreamId* id);
+
+   private:
+    size_t num_blocked_ = 0;
+    StreamsVector streams_;
+  };
+
+  StaticStreamCollection static_stream_collection_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
diff --git a/quiche/quic/core/quic_write_blocked_list_test.cc b/quiche/quic/core/quic_write_blocked_list_test.cc
new file mode 100644
index 0000000..4d294f0
--- /dev/null
+++ b/quiche/quic/core/quic_write_blocked_list_test.cc
@@ -0,0 +1,269 @@
+// 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 "quiche/quic/core/quic_write_blocked_list.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using spdy::kHttp2DefaultStreamWeight;
+using spdy::kV3HighestPriority;
+using spdy::kV3LowestPriority;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicWriteBlockedListTest : public QuicTestWithParam<bool> {
+ public:
+  QuicWriteBlockedListTest()
+      : write_blocked_list_(AllSupportedVersions()[0].transport_version) {}
+
+ protected:
+  QuicWriteBlockedList write_blocked_list_;
+};
+
+TEST_F(QuicWriteBlockedListTest, PriorityOrder) {
+  /*
+       0
+       |
+       23
+       |
+       17
+       |
+       40
+  */
+  // Mark streams blocked in roughly reverse priority order, and
+  // verify that streams are sorted.
+  write_blocked_list_.RegisterStream(
+      40, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
+  write_blocked_list_.RegisterStream(
+      23, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      17, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+  write_blocked_list_.AddStream(40);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(40));
+  write_blocked_list_.AddStream(23);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(23));
+  write_blocked_list_.AddStream(17);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(17));
+  write_blocked_list_.AddStream(3);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(3));
+  write_blocked_list_.AddStream(1);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(1));
+
+  EXPECT_EQ(5u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedSpecialStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
+  // The Crypto stream is highest priority.
+  EXPECT_EQ(1u, write_blocked_list_.PopFront());
+  EXPECT_EQ(1u, write_blocked_list_.NumBlockedSpecialStreams());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(1));
+  // Followed by the Headers stream.
+  EXPECT_EQ(3u, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedSpecialStreams());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(3));
+  // Streams with same priority are popped in the order they were inserted.
+  EXPECT_EQ(23u, write_blocked_list_.PopFront());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(23));
+  EXPECT_EQ(17u, write_blocked_list_.PopFront());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(17));
+  // Low priority stream appears last.
+  EXPECT_EQ(40u, write_blocked_list_.PopFront());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(40));
+
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
+}
+
+TEST_F(QuicWriteBlockedListTest, CryptoStream) {
+  write_blocked_list_.RegisterStream(
+      1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.AddStream(1);
+
+  EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_EQ(1u, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
+}
+
+TEST_F(QuicWriteBlockedListTest, HeadersStream) {
+  write_blocked_list_.RegisterStream(
+      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.AddStream(3);
+
+  EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_EQ(3u, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
+}
+
+TEST_F(QuicWriteBlockedListTest, VerifyHeadersStream) {
+  write_blocked_list_.RegisterStream(
+      5, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.AddStream(5);
+  write_blocked_list_.AddStream(3);
+
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
+  // In newer QUIC versions, there is a headers stream which is
+  // higher priority than data streams.
+  EXPECT_EQ(3u, write_blocked_list_.PopFront());
+  EXPECT_EQ(5u, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
+}
+
+TEST_F(QuicWriteBlockedListTest, NoDuplicateEntries) {
+  // Test that QuicWriteBlockedList doesn't allow duplicate entries.
+  // Try to add a stream to the write blocked list multiple times at the same
+  // priority.
+  const QuicStreamId kBlockedId = 3 + 2;
+    write_blocked_list_.RegisterStream(
+        kBlockedId, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.AddStream(kBlockedId);
+  write_blocked_list_.AddStream(kBlockedId);
+  write_blocked_list_.AddStream(kBlockedId);
+
+  // This should only result in one blocked stream being added.
+  EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
+
+  // There should only be one stream to pop off the front.
+  EXPECT_EQ(kBlockedId, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
+}
+
+TEST_F(QuicWriteBlockedListTest, BatchingWrites) {
+  const QuicStreamId id1 = 3 + 2;
+  const QuicStreamId id2 = id1 + 2;
+  const QuicStreamId id3 = id2 + 2;
+  write_blocked_list_.RegisterStream(
+      id1, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
+  write_blocked_list_.RegisterStream(
+      id2, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
+  write_blocked_list_.RegisterStream(
+      id3, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+  write_blocked_list_.AddStream(id1);
+  write_blocked_list_.AddStream(id2);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+
+  // The first stream we push back should stay at the front until 16k is
+  // written.
+  EXPECT_EQ(id1, write_blocked_list_.PopFront());
+  write_blocked_list_.UpdateBytesForStream(id1, 15999);
+  write_blocked_list_.AddStream(id1);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_EQ(id1, write_blocked_list_.PopFront());
+
+  // Once 16k is written the first stream will yield to the next.
+  write_blocked_list_.UpdateBytesForStream(id1, 1);
+  write_blocked_list_.AddStream(id1);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_EQ(id2, write_blocked_list_.PopFront());
+
+  // Set the new stream to have written all but one byte.
+  write_blocked_list_.UpdateBytesForStream(id2, 15999);
+  write_blocked_list_.AddStream(id2);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+
+  // Ensure higher priority streams are popped first.
+  write_blocked_list_.AddStream(id3);
+  EXPECT_EQ(id3, write_blocked_list_.PopFront());
+
+  // Higher priority streams will always be popped first, even if using their
+  // byte quota
+  write_blocked_list_.UpdateBytesForStream(id3, 20000);
+  write_blocked_list_.AddStream(id3);
+  EXPECT_EQ(id3, write_blocked_list_.PopFront());
+
+  // Once the higher priority stream is out of the way, id2 will resume its 16k
+  // write, with only 1 byte remaining of its guaranteed write allocation.
+  EXPECT_EQ(id2, write_blocked_list_.PopFront());
+  write_blocked_list_.UpdateBytesForStream(id2, 1);
+  write_blocked_list_.AddStream(id2);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_EQ(id1, write_blocked_list_.PopFront());
+}
+
+TEST_F(QuicWriteBlockedListTest, Ceding) {
+  /*
+       0
+       |
+       15
+       |
+       16
+       |
+       5
+       |
+       4
+       |
+       7
+  */
+  write_blocked_list_.RegisterStream(
+      15, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      16, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(5, false, spdy::SpdyStreamPrecedence(5));
+  write_blocked_list_.RegisterStream(4, false, spdy::SpdyStreamPrecedence(5));
+  write_blocked_list_.RegisterStream(7, false, spdy::SpdyStreamPrecedence(7));
+  write_blocked_list_.RegisterStream(
+      1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+  // When nothing is on the list, nothing yields.
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(5));
+
+  write_blocked_list_.AddStream(5);
+  // 5 should not yield to itself.
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(5));
+  // 4 and 7 are equal or lower priority and should yield to 5.
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(4));
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(7));
+  // 15, headers and crypto should preempt 5.
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(15));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
+
+  // Block a high priority stream.
+  write_blocked_list_.AddStream(15);
+  // 16 should yield (same priority) but headers and crypto will still not.
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
+
+  // Block the headers stream.  All streams but crypto and headers should yield.
+  write_blocked_list_.AddStream(3);
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(15));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
+
+  // Block the crypto stream.  All streams but crypto should yield.
+  write_blocked_list_.AddStream(1);
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(15));
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(3));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/session_notifier_interface.h b/quiche/quic/core/session_notifier_interface.h
new file mode 100644
index 0000000..ee4453a
--- /dev/null
+++ b/quiche/quic/core/session_notifier_interface.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2017 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_SESSION_NOTIFIER_INTERFACE_H_
+#define QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
+
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_time.h"
+
+namespace quic {
+
+// Pure virtual class to be notified when a packet containing a frame is acked
+// or lost.
+class QUIC_EXPORT_PRIVATE SessionNotifierInterface {
+ public:
+  virtual ~SessionNotifierInterface() {}
+
+  // Called when |frame| is acked. Returns true if any new data gets acked,
+  // returns false otherwise.
+  virtual bool OnFrameAcked(const QuicFrame& frame,
+                            QuicTime::Delta ack_delay_time,
+                            QuicTime receive_timestamp) = 0;
+
+  // Called when |frame| is retransmitted.
+  virtual void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) = 0;
+
+  // Called when |frame| is considered as lost.
+  virtual void OnFrameLost(const QuicFrame& frame) = 0;
+
+  // Called to retransmit |frames| with transmission |type|. Returns true if all
+  // data gets retransmitted.
+  virtual bool RetransmitFrames(const QuicFrames& frames,
+                                TransmissionType type) = 0;
+
+  // Returns true if |frame| is outstanding and waiting to be acked.
+  virtual bool IsFrameOutstanding(const QuicFrame& frame) const = 0;
+
+  // Returns true if crypto stream is waiting for acks.
+  virtual bool HasUnackedCryptoData() const = 0;
+
+  // Returns true if any stream is waiting for acks.
+  virtual bool HasUnackedStreamData() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
diff --git a/quiche/quic/core/stream_delegate_interface.h b/quiche/quic/core/stream_delegate_interface.h
new file mode 100644
index 0000000..f93812c
--- /dev/null
+++ b/quiche/quic/core/stream_delegate_interface.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2019 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_STREAM_DELEGATE_INTERFACE_H_
+#define QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
+
+#include <cstddef>
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace quic {
+
+class QuicStream;
+
+// Pure virtual class to get notified when particular QuicStream events
+// occurred.
+class QUIC_EXPORT_PRIVATE StreamDelegateInterface {
+ public:
+  virtual ~StreamDelegateInterface() {}
+
+  // Called when the stream has encountered errors that it can't handle.
+  virtual void OnStreamError(QuicErrorCode error_code,
+                             std::string error_details) = 0;
+  // Called when the stream has encountered errors that it can't handle,
+  // specifying the wire error code |ietf_error| explicitly.
+  virtual void OnStreamError(QuicErrorCode error_code,
+                             QuicIetfTransportErrorCodes ietf_error,
+                             std::string error_details) = 0;
+  // Called when the stream needs to write data at specified |level| and
+  // transmission |type|.
+  virtual QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
+                                      QuicStreamOffset offset,
+                                      StreamSendingState state,
+                                      TransmissionType type,
+                                      EncryptionLevel level) = 0;
+  // Called to write crypto data.
+  virtual size_t SendCryptoData(EncryptionLevel level,
+                                size_t write_length,
+                                QuicStreamOffset offset,
+                                TransmissionType type) = 0;
+  // Called on stream creation.
+  virtual void RegisterStreamPriority(
+      QuicStreamId id,
+      bool is_static,
+      const spdy::SpdyStreamPrecedence& precedence) = 0;
+  // Called on stream destruction to clear priority.
+  virtual void UnregisterStreamPriority(QuicStreamId id, bool is_static) = 0;
+  // Called by the stream on SetPriority to update priority.
+  virtual void UpdateStreamPriority(
+      QuicStreamId id,
+      const spdy::SpdyStreamPrecedence& new_precedence) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
diff --git a/quiche/quic/core/tls_chlo_extractor.cc b/quiche/quic/core/tls_chlo_extractor.cc
new file mode 100644
index 0000000..03810e9
--- /dev/null
+++ b/quiche/quic/core/tls_chlo_extractor.cc
@@ -0,0 +1,425 @@
+// Copyright (c) 2020 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 "quiche/quic/core/tls_chlo_extractor.h"
+#include <cstring>
+#include <memory>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+namespace {
+bool HasExtension(const SSL_CLIENT_HELLO* client_hello, uint16_t extension) {
+  const uint8_t* unused_extension_bytes;
+  size_t unused_extension_len;
+  return 1 == SSL_early_callback_ctx_extension_get(client_hello, extension,
+                                                   &unused_extension_bytes,
+                                                   &unused_extension_len);
+}
+}  // namespace
+
+TlsChloExtractor::TlsChloExtractor()
+    : crypto_stream_sequencer_(this),
+      state_(State::kInitial),
+      parsed_crypto_frame_in_this_packet_(false) {}
+
+TlsChloExtractor::TlsChloExtractor(TlsChloExtractor&& other)
+    : TlsChloExtractor() {
+  *this = std::move(other);
+}
+
+TlsChloExtractor& TlsChloExtractor::operator=(TlsChloExtractor&& other) {
+  framer_ = std::move(other.framer_);
+  if (framer_) {
+    framer_->set_visitor(this);
+  }
+  crypto_stream_sequencer_ = std::move(other.crypto_stream_sequencer_);
+  crypto_stream_sequencer_.set_stream(this);
+  ssl_ = std::move(other.ssl_);
+  if (ssl_) {
+    std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
+    int ex_data_index = shared_handles.second;
+    const int rv = SSL_set_ex_data(ssl_.get(), ex_data_index, this);
+    QUICHE_CHECK_EQ(rv, 1) << "Internal allocation failure in SSL_set_ex_data";
+  }
+  state_ = other.state_;
+  error_details_ = std::move(other.error_details_);
+  parsed_crypto_frame_in_this_packet_ =
+      other.parsed_crypto_frame_in_this_packet_;
+  alpns_ = std::move(other.alpns_);
+  server_name_ = std::move(other.server_name_);
+  return *this;
+}
+
+void TlsChloExtractor::IngestPacket(const ParsedQuicVersion& version,
+                                    const QuicReceivedPacket& packet) {
+  if (state_ == State::kUnrecoverableFailure) {
+    QUIC_DLOG(ERROR) << "Not ingesting packet after unrecoverable error";
+    return;
+  }
+  if (version == UnsupportedQuicVersion()) {
+    QUIC_DLOG(ERROR) << "Not ingesting packet with unsupported version";
+    return;
+  }
+  if (version.handshake_protocol != PROTOCOL_TLS1_3) {
+    QUIC_DLOG(ERROR) << "Not ingesting packet with non-TLS version " << version;
+    return;
+  }
+  if (framer_) {
+    // This is not the first packet we have ingested, check if version matches.
+    if (!framer_->IsSupportedVersion(version)) {
+      QUIC_DLOG(ERROR)
+          << "Not ingesting packet with version mismatch, expected "
+          << framer_->version() << ", got " << version;
+      return;
+    }
+  } else {
+    // This is the first packet we have ingested, setup parser.
+    framer_ = std::make_unique<QuicFramer>(
+        ParsedQuicVersionVector{version}, QuicTime::Zero(),
+        Perspective::IS_SERVER, /*expected_server_connection_id_length=*/0);
+    // Note that expected_server_connection_id_length only matters for short
+    // headers and we explicitly drop those so we can pass any value here.
+    framer_->set_visitor(this);
+  }
+
+  // When the framer parses |packet|, if it sees a CRYPTO frame it will call
+  // OnCryptoFrame below and that will set parsed_crypto_frame_in_this_packet_
+  // to true.
+  parsed_crypto_frame_in_this_packet_ = false;
+  const bool parse_success = framer_->ProcessPacket(packet);
+  if (state_ == State::kInitial && parsed_crypto_frame_in_this_packet_) {
+    // If we parsed a CRYPTO frame but didn't advance the state from initial,
+    // then it means that we will need more packets to reassemble the full CHLO,
+    // so we advance the state here. This can happen when the first packet
+    // received is not the first one in the crypto stream. This allows us to
+    // differentiate our state between single-packet CHLO and multi-packet CHLO.
+    state_ = State::kParsedPartialChloFragment;
+  }
+
+  if (!parse_success) {
+    // This could be due to the packet being non-initial for example.
+    QUIC_DLOG(ERROR) << "Failed to process packet";
+    return;
+  }
+}
+
+// This is called when the framer parsed the unencrypted parts of the header.
+bool TlsChloExtractor::OnUnauthenticatedPublicHeader(
+    const QuicPacketHeader& header) {
+  if (header.form != IETF_QUIC_LONG_HEADER_PACKET) {
+    QUIC_DLOG(ERROR) << "Not parsing non-long-header packet " << header;
+    return false;
+  }
+  if (header.long_packet_type != INITIAL) {
+    QUIC_DLOG(ERROR) << "Not parsing non-initial packet " << header;
+    return false;
+  }
+  // QuicFramer is constructed without knowledge of the server's connection ID
+  // so it needs to be set up here in order to decrypt the packet.
+  framer_->SetInitialObfuscators(header.destination_connection_id);
+  return true;
+}
+
+// This is called by the framer if it detects a change in version during
+// parsing.
+bool TlsChloExtractor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
+  // This should never be called because we already check versions in
+  // IngestPacket.
+  QUIC_BUG(quic_bug_10855_1) << "Unexpected version mismatch, expected "
+                             << framer_->version() << ", got " << version;
+  return false;
+}
+
+// This is called by the QuicStreamSequencer if it encounters an unrecoverable
+// error that will prevent it from reassembling the crypto stream data.
+void TlsChloExtractor::OnUnrecoverableError(QuicErrorCode error,
+                                            const std::string& details) {
+  HandleUnrecoverableError(absl::StrCat(
+      "Crypto stream error ", QuicErrorCodeToString(error), ": ", details));
+}
+
+void TlsChloExtractor::OnUnrecoverableError(
+    QuicErrorCode error,
+    QuicIetfTransportErrorCodes ietf_error,
+    const std::string& details) {
+  HandleUnrecoverableError(absl::StrCat(
+      "Crypto stream error ", QuicErrorCodeToString(error), "(",
+      QuicIetfTransportErrorCodeString(ietf_error), "): ", details));
+}
+
+// This is called by the framer if it sees a CRYPTO frame during parsing.
+bool TlsChloExtractor::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  if (frame.level != ENCRYPTION_INITIAL) {
+    // Since we drop non-INITIAL packets in OnUnauthenticatedPublicHeader,
+    // we should never receive any CRYPTO frames at other encryption levels.
+    QUIC_BUG(quic_bug_10855_2) << "Parsed bad-level CRYPTO frame " << frame;
+    return false;
+  }
+  // parsed_crypto_frame_in_this_packet_ is checked in IngestPacket to allow
+  // advancing our state to track the difference between single-packet CHLO
+  // and multi-packet CHLO.
+  parsed_crypto_frame_in_this_packet_ = true;
+  crypto_stream_sequencer_.OnCryptoFrame(frame);
+  return true;
+}
+
+// Called by the QuicStreamSequencer when it receives a CRYPTO frame that
+// advances the amount of contiguous data we now have starting from offset 0.
+void TlsChloExtractor::OnDataAvailable() {
+  // Lazily set up BoringSSL handle.
+  SetupSslHandle();
+
+  // Get data from the stream sequencer and pass it to BoringSSL.
+  struct iovec iov;
+  while (crypto_stream_sequencer_.GetReadableRegion(&iov)) {
+    const int rv = SSL_provide_quic_data(
+        ssl_.get(), ssl_encryption_initial,
+        reinterpret_cast<const uint8_t*>(iov.iov_base), iov.iov_len);
+    if (rv != 1) {
+      HandleUnrecoverableError("SSL_provide_quic_data failed");
+      return;
+    }
+    crypto_stream_sequencer_.MarkConsumed(iov.iov_len);
+  }
+
+  // Instruct BoringSSL to attempt parsing a full CHLO from the provided data.
+  // We ignore the return value since we know the handshake is going to fail
+  // because we explicitly cancel processing once we've parsed the CHLO.
+  (void)SSL_do_handshake(ssl_.get());
+}
+
+// static
+TlsChloExtractor* TlsChloExtractor::GetInstanceFromSSL(SSL* ssl) {
+  std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
+  int ex_data_index = shared_handles.second;
+  return reinterpret_cast<TlsChloExtractor*>(
+      SSL_get_ex_data(ssl, ex_data_index));
+}
+
+// static
+int TlsChloExtractor::SetReadSecretCallback(
+    SSL* ssl,
+    enum ssl_encryption_level_t /*level*/,
+    const SSL_CIPHER* /*cipher*/,
+    const uint8_t* /*secret*/,
+    size_t /*secret_length*/) {
+  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("SetReadSecretCallback");
+  return 0;
+}
+
+// static
+int TlsChloExtractor::SetWriteSecretCallback(
+    SSL* ssl,
+    enum ssl_encryption_level_t /*level*/,
+    const SSL_CIPHER* /*cipher*/,
+    const uint8_t* /*secret*/,
+    size_t /*secret_length*/) {
+  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("SetWriteSecretCallback");
+  return 0;
+}
+
+// static
+int TlsChloExtractor::WriteMessageCallback(
+    SSL* ssl,
+    enum ssl_encryption_level_t /*level*/,
+    const uint8_t* /*data*/,
+    size_t /*len*/) {
+  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("WriteMessageCallback");
+  return 0;
+}
+
+// static
+int TlsChloExtractor::FlushFlightCallback(SSL* ssl) {
+  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("FlushFlightCallback");
+  return 0;
+}
+
+void TlsChloExtractor::HandleUnexpectedCallback(
+    const std::string& callback_name) {
+  std::string error_details =
+      absl::StrCat("Unexpected callback ", callback_name);
+  QUIC_BUG(quic_bug_10855_3) << error_details;
+  HandleUnrecoverableError(error_details);
+}
+
+// static
+int TlsChloExtractor::SendAlertCallback(SSL* ssl,
+                                        enum ssl_encryption_level_t /*level*/,
+                                        uint8_t desc) {
+  GetInstanceFromSSL(ssl)->SendAlert(desc);
+  return 0;
+}
+
+void TlsChloExtractor::SendAlert(uint8_t tls_alert_value) {
+  if (tls_alert_value == SSL3_AD_HANDSHAKE_FAILURE && HasParsedFullChlo()) {
+    // This is the most common scenario. Since we return an error from
+    // SelectCertCallback in order to cancel further processing, BoringSSL will
+    // try to send this alert to tell the client that the handshake failed.
+    return;
+  }
+  HandleUnrecoverableError(absl::StrCat(
+      "BoringSSL attempted to send alert ", static_cast<int>(tls_alert_value),
+      " ", SSL_alert_desc_string_long(tls_alert_value)));
+}
+
+// static
+enum ssl_select_cert_result_t TlsChloExtractor::SelectCertCallback(
+    const SSL_CLIENT_HELLO* client_hello) {
+  GetInstanceFromSSL(client_hello->ssl)->HandleParsedChlo(client_hello);
+  // Always return an error to cancel any further processing in BoringSSL.
+  return ssl_select_cert_error;
+}
+
+// Extracts the server name and ALPN from the parsed ClientHello.
+void TlsChloExtractor::HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello) {
+  const char* server_name =
+      SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name);
+  if (server_name) {
+    server_name_ = std::string(server_name);
+  }
+
+  resumption_attempted_ =
+      HasExtension(client_hello, TLSEXT_TYPE_pre_shared_key);
+  early_data_attempted_ = HasExtension(client_hello, TLSEXT_TYPE_early_data);
+
+  const uint8_t* alpn_data;
+  size_t alpn_len;
+  int rv = SSL_early_callback_ctx_extension_get(
+      client_hello, TLSEXT_TYPE_application_layer_protocol_negotiation,
+      &alpn_data, &alpn_len);
+  if (rv == 1) {
+    QuicDataReader alpns_reader(reinterpret_cast<const char*>(alpn_data),
+                                alpn_len);
+    absl::string_view alpns_payload;
+    if (!alpns_reader.ReadStringPiece16(&alpns_payload)) {
+      HandleUnrecoverableError("Failed to read alpns_payload");
+      return;
+    }
+    QuicDataReader alpns_payload_reader(alpns_payload);
+    while (!alpns_payload_reader.IsDoneReading()) {
+      absl::string_view alpn_payload;
+      if (!alpns_payload_reader.ReadStringPiece8(&alpn_payload)) {
+        HandleUnrecoverableError("Failed to read alpn_payload");
+        return;
+      }
+      alpns_.emplace_back(std::string(alpn_payload));
+    }
+  }
+
+  // Update our state now that we've parsed a full CHLO.
+  if (state_ == State::kInitial) {
+    state_ = State::kParsedFullSinglePacketChlo;
+  } else if (state_ == State::kParsedPartialChloFragment) {
+    state_ = State::kParsedFullMultiPacketChlo;
+  } else {
+    QUIC_BUG(quic_bug_10855_4)
+        << "Unexpected state on successful parse " << StateToString(state_);
+  }
+}
+
+// static
+std::pair<SSL_CTX*, int> TlsChloExtractor::GetSharedSslHandles() {
+  // Use a lambda to benefit from C++11 guarantee that static variables are
+  // initialized lazily in a thread-safe manner. |shared_handles| is therefore
+  // guaranteed to be initialized exactly once and never destructed.
+  static std::pair<SSL_CTX*, int>* shared_handles = []() {
+    CRYPTO_library_init();
+    SSL_CTX* ssl_ctx = SSL_CTX_new(TLS_with_buffers_method());
+    SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
+    SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
+    static const SSL_QUIC_METHOD kQuicCallbacks{
+        TlsChloExtractor::SetReadSecretCallback,
+        TlsChloExtractor::SetWriteSecretCallback,
+        TlsChloExtractor::WriteMessageCallback,
+        TlsChloExtractor::FlushFlightCallback,
+        TlsChloExtractor::SendAlertCallback};
+    SSL_CTX_set_quic_method(ssl_ctx, &kQuicCallbacks);
+    SSL_CTX_set_select_certificate_cb(ssl_ctx,
+                                      TlsChloExtractor::SelectCertCallback);
+    int ex_data_index =
+        SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
+    return new std::pair<SSL_CTX*, int>(ssl_ctx, ex_data_index);
+  }();
+  return *shared_handles;
+}
+
+// Sets up the per-instance SSL handle needed by BoringSSL.
+void TlsChloExtractor::SetupSslHandle() {
+  if (ssl_) {
+    // Handles have already been set up.
+    return;
+  }
+
+  std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
+  SSL_CTX* ssl_ctx = shared_handles.first;
+  int ex_data_index = shared_handles.second;
+
+  ssl_ = bssl::UniquePtr<SSL>(SSL_new(ssl_ctx));
+  const int rv = SSL_set_ex_data(ssl_.get(), ex_data_index, this);
+  QUICHE_CHECK_EQ(rv, 1) << "Internal allocation failure in SSL_set_ex_data";
+  SSL_set_accept_state(ssl_.get());
+
+  // Make sure we use the right TLS extension codepoint.
+  int use_legacy_extension = 0;
+  if (framer_->version().UsesLegacyTlsExtension()) {
+    use_legacy_extension = 1;
+  }
+  SSL_set_quic_use_legacy_codepoint(ssl_.get(), use_legacy_extension);
+}
+
+// Called by other methods to record any unrecoverable failures they experience.
+void TlsChloExtractor::HandleUnrecoverableError(
+    const std::string& error_details) {
+  if (HasParsedFullChlo()) {
+    // Ignore errors if we've parsed everything successfully.
+    QUIC_DLOG(ERROR) << "Ignoring error: " << error_details;
+    return;
+  }
+  QUIC_DLOG(ERROR) << "Handling error: " << error_details;
+
+  state_ = State::kUnrecoverableFailure;
+
+  if (error_details_.empty()) {
+    error_details_ = error_details;
+  } else {
+    error_details_ = absl::StrCat(error_details_, "; ", error_details);
+  }
+}
+
+// static
+std::string TlsChloExtractor::StateToString(State state) {
+  switch (state) {
+    case State::kInitial:
+      return "Initial";
+    case State::kParsedFullSinglePacketChlo:
+      return "ParsedFullSinglePacketChlo";
+    case State::kParsedFullMultiPacketChlo:
+      return "ParsedFullMultiPacketChlo";
+    case State::kParsedPartialChloFragment:
+      return "ParsedPartialChloFragment";
+    case State::kUnrecoverableFailure:
+      return "UnrecoverableFailure";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(state), ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const TlsChloExtractor::State& state) {
+  os << TlsChloExtractor::StateToString(state);
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/tls_chlo_extractor.h b/quiche/quic/core/tls_chlo_extractor.h
new file mode 100644
index 0000000..876dbd9
--- /dev/null
+++ b/quiche/quic/core/tls_chlo_extractor.h
@@ -0,0 +1,265 @@
+// Copyright (c) 2020 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_TLS_CHLO_EXTRACTOR_H_
+#define QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Utility class that allows extracting information from a QUIC-TLS Client
+// Hello. This class creates a QuicFramer to parse the packet, and implements
+// QuicFramerVisitorInterface to access the frames parsed by the QuicFramer. It
+// then uses a QuicStreamSequencer to reassemble the contents of the crypto
+// stream, and implements QuicStreamSequencer::StreamInterface to access the
+// reassembled data.
+class QUIC_NO_EXPORT TlsChloExtractor
+    : public QuicFramerVisitorInterface,
+      public QuicStreamSequencer::StreamInterface {
+ public:
+  TlsChloExtractor();
+  TlsChloExtractor(const TlsChloExtractor&) = delete;
+  TlsChloExtractor(TlsChloExtractor&&);
+  TlsChloExtractor& operator=(const TlsChloExtractor&) = delete;
+  TlsChloExtractor& operator=(TlsChloExtractor&&);
+
+  enum class State : uint8_t {
+    kInitial = 0,
+    kParsedFullSinglePacketChlo = 1,
+    kParsedFullMultiPacketChlo = 2,
+    kParsedPartialChloFragment = 3,
+    kUnrecoverableFailure = 4,
+  };
+
+  State state() const { return state_; }
+  std::vector<std::string> alpns() const { return alpns_; }
+  std::string server_name() const { return server_name_; }
+  bool resumption_attempted() const { return resumption_attempted_; }
+  bool early_data_attempted() const { return early_data_attempted_; }
+
+  // Converts |state| to a human-readable string suitable for logging.
+  static std::string StateToString(State state);
+
+  // Ingests |packet| and attempts to parse out the CHLO.
+  void IngestPacket(const ParsedQuicVersion& version,
+                    const QuicReceivedPacket& packet);
+
+  // Returns whether the ingested packets have allowed parsing a complete CHLO.
+  bool HasParsedFullChlo() const {
+    return state_ == State::kParsedFullSinglePacketChlo ||
+           state_ == State::kParsedFullMultiPacketChlo;
+  }
+
+  // Methods from QuicFramerVisitorInterface.
+  void OnError(QuicFramer* /*framer*/) override {}
+  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
+  void OnPacket() override {}
+  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& /*packet*/) override {}
+  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
+                     QuicConnectionId /*new_connection_id*/,
+                     absl::string_view /*retry_token*/,
+                     absl::string_view /*retry_integrity_tag*/,
+                     absl::string_view /*retry_without_tag*/) override {}
+  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
+    return true;
+  }
+  void OnDecryptedPacket(size_t /*packet_length*/,
+                         EncryptionLevel /*level*/) override {}
+  bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
+    return true;
+  }
+  void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {}
+  void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
+                             EncryptionLevel /*decryption_level*/,
+                             bool /*has_decryption_key*/) override {}
+  bool OnStreamFrame(const QuicStreamFrame& /*frame*/) override { return true; }
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  bool OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
+                       QuicTime::Delta /*ack_delay_time*/) override {
+    return true;
+  }
+  bool OnAckRange(QuicPacketNumber /*start*/,
+                  QuicPacketNumber /*end*/) override {
+    return true;
+  }
+  bool OnAckTimestamp(QuicPacketNumber /*packet_number*/,
+                      QuicTime /*timestamp*/) override {
+    return true;
+  }
+  bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnPingFrame(const QuicPingFrame& /*frame*/) override { return true; }
+  bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnConnectionCloseFrame(
+      const QuicConnectionCloseFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnNewConnectionIdFrame(
+      const QuicNewConnectionIdFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) override { return true; }
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnStreamsBlockedFrame(
+      const QuicStreamsBlockedFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnPaddingFrame(const QuicPaddingFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnMessageFrame(const QuicMessageFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) override {
+    return true;
+  }
+  void OnPacketComplete() override {}
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& /*token*/) const override {
+    return true;
+  }
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& /*packet*/) override {}
+  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
+  void OnDecryptedFirstPacketInKeyPhase() override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+
+  // Methods from QuicStreamSequencer::StreamInterface.
+  void OnDataAvailable() override;
+  void OnFinRead() override {}
+  void AddBytesConsumed(QuicByteCount /*bytes*/) override {}
+  void ResetWithError(QuicResetStreamError /*error*/) override {}
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& details) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            QuicIetfTransportErrorCodes ietf_error,
+                            const std::string& details) override;
+  QuicStreamId id() const override { return 0; }
+  ParsedQuicVersion version() const override { return framer_->version(); }
+
+ private:
+  // Parses the length of the CHLO message by looking at the first four bytes.
+  // Returns whether we have received enough data to parse the full CHLO now.
+  bool MaybeAttemptToParseChloLength();
+  // Parses the full CHLO message if enough data has been received.
+  void AttemptToParseFullChlo();
+  // Moves to the failed state and records the error details.
+  void HandleUnrecoverableError(const std::string& error_details);
+  // Lazily sets up shared SSL handles if needed.
+  static std::pair<SSL_CTX*, int> GetSharedSslHandles();
+  // Lazily sets up the per-instance SSL handle if needed.
+  void SetupSslHandle();
+  // Extract the TlsChloExtractor instance from |ssl|.
+  static TlsChloExtractor* GetInstanceFromSSL(SSL* ssl);
+
+  // BoringSSL static TLS callbacks.
+  static enum ssl_select_cert_result_t SelectCertCallback(
+      const SSL_CLIENT_HELLO* client_hello);
+  static int SetReadSecretCallback(SSL* ssl,
+                                   enum ssl_encryption_level_t level,
+                                   const SSL_CIPHER* cipher,
+                                   const uint8_t* secret,
+                                   size_t secret_length);
+  static int SetWriteSecretCallback(SSL* ssl,
+                                    enum ssl_encryption_level_t level,
+                                    const SSL_CIPHER* cipher,
+                                    const uint8_t* secret,
+                                    size_t secret_length);
+  static int WriteMessageCallback(SSL* ssl,
+                                  enum ssl_encryption_level_t level,
+                                  const uint8_t* data,
+                                  size_t len);
+  static int FlushFlightCallback(SSL* ssl);
+  static int SendAlertCallback(SSL* ssl,
+                               enum ssl_encryption_level_t level,
+                               uint8_t desc);
+
+  // Called by SelectCertCallback.
+  void HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello);
+  // Called by callbacks that should never be called.
+  void HandleUnexpectedCallback(const std::string& callback_name);
+  // Called by SendAlertCallback.
+  void SendAlert(uint8_t tls_alert_value);
+
+  // Used to parse received packets to extract single frames.
+  std::unique_ptr<QuicFramer> framer_;
+  // Used to reassemble the crypto stream from received CRYPTO frames.
+  QuicStreamSequencer crypto_stream_sequencer_;
+  // BoringSSL handle required to parse the CHLO.
+  bssl::UniquePtr<SSL> ssl_;
+  // State of this TlsChloExtractor.
+  State state_;
+  // Detail string that can be logged in the presence of unrecoverable errors.
+  std::string error_details_;
+  // Whether a CRYPTO frame was parsed in this packet.
+  bool parsed_crypto_frame_in_this_packet_;
+  // Array of ALPNs parsed from the CHLO.
+  std::vector<std::string> alpns_;
+  // SNI parsed from the CHLO.
+  std::string server_name_;
+  // Whether resumption is attempted from the CHLO, indicated by the
+  // 'pre_shared_key' TLS extension.
+  bool resumption_attempted_ = false;
+  // Whether early data is attempted from the CHLO, indicated by the
+  // 'early_data' TLS extension.
+  bool early_data_attempted_ = false;
+};
+
+// Convenience method to facilitate logging TlsChloExtractor::State.
+QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
+                                        const TlsChloExtractor::State& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
diff --git a/quiche/quic/core/tls_chlo_extractor_test.cc b/quiche/quic/core/tls_chlo_extractor_test.cc
new file mode 100644
index 0000000..51e6a9a
--- /dev/null
+++ b/quiche/quic/core/tls_chlo_extractor_test.cc
@@ -0,0 +1,253 @@
+// Copyright (c) 2020 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 "quiche/quic/core/tls_chlo_extractor.h"
+
+#include <memory>
+
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/first_flight.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using testing::_;
+using testing::AnyNumber;
+
+class TlsChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  TlsChloExtractorTest() : version_(GetParam()), server_id_(TestServerId()) {}
+
+  void Initialize() { packets_ = GetFirstFlightOfPackets(version_, config_); }
+  void Initialize(std::unique_ptr<QuicCryptoClientConfig> crypto_config) {
+    packets_ = GetFirstFlightOfPackets(version_, config_, TestConnectionId(),
+                                       EmptyQuicConnectionId(),
+                                       std::move(crypto_config));
+  }
+
+  // Perform a full handshake in order to insert a SSL_SESSION into
+  // crypto_config->session_cache(), which can be used by a TLS resumption.
+  void PerformFullHandshake(QuicCryptoClientConfig* crypto_config) const {
+    ASSERT_NE(crypto_config->session_cache(), nullptr);
+    MockQuicConnectionHelper client_helper, server_helper;
+    MockAlarmFactory alarm_factory;
+    ParsedQuicVersionVector supported_versions = {version_};
+    PacketSavingConnection* client_connection =
+        new PacketSavingConnection(&client_helper, &alarm_factory,
+                                   Perspective::IS_CLIENT, supported_versions);
+    // Advance the time, because timers do not like uninitialized times.
+    client_connection->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    QuicClientPushPromiseIndex push_promise_index;
+    QuicSpdyClientSession client_session(config_, supported_versions,
+                                         client_connection, server_id_,
+                                         crypto_config, &push_promise_index);
+    client_session.Initialize();
+
+    std::unique_ptr<QuicCryptoServerConfig> server_crypto_config =
+        crypto_test_utils::CryptoServerConfigForTesting();
+    QuicConfig server_config;
+
+    EXPECT_CALL(*client_connection, SendCryptoData(_, _, _)).Times(AnyNumber());
+    client_session.GetMutableCryptoStream()->CryptoConnect();
+
+    crypto_test_utils::HandshakeWithFakeServer(
+        &server_config, server_crypto_config.get(), &server_helper,
+        &alarm_factory, client_connection,
+        client_session.GetMutableCryptoStream(),
+        AlpnForVersion(client_connection->version()));
+
+    // For some reason, the test client can not receive the server settings and
+    // the SSL_SESSION will not be inserted to client's session_cache. We create
+    // a dummy settings and call SetServerApplicationStateForResumption manually
+    // to ensure the SSL_SESSION is cached.
+    // TODO(wub): Fix crypto_test_utils::HandshakeWithFakeServer to make sure a
+    // SSL_SESSION is cached at the client, and remove the rest of the function.
+    SettingsFrame server_settings;
+    server_settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
+        kDefaultQpackMaxDynamicTableCapacity;
+    std::unique_ptr<char[]> buffer;
+    uint64_t length =
+        HttpEncoder::SerializeSettingsFrame(server_settings, &buffer);
+    client_session.GetMutableCryptoStream()
+        ->SetServerApplicationStateForResumption(
+            std::make_unique<ApplicationState>(buffer.get(),
+                                               buffer.get() + length));
+  }
+
+  void IngestPackets() {
+    for (const std::unique_ptr<QuicReceivedPacket>& packet : packets_) {
+      ReceivedPacketInfo packet_info(
+          QuicSocketAddress(TestPeerIPAddress(), kTestPort),
+          QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packet);
+      std::string detailed_error;
+      absl::optional<absl::string_view> retry_token;
+      const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+          *packet, /*expected_destination_connection_id_length=*/0,
+          &packet_info.form, &packet_info.long_packet_type,
+          &packet_info.version_flag, &packet_info.use_length_prefix,
+          &packet_info.version_label, &packet_info.version,
+          &packet_info.destination_connection_id,
+          &packet_info.source_connection_id, &retry_token, &detailed_error);
+      ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+      tls_chlo_extractor_.IngestPacket(packet_info.version, packet_info.packet);
+    }
+    packets_.clear();
+  }
+
+  void ValidateChloDetails() {
+    EXPECT_TRUE(tls_chlo_extractor_.HasParsedFullChlo());
+    std::vector<std::string> alpns = tls_chlo_extractor_.alpns();
+    ASSERT_EQ(alpns.size(), 1u);
+    EXPECT_EQ(alpns[0], AlpnForVersion(version_));
+    EXPECT_EQ(tls_chlo_extractor_.server_name(), TestHostname());
+  }
+
+  void IncreaseSizeOfChlo() {
+    // Add a 2000-byte custom parameter to increase the length of the CHLO.
+    constexpr auto kCustomParameterId =
+        static_cast<TransportParameters::TransportParameterId>(0xff33);
+    std::string kCustomParameterValue(2000, '-');
+    config_.custom_transport_parameters_to_send()[kCustomParameterId] =
+        kCustomParameterValue;
+  }
+
+  ParsedQuicVersion version_;
+  QuicServerId server_id_;
+  TlsChloExtractor tls_chlo_extractor_;
+  QuicConfig config_;
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets_;
+};
+
+INSTANTIATE_TEST_SUITE_P(TlsChloExtractorTests,
+                         TlsChloExtractorTest,
+                         ::testing::ValuesIn(AllSupportedVersionsWithTls()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(TlsChloExtractorTest, Simple) {
+  Initialize();
+  EXPECT_EQ(packets_.size(), 1u);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullSinglePacketChlo);
+  EXPECT_FALSE(tls_chlo_extractor_.resumption_attempted());
+  EXPECT_FALSE(tls_chlo_extractor_.early_data_attempted());
+}
+
+TEST_P(TlsChloExtractorTest, TlsExtentionInfo_ResumptionOnly) {
+  auto crypto_client_config = std::make_unique<QuicCryptoClientConfig>(
+      crypto_test_utils::ProofVerifierForTesting(),
+      std::make_unique<SimpleSessionCache>());
+  PerformFullHandshake(crypto_client_config.get());
+
+  SSL_CTX_set_early_data_enabled(crypto_client_config->ssl_ctx(), 0);
+  Initialize(std::move(crypto_client_config));
+  EXPECT_GE(packets_.size(), 1u);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullSinglePacketChlo);
+  EXPECT_TRUE(tls_chlo_extractor_.resumption_attempted());
+  EXPECT_FALSE(tls_chlo_extractor_.early_data_attempted());
+}
+
+TEST_P(TlsChloExtractorTest, TlsExtentionInfo_ZeroRtt) {
+  auto crypto_client_config = std::make_unique<QuicCryptoClientConfig>(
+      crypto_test_utils::ProofVerifierForTesting(),
+      std::make_unique<SimpleSessionCache>());
+  PerformFullHandshake(crypto_client_config.get());
+
+  IncreaseSizeOfChlo();
+  Initialize(std::move(crypto_client_config));
+  EXPECT_GE(packets_.size(), 1u);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
+  EXPECT_TRUE(tls_chlo_extractor_.resumption_attempted());
+  EXPECT_TRUE(tls_chlo_extractor_.early_data_attempted());
+}
+
+TEST_P(TlsChloExtractorTest, MultiPacket) {
+  IncreaseSizeOfChlo();
+  Initialize();
+  EXPECT_EQ(packets_.size(), 2u);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
+}
+
+TEST_P(TlsChloExtractorTest, MultiPacketReordered) {
+  IncreaseSizeOfChlo();
+  Initialize();
+  ASSERT_EQ(packets_.size(), 2u);
+  // Artifically reorder both packets.
+  std::swap(packets_[0], packets_[1]);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
+}
+
+TEST_P(TlsChloExtractorTest, MoveAssignment) {
+  Initialize();
+  EXPECT_EQ(packets_.size(), 1u);
+  TlsChloExtractor other_extractor;
+  tls_chlo_extractor_ = std::move(other_extractor);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullSinglePacketChlo);
+}
+
+TEST_P(TlsChloExtractorTest, MoveAssignmentBetweenPackets) {
+  IncreaseSizeOfChlo();
+  Initialize();
+  ASSERT_EQ(packets_.size(), 2u);
+  TlsChloExtractor other_extractor;
+
+  // Have |other_extractor| parse the first packet.
+  ReceivedPacketInfo packet_info(
+      QuicSocketAddress(TestPeerIPAddress(), kTestPort),
+      QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packets_[0]);
+  std::string detailed_error;
+  absl::optional<absl::string_view> retry_token;
+  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+      *packets_[0], /*expected_destination_connection_id_length=*/0,
+      &packet_info.form, &packet_info.long_packet_type,
+      &packet_info.version_flag, &packet_info.use_length_prefix,
+      &packet_info.version_label, &packet_info.version,
+      &packet_info.destination_connection_id, &packet_info.source_connection_id,
+      &retry_token, &detailed_error);
+  ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+  other_extractor.IngestPacket(packet_info.version, packet_info.packet);
+  // Remove the first packet from the list.
+  packets_.erase(packets_.begin());
+  EXPECT_EQ(packets_.size(), 1u);
+
+  // Move the extractor.
+  tls_chlo_extractor_ = std::move(other_extractor);
+
+  // Have |tls_chlo_extractor_| parse the second packet.
+  IngestPackets();
+
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/tls_client_handshaker.cc b/quiche/quic/core/tls_client_handshaker.cc
new file mode 100644
index 0000000..641dcc5
--- /dev/null
+++ b/quiche/quic/core/tls_client_handshaker.cc
@@ -0,0 +1,649 @@
+// Copyright (c) 2017 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 "quiche/quic/core/tls_client_handshaker.h"
+
+#include <cstring>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+TlsClientHandshaker::TlsClientHandshaker(
+    const QuicServerId& server_id,
+    QuicCryptoStream* stream,
+    QuicSession* session,
+    std::unique_ptr<ProofVerifyContext> verify_context,
+    QuicCryptoClientConfig* crypto_config,
+    QuicCryptoClientStream::ProofHandler* proof_handler,
+    bool has_application_state)
+    : TlsHandshaker(stream, session),
+      session_(session),
+      server_id_(server_id),
+      proof_verifier_(crypto_config->proof_verifier()),
+      verify_context_(std::move(verify_context)),
+      proof_handler_(proof_handler),
+      session_cache_(crypto_config->session_cache()),
+      user_agent_id_(crypto_config->user_agent_id()),
+      pre_shared_key_(crypto_config->pre_shared_key()),
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
+      has_application_state_(has_application_state),
+      tls_connection_(crypto_config->ssl_ctx(), this, session->GetSSLConfig()) {
+  if (crypto_config->tls_signature_algorithms().has_value()) {
+    SSL_set1_sigalgs_list(ssl(),
+                          crypto_config->tls_signature_algorithms()->c_str());
+  }
+  if (crypto_config->proof_source() != nullptr) {
+    const ClientProofSource::CertAndKey* cert_and_key =
+        crypto_config->proof_source()->GetCertAndKey(server_id.host());
+    if (cert_and_key != nullptr) {
+      QUIC_DVLOG(1) << "Setting client cert and key for " << server_id.host();
+      tls_connection_.SetCertChain(cert_and_key->chain->ToCryptoBuffers().value,
+                                   cert_and_key->private_key.private_key());
+    }
+  }
+}
+
+TlsClientHandshaker::~TlsClientHandshaker() {}
+
+bool TlsClientHandshaker::CryptoConnect() {
+  if (!pre_shared_key_.empty()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    std::string error_details =
+        "QUIC client pre-shared keys not yet supported with TLS";
+    QUIC_BUG(quic_bug_10576_1) << error_details;
+    CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
+    return false;
+  }
+
+  // Make sure we use the right TLS extension codepoint.
+  int use_legacy_extension = 0;
+  if (session()->version().UsesLegacyTlsExtension()) {
+    use_legacy_extension = 1;
+  }
+  SSL_set_quic_use_legacy_codepoint(ssl(), use_legacy_extension);
+
+  // TODO(b/193650832) Add SetFromConfig to QUIC handshakers and remove reliance
+  // on session pointer.
+  const bool permutes_tls_extensions = session()->permutes_tls_extensions();
+  if (!permutes_tls_extensions) {
+    QUIC_DLOG(INFO) << "Disabling TLS extension permutation";
+  }
+#if BORINGSSL_API_VERSION >= 16
+  // Ask BoringSSL to randomize the order of TLS extensions.
+  SSL_set_permute_extensions(ssl(), permutes_tls_extensions);
+#endif  // BORINGSSL_API_VERSION
+
+  // Set the SNI to send, if any.
+  SSL_set_connect_state(ssl());
+  if (QUIC_DLOG_INFO_IS_ON() &&
+      !QuicHostnameUtils::IsValidSNI(server_id_.host())) {
+    QUIC_DLOG(INFO) << "Client configured with invalid hostname \""
+                    << server_id_.host() << "\", not sending as SNI";
+  }
+  if (!server_id_.host().empty() &&
+      (QuicHostnameUtils::IsValidSNI(server_id_.host()) ||
+       allow_invalid_sni_for_tests_) &&
+      SSL_set_tlsext_host_name(ssl(), server_id_.host().c_str()) != 1) {
+    return false;
+  }
+
+  if (!SetAlpn()) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "Client failed to set ALPN");
+    return false;
+  }
+
+  // Set the Transport Parameters to send in the ClientHello
+  if (!SetTransportParameters()) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED,
+                    "Client failed to set Transport Parameters");
+    return false;
+  }
+
+  // Set a session to resume, if there is one.
+  if (session_cache_) {
+    cached_state_ = session_cache_->Lookup(
+        server_id_, session()->GetClock()->WallNow(), SSL_get_SSL_CTX(ssl()));
+  }
+  if (cached_state_) {
+    SSL_set_session(ssl(), cached_state_->tls_session.get());
+    if (!cached_state_->token.empty()) {
+      session()->SetSourceAddressTokenToSend(cached_state_->token);
+    }
+  }
+
+  // Start the handshake.
+  AdvanceHandshake();
+  return session()->connection()->connected();
+}
+
+bool TlsClientHandshaker::PrepareZeroRttConfig(
+    QuicResumptionState* cached_state) {
+  std::string error_details;
+  if (!cached_state->transport_params ||
+      handshaker_delegate()->ProcessTransportParameters(
+          *(cached_state->transport_params),
+          /*is_resumption = */ true, &error_details) != QUIC_NO_ERROR) {
+    QUIC_BUG(quic_bug_10576_2)
+        << "Unable to parse cached transport parameters.";
+    CloseConnection(QUIC_HANDSHAKE_FAILED,
+                    "Client failed to parse cached Transport Parameters.");
+    return false;
+  }
+
+  session()->connection()->OnTransportParametersResumed(
+      *(cached_state->transport_params));
+  session()->OnConfigNegotiated();
+
+  if (has_application_state_) {
+    if (!cached_state->application_state ||
+        !session()->ResumeApplicationState(
+            cached_state->application_state.get())) {
+      QUIC_BUG(quic_bug_10576_3) << "Unable to parse cached application state.";
+      CloseConnection(QUIC_HANDSHAKE_FAILED,
+                      "Client failed to parse cached application state.");
+      return false;
+    }
+  }
+  return true;
+}
+
+static bool IsValidAlpn(const std::string& alpn_string) {
+  return alpn_string.length() <= std::numeric_limits<uint8_t>::max();
+}
+
+bool TlsClientHandshaker::SetAlpn() {
+  std::vector<std::string> alpns = session()->GetAlpnsToOffer();
+  if (alpns.empty()) {
+    if (allow_empty_alpn_for_tests_) {
+      return true;
+    }
+
+    QUIC_BUG(quic_bug_10576_4) << "ALPN missing";
+    return false;
+  }
+  if (!std::all_of(alpns.begin(), alpns.end(), IsValidAlpn)) {
+    QUIC_BUG(quic_bug_10576_5) << "ALPN too long";
+    return false;
+  }
+
+  // SSL_set_alpn_protos expects a sequence of one-byte-length-prefixed
+  // strings.
+  uint8_t alpn[1024];
+  QuicDataWriter alpn_writer(sizeof(alpn), reinterpret_cast<char*>(alpn));
+  bool success = true;
+  for (const std::string& alpn_string : alpns) {
+    success = success && alpn_writer.WriteUInt8(alpn_string.size()) &&
+              alpn_writer.WriteStringPiece(alpn_string);
+  }
+  success =
+      success && (SSL_set_alpn_protos(ssl(), alpn, alpn_writer.length()) == 0);
+  if (!success) {
+    QUIC_BUG(quic_bug_10576_6)
+        << "Failed to set ALPN: "
+        << quiche::QuicheTextUtils::HexDump(
+               absl::string_view(alpn_writer.data(), alpn_writer.length()));
+    return false;
+  }
+
+  // Enable ALPS only for versions that use HTTP/3 frames.
+  for (const std::string& alpn_string : alpns) {
+    for (const ParsedQuicVersion& version : session()->supported_versions()) {
+      if (!version.UsesHttp3() || AlpnForVersion(version) != alpn_string) {
+        continue;
+      }
+      if (SSL_add_application_settings(
+              ssl(), reinterpret_cast<const uint8_t*>(alpn_string.data()),
+              alpn_string.size(), nullptr, /* settings_len = */ 0) != 1) {
+        QUIC_BUG(quic_bug_10576_7) << "Failed to enable ALPS.";
+        return false;
+      }
+      break;
+    }
+  }
+
+  QUIC_DLOG(INFO) << "Client using ALPN: '" << alpns[0] << "'";
+  return true;
+}
+
+bool TlsClientHandshaker::SetTransportParameters() {
+  TransportParameters params;
+  params.perspective = Perspective::IS_CLIENT;
+  params.legacy_version_information =
+      TransportParameters::LegacyVersionInformation();
+  params.legacy_version_information.value().version =
+      CreateQuicVersionLabel(session()->supported_versions().front());
+  params.version_information = TransportParameters::VersionInformation();
+  const QuicVersionLabel version = CreateQuicVersionLabel(session()->version());
+  params.version_information.value().chosen_version = version;
+  params.version_information.value().other_versions.push_back(version);
+
+  if (!handshaker_delegate()->FillTransportParameters(&params)) {
+    return false;
+  }
+
+  // Notify QuicConnectionDebugVisitor.
+  session()->connection()->OnTransportParametersSent(params);
+
+  std::vector<uint8_t> param_bytes;
+  return SerializeTransportParameters(session()->connection()->version(),
+                                      params, &param_bytes) &&
+         SSL_set_quic_transport_params(ssl(), param_bytes.data(),
+                                       param_bytes.size()) == 1;
+}
+
+bool TlsClientHandshaker::ProcessTransportParameters(
+    std::string* error_details) {
+  received_transport_params_ = std::make_unique<TransportParameters>();
+  const uint8_t* param_bytes;
+  size_t param_bytes_len;
+  SSL_get_peer_quic_transport_params(ssl(), &param_bytes, &param_bytes_len);
+  if (param_bytes_len == 0) {
+    *error_details = "Server's transport parameters are missing";
+    return false;
+  }
+  std::string parse_error_details;
+  if (!ParseTransportParameters(
+          session()->connection()->version(), Perspective::IS_SERVER,
+          param_bytes, param_bytes_len, received_transport_params_.get(),
+          &parse_error_details)) {
+    QUICHE_DCHECK(!parse_error_details.empty());
+    *error_details =
+        "Unable to parse server's transport parameters: " + parse_error_details;
+    return false;
+  }
+
+  // Notify QuicConnectionDebugVisitor.
+  session()->connection()->OnTransportParametersReceived(
+      *received_transport_params_);
+
+  if (received_transport_params_->legacy_version_information.has_value()) {
+    if (received_transport_params_->legacy_version_information.value()
+            .version !=
+        CreateQuicVersionLabel(session()->connection()->version())) {
+      *error_details = "Version mismatch detected";
+      return false;
+    }
+    if (CryptoUtils::ValidateServerHelloVersions(
+            received_transport_params_->legacy_version_information.value()
+                .supported_versions,
+            session()->connection()->server_supported_versions(),
+            error_details) != QUIC_NO_ERROR) {
+      QUICHE_DCHECK(!error_details->empty());
+      return false;
+    }
+  }
+  if (received_transport_params_->version_information.has_value()) {
+    if (!CryptoUtils::ValidateChosenVersion(
+            received_transport_params_->version_information.value()
+                .chosen_version,
+            session()->version(), error_details)) {
+      QUICHE_DCHECK(!error_details->empty());
+      return false;
+    }
+    if (!CryptoUtils::CryptoUtils::ValidateServerVersions(
+            received_transport_params_->version_information.value()
+                .other_versions,
+            session()->version(),
+            session()->client_original_supported_versions(), error_details)) {
+      QUICHE_DCHECK(!error_details->empty());
+      return false;
+    }
+  }
+
+  if (handshaker_delegate()->ProcessTransportParameters(
+          *received_transport_params_, /* is_resumption = */ false,
+          error_details) != QUIC_NO_ERROR) {
+    QUICHE_DCHECK(!error_details->empty());
+    return false;
+  }
+
+  session()->OnConfigNegotiated();
+  if (is_connection_closed()) {
+    *error_details =
+        "Session closed the connection when parsing negotiated config.";
+    return false;
+  }
+  return true;
+}
+
+int TlsClientHandshaker::num_sent_client_hellos() const {
+  return 0;
+}
+
+bool TlsClientHandshaker::IsResumption() const {
+  QUIC_BUG_IF(quic_bug_12736_1, !one_rtt_keys_available());
+  return SSL_session_reused(ssl()) == 1;
+}
+
+bool TlsClientHandshaker::EarlyDataAccepted() const {
+  QUIC_BUG_IF(quic_bug_12736_2, !one_rtt_keys_available());
+  return SSL_early_data_accepted(ssl()) == 1;
+}
+
+ssl_early_data_reason_t TlsClientHandshaker::EarlyDataReason() const {
+  return TlsHandshaker::EarlyDataReason();
+}
+
+bool TlsClientHandshaker::ReceivedInchoateReject() const {
+  QUIC_BUG_IF(quic_bug_12736_3, !one_rtt_keys_available());
+  // REJ messages are a QUIC crypto feature, so TLS always returns false.
+  return false;
+}
+
+int TlsClientHandshaker::num_scup_messages_received() const {
+  // SCUP messages aren't sent or received when using the TLS handshake.
+  return 0;
+}
+
+std::string TlsClientHandshaker::chlo_hash() const {
+  return "";
+}
+
+bool TlsClientHandshaker::ExportKeyingMaterial(absl::string_view label,
+                                               absl::string_view context,
+                                               size_t result_len,
+                                               std::string* result) {
+  return ExportKeyingMaterialForLabel(label, context, result_len, result);
+}
+
+bool TlsClientHandshaker::encryption_established() const {
+  return encryption_established_;
+}
+
+bool TlsClientHandshaker::one_rtt_keys_available() const {
+  return state_ >= HANDSHAKE_COMPLETE;
+}
+
+const QuicCryptoNegotiatedParameters&
+TlsClientHandshaker::crypto_negotiated_params() const {
+  return *crypto_negotiated_params_;
+}
+
+CryptoMessageParser* TlsClientHandshaker::crypto_message_parser() {
+  return TlsHandshaker::crypto_message_parser();
+}
+
+HandshakeState TlsClientHandshaker::GetHandshakeState() const {
+  return state_;
+}
+
+size_t TlsClientHandshaker::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return TlsHandshaker::BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+TlsClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter>
+TlsClientHandshaker::CreateCurrentOneRttEncrypter() {
+  return TlsHandshaker::CreateCurrentOneRttEncrypter();
+}
+
+void TlsClientHandshaker::OnOneRttPacketAcknowledged() {
+  OnHandshakeConfirmed();
+}
+
+void TlsClientHandshaker::OnHandshakePacketSent() {
+  if (initial_keys_dropped_) {
+    return;
+  }
+  initial_keys_dropped_ = true;
+  handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
+}
+
+void TlsClientHandshaker::OnConnectionClosed(QuicErrorCode error,
+                                             ConnectionCloseSource source) {
+  TlsHandshaker::OnConnectionClosed(error, source);
+}
+
+void TlsClientHandshaker::OnHandshakeDoneReceived() {
+  if (!one_rtt_keys_available()) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED,
+                    "Unexpected handshake done received");
+    return;
+  }
+  OnHandshakeConfirmed();
+}
+
+void TlsClientHandshaker::OnNewTokenReceived(absl::string_view token) {
+  if (token.empty()) {
+    return;
+  }
+  if (session_cache_ != nullptr) {
+    session_cache_->OnNewTokenReceived(server_id_, token);
+  }
+}
+
+void TlsClientHandshaker::SetWriteSecret(
+    EncryptionLevel level,
+    const SSL_CIPHER* cipher,
+    const std::vector<uint8_t>& write_secret) {
+  if (is_connection_closed()) {
+    return;
+  }
+  if (level == ENCRYPTION_FORWARD_SECURE || level == ENCRYPTION_ZERO_RTT) {
+    encryption_established_ = true;
+  }
+  TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_ZERO_RTT);
+  }
+}
+
+void TlsClientHandshaker::OnHandshakeConfirmed() {
+  QUICHE_DCHECK(one_rtt_keys_available());
+  if (state_ >= HANDSHAKE_CONFIRMED) {
+    return;
+  }
+  state_ = HANDSHAKE_CONFIRMED;
+  handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
+  handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
+}
+
+QuicAsyncStatus TlsClientHandshaker::VerifyCertChain(
+    const std::vector<std::string>& certs,
+    std::string* error_details,
+    std::unique_ptr<ProofVerifyDetails>* details,
+    uint8_t* out_alert,
+    std::unique_ptr<ProofVerifierCallback> callback) {
+  const uint8_t* ocsp_response_raw;
+  size_t ocsp_response_len;
+  SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len);
+  std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw),
+                            ocsp_response_len);
+  const uint8_t* sct_list_raw;
+  size_t sct_list_len;
+  SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len);
+  std::string sct_list(reinterpret_cast<const char*>(sct_list_raw),
+                       sct_list_len);
+
+  return proof_verifier_->VerifyCertChain(
+      server_id_.host(), server_id_.port(), certs, ocsp_response, sct_list,
+      verify_context_.get(), error_details, details, out_alert,
+      std::move(callback));
+}
+
+void TlsClientHandshaker::OnProofVerifyDetailsAvailable(
+    const ProofVerifyDetails& verify_details) {
+  proof_handler_->OnProofVerifyDetailsAvailable(verify_details);
+}
+
+void TlsClientHandshaker::FinishHandshake() {
+  FillNegotiatedParams();
+
+  QUICHE_CHECK(!SSL_in_early_data(ssl()));
+
+  QUIC_LOG(INFO) << "Client: handshake finished";
+
+  std::string error_details;
+  if (!ProcessTransportParameters(&error_details)) {
+    QUICHE_DCHECK(!error_details.empty());
+    CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
+    return;
+  }
+
+  const uint8_t* alpn_data = nullptr;
+  unsigned alpn_length = 0;
+  SSL_get0_alpn_selected(ssl(), &alpn_data, &alpn_length);
+
+  if (alpn_length == 0) {
+    QUIC_DLOG(ERROR) << "Client: server did not select ALPN";
+    // TODO(b/130164908) this should send no_application_protocol
+    // instead of QUIC_HANDSHAKE_FAILED.
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "Server did not select ALPN");
+    return;
+  }
+
+  std::string received_alpn_string(reinterpret_cast<const char*>(alpn_data),
+                                   alpn_length);
+  std::vector<std::string> offered_alpns = session()->GetAlpnsToOffer();
+  if (std::find(offered_alpns.begin(), offered_alpns.end(),
+                received_alpn_string) == offered_alpns.end()) {
+    QUIC_LOG(ERROR) << "Client: received mismatched ALPN '"
+                    << received_alpn_string;
+    // TODO(b/130164908) this should send no_application_protocol
+    // instead of QUIC_HANDSHAKE_FAILED.
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "Client received mismatched ALPN");
+    return;
+  }
+  session()->OnAlpnSelected(received_alpn_string);
+  QUIC_DLOG(INFO) << "Client: server selected ALPN: '" << received_alpn_string
+                  << "'";
+
+  // Parse ALPS extension.
+  const uint8_t* alps_data;
+  size_t alps_length;
+  SSL_get0_peer_application_settings(ssl(), &alps_data, &alps_length);
+  if (alps_length > 0) {
+    auto error = session()->OnAlpsData(alps_data, alps_length);
+    if (error) {
+      // Calling CloseConnection() is safe even in case OnAlpsData() has
+      // already closed the connection.
+      CloseConnection(
+          QUIC_HANDSHAKE_FAILED,
+          absl::StrCat("Error processing ALPS data: ", error.value()));
+      return;
+    }
+  }
+
+  state_ = HANDSHAKE_COMPLETE;
+  handshaker_delegate()->OnTlsHandshakeComplete();
+}
+
+void TlsClientHandshaker::OnEnterEarlyData() {
+  QUICHE_DCHECK(SSL_in_early_data(ssl()));
+
+  // TODO(wub): It might be unnecessary to FillNegotiatedParams() at this time,
+  // because we fill it again when handshake completes.
+  FillNegotiatedParams();
+
+  // If we're attempting a 0-RTT handshake, then we need to let the transport
+  // and application know what state to apply to early data.
+  PrepareZeroRttConfig(cached_state_.get());
+}
+
+void TlsClientHandshaker::FillNegotiatedParams() {
+  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
+  if (cipher) {
+    crypto_negotiated_params_->cipher_suite =
+        SSL_CIPHER_get_protocol_id(cipher);
+  }
+  crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
+  crypto_negotiated_params_->peer_signature_algorithm =
+      SSL_get_peer_signature_algorithm(ssl());
+}
+
+void TlsClientHandshaker::ProcessPostHandshakeMessage() {
+  int rv = SSL_process_quic_post_handshake(ssl());
+  if (rv != 1) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data");
+  }
+}
+
+bool TlsClientHandshaker::ShouldCloseConnectionOnUnexpectedError(
+    int ssl_error) {
+  if (ssl_error != SSL_ERROR_EARLY_DATA_REJECTED) {
+    return true;
+  }
+  HandleZeroRttReject();
+  return false;
+}
+
+void TlsClientHandshaker::HandleZeroRttReject() {
+  QUIC_LOG(INFO) << "0-RTT handshake attempted but was rejected by the server";
+  QUICHE_DCHECK(session_cache_);
+  // Disable encrytion to block outgoing data until 1-RTT keys are available.
+  encryption_established_ = false;
+  handshaker_delegate()->OnZeroRttRejected(EarlyDataReason());
+  SSL_reset_early_data_reject(ssl());
+  session_cache_->ClearEarlyData(server_id_);
+  AdvanceHandshake();
+}
+
+void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) {
+  if (!received_transport_params_) {
+    QUIC_BUG(quic_bug_10576_8) << "Transport parameters isn't received";
+    return;
+  }
+  if (session_cache_ == nullptr) {
+    QUIC_DVLOG(1) << "No session cache, not inserting a session";
+    return;
+  }
+  if (has_application_state_ && !received_application_state_) {
+    // Application state is not received yet. cache the sessions.
+    if (cached_tls_sessions_[0] != nullptr) {
+      cached_tls_sessions_[1] = std::move(cached_tls_sessions_[0]);
+    }
+    cached_tls_sessions_[0] = std::move(session);
+    return;
+  }
+  session_cache_->Insert(server_id_, std::move(session),
+                         *received_transport_params_,
+                         received_application_state_.get());
+}
+
+void TlsClientHandshaker::WriteMessage(EncryptionLevel level,
+                                       absl::string_view data) {
+  if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) {
+    state_ = HANDSHAKE_PROCESSED;
+  }
+  TlsHandshaker::WriteMessage(level, data);
+}
+
+void TlsClientHandshaker::SetServerApplicationStateForResumption(
+    std::unique_ptr<ApplicationState> application_state) {
+  QUICHE_DCHECK(one_rtt_keys_available());
+  received_application_state_ = std::move(application_state);
+  // At least one tls session is cached before application state is received. So
+  // insert now.
+  if (session_cache_ != nullptr && cached_tls_sessions_[0] != nullptr) {
+    if (cached_tls_sessions_[1] != nullptr) {
+      // Insert the older session first.
+      session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[1]),
+                             *received_transport_params_,
+                             received_application_state_.get());
+    }
+    session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[0]),
+                           *received_transport_params_,
+                           received_application_state_.get());
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/tls_client_handshaker.h b/quiche/quic/core/tls_client_handshaker.h
new file mode 100644
index 0000000..2aa787c
--- /dev/null
+++ b/quiche/quic/core/tls_client_handshaker.h
@@ -0,0 +1,175 @@
+// Copyright (c) 2017 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_TLS_CLIENT_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/crypto/tls_client_connection.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/tls_handshaker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An implementation of QuicCryptoClientStream::HandshakerInterface which uses
+// TLS 1.3 for the crypto handshake protocol.
+class QUIC_EXPORT_PRIVATE TlsClientHandshaker
+    : public TlsHandshaker,
+      public QuicCryptoClientStream::HandshakerInterface,
+      public TlsClientConnection::Delegate {
+ public:
+  // |crypto_config| must outlive TlsClientHandshaker.
+  TlsClientHandshaker(const QuicServerId& server_id,
+                      QuicCryptoStream* stream,
+                      QuicSession* session,
+                      std::unique_ptr<ProofVerifyContext> verify_context,
+                      QuicCryptoClientConfig* crypto_config,
+                      QuicCryptoClientStream::ProofHandler* proof_handler,
+                      bool has_application_state);
+  TlsClientHandshaker(const TlsClientHandshaker&) = delete;
+  TlsClientHandshaker& operator=(const TlsClientHandshaker&) = delete;
+
+  ~TlsClientHandshaker() override;
+
+  // From QuicCryptoClientStream::HandshakerInterface
+  bool CryptoConnect() override;
+  int num_sent_client_hellos() const override;
+  bool IsResumption() const override;
+  bool EarlyDataAccepted() const override;
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool ReceivedInchoateReject() const override;
+  int num_scup_messages_received() const override;
+  std::string chlo_hash() const override;
+  bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
+                            size_t result_len, std::string* result) override;
+
+  // From QuicCryptoClientStream::HandshakerInterface and TlsHandshaker
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  HandshakeState GetHandshakeState() const override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  void OnOneRttPacketAcknowledged() override;
+  void OnHandshakePacketSent() override;
+  void OnConnectionClosed(QuicErrorCode error,
+                          ConnectionCloseSource source) override;
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  void SetWriteSecret(EncryptionLevel level,
+                      const SSL_CIPHER* cipher,
+                      const std::vector<uint8_t>& write_secret) override;
+
+  // Override to drop initial keys if trying to write ENCRYPTION_HANDSHAKE data.
+  void WriteMessage(EncryptionLevel level, absl::string_view data) override;
+
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> application_state) override;
+
+  void AllowEmptyAlpnForTests() { allow_empty_alpn_for_tests_ = true; }
+  void AllowInvalidSNIForTests() { allow_invalid_sni_for_tests_ = true; }
+
+  // Make the SSL object from BoringSSL publicly accessible.
+  using TlsHandshaker::ssl;
+
+ protected:
+  const TlsConnection* tls_connection() const override {
+    return &tls_connection_;
+  }
+
+  void FinishHandshake() override;
+  void OnEnterEarlyData() override;
+  void FillNegotiatedParams();
+  void ProcessPostHandshakeMessage() override;
+  bool ShouldCloseConnectionOnUnexpectedError(int ssl_error) override;
+  QuicAsyncStatus VerifyCertChain(
+      const std::vector<std::string>& certs,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override;
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) override;
+
+  // TlsClientConnection::Delegate implementation:
+  TlsConnection::Delegate* ConnectionDelegate() override { return this; }
+
+ private:
+  bool SetAlpn();
+  bool SetTransportParameters();
+  bool ProcessTransportParameters(std::string* error_details);
+  void HandleZeroRttReject();
+
+  // Called when server completes handshake (i.e., either handshake done is
+  // received or 1-RTT packet gets acknowledged).
+  void OnHandshakeConfirmed();
+
+  void InsertSession(bssl::UniquePtr<SSL_SESSION> session) override;
+
+  bool PrepareZeroRttConfig(QuicResumptionState* cached_state);
+
+  QuicSession* session() { return session_; }
+  QuicSession* session_;
+
+  QuicServerId server_id_;
+
+  // Objects used for verifying the server's certificate chain.
+  // |proof_verifier_| is owned by the caller of TlsHandshaker's constructor.
+  ProofVerifier* proof_verifier_;
+  std::unique_ptr<ProofVerifyContext> verify_context_;
+
+  // Unowned pointer to the proof handler which has the
+  // OnProofVerifyDetailsAvailable callback to use for notifying the result of
+  // certificate verification.
+  QuicCryptoClientStream::ProofHandler* proof_handler_;
+
+  // Used for session resumption. |session_cache_| is owned by the
+  // QuicCryptoClientConfig passed into TlsClientHandshaker's constructor.
+  SessionCache* session_cache_;
+
+  std::string user_agent_id_;
+
+  // Pre-shared key used during the handshake.
+  std::string pre_shared_key_;
+
+  HandshakeState state_ = HANDSHAKE_START;
+  bool encryption_established_ = false;
+  bool initial_keys_dropped_ = false;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      crypto_negotiated_params_;
+
+  bool allow_empty_alpn_for_tests_ = false;
+  bool allow_invalid_sni_for_tests_ = false;
+
+  const bool has_application_state_;
+  // Contains the state for performing a resumption, if one is attempted. This
+  // will always be non-null if a 0-RTT resumption is attempted.
+  std::unique_ptr<QuicResumptionState> cached_state_;
+
+  TlsClientConnection tls_connection_;
+
+  // If |has_application_state_|, stores the tls session tickets before
+  // application state is received. The latest one is put in the front.
+  bssl::UniquePtr<SSL_SESSION> cached_tls_sessions_[2] = {};
+
+  std::unique_ptr<TransportParameters> received_transport_params_ = nullptr;
+  std::unique_ptr<ApplicationState> received_application_state_ = nullptr;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
diff --git a/quiche/quic/core/tls_client_handshaker_test.cc b/quiche/quic/core/tls_client_handshaker_test.cc
new file mode 100644
index 0000000..e77b7af
--- /dev/null
+++ b/quiche/quic/core/tls_client_handshaker_test.cc
@@ -0,0 +1,712 @@
+// 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 <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+#include "quiche/quic/tools/fake_proof_verifier.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using testing::_;
+
+namespace quic {
+namespace test {
+namespace {
+
+constexpr char kServerHostname[] = "test.example.com";
+constexpr uint16_t kServerPort = 443;
+
+// TestProofVerifier wraps ProofVerifierForTesting, except for VerifyCertChain
+// which, if TestProofVerifier is active, always returns QUIC_PENDING. (If this
+// test proof verifier is not active, it delegates VerifyCertChain to the
+// ProofVerifierForTesting.) The pending VerifyCertChain operation can be
+// completed by calling InvokePendingCallback. This allows for testing
+// asynchronous VerifyCertChain operations.
+class TestProofVerifier : public ProofVerifier {
+ public:
+  TestProofVerifier()
+      : verifier_(crypto_test_utils::ProofVerifierForTesting()) {}
+
+  QuicAsyncStatus VerifyProof(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::string& server_config,
+      QuicTransportVersion quic_version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& certs,
+      const std::string& cert_sct,
+      const std::string& signature,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      std::unique_ptr<ProofVerifierCallback> callback) override {
+    return verifier_->VerifyProof(
+        hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
+        signature, context, error_details, details, std::move(callback));
+  }
+
+  QuicAsyncStatus VerifyCertChain(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::vector<std::string>& certs,
+      const std::string& ocsp_response,
+      const std::string& cert_sct,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override {
+    if (!active_) {
+      return verifier_->VerifyCertChain(
+          hostname, port, certs, ocsp_response, cert_sct, context,
+          error_details, details, out_alert, std::move(callback));
+    }
+    pending_ops_.push_back(std::make_unique<VerifyChainPendingOp>(
+        hostname, port, certs, ocsp_response, cert_sct, context, error_details,
+        details, out_alert, std::move(callback), verifier_.get()));
+    return QUIC_PENDING;
+  }
+
+  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
+    return nullptr;
+  }
+
+  void Activate() { active_ = true; }
+
+  size_t NumPendingCallbacks() const { return pending_ops_.size(); }
+
+  void InvokePendingCallback(size_t n) {
+    ASSERT_GT(NumPendingCallbacks(), n);
+    pending_ops_[n]->Run();
+    auto it = pending_ops_.begin() + n;
+    pending_ops_.erase(it);
+  }
+
+ private:
+  // Implementation of ProofVerifierCallback that fails if the callback is ever
+  // run.
+  class FailingProofVerifierCallback : public ProofVerifierCallback {
+   public:
+    void Run(bool /*ok*/,
+             const std::string& /*error_details*/,
+             std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
+      FAIL();
+    }
+  };
+
+  class VerifyChainPendingOp {
+   public:
+    VerifyChainPendingOp(const std::string& hostname,
+                         const uint16_t port,
+                         const std::vector<std::string>& certs,
+                         const std::string& ocsp_response,
+                         const std::string& cert_sct,
+                         const ProofVerifyContext* context,
+                         std::string* error_details,
+                         std::unique_ptr<ProofVerifyDetails>* details,
+                         uint8_t* out_alert,
+                         std::unique_ptr<ProofVerifierCallback> callback,
+                         ProofVerifier* delegate)
+        : hostname_(hostname),
+          port_(port),
+          certs_(certs),
+          ocsp_response_(ocsp_response),
+          cert_sct_(cert_sct),
+          context_(context),
+          error_details_(error_details),
+          details_(details),
+          out_alert_(out_alert),
+          callback_(std::move(callback)),
+          delegate_(delegate) {}
+
+    void Run() {
+      // TestProofVerifier depends on crypto_test_utils::ProofVerifierForTesting
+      // running synchronously. It passes a FailingProofVerifierCallback and
+      // runs the original callback after asserting that the verification ran
+      // synchronously.
+      QuicAsyncStatus status = delegate_->VerifyCertChain(
+          hostname_, port_, certs_, ocsp_response_, cert_sct_, context_,
+          error_details_, details_, out_alert_,
+          std::make_unique<FailingProofVerifierCallback>());
+      ASSERT_NE(status, QUIC_PENDING);
+      callback_->Run(status == QUIC_SUCCESS, *error_details_, details_);
+    }
+
+   private:
+    std::string hostname_;
+    const uint16_t port_;
+    std::vector<std::string> certs_;
+    std::string ocsp_response_;
+    std::string cert_sct_;
+    const ProofVerifyContext* context_;
+    std::string* error_details_;
+    std::unique_ptr<ProofVerifyDetails>* details_;
+    uint8_t* out_alert_;
+    std::unique_ptr<ProofVerifierCallback> callback_;
+    ProofVerifier* delegate_;
+  };
+
+  std::unique_ptr<ProofVerifier> verifier_;
+  bool active_ = false;
+  std::vector<std::unique_ptr<VerifyChainPendingOp>> pending_ops_;
+};
+
+class TlsClientHandshakerTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  TlsClientHandshakerTest()
+      : supported_versions_({GetParam()}),
+        server_id_(kServerHostname, kServerPort, false),
+        server_compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
+    crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+        std::make_unique<TestProofVerifier>(),
+        std::make_unique<test::SimpleSessionCache>());
+    server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
+    CreateConnection();
+  }
+
+  void CreateSession() {
+    session_ = std::make_unique<TestQuicSpdyClientSession>(
+        connection_, DefaultQuicConfig(), supported_versions_, server_id_,
+        crypto_config_.get());
+    EXPECT_CALL(*session_, GetAlpnsToOffer())
+        .WillRepeatedly(testing::Return(std::vector<std::string>(
+            {AlpnForVersion(connection_->version())})));
+  }
+
+  void CreateConnection() {
+    connection_ =
+        new PacketSavingConnection(&client_helper_, &alarm_factory_,
+                                   Perspective::IS_CLIENT, supported_versions_);
+    // Advance the time, because timers do not like uninitialized times.
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    CreateSession();
+  }
+
+  void CompleteCryptoHandshake() {
+    CompleteCryptoHandshakeWithServerALPN(
+        AlpnForVersion(connection_->version()));
+  }
+
+  void CompleteCryptoHandshakeWithServerALPN(const std::string& alpn) {
+    EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
+        .Times(testing::AnyNumber());
+    stream()->CryptoConnect();
+    QuicConfig config;
+    crypto_test_utils::HandshakeWithFakeServer(
+        &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+        connection_, stream(), alpn);
+  }
+
+  QuicCryptoClientStream* stream() {
+    return session_->GetMutableCryptoStream();
+  }
+
+  QuicCryptoServerStreamBase* server_stream() {
+    return server_session_->GetMutableCryptoStream();
+  }
+
+  // Initializes a fake server, and all its associated state, for testing.
+  void InitializeFakeServer() {
+    TestQuicSpdyServerSession* server_session = nullptr;
+    CreateServerSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        &server_helper_, &alarm_factory_, server_crypto_config_.get(),
+        &server_compressed_certs_cache_, &server_connection_, &server_session);
+    server_session_.reset(server_session);
+    std::string alpn = AlpnForVersion(connection_->version());
+    EXPECT_CALL(*server_session_, SelectAlpn(_))
+        .WillRepeatedly([alpn](const std::vector<absl::string_view>& alpns) {
+          return std::find(alpns.cbegin(), alpns.cend(), alpn);
+        });
+  }
+
+  MockQuicConnectionHelper server_helper_;
+  MockQuicConnectionHelper client_helper_;
+  MockAlarmFactory alarm_factory_;
+  PacketSavingConnection* connection_;
+  ParsedQuicVersionVector supported_versions_;
+  std::unique_ptr<TestQuicSpdyClientSession> session_;
+  QuicServerId server_id_;
+  CryptoHandshakeMessage message_;
+  std::unique_ptr<QuicCryptoClientConfig> crypto_config_;
+
+  // Server state.
+  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+  PacketSavingConnection* server_connection_;
+  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
+  QuicCompressedCertsCache server_compressed_certs_cache_;
+};
+
+INSTANTIATE_TEST_SUITE_P(TlsHandshakerTests,
+                         TlsClientHandshakerTest,
+                         ::testing::ValuesIn(AllSupportedVersionsWithTls()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(TlsClientHandshakerTest, NotInitiallyConnected) {
+  EXPECT_FALSE(stream()->encryption_established());
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsClientHandshakerTest, ConnectedAfterHandshake) {
+  CompleteCryptoHandshake();
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+}
+
+TEST_P(TlsClientHandshakerTest, ConnectionClosedOnTlsError) {
+  // Have client send ClientHello.
+  stream()->CryptoConnect();
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _, _));
+
+  // Send a zero-length ServerHello from server to client.
+  char bogus_handshake_message[] = {
+      // Handshake struct (RFC 8446 appendix B.3)
+      2,        // HandshakeType server_hello
+      0, 0, 0,  // uint24 length
+  };
+  stream()->crypto_message_parser()->ProcessInput(
+      absl::string_view(bogus_handshake_message,
+                        ABSL_ARRAYSIZE(bogus_handshake_message)),
+      ENCRYPTION_INITIAL);
+
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsClientHandshakerTest, ProofVerifyDetailsAvailableAfterHandshake) {
+  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_));
+  stream()->CryptoConnect();
+  QuicConfig config;
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+      connection_, stream(), AlpnForVersion(connection_->version()));
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsClientHandshakerTest, HandshakeWithAsyncProofVerifier) {
+  InitializeFakeServer();
+
+  // Enable TestProofVerifier to capture call to VerifyCertChain and run it
+  // asynchronously.
+  TestProofVerifier* proof_verifier =
+      static_cast<TestProofVerifier*>(crypto_config_->proof_verifier());
+  proof_verifier->Activate();
+
+  stream()->CryptoConnect();
+  // Exchange handshake messages.
+  std::pair<size_t, size_t> moved_message_counts =
+      crypto_test_utils::AdvanceHandshake(
+          connection_, stream(), 0, server_connection_, server_stream(), 0);
+
+  ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
+  proof_verifier->InvokePendingCallback(0);
+
+  // Exchange more handshake messages.
+  crypto_test_utils::AdvanceHandshake(
+      connection_, stream(), moved_message_counts.first, server_connection_,
+      server_stream(), moved_message_counts.second);
+
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsClientHandshakerTest, Resumption) {
+  // Disable 0-RTT on the server so that we're only testing 1-RTT resumption:
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection
+  CreateConnection();
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_TRUE(stream()->IsResumption());
+}
+
+TEST_P(TlsClientHandshakerTest, ResumptionRejection) {
+  // Disable 0-RTT on the server before the first connection so the client
+  // doesn't attempt a 0-RTT resumption, only a 1-RTT resumption.
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection, but disable resumption on the server.
+  SSL_CTX_set_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
+  CreateConnection();
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(),
+            ssl_early_data_unsupported_for_session);
+}
+
+TEST_P(TlsClientHandshakerTest, ZeroRttResumption) {
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection
+  CreateConnection();
+  // OnConfigNegotiated should be called twice - once when processing saved
+  // 0-RTT transport parameters, and then again when receiving transport
+  // parameters from the server.
+  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
+      .Times(testing::AnyNumber());
+  // Start the second handshake and confirm we have keys before receiving any
+  // messages from the server.
+  stream()->CryptoConnect();
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_NE(stream()->crypto_negotiated_params().cipher_suite, 0);
+  EXPECT_NE(stream()->crypto_negotiated_params().key_exchange_group, 0);
+  EXPECT_NE(stream()->crypto_negotiated_params().peer_signature_algorithm, 0);
+  // Finish the handshake with the server.
+  QuicConfig config;
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+      connection_, stream(), AlpnForVersion(connection_->version()));
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_TRUE(stream()->IsResumption());
+  EXPECT_TRUE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_accepted);
+}
+
+// Regression test for b/186438140.
+TEST_P(TlsClientHandshakerTest, ZeroRttResumptionWithAyncProofVerifier) {
+  // Finish establishing the first connection, so the second connection can
+  // resume.
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection.
+  CreateConnection();
+  InitializeFakeServer();
+  EXPECT_CALL(*session_, OnConfigNegotiated());
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
+      .Times(testing::AnyNumber());
+  // Enable TestProofVerifier to capture the call to VerifyCertChain and run it
+  // asynchronously.
+  TestProofVerifier* proof_verifier =
+      static_cast<TestProofVerifier*>(crypto_config_->proof_verifier());
+  proof_verifier->Activate();
+  // Start the second handshake.
+  stream()->CryptoConnect();
+
+  ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
+
+  // Advance the handshake with the server. Since cert verification has not
+  // finished yet, client cannot derive HANDSHAKE and 1-RTT keys.
+  crypto_test_utils::AdvanceHandshake(connection_, stream(), 0,
+                                      server_connection_, server_stream(), 0);
+
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+
+  // Finish cert verification after receiving packets from server.
+  proof_verifier->InvokePendingCallback(0);
+
+  QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
+  // Verify client has derived HANDSHAKE key.
+  EXPECT_NE(nullptr,
+            QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_HANDSHAKE));
+
+  // Ideally, we should also verify that the process_undecryptable_packets_alarm
+  // is set and processing the undecryptable packets can advance the handshake
+  // to completion. Unfortunately, the test facilities used in this test does
+  // not support queuing and processing undecryptable packets.
+}
+
+TEST_P(TlsClientHandshakerTest, ZeroRttRejection) {
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection, but disable 0-RTT on the server.
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  CreateConnection();
+
+  // OnConfigNegotiated should be called twice - once when processing saved
+  // 0-RTT transport parameters, and then again when receiving transport
+  // parameters from the server.
+  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
+
+  // 4 packets will be sent in this connection: initial handshake packet, 0-RTT
+  // packet containing SETTINGS, handshake packet upon 0-RTT rejection, 0-RTT
+  // packet retransmission.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
+  if (VersionUsesHttp3(session_->transport_version())) {
+    EXPECT_CALL(*connection_,
+                OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION));
+  }
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
+  if (VersionUsesHttp3(session_->transport_version())) {
+    // TODO(b/158027651): change transmission type to
+    // ALL_ZERO_RTT_RETRANSMISSION.
+    EXPECT_CALL(*connection_,
+                OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
+  }
+
+  CompleteCryptoHandshake();
+
+  QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
+  EXPECT_EQ(nullptr, QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_ZERO_RTT));
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_TRUE(stream()->IsResumption());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_peer_declined);
+}
+
+TEST_P(TlsClientHandshakerTest, ZeroRttAndResumptionRejection) {
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection, but disable resumption on the server.
+  SSL_CTX_set_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
+  CreateConnection();
+
+  // OnConfigNegotiated should be called twice - once when processing saved
+  // 0-RTT transport parameters, and then again when receiving transport
+  // parameters from the server.
+  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
+
+  // 4 packets will be sent in this connection: initial handshake packet, 0-RTT
+  // packet containing SETTINGS, handshake packet upon 0-RTT rejection, 0-RTT
+  // packet retransmission.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
+  if (VersionUsesHttp3(session_->transport_version())) {
+    EXPECT_CALL(*connection_,
+                OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION));
+  }
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
+  if (VersionUsesHttp3(session_->transport_version())) {
+    // TODO(b/158027651): change transmission type to
+    // ALL_ZERO_RTT_RETRANSMISSION.
+    EXPECT_CALL(*connection_,
+                OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
+  }
+
+  CompleteCryptoHandshake();
+
+  QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
+  EXPECT_EQ(nullptr, QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_ZERO_RTT));
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_session_not_resumed);
+}
+
+TEST_P(TlsClientHandshakerTest, ClientSendsNoSNI) {
+  // Reconfigure client to sent an empty server hostname. The crypto config also
+  // needs to be recreated to use a FakeProofVerifier since the server's cert
+  // won't match the empty hostname.
+  server_id_ = QuicServerId("", 443);
+  crypto_config_.reset(new QuicCryptoClientConfig(
+      std::make_unique<FakeProofVerifier>(), nullptr));
+  CreateConnection();
+  InitializeFakeServer();
+
+  stream()->CryptoConnect();
+  crypto_test_utils::CommunicateHandshakeMessages(
+      connection_, stream(), server_connection_, server_stream());
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+
+  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni, "");
+}
+
+TEST_P(TlsClientHandshakerTest, ClientSendingTooManyALPNs) {
+  std::string long_alpn(250, 'A');
+  EXPECT_CALL(*session_, GetAlpnsToOffer())
+      .WillOnce(testing::Return(std::vector<std::string>({
+          long_alpn + "1",
+          long_alpn + "2",
+          long_alpn + "3",
+          long_alpn + "4",
+          long_alpn + "5",
+          long_alpn + "6",
+          long_alpn + "7",
+          long_alpn + "8",
+      })));
+  EXPECT_QUIC_BUG(stream()->CryptoConnect(), "Failed to set ALPN");
+}
+
+TEST_P(TlsClientHandshakerTest, ServerRequiresCustomALPN) {
+  InitializeFakeServer();
+  const std::string kTestAlpn = "An ALPN That Client Did Not Offer";
+  EXPECT_CALL(*server_session_, SelectAlpn(_))
+      .WillOnce([kTestAlpn](const std::vector<absl::string_view>& alpns) {
+        return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
+      });
+
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED,
+                              static_cast<QuicIetfTransportErrorCodes>(
+                                  CRYPTO_ERROR_FIRST + 120),
+                              "TLS handshake failure (ENCRYPTION_INITIAL) 120: "
+                              "no application protocol",
+                              _));
+
+  stream()->CryptoConnect();
+  crypto_test_utils::AdvanceHandshake(connection_, stream(), 0,
+                                      server_connection_, server_stream(), 0);
+
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->encryption_established());
+}
+
+TEST_P(TlsClientHandshakerTest, ZeroRTTNotAttemptedOnALPNChange) {
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection
+  CreateConnection();
+  // Override the ALPN to send on the second connection.
+  const std::string kTestAlpn = "Test ALPN";
+  EXPECT_CALL(*session_, GetAlpnsToOffer())
+      .WillRepeatedly(testing::Return(std::vector<std::string>({kTestAlpn})));
+  // OnConfigNegotiated should only be called once: when transport parameters
+  // are received from the server.
+  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(1);
+
+  CompleteCryptoHandshakeWithServerALPN(kTestAlpn);
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_alpn_mismatch);
+}
+
+TEST_P(TlsClientHandshakerTest, InvalidSNI) {
+  // Test that a client will skip sending SNI if configured to send an invalid
+  // hostname. In this case, the inclusion of '!' is invalid.
+  server_id_ = QuicServerId("invalid!.example.com", 443);
+  crypto_config_.reset(new QuicCryptoClientConfig(
+      std::make_unique<FakeProofVerifier>(), nullptr));
+  CreateConnection();
+  InitializeFakeServer();
+
+  stream()->CryptoConnect();
+  crypto_test_utils::CommunicateHandshakeMessages(
+      connection_, stream(), server_connection_, server_stream());
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+
+  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni, "");
+}
+
+TEST_P(TlsClientHandshakerTest, BadTransportParams) {
+  if (!connection_->version().UsesHttp3()) {
+    return;
+  }
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  // Create a second connection
+  CreateConnection();
+
+  stream()->CryptoConnect();
+  auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            id_manager->max_outgoing_bidirectional_streams());
+  QuicConfig config;
+  config.SetMaxBidirectionalStreamsToSend(
+      config.GetMaxBidirectionalStreamsToSend() - 1);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  // Close connection will be called again in the handshaker, but this will be
+  // no-op as the connection is already closed.
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+      connection_, stream(), AlpnForVersion(connection_->version()));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/tls_handshaker.cc b/quiche/quic/core/tls_handshaker.cc
new file mode 100644
index 0000000..1a94775
--- /dev/null
+++ b/quiche/quic/core/tls_handshaker.cc
@@ -0,0 +1,372 @@
+// Copyright (c) 2017 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 "quiche/quic/core/tls_handshaker.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/crypto.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/tls_client_handshaker.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+
+namespace quic {
+
+#define ENDPOINT (SSL_is_server(ssl()) ? "TlsServer: " : "TlsClient: ")
+
+TlsHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
+    TlsHandshaker* parent)
+    : parent_(parent) {}
+
+TlsHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
+
+void TlsHandshaker::ProofVerifierCallbackImpl::Run(
+    bool ok, const std::string& /*error_details*/,
+    std::unique_ptr<ProofVerifyDetails>* details) {
+  if (parent_ == nullptr) {
+    return;
+  }
+
+  parent_->verify_details_ = std::move(*details);
+  parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid;
+  parent_->set_expected_ssl_error(SSL_ERROR_WANT_READ);
+  parent_->proof_verify_callback_ = nullptr;
+  if (parent_->verify_details_) {
+    parent_->OnProofVerifyDetailsAvailable(*parent_->verify_details_);
+  }
+  parent_->AdvanceHandshake();
+}
+
+void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() { parent_ = nullptr; }
+
+TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream, QuicSession* session)
+    : stream_(stream), handshaker_delegate_(session) {}
+
+TlsHandshaker::~TlsHandshaker() {
+  if (proof_verify_callback_) {
+    proof_verify_callback_->Cancel();
+  }
+}
+
+bool TlsHandshaker::ProcessInput(absl::string_view input,
+                                 EncryptionLevel level) {
+  if (parser_error_ != QUIC_NO_ERROR) {
+    return false;
+  }
+  // TODO(nharper): Call SSL_quic_read_level(ssl()) and check whether the
+  // encryption level BoringSSL expects matches the encryption level that we
+  // just received input at. If they mismatch, should ProcessInput return true
+  // or false? If data is for a future encryption level, it should be queued for
+  // later?
+  if (SSL_provide_quic_data(ssl(), TlsConnection::BoringEncryptionLevel(level),
+                            reinterpret_cast<const uint8_t*>(input.data()),
+                            input.size()) != 1) {
+    // SSL_provide_quic_data can fail for 3 reasons:
+    // - API misuse (calling it before SSL_set_custom_quic_method, which we
+    //   call in the TlsHandshaker c'tor)
+    // - Memory exhaustion when appending data to its buffer
+    // - Data provided at the wrong encryption level
+    //
+    // Of these, the only sensible error to handle is data provided at the wrong
+    // encryption level.
+    //
+    // Note: the error provided below has a good-sounding enum value, although
+    // it doesn't match the description as it's a QUIC Crypto specific error.
+    parser_error_ = QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+    parser_error_detail_ = "TLS stack failed to receive data";
+    return false;
+  }
+  AdvanceHandshake();
+  return true;
+}
+
+void TlsHandshaker::AdvanceHandshake() {
+  if (is_connection_closed_) {
+    return;
+  }
+  if (GetHandshakeState() >= HANDSHAKE_COMPLETE) {
+    ProcessPostHandshakeMessage();
+    return;
+  }
+
+  QUICHE_BUG_IF(
+      quic_tls_server_async_done_no_flusher,
+      SSL_is_server(ssl()) && !handshaker_delegate_->PacketFlusherAttached())
+      << "is_server:" << SSL_is_server(ssl());
+
+  QUIC_VLOG(1) << ENDPOINT << "Continuing handshake";
+  int rv = SSL_do_handshake(ssl());
+
+  // If SSL_do_handshake return success(1) and we are in early data, it is
+  // possible that we have provided ServerHello to BoringSSL but it hasn't been
+  // processed. Retry SSL_do_handshake once will advance the handshake more in
+  // that case. If there are no unprocessed ServerHello, the retry will return a
+  // non-positive number.
+  if (rv == 1 && SSL_in_early_data(ssl())) {
+    OnEnterEarlyData();
+    rv = SSL_do_handshake(ssl());
+    QUIC_VLOG(1) << ENDPOINT
+                 << "SSL_do_handshake returned when entering early data. After "
+                 << "retry, rv=" << rv
+                 << ", SSL_in_early_data=" << SSL_in_early_data(ssl());
+    // The retry should either
+    // - Return <= 0 if the handshake is still pending, likely still in early
+    //   data.
+    // - Return 1 if the handshake has _actually_ finished. i.e.
+    //   SSL_in_early_data should be false.
+    //
+    // In either case, it should not both return 1 and stay in early data.
+    if (rv == 1 && SSL_in_early_data(ssl()) && !is_connection_closed_) {
+      QUIC_BUG(quic_handshaker_stay_in_early_data)
+          << "The original and the retry of SSL_do_handshake both returned "
+             "success and in early data";
+      CloseConnection(QUIC_HANDSHAKE_FAILED,
+                      "TLS handshake failed: Still in early data after retry");
+      return;
+    }
+  }
+
+  if (rv == 1) {
+    FinishHandshake();
+    return;
+  }
+  int ssl_error = SSL_get_error(ssl(), rv);
+  if (ssl_error == expected_ssl_error_) {
+    return;
+  }
+  if (ShouldCloseConnectionOnUnexpectedError(ssl_error) &&
+      !is_connection_closed_) {
+    QUIC_VLOG(1) << "SSL_do_handshake failed; SSL_get_error returns "
+                 << ssl_error;
+    ERR_print_errors_fp(stderr);
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failed");
+  }
+}
+
+void TlsHandshaker::CloseConnection(QuicErrorCode error,
+                                    const std::string& reason_phrase) {
+  QUICHE_DCHECK(!reason_phrase.empty());
+  stream()->OnUnrecoverableError(error, reason_phrase);
+  is_connection_closed_ = true;
+}
+
+void TlsHandshaker::CloseConnection(QuicErrorCode error,
+                                    QuicIetfTransportErrorCodes ietf_error,
+                                    const std::string& reason_phrase) {
+  QUICHE_DCHECK(!reason_phrase.empty());
+  stream()->OnUnrecoverableError(error, ietf_error, reason_phrase);
+  is_connection_closed_ = true;
+}
+
+void TlsHandshaker::OnConnectionClosed(QuicErrorCode /*error*/,
+                                       ConnectionCloseSource /*source*/) {
+  is_connection_closed_ = true;
+}
+
+bool TlsHandshaker::ShouldCloseConnectionOnUnexpectedError(int /*ssl_error*/) {
+  return true;
+}
+
+size_t TlsHandshaker::BufferSizeLimitForLevel(EncryptionLevel level) const {
+  return SSL_quic_max_handshake_flight_len(
+      ssl(), TlsConnection::BoringEncryptionLevel(level));
+}
+
+ssl_early_data_reason_t TlsHandshaker::EarlyDataReason() const {
+  return SSL_get_early_data_reason(ssl());
+}
+
+const EVP_MD* TlsHandshaker::Prf(const SSL_CIPHER* cipher) {
+  return EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher));
+}
+
+enum ssl_verify_result_t TlsHandshaker::VerifyCert(uint8_t* out_alert) {
+  if (verify_result_ != ssl_verify_retry ||
+      expected_ssl_error() == SSL_ERROR_WANT_CERTIFICATE_VERIFY) {
+    enum ssl_verify_result_t result = verify_result_;
+    verify_result_ = ssl_verify_retry;
+    *out_alert = cert_verify_tls_alert_;
+    return result;
+  }
+  const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl());
+  if (cert_chain == nullptr) {
+    *out_alert = SSL_AD_INTERNAL_ERROR;
+    return ssl_verify_invalid;
+  }
+  // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies.
+  std::vector<std::string> certs;
+  for (CRYPTO_BUFFER* cert : cert_chain) {
+    certs.push_back(
+        std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
+                    CRYPTO_BUFFER_len(cert)));
+  }
+  QUIC_DVLOG(1) << "VerifyCert: peer cert_chain length: " << certs.size();
+
+  ProofVerifierCallbackImpl* proof_verify_callback =
+      new ProofVerifierCallbackImpl(this);
+
+  cert_verify_tls_alert_ = *out_alert;
+  QuicAsyncStatus verify_result = VerifyCertChain(
+      certs, &cert_verify_error_details_, &verify_details_,
+      &cert_verify_tls_alert_,
+      std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
+  switch (verify_result) {
+    case QUIC_SUCCESS:
+      if (verify_details_) {
+        OnProofVerifyDetailsAvailable(*verify_details_);
+      }
+      return ssl_verify_ok;
+    case QUIC_PENDING:
+      proof_verify_callback_ = proof_verify_callback;
+      set_expected_ssl_error(SSL_ERROR_WANT_CERTIFICATE_VERIFY);
+      return ssl_verify_retry;
+    case QUIC_FAILURE:
+    default:
+      *out_alert = cert_verify_tls_alert_;
+      QUIC_LOG(INFO) << "Cert chain verification failed: "
+                     << cert_verify_error_details_;
+      return ssl_verify_invalid;
+  }
+}
+
+void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
+                                   const SSL_CIPHER* cipher,
+                                   const std::vector<uint8_t>& write_secret) {
+  QUIC_DVLOG(1) << ENDPOINT << "SetWriteSecret level=" << level;
+  std::unique_ptr<QuicEncrypter> encrypter =
+      QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
+  const EVP_MD* prf = Prf(cipher);
+  CryptoUtils::SetKeyAndIV(prf, write_secret,
+                           handshaker_delegate_->parsed_version(),
+                           encrypter.get());
+  std::vector<uint8_t> header_protection_key =
+      CryptoUtils::GenerateHeaderProtectionKey(
+          prf, write_secret, handshaker_delegate_->parsed_version(),
+          encrypter->GetKeySize());
+  encrypter->SetHeaderProtectionKey(
+      absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
+                        header_protection_key.size()));
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    QUICHE_DCHECK(latest_write_secret_.empty());
+    latest_write_secret_ = write_secret;
+    one_rtt_write_header_protection_key_ = header_protection_key;
+  }
+  handshaker_delegate_->OnNewEncryptionKeyAvailable(level,
+                                                    std::move(encrypter));
+}
+
+bool TlsHandshaker::SetReadSecret(EncryptionLevel level,
+                                  const SSL_CIPHER* cipher,
+                                  const std::vector<uint8_t>& read_secret) {
+  QUIC_DVLOG(1) << ENDPOINT << "SetReadSecret level=" << level;
+  std::unique_ptr<QuicDecrypter> decrypter =
+      QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
+  const EVP_MD* prf = Prf(cipher);
+  CryptoUtils::SetKeyAndIV(prf, read_secret,
+                           handshaker_delegate_->parsed_version(),
+                           decrypter.get());
+  std::vector<uint8_t> header_protection_key =
+      CryptoUtils::GenerateHeaderProtectionKey(
+          prf, read_secret, handshaker_delegate_->parsed_version(),
+          decrypter->GetKeySize());
+  decrypter->SetHeaderProtectionKey(
+      absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
+                        header_protection_key.size()));
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    QUICHE_DCHECK(latest_read_secret_.empty());
+    latest_read_secret_ = read_secret;
+    one_rtt_read_header_protection_key_ = header_protection_key;
+  }
+  return handshaker_delegate_->OnNewDecryptionKeyAvailable(
+      level, std::move(decrypter),
+      /*set_alternative_decrypter=*/false,
+      /*latch_once_used=*/false);
+}
+
+std::unique_ptr<QuicDecrypter>
+TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  if (latest_read_secret_.empty() || latest_write_secret_.empty() ||
+      one_rtt_read_header_protection_key_.empty() ||
+      one_rtt_write_header_protection_key_.empty()) {
+    std::string error_details = "1-RTT secret(s) not set yet.";
+    QUIC_BUG(quic_bug_10312_1) << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details);
+    return nullptr;
+  }
+  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
+  const EVP_MD* prf = Prf(cipher);
+  latest_read_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
+      prf, handshaker_delegate_->parsed_version(), latest_read_secret_);
+  latest_write_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
+      prf, handshaker_delegate_->parsed_version(), latest_write_secret_);
+
+  std::unique_ptr<QuicDecrypter> decrypter =
+      QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
+  CryptoUtils::SetKeyAndIV(prf, latest_read_secret_,
+                           handshaker_delegate_->parsed_version(),
+                           decrypter.get());
+  decrypter->SetHeaderProtectionKey(absl::string_view(
+      reinterpret_cast<char*>(one_rtt_read_header_protection_key_.data()),
+      one_rtt_read_header_protection_key_.size()));
+
+  return decrypter;
+}
+
+std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateCurrentOneRttEncrypter() {
+  if (latest_write_secret_.empty() ||
+      one_rtt_write_header_protection_key_.empty()) {
+    std::string error_details = "1-RTT write secret not set yet.";
+    QUIC_BUG(quic_bug_10312_2) << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details);
+    return nullptr;
+  }
+  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
+  std::unique_ptr<QuicEncrypter> encrypter =
+      QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
+  CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_,
+                           handshaker_delegate_->parsed_version(),
+                           encrypter.get());
+  encrypter->SetHeaderProtectionKey(absl::string_view(
+      reinterpret_cast<char*>(one_rtt_write_header_protection_key_.data()),
+      one_rtt_write_header_protection_key_.size()));
+  return encrypter;
+}
+
+bool TlsHandshaker::ExportKeyingMaterialForLabel(absl::string_view label,
+                                                 absl::string_view context,
+                                                 size_t result_len,
+                                                 std::string* result) {
+  if (result == nullptr) {
+    return false;
+  }
+  result->resize(result_len);
+  return SSL_export_keying_material(
+             ssl(), reinterpret_cast<uint8_t*>(&*result->begin()), result_len,
+             label.data(), label.size(),
+             reinterpret_cast<const uint8_t*>(context.data()), context.size(),
+             !context.empty()) == 1;
+}
+
+void TlsHandshaker::WriteMessage(EncryptionLevel level,
+                                 absl::string_view data) {
+  stream_->WriteCryptoData(level, data);
+}
+
+void TlsHandshaker::FlushFlight() {}
+
+void TlsHandshaker::SendAlert(EncryptionLevel level, uint8_t desc) {
+  std::string error_details = absl::StrCat(
+      "TLS handshake failure (", EncryptionLevelToString(level), ") ",
+      static_cast<int>(desc), ": ", SSL_alert_desc_string_long(desc));
+  QUIC_DLOG(ERROR) << error_details;
+  CloseConnection(
+      TlsAlertToQuicErrorCode(desc),
+      static_cast<QuicIetfTransportErrorCodes>(CRYPTO_ERROR_FIRST + desc),
+      error_details);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/tls_handshaker.h b/quiche/quic/core/tls_handshaker.h
new file mode 100644
index 0000000..bef4020
--- /dev/null
+++ b/quiche/quic/core/tls_handshaker.h
@@ -0,0 +1,225 @@
+// Copyright (c) 2017 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_TLS_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_message_parser.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/tls_connection.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class QuicCryptoStream;
+
+// Base class for TlsClientHandshaker and TlsServerHandshaker. TlsHandshaker
+// provides functionality common to both the client and server, such as moving
+// messages between the TLS stack and the QUIC crypto stream, and handling
+// derivation of secrets.
+class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate,
+                                          public CryptoMessageParser {
+ public:
+  // TlsHandshaker does not take ownership of any of its arguments; they must
+  // outlive the TlsHandshaker.
+  TlsHandshaker(QuicCryptoStream* stream, QuicSession* session);
+  TlsHandshaker(const TlsHandshaker&) = delete;
+  TlsHandshaker& operator=(const TlsHandshaker&) = delete;
+
+  ~TlsHandshaker() override;
+
+  // From CryptoMessageParser
+  bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
+  size_t InputBytesRemaining() const override { return 0; }
+  QuicErrorCode error() const override { return parser_error_; }
+  const std::string& error_detail() const override {
+    return parser_error_detail_;
+  }
+
+  // The following methods provide implementations to subclasses of
+  // TlsHandshaker which use them to implement methods of QuicCryptoStream.
+  CryptoMessageParser* crypto_message_parser() { return this; }
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
+  ssl_early_data_reason_t EarlyDataReason() const;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter();
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter();
+  virtual HandshakeState GetHandshakeState() const = 0;
+  bool ExportKeyingMaterialForLabel(absl::string_view label,
+                                    absl::string_view context,
+                                    size_t result_len, std::string* result);
+
+ protected:
+  // Called when a new message is received on the crypto stream and is available
+  // for the TLS stack to read.
+  virtual void AdvanceHandshake();
+
+  void CloseConnection(QuicErrorCode error, const std::string& reason_phrase);
+  // Closes the connection, specifying the wire error code |ietf_error|
+  // explicitly.
+  void CloseConnection(QuicErrorCode error,
+                       QuicIetfTransportErrorCodes ietf_error,
+                       const std::string& reason_phrase);
+
+  void OnConnectionClosed(QuicErrorCode error, ConnectionCloseSource source);
+
+  bool is_connection_closed() const { return is_connection_closed_; }
+
+  // Called when |SSL_do_handshake| returns 1, indicating that the handshake has
+  // finished. Note that a handshake only finishes once, entering early data
+  // does not count.
+  virtual void FinishHandshake() = 0;
+
+  // Called when |SSL_do_handshake| returns 1 and the connection is in early
+  // data. In that case, |AdvanceHandshake| will call |OnEnterEarlyData| and
+  // retry |SSL_do_handshake| once.
+  virtual void OnEnterEarlyData() {
+    // By default, do nothing but check the preconditions.
+    QUICHE_DCHECK(SSL_in_early_data(ssl()));
+  }
+
+  // Called when a handshake message is received after the handshake is
+  // complete.
+  virtual void ProcessPostHandshakeMessage() = 0;
+
+  // Called when an unexpected error code is received from |SSL_get_error|. If a
+  // subclass can expect more than just a single error (as provided by
+  // |set_expected_ssl_error|), it can override this method to handle that case.
+  virtual bool ShouldCloseConnectionOnUnexpectedError(int ssl_error);
+
+  void set_expected_ssl_error(int ssl_error) {
+    expected_ssl_error_ = ssl_error;
+  }
+  int expected_ssl_error() const { return expected_ssl_error_; }
+
+  // Called to verify a cert chain. This can be implemented as a simple wrapper
+  // around ProofVerifier, which optionally gathers additional arguments to pass
+  // into their VerifyCertChain method. This class retains a non-owning pointer
+  // to |callback|; the callback must live until this function returns
+  // QUIC_SUCCESS or QUIC_FAILURE, or until the callback is run.
+  //
+  // If certificate verification fails, |*out_alert| may be set to a TLS alert
+  // that will be sent when closing the connection; it defaults to
+  // certificate_unknown. Implementations of VerifyCertChain may retain the
+  // |out_alert| pointer while performing an async operation.
+  virtual QuicAsyncStatus VerifyCertChain(
+      const std::vector<std::string>& certs,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) = 0;
+  // Called when certificate verification is completed.
+  virtual void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) = 0;
+
+  // Returns the PRF used by the cipher suite negotiated in the TLS handshake.
+  const EVP_MD* Prf(const SSL_CIPHER* cipher);
+
+  virtual const TlsConnection* tls_connection() const = 0;
+
+  SSL* ssl() const { return tls_connection()->ssl(); }
+
+  QuicCryptoStream* stream() { return stream_; }
+  HandshakerDelegateInterface* handshaker_delegate() {
+    return handshaker_delegate_;
+  }
+
+  enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) override;
+
+  // SetWriteSecret provides the encryption secret used to encrypt messages at
+  // encryption level |level|. The secret provided here is the one from the TLS
+  // 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
+  // traffic secrets and application traffic secrets. The provided write secret
+  // must be used with the provided cipher suite |cipher|.
+  void SetWriteSecret(EncryptionLevel level,
+                      const SSL_CIPHER* cipher,
+                      const std::vector<uint8_t>& write_secret) override;
+
+  // SetReadSecret is similar to SetWriteSecret, except that it is used for
+  // decrypting messages. SetReadSecret at a particular level is always called
+  // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT, where
+  // the EncryptionLevel for SetWriteSecret is ENCRYPTION_FORWARD_SECURE.
+  bool SetReadSecret(EncryptionLevel level,
+                     const SSL_CIPHER* cipher,
+                     const std::vector<uint8_t>& read_secret) override;
+
+  // WriteMessage is called when there is |data| from the TLS stack ready for
+  // the QUIC stack to write in a crypto frame. The data must be transmitted at
+  // encryption level |level|.
+  void WriteMessage(EncryptionLevel level, absl::string_view data) override;
+
+  // FlushFlight is called to signal that the current flight of
+  // messages have all been written (via calls to WriteMessage) and can be
+  // flushed to the underlying transport.
+  void FlushFlight() override;
+
+  // SendAlert causes this TlsHandshaker to close the QUIC connection with an
+  // error code corresponding to the TLS alert description |desc|.
+  void SendAlert(EncryptionLevel level, uint8_t desc) override;
+
+  // Informational callback from BoringSSL. Subclasses can override it to do
+  // logging, tracing, etc.
+  // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
+  void InfoCallback(int /*type*/, int /*value*/) override {}
+
+ private:
+  // ProofVerifierCallbackImpl handles the result of an asynchronous certificate
+  // verification operation.
+  class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl
+      : public ProofVerifierCallback {
+   public:
+    explicit ProofVerifierCallbackImpl(TlsHandshaker* parent);
+    ~ProofVerifierCallbackImpl() override;
+
+    // ProofVerifierCallback interface.
+    void Run(bool ok,
+             const std::string& error_details,
+             std::unique_ptr<ProofVerifyDetails>* details) override;
+
+    // If called, Cancel causes the pending callback to be a no-op.
+    void Cancel();
+
+   private:
+    // Non-owning pointer to the TlsHandshaker responsible for this callback.
+    // |parent_| must be valid for the life of this callback or until |Cancel|
+    // is called.
+    TlsHandshaker* parent_;
+  };
+
+  // ProofVerifierCallback used for async certificate verification. Ownership of
+  // this object is transferred to |VerifyCertChain|;
+  ProofVerifierCallbackImpl* proof_verify_callback_ = nullptr;
+  std::unique_ptr<ProofVerifyDetails> verify_details_;
+  enum ssl_verify_result_t verify_result_ = ssl_verify_retry;
+  uint8_t cert_verify_tls_alert_ = SSL_AD_CERTIFICATE_UNKNOWN;
+  std::string cert_verify_error_details_;
+
+  int expected_ssl_error_ = SSL_ERROR_WANT_READ;
+  bool is_connection_closed_ = false;
+
+  QuicCryptoStream* stream_;
+  HandshakerDelegateInterface* handshaker_delegate_;
+
+  QuicErrorCode parser_error_ = QUIC_NO_ERROR;
+  std::string parser_error_detail_;
+
+  // The most recently derived 1-RTT read and write secrets, which are updated
+  // on each key update.
+  std::vector<uint8_t> latest_read_secret_;
+  std::vector<uint8_t> latest_write_secret_;
+  // 1-RTT header protection keys, which are not changed during key update.
+  std::vector<uint8_t> one_rtt_read_header_protection_key_;
+  std::vector<uint8_t> one_rtt_write_header_protection_key_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
diff --git a/quiche/quic/core/tls_server_handshaker.cc b/quiche/quic/core/tls_server_handshaker.cc
new file mode 100644
index 0000000..7d14507
--- /dev/null
+++ b/quiche/quic/core/tls_server_handshaker.cc
@@ -0,0 +1,1173 @@
+// Copyright (c) 2017 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 "quiche/quic/core/tls_server_handshaker.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+
+#define RECORD_LATENCY_IN_US(stat_name, latency, comment)                   \
+  do {                                                                      \
+    const int64_t latency_in_us = (latency).ToMicroseconds();               \
+    QUIC_DVLOG(1) << "Recording " stat_name ": " << latency_in_us;          \
+    QUIC_SERVER_HISTOGRAM_COUNTS(stat_name, latency_in_us, 1, 10000000, 50, \
+                                 comment);                                  \
+  } while (0)
+
+namespace quic {
+
+namespace {
+
+// Default port for HTTP/3.
+uint16_t kDefaultPort = 443;
+
+}  // namespace
+
+TlsServerHandshaker::DefaultProofSourceHandle::DefaultProofSourceHandle(
+    TlsServerHandshaker* handshaker,
+    ProofSource* proof_source)
+    : handshaker_(handshaker), proof_source_(proof_source) {}
+
+TlsServerHandshaker::DefaultProofSourceHandle::~DefaultProofSourceHandle() {
+  CloseHandle();
+}
+
+void TlsServerHandshaker::DefaultProofSourceHandle::CloseHandle() {
+  QUIC_DVLOG(1) << "CloseHandle. is_signature_pending="
+                << (signature_callback_ != nullptr);
+  if (signature_callback_) {
+    signature_callback_->Cancel();
+    signature_callback_ = nullptr;
+  }
+}
+
+QuicAsyncStatus
+TlsServerHandshaker::DefaultProofSourceHandle::SelectCertificate(
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    absl::string_view /*ssl_capabilities*/,
+    const std::string& hostname,
+    absl::string_view /*client_hello*/,
+    const std::string& /*alpn*/,
+    absl::optional<std::string> /*alps*/,
+    const std::vector<uint8_t>& /*quic_transport_params*/,
+    const absl::optional<std::vector<uint8_t>>& /*early_data_context*/,
+    const QuicSSLConfig& /*ssl_config*/) {
+  if (!handshaker_ || !proof_source_) {
+    QUIC_BUG(quic_bug_10341_1)
+        << "SelectCertificate called on a detached handle";
+    return QUIC_FAILURE;
+  }
+
+  bool cert_matched_sni;
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
+      proof_source_->GetCertChain(server_address, client_address, hostname,
+                                  &cert_matched_sni);
+
+  handshaker_->OnSelectCertificateDone(
+      /*ok=*/true, /*is_sync=*/true, chain.get(),
+      /*handshake_hints=*/absl::string_view(),
+      /*ticket_encryption_key=*/absl::string_view(), cert_matched_sni,
+      QuicDelayedSSLConfig());
+  if (!handshaker_->select_cert_status().has_value()) {
+    QUIC_BUG(quic_bug_12423_1)
+        << "select_cert_status() has no value after a synchronous select cert";
+    // Return success to continue the handshake.
+    return QUIC_SUCCESS;
+  }
+  return handshaker_->select_cert_status().value();
+}
+
+QuicAsyncStatus TlsServerHandshaker::DefaultProofSourceHandle::ComputeSignature(
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    const std::string& hostname,
+    uint16_t signature_algorithm,
+    absl::string_view in,
+    size_t max_signature_size) {
+  if (!handshaker_ || !proof_source_) {
+    QUIC_BUG(quic_bug_10341_2)
+        << "ComputeSignature called on a detached handle";
+    return QUIC_FAILURE;
+  }
+
+  if (signature_callback_) {
+    QUIC_BUG(quic_bug_10341_3) << "ComputeSignature called while pending";
+    return QUIC_FAILURE;
+  }
+
+  signature_callback_ = new DefaultSignatureCallback(this);
+  proof_source_->ComputeTlsSignature(
+      server_address, client_address, hostname, signature_algorithm, in,
+      std::unique_ptr<DefaultSignatureCallback>(signature_callback_));
+
+  if (signature_callback_) {
+    QUIC_DVLOG(1) << "ComputeTlsSignature is pending";
+    signature_callback_->set_is_sync(false);
+    return QUIC_PENDING;
+  }
+
+  bool success = handshaker_->HasValidSignature(max_signature_size);
+  QUIC_DVLOG(1) << "ComputeTlsSignature completed synchronously. success:"
+                << success;
+  // OnComputeSignatureDone should have been called by signature_callback_->Run.
+  return success ? QUIC_SUCCESS : QUIC_FAILURE;
+}
+
+TlsServerHandshaker::DecryptCallback::DecryptCallback(
+    TlsServerHandshaker* handshaker)
+    : handshaker_(handshaker) {}
+
+void TlsServerHandshaker::DecryptCallback::Run(std::vector<uint8_t> plaintext) {
+  if (handshaker_ == nullptr) {
+    // The callback was cancelled before we could run.
+    return;
+  }
+
+  TlsServerHandshaker* handshaker = handshaker_;
+  handshaker_ = nullptr;
+
+  handshaker->decrypted_session_ticket_ = std::move(plaintext);
+  const bool is_async =
+      (handshaker->expected_ssl_error() == SSL_ERROR_PENDING_TICKET);
+
+  absl::optional<QuicConnectionContextSwitcher> context_switcher;
+
+  if (is_async) {
+    context_switcher.emplace(handshaker->connection_context());
+  }
+  QUIC_TRACESTRING(
+      absl::StrCat("TLS ticket decryption done. len(decrypted_ticket):",
+                   handshaker->decrypted_session_ticket_.size()));
+
+  // DecryptCallback::Run could be called synchronously. When that happens, we
+  // are currently in the middle of a call to AdvanceHandshake.
+  // (AdvanceHandshake called SSL_do_handshake, which through some layers
+  // called SessionTicketOpen, which called TicketCrypter::Decrypt, which
+  // synchronously called this function.) In that case, the handshake will
+  // continue to be processed when this function returns.
+  //
+  // When this callback is called asynchronously (i.e. the ticket decryption
+  // is pending), TlsServerHandshaker is not actively processing handshake
+  // messages. We need to have it resume processing handshake messages by
+  // calling AdvanceHandshake.
+  if (is_async) {
+    handshaker->AdvanceHandshakeFromCallback();
+  }
+
+  handshaker->ticket_decryption_callback_ = nullptr;
+}
+
+void TlsServerHandshaker::DecryptCallback::Cancel() {
+  QUICHE_DCHECK(handshaker_);
+  handshaker_ = nullptr;
+}
+
+TlsServerHandshaker::TlsServerHandshaker(
+    QuicSession* session, const QuicCryptoServerConfig* crypto_config)
+    : TlsHandshaker(this, session),
+      QuicCryptoServerStreamBase(session),
+      proof_source_(crypto_config->proof_source()),
+      pre_shared_key_(crypto_config->pre_shared_key()),
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
+      tls_connection_(crypto_config->ssl_ctx(), this, session->GetSSLConfig()),
+      crypto_config_(crypto_config) {
+  QUIC_DVLOG(1) << "TlsServerHandshaker: support_client_cert:"
+                << session->support_client_cert()
+                << ", client_cert_mode initial value: " << client_cert_mode();
+
+  QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3,
+                   session->connection()->version().handshake_protocol);
+
+  // Configure the SSL to be a server.
+  SSL_set_accept_state(ssl());
+
+  // Make sure we use the right TLS extension codepoint.
+  int use_legacy_extension = 0;
+  if (session->version().UsesLegacyTlsExtension()) {
+    use_legacy_extension = 1;
+  }
+  SSL_set_quic_use_legacy_codepoint(ssl(), use_legacy_extension);
+
+  if (session->connection()->context()->tracer) {
+    tls_connection_.EnableInfoCallback();
+  }
+
+  if (no_select_cert_if_disconnected_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_no_select_cert_if_disconnected, 1, 2);
+  }
+}
+
+TlsServerHandshaker::~TlsServerHandshaker() { CancelOutstandingCallbacks(); }
+
+void TlsServerHandshaker::CancelOutstandingCallbacks() {
+  if (proof_source_handle_) {
+    proof_source_handle_->CloseHandle();
+  }
+  if (ticket_decryption_callback_) {
+    ticket_decryption_callback_->Cancel();
+    ticket_decryption_callback_ = nullptr;
+  }
+}
+
+void TlsServerHandshaker::InfoCallback(int type, int value) {
+  QuicConnectionTracer* tracer =
+      session()->connection()->context()->tracer.get();
+
+  if (tracer == nullptr) {
+    return;
+  }
+
+  if (type & SSL_CB_LOOP) {
+    tracer->PrintString(
+        absl::StrCat("SSL:ACCEPT_LOOP:", SSL_state_string_long(ssl())));
+  } else if (type & SSL_CB_ALERT) {
+    const char* prefix =
+        (type & SSL_CB_READ) ? "SSL:READ_ALERT:" : "SSL:WRITE_ALERT:";
+    tracer->PrintString(absl::StrCat(prefix, SSL_alert_type_string_long(value),
+                                     ":", SSL_alert_desc_string_long(value)));
+  } else if (type & SSL_CB_EXIT) {
+    const char* prefix =
+        (value == 1) ? "SSL:ACCEPT_EXIT_OK:" : "SSL:ACCEPT_EXIT_FAIL:";
+    tracer->PrintString(absl::StrCat(prefix, SSL_state_string_long(ssl())));
+  } else if (type & SSL_CB_HANDSHAKE_START) {
+    tracer->PrintString(
+        absl::StrCat("SSL:HANDSHAKE_START:", SSL_state_string_long(ssl())));
+  } else if (type & SSL_CB_HANDSHAKE_DONE) {
+    tracer->PrintString(
+        absl::StrCat("SSL:HANDSHAKE_DONE:", SSL_state_string_long(ssl())));
+  } else {
+    QUIC_DLOG(INFO) << "Unknown event type " << type << ": "
+                    << SSL_state_string_long(ssl());
+    tracer->PrintString(
+        absl::StrCat("SSL:unknown:", value, ":", SSL_state_string_long(ssl())));
+  }
+}
+
+std::unique_ptr<ProofSourceHandle>
+TlsServerHandshaker::MaybeCreateProofSourceHandle() {
+  return std::make_unique<DefaultProofSourceHandle>(this, proof_source_);
+}
+
+bool TlsServerHandshaker::GetBase64SHA256ClientChannelID(
+    std::string* /*output*/) const {
+  // Channel ID is not supported when TLS is used in QUIC.
+  return false;
+}
+
+void TlsServerHandshaker::SendServerConfigUpdate(
+    const CachedNetworkParameters* /*cached_network_params*/) {
+  // SCUP messages aren't supported when using the TLS handshake.
+}
+
+bool TlsServerHandshaker::DisableResumption() {
+  if (!can_disable_resumption_ || !session()->connection()->connected()) {
+    return false;
+  }
+  tls_connection_.DisableTicketSupport();
+  return true;
+}
+
+bool TlsServerHandshaker::IsZeroRtt() const {
+  return SSL_early_data_accepted(ssl());
+}
+
+bool TlsServerHandshaker::IsResumption() const {
+  return SSL_session_reused(ssl());
+}
+
+bool TlsServerHandshaker::ResumptionAttempted() const {
+  return ticket_received_;
+}
+
+bool TlsServerHandshaker::EarlyDataAttempted() const {
+  QUIC_BUG_IF(quic_tls_early_data_attempted_too_early,
+              !select_cert_status_.has_value())
+      << "EarlyDataAttempted must be called after EarlySelectCertCallback is "
+         "started";
+  return early_data_attempted_;
+}
+
+int TlsServerHandshaker::NumServerConfigUpdateMessagesSent() const {
+  // SCUP messages aren't supported when using the TLS handshake.
+  return 0;
+}
+
+const CachedNetworkParameters*
+TlsServerHandshaker::PreviousCachedNetworkParams() const {
+  return last_received_cached_network_params_.get();
+}
+
+void TlsServerHandshaker::SetPreviousCachedNetworkParams(
+    CachedNetworkParameters cached_network_params) {
+  last_received_cached_network_params_ =
+      std::make_unique<CachedNetworkParameters>(cached_network_params);
+}
+
+void TlsServerHandshaker::OnPacketDecrypted(EncryptionLevel level) {
+  if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) {
+    state_ = HANDSHAKE_PROCESSED;
+    handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+    handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
+  }
+}
+
+void TlsServerHandshaker::OnHandshakeDoneReceived() {
+  QUICHE_DCHECK(false);
+}
+
+void TlsServerHandshaker::OnNewTokenReceived(absl::string_view /*token*/) {
+  QUICHE_DCHECK(false);
+}
+
+std::string TlsServerHandshaker::GetAddressToken(
+    const CachedNetworkParameters* cached_network_params) const {
+  SourceAddressTokens empty_previous_tokens;
+  const QuicConnection* connection = session()->connection();
+  return crypto_config_->NewSourceAddressToken(
+      crypto_config_->source_address_token_boxer(), empty_previous_tokens,
+      connection->effective_peer_address().host(),
+      connection->random_generator(), connection->clock()->WallNow(),
+      cached_network_params);
+}
+
+bool TlsServerHandshaker::ValidateAddressToken(absl::string_view token) const {
+  SourceAddressTokens tokens;
+  HandshakeFailureReason reason = crypto_config_->ParseSourceAddressToken(
+      crypto_config_->source_address_token_boxer(), token, tokens);
+  if (reason != HANDSHAKE_OK) {
+    QUIC_DLOG(WARNING) << "Failed to parse source address token: "
+                       << CryptoUtils::HandshakeFailureReasonToString(reason);
+    return false;
+  }
+  auto cached_network_params = std::make_unique<CachedNetworkParameters>();
+  reason = crypto_config_->ValidateSourceAddressTokens(
+      tokens, session()->connection()->effective_peer_address().host(),
+      session()->connection()->clock()->WallNow(), cached_network_params.get());
+  if (reason != HANDSHAKE_OK) {
+    QUIC_DLOG(WARNING) << "Failed to validate source address token: "
+                       << CryptoUtils::HandshakeFailureReasonToString(reason);
+    return false;
+  }
+
+  last_received_cached_network_params_ = std::move(cached_network_params);
+  return true;
+}
+
+bool TlsServerHandshaker::ShouldSendExpectCTHeader() const {
+  return false;
+}
+
+bool TlsServerHandshaker::DidCertMatchSni() const { return cert_matched_sni_; }
+
+const ProofSource::Details* TlsServerHandshaker::ProofSourceDetails() const {
+  return proof_source_details_.get();
+}
+
+bool TlsServerHandshaker::ExportKeyingMaterial(absl::string_view label,
+                                               absl::string_view context,
+                                               size_t result_len,
+                                               std::string* result) {
+  return ExportKeyingMaterialForLabel(label, context, result_len, result);
+}
+
+void TlsServerHandshaker::OnConnectionClosed(QuicErrorCode error,
+                                             ConnectionCloseSource source) {
+  TlsHandshaker::OnConnectionClosed(error, source);
+}
+
+ssl_early_data_reason_t TlsServerHandshaker::EarlyDataReason() const {
+  return TlsHandshaker::EarlyDataReason();
+}
+
+bool TlsServerHandshaker::encryption_established() const {
+  return encryption_established_;
+}
+
+bool TlsServerHandshaker::one_rtt_keys_available() const {
+  return state_ == HANDSHAKE_CONFIRMED;
+}
+
+const QuicCryptoNegotiatedParameters&
+TlsServerHandshaker::crypto_negotiated_params() const {
+  return *crypto_negotiated_params_;
+}
+
+CryptoMessageParser* TlsServerHandshaker::crypto_message_parser() {
+  return TlsHandshaker::crypto_message_parser();
+}
+
+HandshakeState TlsServerHandshaker::GetHandshakeState() const {
+  return state_;
+}
+
+void TlsServerHandshaker::SetServerApplicationStateForResumption(
+    std::unique_ptr<ApplicationState> state) {
+  application_state_ = std::move(state);
+}
+
+size_t TlsServerHandshaker::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return TlsHandshaker::BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+TlsServerHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter>
+TlsServerHandshaker::CreateCurrentOneRttEncrypter() {
+  return TlsHandshaker::CreateCurrentOneRttEncrypter();
+}
+
+void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {}
+
+void TlsServerHandshaker::AdvanceHandshakeFromCallback() {
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+
+  AdvanceHandshake();
+  if (!is_connection_closed()) {
+    handshaker_delegate()->OnHandshakeCallbackDone();
+  }
+}
+
+bool TlsServerHandshaker::ProcessTransportParameters(
+    const SSL_CLIENT_HELLO* client_hello,
+    std::string* error_details) {
+  TransportParameters client_params;
+  const uint8_t* client_params_bytes;
+  size_t params_bytes_len;
+
+  // Make sure we use the right TLS extension codepoint.
+  uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters_standard;
+  if (session()->version().UsesLegacyTlsExtension()) {
+    extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy;
+  }
+  // When using early select cert callback, SSL_get_peer_quic_transport_params
+  // can not be used to retrieve the client's transport parameters, but we can
+  // use SSL_early_callback_ctx_extension_get to do that.
+  if (!SSL_early_callback_ctx_extension_get(client_hello, extension_type,
+                                            &client_params_bytes,
+                                            &params_bytes_len)) {
+    params_bytes_len = 0;
+  }
+
+  if (params_bytes_len == 0) {
+    *error_details = "Client's transport parameters are missing";
+    return false;
+  }
+  std::string parse_error_details;
+  if (!ParseTransportParameters(session()->connection()->version(),
+                                Perspective::IS_CLIENT, client_params_bytes,
+                                params_bytes_len, &client_params,
+                                &parse_error_details)) {
+    QUICHE_DCHECK(!parse_error_details.empty());
+    *error_details =
+        "Unable to parse client's transport parameters: " + parse_error_details;
+    return false;
+  }
+
+  // Notify QuicConnectionDebugVisitor.
+  session()->connection()->OnTransportParametersReceived(client_params);
+
+  if (client_params.legacy_version_information.has_value() &&
+      CryptoUtils::ValidateClientHelloVersion(
+          client_params.legacy_version_information.value().version,
+          session()->connection()->version(), session()->supported_versions(),
+          error_details) != QUIC_NO_ERROR) {
+    return false;
+  }
+
+  if (client_params.version_information.has_value() &&
+      !CryptoUtils::ValidateChosenVersion(
+          client_params.version_information.value().chosen_version,
+          session()->version(), error_details)) {
+    QUICHE_DCHECK(!error_details->empty());
+    return false;
+  }
+
+  if (handshaker_delegate()->ProcessTransportParameters(
+          client_params, /* is_resumption = */ false, error_details) !=
+      QUIC_NO_ERROR) {
+    return false;
+  }
+
+  ProcessAdditionalTransportParameters(client_params);
+
+  return true;
+}
+
+TlsServerHandshaker::SetTransportParametersResult
+TlsServerHandshaker::SetTransportParameters() {
+  SetTransportParametersResult result;
+  QUICHE_DCHECK(!result.success);
+
+  TransportParameters server_params;
+  server_params.perspective = Perspective::IS_SERVER;
+  server_params.legacy_version_information =
+      TransportParameters::LegacyVersionInformation();
+  server_params.legacy_version_information.value().supported_versions =
+      CreateQuicVersionLabelVector(session()->supported_versions());
+  server_params.legacy_version_information.value().version =
+      CreateQuicVersionLabel(session()->connection()->version());
+  server_params.version_information = TransportParameters::VersionInformation();
+  server_params.version_information.value().chosen_version =
+      CreateQuicVersionLabel(session()->version());
+  server_params.version_information.value().other_versions =
+      CreateQuicVersionLabelVector(session()->supported_versions());
+
+  if (!handshaker_delegate()->FillTransportParameters(&server_params)) {
+    return result;
+  }
+
+  // Notify QuicConnectionDebugVisitor.
+  session()->connection()->OnTransportParametersSent(server_params);
+
+  {  // Ensure |server_params_bytes| is not accessed out of the scope.
+    std::vector<uint8_t> server_params_bytes;
+    if (!SerializeTransportParameters(session()->connection()->version(),
+                                      server_params, &server_params_bytes) ||
+        SSL_set_quic_transport_params(ssl(), server_params_bytes.data(),
+                                      server_params_bytes.size()) != 1) {
+      return result;
+    }
+    result.quic_transport_params = std::move(server_params_bytes);
+  }
+
+  if (application_state_) {
+    std::vector<uint8_t> early_data_context;
+    if (!SerializeTransportParametersForTicket(
+            server_params, *application_state_, &early_data_context)) {
+      QUIC_BUG(quic_bug_10341_4)
+          << "Failed to serialize Transport Parameters for ticket.";
+      result.early_data_context = std::vector<uint8_t>();
+      return result;
+    }
+    SSL_set_quic_early_data_context(ssl(), early_data_context.data(),
+                                    early_data_context.size());
+    result.early_data_context = std::move(early_data_context);
+    application_state_.reset(nullptr);
+  }
+  result.success = true;
+  return result;
+}
+
+void TlsServerHandshaker::SetWriteSecret(
+    EncryptionLevel level,
+    const SSL_CIPHER* cipher,
+    const std::vector<uint8_t>& write_secret) {
+  if (is_connection_closed()) {
+    return;
+  }
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    encryption_established_ = true;
+    // Fill crypto_negotiated_params_:
+    const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
+    if (cipher) {
+      crypto_negotiated_params_->cipher_suite =
+          SSL_CIPHER_get_protocol_id(cipher);
+    }
+    crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
+  }
+  TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
+}
+
+std::string TlsServerHandshaker::GetAcceptChValueForHostname(
+    const std::string& /*hostname*/) const {
+  return {};
+}
+
+void TlsServerHandshaker::FinishHandshake() {
+  QUICHE_DCHECK(!SSL_in_early_data(ssl()));
+
+  if (!valid_alpn_received_) {
+    QUIC_DLOG(ERROR)
+        << "Server: handshake finished without receiving a known ALPN";
+    // TODO(b/130164908) this should send no_application_protocol
+    // instead of QUIC_HANDSHAKE_FAILED.
+    CloseConnection(QUIC_HANDSHAKE_FAILED,
+                    "Server did not receive a known ALPN");
+    return;
+  }
+
+  ssl_early_data_reason_t reason_code = EarlyDataReason();
+  QUIC_DLOG(INFO) << "Server: handshake finished. Early data reason "
+                  << reason_code << " ("
+                  << CryptoUtils::EarlyDataReasonToString(reason_code) << ")";
+  state_ = HANDSHAKE_CONFIRMED;
+
+  handshaker_delegate()->OnTlsHandshakeComplete();
+  handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
+  handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
+  // ENCRYPTION_ZERO_RTT decryption key is not discarded here as "Servers MAY
+  // temporarily retain 0-RTT keys to allow decrypting reordered packets
+  // without requiring their contents to be retransmitted with 1-RTT keys."
+  // It is expected that QuicConnection will discard the key at an
+  // appropriate time.
+}
+
+QuicAsyncStatus TlsServerHandshaker::VerifyCertChain(
+    const std::vector<std::string>& /*certs*/,
+    std::string* /*error_details*/,
+    std::unique_ptr<ProofVerifyDetails>* /*details*/,
+    uint8_t* /*out_alert*/,
+    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
+  if (!session()->support_client_cert()) {
+    QUIC_BUG(quic_bug_10341_5)
+        << "Client certificates are not yet supported on the server";
+    return QUIC_FAILURE;
+  }
+
+  QUIC_RESTART_FLAG_COUNT_N(quic_tls_server_support_client_cert, 2, 2);
+  QUIC_DVLOG(1) << "VerifyCertChain returning success";
+
+  // No real verification here. A subclass can override this function to verify
+  // the client cert if needed.
+  return QUIC_SUCCESS;
+}
+
+void TlsServerHandshaker::OnProofVerifyDetailsAvailable(
+    const ProofVerifyDetails& /*verify_details*/) {}
+
+ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign(
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out,
+    uint16_t sig_alg,
+    absl::string_view in) {
+  QUICHE_DCHECK_EQ(expected_ssl_error(), SSL_ERROR_WANT_READ);
+
+  QuicAsyncStatus status = proof_source_handle_->ComputeSignature(
+      session()->connection()->self_address(),
+      session()->connection()->peer_address(), crypto_negotiated_params_->sni,
+      sig_alg, in, max_out);
+  if (status == QUIC_PENDING) {
+    set_expected_ssl_error(SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
+    if (async_op_timer_.has_value()) {
+      QUIC_CODE_COUNT(
+          quic_tls_server_computing_signature_while_another_op_pending);
+    }
+    async_op_timer_ = QuicTimeAccumulator();
+    async_op_timer_->Start(now());
+  }
+  return PrivateKeyComplete(out, out_len, max_out);
+}
+
+ssl_private_key_result_t TlsServerHandshaker::PrivateKeyComplete(
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out) {
+  if (expected_ssl_error() == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
+    return ssl_private_key_retry;
+  }
+
+  const bool success = HasValidSignature(max_out);
+  QuicConnectionStats::TlsServerOperationStats compute_signature_stats;
+  compute_signature_stats.success = success;
+  if (async_op_timer_.has_value()) {
+    async_op_timer_->Stop(now());
+    compute_signature_stats.async_latency =
+        async_op_timer_->GetTotalElapsedTime();
+    async_op_timer_.reset();
+    RECORD_LATENCY_IN_US("tls_server_async_compute_signature_latency_us",
+                         compute_signature_stats.async_latency,
+                         "Async compute signature latency in microseconds");
+  }
+  connection_stats().tls_server_compute_signature_stats =
+      std::move(compute_signature_stats);
+
+  if (!success) {
+    return ssl_private_key_failure;
+  }
+  *out_len = cert_verify_sig_.size();
+  memcpy(out, cert_verify_sig_.data(), *out_len);
+  cert_verify_sig_.clear();
+  cert_verify_sig_.shrink_to_fit();
+  return ssl_private_key_success;
+}
+
+void TlsServerHandshaker::OnComputeSignatureDone(
+    bool ok,
+    bool is_sync,
+    std::string signature,
+    std::unique_ptr<ProofSource::Details> details) {
+  QUIC_DVLOG(1) << "OnComputeSignatureDone. ok:" << ok
+                << ", is_sync:" << is_sync
+                << ", len(signature):" << signature.size();
+  absl::optional<QuicConnectionContextSwitcher> context_switcher;
+
+  if (!is_sync) {
+    context_switcher.emplace(connection_context());
+  }
+
+  QUIC_TRACESTRING(absl::StrCat("TLS compute signature done. ok:", ok,
+                                ", len(signature):", signature.size()));
+
+  if (ok) {
+    cert_verify_sig_ = std::move(signature);
+    proof_source_details_ = std::move(details);
+  }
+  const int last_expected_ssl_error = expected_ssl_error();
+  set_expected_ssl_error(SSL_ERROR_WANT_READ);
+  if (!is_sync) {
+    QUICHE_DCHECK_EQ(last_expected_ssl_error,
+                     SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
+    AdvanceHandshakeFromCallback();
+  }
+}
+
+bool TlsServerHandshaker::HasValidSignature(size_t max_signature_size) const {
+  return !cert_verify_sig_.empty() &&
+         cert_verify_sig_.size() <= max_signature_size;
+}
+
+size_t TlsServerHandshaker::SessionTicketMaxOverhead() {
+  QUICHE_DCHECK(proof_source_->GetTicketCrypter());
+  return proof_source_->GetTicketCrypter()->MaxOverhead();
+}
+
+int TlsServerHandshaker::SessionTicketSeal(uint8_t* out,
+                                           size_t* out_len,
+                                           size_t max_out_len,
+                                           absl::string_view in) {
+  QUICHE_DCHECK(proof_source_->GetTicketCrypter());
+  std::vector<uint8_t> ticket =
+      proof_source_->GetTicketCrypter()->Encrypt(in, ticket_encryption_key_);
+  if (max_out_len < ticket.size()) {
+    QUIC_BUG(quic_bug_12423_2)
+        << "TicketCrypter returned " << ticket.size()
+        << " bytes of ciphertext, which is larger than its max overhead of "
+        << max_out_len;
+    return 0;  // failure
+  }
+  *out_len = ticket.size();
+  memcpy(out, ticket.data(), ticket.size());
+  QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_sealed);
+  return 1;  // success
+}
+
+ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen(
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out_len,
+    absl::string_view in) {
+  QUICHE_DCHECK(proof_source_->GetTicketCrypter());
+
+  if (ignore_ticket_open_) {
+    // SetIgnoreTicketOpen has been called. Typically this means the caller is
+    // using handshake hints and expect the hints to contain ticket decryption
+    // results.
+    QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_1);
+    return ssl_ticket_aead_ignore_ticket;
+  }
+
+  if (!ticket_decryption_callback_) {
+    ticket_decryption_callback_ = new DecryptCallback(this);
+    proof_source_->GetTicketCrypter()->Decrypt(
+        in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
+
+    // Decrypt can run the callback synchronously. In that case, the callback
+    // will clear the ticket_decryption_callback_ pointer, and instead of
+    // returning ssl_ticket_aead_retry, we should continue processing to
+    // return the decrypted ticket.
+    //
+    // If the callback is not run synchronously, return ssl_ticket_aead_retry
+    // and when the callback is complete this function will be run again to
+    // return the result.
+    if (ticket_decryption_callback_) {
+      QUICHE_DCHECK(!ticket_decryption_callback_->IsDone());
+      set_expected_ssl_error(SSL_ERROR_PENDING_TICKET);
+      if (async_op_timer_.has_value()) {
+        QUIC_CODE_COUNT(
+            quic_tls_server_decrypting_ticket_while_another_op_pending);
+      }
+      async_op_timer_ = QuicTimeAccumulator();
+      async_op_timer_->Start(now());
+    }
+  }
+
+  // If the async ticket decryption is pending, either started by this
+  // SessionTicketOpen call or one that happened earlier, return
+  // ssl_ticket_aead_retry.
+  if (ticket_decryption_callback_ && !ticket_decryption_callback_->IsDone()) {
+    return ssl_ticket_aead_retry;
+  }
+
+  ssl_ticket_aead_result_t result =
+      FinalizeSessionTicketOpen(out, out_len, max_out_len);
+
+  QuicConnectionStats::TlsServerOperationStats decrypt_ticket_stats;
+  decrypt_ticket_stats.success = (result == ssl_ticket_aead_success);
+  if (async_op_timer_.has_value()) {
+    async_op_timer_->Stop(now());
+    decrypt_ticket_stats.async_latency = async_op_timer_->GetTotalElapsedTime();
+    async_op_timer_.reset();
+    RECORD_LATENCY_IN_US("tls_server_async_decrypt_ticket_latency_us",
+                         decrypt_ticket_stats.async_latency,
+                         "Async decrypt ticket latency in microseconds");
+  }
+  connection_stats().tls_server_decrypt_ticket_stats =
+      std::move(decrypt_ticket_stats);
+
+  return result;
+}
+
+ssl_ticket_aead_result_t TlsServerHandshaker::FinalizeSessionTicketOpen(
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out_len) {
+  ticket_decryption_callback_ = nullptr;
+  set_expected_ssl_error(SSL_ERROR_WANT_READ);
+  if (decrypted_session_ticket_.empty()) {
+    QUIC_DLOG(ERROR) << "Session ticket decryption failed; ignoring ticket";
+    // Ticket decryption failed. Ignore the ticket.
+    QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_2);
+    return ssl_ticket_aead_ignore_ticket;
+  }
+  if (max_out_len < decrypted_session_ticket_.size()) {
+    return ssl_ticket_aead_error;
+  }
+  memcpy(out, decrypted_session_ticket_.data(),
+         decrypted_session_ticket_.size());
+  *out_len = decrypted_session_ticket_.size();
+
+  QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_opened);
+  return ssl_ticket_aead_success;
+}
+
+ssl_select_cert_result_t TlsServerHandshaker::EarlySelectCertCallback(
+    const SSL_CLIENT_HELLO* client_hello) {
+  // EarlySelectCertCallback can be called twice from BoringSSL: If the first
+  // call returns ssl_select_cert_retry, when cert selection completes,
+  // SSL_do_handshake will call it again.
+
+  if (select_cert_status_.has_value()) {
+    // This is the second call, return the result directly.
+    QUIC_DVLOG(1) << "EarlySelectCertCallback called to continue handshake, "
+                     "returning directly. success:"
+                  << (select_cert_status_.value() == QUIC_SUCCESS);
+    return (select_cert_status_.value() == QUIC_SUCCESS)
+               ? ssl_select_cert_success
+               : ssl_select_cert_error;
+  }
+
+  // This is the first call.
+  select_cert_status_ = QUIC_PENDING;
+  proof_source_handle_ = MaybeCreateProofSourceHandle();
+
+  if (!pre_shared_key_.empty()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    QUIC_BUG(quic_bug_10341_6)
+        << "QUIC server pre-shared keys not yet supported with TLS";
+    return ssl_select_cert_error;
+  }
+
+  {
+    const uint8_t* unused_extension_bytes;
+    size_t unused_extension_len;
+    ticket_received_ = SSL_early_callback_ctx_extension_get(
+        client_hello, TLSEXT_TYPE_pre_shared_key, &unused_extension_bytes,
+        &unused_extension_len);
+
+    early_data_attempted_ = SSL_early_callback_ctx_extension_get(
+        client_hello, TLSEXT_TYPE_early_data, &unused_extension_bytes,
+        &unused_extension_len);
+  }
+
+  // This callback is called very early by Boring SSL, most of the SSL_get_foo
+  // function do not work at this point, but SSL_get_servername does.
+  const char* hostname = SSL_get_servername(ssl(), TLSEXT_NAMETYPE_host_name);
+  if (hostname) {
+    crypto_negotiated_params_->sni =
+        QuicHostnameUtils::NormalizeHostname(hostname);
+    if (!ValidateHostname(hostname)) {
+      return ssl_select_cert_error;
+    }
+    if (hostname != crypto_negotiated_params_->sni) {
+      QUIC_CODE_COUNT(quic_tls_server_hostname_diff);
+      QUIC_LOG_EVERY_N_SEC(WARNING, 300)
+          << "Raw and normalized hostnames differ, but both are valid SNIs. "
+             "raw hostname:"
+          << hostname << ", normalized:" << crypto_negotiated_params_->sni;
+    } else {
+      QUIC_CODE_COUNT(quic_tls_server_hostname_same);
+    }
+  } else {
+    QUIC_LOG(INFO) << "No hostname indicated in SNI";
+  }
+
+  std::string error_details;
+  if (!ProcessTransportParameters(client_hello, &error_details)) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
+    return ssl_select_cert_error;
+  }
+  OverrideQuicConfigDefaults(session()->config());
+  session()->OnConfigNegotiated();
+
+  auto set_transport_params_result = SetTransportParameters();
+  if (!set_transport_params_result.success) {
+    QUIC_LOG(ERROR) << "Failed to set transport parameters";
+    return ssl_select_cert_error;
+  }
+
+  bssl::UniquePtr<uint8_t> ssl_capabilities;
+  size_t ssl_capabilities_len = 0;
+  absl::string_view ssl_capabilities_view;
+
+  absl::optional<std::string> alps;
+
+  if (CryptoUtils::GetSSLCapabilities(ssl(), &ssl_capabilities,
+                                      &ssl_capabilities_len)) {
+    ssl_capabilities_view =
+        absl::string_view(reinterpret_cast<const char*>(ssl_capabilities.get()),
+                          ssl_capabilities_len);
+  }
+
+  // Enable ALPS for the session's ALPN.
+  SetApplicationSettingsResult alps_result =
+      SetApplicationSettings(AlpnForVersion(session()->version()));
+  if (!alps_result.success) {
+    return ssl_select_cert_error;
+  }
+  alps =
+      alps_result.alps_length > 0
+          ? std::string(alps_result.alps_buffer.get(), alps_result.alps_length)
+          : std::string();
+
+  if (no_select_cert_if_disconnected_ &&
+      !session()->connection()->connected()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_no_select_cert_if_disconnected, 2, 2);
+    select_cert_status_ = QUIC_FAILURE;
+    return ssl_select_cert_error;
+  }
+
+  can_disable_resumption_ = false;
+  const QuicAsyncStatus status = proof_source_handle_->SelectCertificate(
+      session()->connection()->self_address().Normalized(),
+      session()->connection()->peer_address().Normalized(),
+      ssl_capabilities_view, crypto_negotiated_params_->sni,
+      absl::string_view(
+          reinterpret_cast<const char*>(client_hello->client_hello),
+          client_hello->client_hello_len),
+      AlpnForVersion(session()->version()), std::move(alps),
+      set_transport_params_result.quic_transport_params,
+      set_transport_params_result.early_data_context,
+      tls_connection_.ssl_config());
+
+  QUICHE_DCHECK_EQ(status, select_cert_status().value());
+
+  if (status == QUIC_PENDING) {
+    set_expected_ssl_error(SSL_ERROR_PENDING_CERTIFICATE);
+    if (async_op_timer_.has_value()) {
+      QUIC_CODE_COUNT(quic_tls_server_selecting_cert_while_another_op_pending);
+    }
+    async_op_timer_ = QuicTimeAccumulator();
+    async_op_timer_->Start(now());
+    return ssl_select_cert_retry;
+  }
+
+  if (status == QUIC_FAILURE) {
+    return ssl_select_cert_error;
+  }
+
+  return ssl_select_cert_success;
+}
+
+void TlsServerHandshaker::OnSelectCertificateDone(
+    bool ok, bool is_sync, const ProofSource::Chain* chain,
+    absl::string_view handshake_hints, absl::string_view ticket_encryption_key,
+    bool cert_matched_sni, QuicDelayedSSLConfig delayed_ssl_config) {
+  QUIC_DVLOG(1) << "OnSelectCertificateDone. ok:" << ok
+                << ", is_sync:" << is_sync
+                << ", len(handshake_hints):" << handshake_hints.size()
+                << ", len(ticket_encryption_key):"
+                << ticket_encryption_key.size();
+  absl::optional<QuicConnectionContextSwitcher> context_switcher;
+  if (!is_sync) {
+    context_switcher.emplace(connection_context());
+  }
+
+  QUIC_TRACESTRING(absl::StrCat(
+      "TLS select certificate done: ok:", ok,
+      ", certs_found:", (chain != nullptr && !chain->certs.empty()),
+      ", len(handshake_hints):", handshake_hints.size(),
+      ", len(ticket_encryption_key):", ticket_encryption_key.size()));
+
+  ticket_encryption_key_ = std::string(ticket_encryption_key);
+  select_cert_status_ = QUIC_FAILURE;
+  cert_matched_sni_ = cert_matched_sni;
+  if (session()->support_client_cert()) {
+    if (delayed_ssl_config.client_cert_mode.has_value()) {
+      tls_connection_.SetClientCertMode(*delayed_ssl_config.client_cert_mode);
+      QUIC_DVLOG(1) << "client_cert_mode after cert selection: "
+                    << client_cert_mode();
+    }
+  }
+  if (ok) {
+    if (chain && !chain->certs.empty()) {
+      tls_connection_.SetCertChain(chain->ToCryptoBuffers().value);
+      if (!handshake_hints.empty() &&
+          !SSL_set_handshake_hints(
+              ssl(), reinterpret_cast<const uint8_t*>(handshake_hints.data()),
+              handshake_hints.size())) {
+        // If |SSL_set_handshake_hints| fails, the ssl() object will remain
+        // intact, it is as if we didn't call it. The handshaker will
+        // continue to compute signature/decrypt ticket as normal.
+        QUIC_CODE_COUNT(quic_tls_server_set_handshake_hints_failed);
+        QUIC_DVLOG(1) << "SSL_set_handshake_hints failed";
+      }
+      select_cert_status_ = QUIC_SUCCESS;
+    } else {
+      QUIC_DLOG(ERROR) << "No certs provided for host '"
+                       << crypto_negotiated_params_->sni << "', server_address:"
+                       << session()->connection()->self_address()
+                       << ", client_address:"
+                       << session()->connection()->peer_address();
+    }
+  }
+
+  QuicConnectionStats::TlsServerOperationStats select_cert_stats;
+  select_cert_stats.success = (select_cert_status_ == QUIC_SUCCESS);
+  QUICHE_DCHECK_NE(is_sync, async_op_timer_.has_value());
+  if (async_op_timer_.has_value()) {
+    async_op_timer_->Stop(now());
+    select_cert_stats.async_latency = async_op_timer_->GetTotalElapsedTime();
+    async_op_timer_.reset();
+    RECORD_LATENCY_IN_US("tls_server_async_select_cert_latency_us",
+                         select_cert_stats.async_latency,
+                         "Async select cert latency in microseconds");
+  }
+  connection_stats().tls_server_select_cert_stats =
+      std::move(select_cert_stats);
+
+  const int last_expected_ssl_error = expected_ssl_error();
+  set_expected_ssl_error(SSL_ERROR_WANT_READ);
+  if (!is_sync) {
+    QUICHE_DCHECK_EQ(last_expected_ssl_error, SSL_ERROR_PENDING_CERTIFICATE);
+    AdvanceHandshakeFromCallback();
+  }
+}
+
+bool TlsServerHandshaker::WillNotCallComputeSignature() const {
+  return SSL_can_release_private_key(ssl());
+}
+
+bool TlsServerHandshaker::ValidateHostname(const std::string& hostname) const {
+  if (!QuicHostnameUtils::IsValidSNI(hostname)) {
+    // TODO(b/151676147): Include this error string in the CONNECTION_CLOSE
+    // frame.
+    QUIC_DLOG(ERROR) << "Invalid SNI provided: \"" << hostname << "\"";
+    return false;
+  }
+  return true;
+}
+
+int TlsServerHandshaker::TlsExtServernameCallback(int* /*out_alert*/) {
+  // SSL_TLSEXT_ERR_OK causes the server_name extension to be acked in
+  // ServerHello.
+  return SSL_TLSEXT_ERR_OK;
+}
+
+int TlsServerHandshaker::SelectAlpn(const uint8_t** out,
+                                    uint8_t* out_len,
+                                    const uint8_t* in,
+                                    unsigned in_len) {
+  // |in| contains a sequence of 1-byte-length-prefixed values.
+  *out_len = 0;
+  *out = nullptr;
+  if (in_len == 0) {
+    QUIC_DLOG(ERROR) << "No ALPN provided by client";
+    return SSL_TLSEXT_ERR_NOACK;
+  }
+
+  CBS all_alpns;
+  CBS_init(&all_alpns, in, in_len);
+
+  std::vector<absl::string_view> alpns;
+  while (CBS_len(&all_alpns) > 0) {
+    CBS alpn;
+    if (!CBS_get_u8_length_prefixed(&all_alpns, &alpn)) {
+      QUIC_DLOG(ERROR) << "Failed to parse ALPN length";
+      return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    const size_t alpn_length = CBS_len(&alpn);
+    if (alpn_length == 0) {
+      QUIC_DLOG(ERROR) << "Received invalid zero-length ALPN";
+      return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    alpns.emplace_back(reinterpret_cast<const char*>(CBS_data(&alpn)),
+                       alpn_length);
+  }
+
+  // TODO(wub): Remove QuicSession::SelectAlpn. QuicSessions should know the
+  // ALPN on construction.
+  auto selected_alpn = session()->SelectAlpn(alpns);
+  if (selected_alpn == alpns.end()) {
+    QUIC_DLOG(ERROR) << "No known ALPN provided by client";
+    return SSL_TLSEXT_ERR_NOACK;
+  }
+
+  session()->OnAlpnSelected(*selected_alpn);
+  valid_alpn_received_ = true;
+  *out_len = selected_alpn->size();
+  *out = reinterpret_cast<const uint8_t*>(selected_alpn->data());
+  return SSL_TLSEXT_ERR_OK;
+}
+
+TlsServerHandshaker::SetApplicationSettingsResult
+TlsServerHandshaker::SetApplicationSettings(absl::string_view alpn) {
+  TlsServerHandshaker::SetApplicationSettingsResult result;
+  const uint8_t* alps_data = nullptr;
+
+  const std::string& hostname = crypto_negotiated_params_->sni;
+  std::string accept_ch_value = GetAcceptChValueForHostname(hostname);
+  std::string origin = absl::StrCat("https://", hostname);
+  uint16_t port = session()->self_address().port();
+  if (port != kDefaultPort) {
+    // This should be rare in production, but useful for test servers.
+    QUIC_CODE_COUNT(quic_server_alps_non_default_port);
+    absl::StrAppend(&origin, ":", port);
+  }
+
+  if (!accept_ch_value.empty()) {
+    AcceptChFrame frame{{{std::move(origin), std::move(accept_ch_value)}}};
+    result.alps_length =
+        HttpEncoder::SerializeAcceptChFrame(frame, &result.alps_buffer);
+    alps_data = reinterpret_cast<const uint8_t*>(result.alps_buffer.get());
+  }
+
+  if (SSL_add_application_settings(
+          ssl(), reinterpret_cast<const uint8_t*>(alpn.data()), alpn.size(),
+          alps_data, result.alps_length) != 1) {
+    QUIC_DLOG(ERROR) << "Failed to enable ALPS";
+    result.success = false;
+  } else {
+    result.success = true;
+  }
+  return result;
+}
+
+SSL* TlsServerHandshaker::GetSsl() const { return ssl(); }
+
+}  // namespace quic
diff --git a/quiche/quic/core/tls_server_handshaker.h b/quiche/quic/core/tls_server_handshaker.h
new file mode 100644
index 0000000..b7df310
--- /dev/null
+++ b/quiche/quic/core/tls_server_handshaker.h
@@ -0,0 +1,392 @@
+// Copyright (c) 2017 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_TLS_SERVER_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/tls_server_connection.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_time_accumulator.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/tls_handshaker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+// An implementation of QuicCryptoServerStreamBase which uses
+// TLS 1.3 for the crypto handshake protocol.
+class QUIC_EXPORT_PRIVATE TlsServerHandshaker
+    : public TlsHandshaker,
+      public TlsServerConnection::Delegate,
+      public ProofSourceHandleCallback,
+      public QuicCryptoServerStreamBase {
+ public:
+  // |crypto_config| must outlive TlsServerHandshaker.
+  TlsServerHandshaker(QuicSession* session,
+                      const QuicCryptoServerConfig* crypto_config);
+  TlsServerHandshaker(const TlsServerHandshaker&) = delete;
+  TlsServerHandshaker& operator=(const TlsServerHandshaker&) = delete;
+
+  ~TlsServerHandshaker() override;
+
+  // From QuicCryptoServerStreamBase
+  void CancelOutstandingCallbacks() override;
+  bool GetBase64SHA256ClientChannelID(std::string* output) const override;
+  void SendServerConfigUpdate(
+      const CachedNetworkParameters* cached_network_params) override;
+  bool DisableResumption() override;
+  bool IsZeroRtt() const override;
+  bool IsResumption() const override;
+  bool ResumptionAttempted() const override;
+  // Must be called after EarlySelectCertCallback is started.
+  bool EarlyDataAttempted() const override;
+  int NumServerConfigUpdateMessagesSent() const override;
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters cached_network_params) override;
+  void OnPacketDecrypted(EncryptionLevel level) override;
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnConnectionClosed(QuicErrorCode error,
+                          ConnectionCloseSource source) override;
+  void OnHandshakeDoneReceived() override;
+  std::string GetAddressToken(
+      const CachedNetworkParameters* cached_network_params) const override;
+  bool ValidateAddressToken(absl::string_view token) const override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  bool ShouldSendExpectCTHeader() const override;
+  bool DidCertMatchSni() const override;
+  const ProofSource::Details* ProofSourceDetails() const override;
+  bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
+                            size_t result_len, std::string* result) override;
+  SSL* GetSsl() const override;
+
+  // From QuicCryptoServerStreamBase and TlsHandshaker
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  HandshakeState GetHandshakeState() const override;
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> state) override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  void SetWriteSecret(EncryptionLevel level,
+                      const SSL_CIPHER* cipher,
+                      const std::vector<uint8_t>& write_secret) override;
+
+  // Called with normalized SNI hostname as |hostname|.  Return value will be
+  // sent in an ACCEPT_CH frame in the TLS ALPS extension, unless empty.
+  virtual std::string GetAcceptChValueForHostname(
+      const std::string& hostname) const;
+
+  // Get the ClientCertMode that is currently in effect on this handshaker.
+  ClientCertMode client_cert_mode() const {
+    return tls_connection_.ssl_config().client_cert_mode;
+  }
+
+ protected:
+  // Override for tracing.
+  void InfoCallback(int type, int value) override;
+
+  // Creates a proof source handle for selecting cert and computing signature.
+  virtual std::unique_ptr<ProofSourceHandle> MaybeCreateProofSourceHandle();
+
+  // Hook to allow the server to override parts of the QuicConfig based on SNI
+  // before we generate transport parameters.
+  virtual void OverrideQuicConfigDefaults(QuicConfig* config);
+
+  virtual bool ValidateHostname(const std::string& hostname) const;
+
+  const TlsConnection* tls_connection() const override {
+    return &tls_connection_;
+  }
+
+  virtual void ProcessAdditionalTransportParameters(
+      const TransportParameters& /*params*/) {}
+
+  // Called when a potentially async operation is done and the done callback
+  // needs to advance the handshake.
+  void AdvanceHandshakeFromCallback();
+
+  // TlsHandshaker implementation:
+  void FinishHandshake() override;
+  void ProcessPostHandshakeMessage() override {}
+  QuicAsyncStatus VerifyCertChain(
+      const std::vector<std::string>& certs,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override;
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) override;
+
+  // TlsServerConnection::Delegate implementation:
+  // Used to select certificates and process transport parameters.
+  ssl_select_cert_result_t EarlySelectCertCallback(
+      const SSL_CLIENT_HELLO* client_hello) override;
+  int TlsExtServernameCallback(int* out_alert) override;
+  int SelectAlpn(const uint8_t** out,
+                 uint8_t* out_len,
+                 const uint8_t* in,
+                 unsigned in_len) override;
+  ssl_private_key_result_t PrivateKeySign(uint8_t* out,
+                                          size_t* out_len,
+                                          size_t max_out,
+                                          uint16_t sig_alg,
+                                          absl::string_view in) override;
+  ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
+                                              size_t* out_len,
+                                              size_t max_out) override;
+  size_t SessionTicketMaxOverhead() override;
+  int SessionTicketSeal(uint8_t* out,
+                        size_t* out_len,
+                        size_t max_out_len,
+                        absl::string_view in) override;
+  ssl_ticket_aead_result_t SessionTicketOpen(uint8_t* out,
+                                             size_t* out_len,
+                                             size_t max_out_len,
+                                             absl::string_view in) override;
+  // Called when ticket_decryption_callback_ is done to determine a final
+  // decryption result.
+  ssl_ticket_aead_result_t FinalizeSessionTicketOpen(uint8_t* out,
+                                                     size_t* out_len,
+                                                     size_t max_out_len);
+  TlsConnection::Delegate* ConnectionDelegate() override { return this; }
+
+  // The status of cert selection. nullopt means it hasn't started.
+  const absl::optional<QuicAsyncStatus>& select_cert_status() const {
+    return select_cert_status_;
+  }
+  // Whether |cert_verify_sig_| contains a valid signature.
+  // NOTE: BoringSSL queries the result of a async signature operation using
+  // PrivateKeyComplete(), a successful PrivateKeyComplete() will clear the
+  // content of |cert_verify_sig_|, this function should not be called after
+  // that.
+  bool HasValidSignature(size_t max_signature_size) const;
+
+  // ProofSourceHandleCallback implementation:
+  void OnSelectCertificateDone(
+      bool ok, bool is_sync, const ProofSource::Chain* chain,
+      absl::string_view handshake_hints,
+      absl::string_view ticket_encryption_key, bool cert_matched_sni,
+      QuicDelayedSSLConfig delayed_ssl_config) override;
+
+  void OnComputeSignatureDone(
+      bool ok,
+      bool is_sync,
+      std::string signature,
+      std::unique_ptr<ProofSource::Details> details) override;
+
+  void set_encryption_established(bool encryption_established) {
+    encryption_established_ = encryption_established;
+  }
+
+  bool WillNotCallComputeSignature() const override;
+
+  void SetIgnoreTicketOpen(bool value) { ignore_ticket_open_ = value; }
+
+ private:
+  class QUIC_EXPORT_PRIVATE DecryptCallback
+      : public ProofSource::DecryptCallback {
+   public:
+    explicit DecryptCallback(TlsServerHandshaker* handshaker);
+    void Run(std::vector<uint8_t> plaintext) override;
+
+    // If called, Cancel causes the pending callback to be a no-op.
+    void Cancel();
+
+    // Return true if either
+    // - Cancel() has been called.
+    // - Run() has been called, or is in the middle of it.
+    bool IsDone() const { return handshaker_ == nullptr; }
+
+   private:
+    TlsServerHandshaker* handshaker_;
+  };
+
+  // DefaultProofSourceHandle delegates all operations to the shared proof
+  // source.
+  class QUIC_EXPORT_PRIVATE DefaultProofSourceHandle
+      : public ProofSourceHandle {
+   public:
+    DefaultProofSourceHandle(TlsServerHandshaker* handshaker,
+                             ProofSource* proof_source);
+
+    ~DefaultProofSourceHandle() override;
+
+    // Close the handle. Cancel the pending signature operation, if any.
+    void CloseHandle() override;
+
+    // Delegates to proof_source_->GetCertChain.
+    // Returns QUIC_SUCCESS or QUIC_FAILURE. Never returns QUIC_PENDING.
+    QuicAsyncStatus SelectCertificate(
+        const QuicSocketAddress& server_address,
+        const QuicSocketAddress& client_address,
+        absl::string_view ssl_capabilities,
+        const std::string& hostname,
+        absl::string_view client_hello,
+        const std::string& alpn,
+        absl::optional<std::string> alps,
+        const std::vector<uint8_t>& quic_transport_params,
+        const absl::optional<std::vector<uint8_t>>& early_data_context,
+        const QuicSSLConfig& ssl_config) override;
+
+    // Delegates to proof_source_->ComputeTlsSignature.
+    // Returns QUIC_SUCCESS, QUIC_FAILURE or QUIC_PENDING.
+    QuicAsyncStatus ComputeSignature(const QuicSocketAddress& server_address,
+                                     const QuicSocketAddress& client_address,
+                                     const std::string& hostname,
+                                     uint16_t signature_algorithm,
+                                     absl::string_view in,
+                                     size_t max_signature_size) override;
+
+   protected:
+    ProofSourceHandleCallback* callback() override { return handshaker_; }
+
+   private:
+    class QUIC_EXPORT_PRIVATE DefaultSignatureCallback
+        : public ProofSource::SignatureCallback {
+     public:
+      explicit DefaultSignatureCallback(DefaultProofSourceHandle* handle)
+          : handle_(handle) {}
+
+      void Run(bool ok,
+               std::string signature,
+               std::unique_ptr<ProofSource::Details> details) override {
+        if (handle_ == nullptr) {
+          // Operation has been canceled, or Run has been called.
+          return;
+        }
+
+        DefaultProofSourceHandle* handle = handle_;
+        handle_ = nullptr;
+
+        handle->signature_callback_ = nullptr;
+        if (handle->handshaker_ != nullptr) {
+          handle->handshaker_->OnComputeSignatureDone(
+              ok, is_sync_, std::move(signature), std::move(details));
+        }
+      }
+
+      // If called, Cancel causes the pending callback to be a no-op.
+      void Cancel() { handle_ = nullptr; }
+
+      void set_is_sync(bool is_sync) { is_sync_ = is_sync; }
+
+     private:
+      DefaultProofSourceHandle* handle_;
+      // Set to false if handle_->ComputeSignature returns QUIC_PENDING.
+      bool is_sync_ = true;
+    };
+
+    // Not nullptr on construction. Set to nullptr when cancelled.
+    TlsServerHandshaker* handshaker_;  // Not owned.
+    ProofSource* proof_source_;        // Not owned.
+    DefaultSignatureCallback* signature_callback_ = nullptr;
+  };
+
+  struct QUIC_NO_EXPORT SetTransportParametersResult {
+    bool success = false;
+    // Empty vector if QUIC transport params are not set successfully.
+    std::vector<uint8_t> quic_transport_params;
+    // absl::nullopt if there is no application state to begin with.
+    // Empty vector if application state is not set successfully.
+    absl::optional<std::vector<uint8_t>> early_data_context;
+  };
+
+  SetTransportParametersResult SetTransportParameters();
+  bool ProcessTransportParameters(const SSL_CLIENT_HELLO* client_hello,
+                                  std::string* error_details);
+
+  struct QUIC_NO_EXPORT SetApplicationSettingsResult {
+    bool success = false;
+    std::unique_ptr<char[]> alps_buffer;
+    size_t alps_length = 0;
+  };
+  SetApplicationSettingsResult SetApplicationSettings(absl::string_view alpn);
+
+  QuicConnectionStats& connection_stats() {
+    return session()->connection()->mutable_stats();
+  }
+  QuicTime now() const { return session()->GetClock()->Now(); }
+
+  QuicConnectionContext* connection_context() {
+    return session()->connection()->context();
+  }
+
+  std::unique_ptr<ProofSourceHandle> proof_source_handle_;
+  ProofSource* proof_source_;
+
+  // State to handle potentially asynchronous session ticket decryption.
+  // |ticket_decryption_callback_| points to the non-owned callback that was
+  // passed to ProofSource::TicketCrypter::Decrypt but hasn't finished running
+  // yet.
+  DecryptCallback* ticket_decryption_callback_ = nullptr;
+  // |decrypted_session_ticket_| contains the decrypted session ticket after the
+  // callback has run but before it is passed to BoringSSL.
+  std::vector<uint8_t> decrypted_session_ticket_;
+  // |ticket_received_| tracks whether we received a resumption ticket from the
+  // client. It does not matter whether we were able to decrypt said ticket or
+  // if we actually resumed a session with it - the presence of this ticket
+  // indicates that the client attempted a resumption.
+  bool ticket_received_ = false;
+
+  // True if the "early_data" extension is in the client hello.
+  bool early_data_attempted_ = false;
+
+  // Force SessionTicketOpen to return ssl_ticket_aead_ignore_ticket if called.
+  bool ignore_ticket_open_ = false;
+
+  // nullopt means select cert hasn't started.
+  absl::optional<QuicAsyncStatus> select_cert_status_;
+
+  std::string cert_verify_sig_;
+  std::unique_ptr<ProofSource::Details> proof_source_details_;
+
+  // Count the duration of the current async operation, if any.
+  absl::optional<QuicTimeAccumulator> async_op_timer_;
+
+  std::unique_ptr<ApplicationState> application_state_;
+
+  // Pre-shared key used during the handshake.
+  std::string pre_shared_key_;
+
+  // (optional) Key to use for encrypting TLS resumption tickets.
+  std::string ticket_encryption_key_;
+
+  HandshakeState state_ = HANDSHAKE_START;
+  bool encryption_established_ = false;
+  bool valid_alpn_received_ = false;
+  bool can_disable_resumption_ = true;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      crypto_negotiated_params_;
+  TlsServerConnection tls_connection_;
+  const QuicCryptoServerConfig* crypto_config_;  // Unowned.
+  // The last received CachedNetworkParameters from a validated address token.
+  mutable std::unique_ptr<CachedNetworkParameters>
+      last_received_cached_network_params_;
+
+  bool cert_matched_sni_ = false;
+  const bool no_select_cert_if_disconnected_ =
+      GetQuicReloadableFlag(quic_tls_no_select_cert_if_disconnected);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
diff --git a/quiche/quic/core/tls_server_handshaker_test.cc b/quiche/quic/core/tls_server_handshaker_test.cc
new file mode 100644
index 0000000..b49d959
--- /dev/null
+++ b/quiche/quic/core/tls_server_handshaker_test.cc
@@ -0,0 +1,1080 @@
+// 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 "quiche/quic/core/tls_server_handshaker.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/certificate_util.h"
+#include "quiche/quic/core/crypto/client_proof_source.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/tls_client_handshaker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/failing_proof_source.h"
+#include "quiche/quic/test_tools/fake_proof_source.h"
+#include "quiche/quic/test_tools/fake_proof_source_handle.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+#include "quiche/quic/test_tools/test_ticket_crypter.h"
+
+namespace quic {
+class QuicConnection;
+class QuicStream;
+}  // namespace quic
+
+using testing::_;
+using testing::NiceMock;
+using testing::Return;
+
+namespace quic {
+namespace test {
+
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kServerPort = 443;
+
+struct TestParams {
+  ParsedQuicVersion version;
+  bool disable_resumption;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version), "_",
+      (p.disable_resumption ? "ResumptionDisabled" : "ResumptionEnabled"));
+}
+
+// Constructs test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const auto& version : AllSupportedVersionsWithTls()) {
+    for (bool disable_resumption : {false, true}) {
+      params.push_back(TestParams{version, disable_resumption});
+    }
+  }
+  return params;
+}
+
+class TestTlsServerHandshaker : public TlsServerHandshaker {
+ public:
+  TestTlsServerHandshaker(QuicSession* session,
+                          const QuicCryptoServerConfig* crypto_config)
+      : TlsServerHandshaker(session, crypto_config),
+        proof_source_(crypto_config->proof_source()) {
+    ON_CALL(*this, MaybeCreateProofSourceHandle())
+        .WillByDefault(testing::Invoke(
+            this, &TestTlsServerHandshaker::RealMaybeCreateProofSourceHandle));
+
+    ON_CALL(*this, OverrideQuicConfigDefaults(_))
+        .WillByDefault(testing::Invoke(
+            this, &TestTlsServerHandshaker::RealOverrideQuicConfigDefaults));
+  }
+
+  MOCK_METHOD(std::unique_ptr<ProofSourceHandle>,
+              MaybeCreateProofSourceHandle,
+              (),
+              (override));
+
+  MOCK_METHOD(void, OverrideQuicConfigDefaults, (QuicConfig * config),
+              (override));
+
+  void SetupProofSourceHandle(
+      FakeProofSourceHandle::Action select_cert_action,
+      FakeProofSourceHandle::Action compute_signature_action,
+      QuicDelayedSSLConfig dealyed_ssl_config = QuicDelayedSSLConfig()) {
+    EXPECT_CALL(*this, MaybeCreateProofSourceHandle())
+        .WillOnce(
+            testing::Invoke([this, select_cert_action, compute_signature_action,
+                             dealyed_ssl_config]() {
+              auto handle = std::make_unique<FakeProofSourceHandle>(
+                  proof_source_, this, select_cert_action,
+                  compute_signature_action, dealyed_ssl_config);
+              fake_proof_source_handle_ = handle.get();
+              return handle;
+            }));
+  }
+
+  FakeProofSourceHandle* fake_proof_source_handle() {
+    return fake_proof_source_handle_;
+  }
+
+  bool received_client_cert() const { return received_client_cert_; }
+
+  using TlsServerHandshaker::AdvanceHandshake;
+  using TlsServerHandshaker::expected_ssl_error;
+
+ protected:
+  QuicAsyncStatus VerifyCertChain(
+      const std::vector<std::string>& certs, std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details, uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override {
+    received_client_cert_ = true;
+    return TlsServerHandshaker::VerifyCertChain(certs, error_details, details,
+                                                out_alert, std::move(callback));
+  }
+
+ private:
+  std::unique_ptr<ProofSourceHandle> RealMaybeCreateProofSourceHandle() {
+    return TlsServerHandshaker::MaybeCreateProofSourceHandle();
+  }
+
+  void RealOverrideQuicConfigDefaults(QuicConfig* config) {
+    return TlsServerHandshaker::OverrideQuicConfigDefaults(config);
+  }
+
+  // Owned by TlsServerHandshaker.
+  FakeProofSourceHandle* fake_proof_source_handle_ = nullptr;
+  ProofSource* proof_source_ = nullptr;
+  bool received_client_cert_ = false;
+};
+
+class TlsServerHandshakerTestSession : public TestQuicSpdyServerSession {
+ public:
+  using TestQuicSpdyServerSession::TestQuicSpdyServerSession;
+
+  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* /*compressed_certs_cache*/) override {
+    if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
+      return std::make_unique<NiceMock<TestTlsServerHandshaker>>(this,
+                                                                 crypto_config);
+    }
+
+    QUICHE_CHECK(false) << "Unsupported handshake protocol: "
+                        << connection()->version().handshake_protocol;
+    return nullptr;
+  }
+};
+
+class TlsServerHandshakerTest : public QuicTestWithParam<TestParams> {
+ public:
+  TlsServerHandshakerTest()
+      : server_compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+        server_id_(kServerHostname, kServerPort, false),
+        supported_versions_({GetParam().version}) {
+    SetQuicFlag(FLAGS_quic_disable_server_tls_resumption,
+                GetParam().disable_resumption);
+    client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+        crypto_test_utils::ProofVerifierForTesting(),
+        std::make_unique<test::SimpleSessionCache>());
+    InitializeServerConfig();
+    InitializeServer();
+    InitializeFakeClient();
+  }
+
+  ~TlsServerHandshakerTest() override {
+    // Ensure that anything that might reference |helpers_| is destroyed before
+    // |helpers_| is destroyed.
+    server_session_.reset();
+    client_session_.reset();
+    helpers_.clear();
+    alarm_factories_.clear();
+  }
+
+  void InitializeServerConfig() {
+    auto ticket_crypter = std::make_unique<TestTicketCrypter>();
+    ticket_crypter_ = ticket_crypter.get();
+    auto proof_source = std::make_unique<FakeProofSource>();
+    proof_source_ = proof_source.get();
+    proof_source_->SetTicketCrypter(std::move(ticket_crypter));
+    server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
+        QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+        std::move(proof_source), KeyExchangeSource::Default());
+  }
+
+  void InitializeServerConfigWithFailingProofSource() {
+    server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
+        QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+        std::make_unique<FailingProofSource>(), KeyExchangeSource::Default());
+  }
+
+  void CreateTlsServerHandshakerTestSession(MockQuicConnectionHelper* helper,
+                                            MockAlarmFactory* alarm_factory) {
+    server_connection_ = new PacketSavingConnection(
+        helper, alarm_factory, Perspective::IS_SERVER,
+        ParsedVersionOfIndex(supported_versions_, 0));
+
+    TlsServerHandshakerTestSession* server_session =
+        new TlsServerHandshakerTestSession(
+            server_connection_, DefaultQuicConfig(), supported_versions_,
+            server_crypto_config_.get(), &server_compressed_certs_cache_);
+    server_session->set_client_cert_mode(initial_client_cert_mode_);
+    server_session->Initialize();
+
+    // We advance the clock initially because the default time is zero and the
+    // strike register worries that we've just overflowed a uint32_t time.
+    server_connection_->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
+
+    QUICHE_CHECK(server_session);
+    server_session_.reset(server_session);
+  }
+
+  void InitializeServerWithFakeProofSourceHandle() {
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateTlsServerHandshakerTestSession(helpers_.back().get(),
+                                         alarm_factories_.back().get());
+    server_handshaker_ = static_cast<NiceMock<TestTlsServerHandshaker>*>(
+        server_session_->GetMutableCryptoStream());
+    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*server_session_, SelectAlpn(_))
+        .WillRepeatedly([this](const std::vector<absl::string_view>& alpns) {
+          return std::find(
+              alpns.cbegin(), alpns.cend(),
+              AlpnForVersion(server_session_->connection()->version()));
+        });
+    crypto_test_utils::SetupCryptoServerConfigForTest(
+        server_connection_->clock(), server_connection_->random_generator(),
+        server_crypto_config_.get());
+  }
+
+  // Initializes the crypto server stream state for testing.  May be
+  // called multiple times.
+  void InitializeServer() {
+    TestQuicSpdyServerSession* server_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateServerSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        server_crypto_config_.get(), &server_compressed_certs_cache_,
+        &server_connection_, &server_session);
+    QUICHE_CHECK(server_session);
+    server_session_.reset(server_session);
+    server_handshaker_ = nullptr;
+    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*server_session_, SelectAlpn(_))
+        .WillRepeatedly([this](const std::vector<absl::string_view>& alpns) {
+          return std::find(
+              alpns.cbegin(), alpns.cend(),
+              AlpnForVersion(server_session_->connection()->version()));
+        });
+    crypto_test_utils::SetupCryptoServerConfigForTest(
+        server_connection_->clock(), server_connection_->random_generator(),
+        server_crypto_config_.get());
+  }
+
+  QuicCryptoServerStreamBase* server_stream() {
+    return server_session_->GetMutableCryptoStream();
+  }
+
+  QuicCryptoClientStream* client_stream() {
+    return client_session_->GetMutableCryptoStream();
+  }
+
+  // Initializes a fake client, and all its associated state, for
+  // testing.  May be called multiple times.
+  void InitializeFakeClient() {
+    TestQuicSpdyClientSession* client_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateClientSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        client_crypto_config_.get(), &client_connection_, &client_session);
+    const std::string default_alpn =
+        AlpnForVersion(client_connection_->version());
+    ON_CALL(*client_session, GetAlpnsToOffer())
+        .WillByDefault(Return(std::vector<std::string>({default_alpn})));
+    QUICHE_CHECK(client_session);
+    client_session_.reset(client_session);
+    moved_messages_counts_ = {0, 0};
+  }
+
+  void CompleteCryptoHandshake() {
+    while (!client_stream()->one_rtt_keys_available() ||
+           !server_stream()->one_rtt_keys_available()) {
+      auto previous_moved_messages_counts = moved_messages_counts_;
+      AdvanceHandshakeWithFakeClient();
+      // Check that the handshake has made forward progress
+      ASSERT_NE(previous_moved_messages_counts, moved_messages_counts_);
+    }
+  }
+
+  // Performs a single round of handshake message-exchange between the
+  // client and server.
+  void AdvanceHandshakeWithFakeClient() {
+    QUICHE_CHECK(server_connection_);
+    QUICHE_CHECK(client_session_ != nullptr);
+
+    EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
+    EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    // Call CryptoConnect if we haven't moved any client messages yet.
+    if (moved_messages_counts_.first == 0) {
+      client_stream()->CryptoConnect();
+    }
+    moved_messages_counts_ = crypto_test_utils::AdvanceHandshake(
+        client_connection_, client_stream(), moved_messages_counts_.first,
+        server_connection_, server_stream(), moved_messages_counts_.second);
+  }
+
+  void ExpectHandshakeSuccessful() {
+    EXPECT_TRUE(client_stream()->one_rtt_keys_available());
+    EXPECT_TRUE(client_stream()->encryption_established());
+    EXPECT_TRUE(server_stream()->one_rtt_keys_available());
+    EXPECT_TRUE(server_stream()->encryption_established());
+    EXPECT_EQ(HANDSHAKE_COMPLETE, client_stream()->GetHandshakeState());
+    EXPECT_EQ(HANDSHAKE_CONFIRMED, server_stream()->GetHandshakeState());
+
+    const auto& client_crypto_params =
+        client_stream()->crypto_negotiated_params();
+    const auto& server_crypto_params =
+        server_stream()->crypto_negotiated_params();
+    // The TLS params should be filled in on the client.
+    EXPECT_NE(0, client_crypto_params.cipher_suite);
+    EXPECT_NE(0, client_crypto_params.key_exchange_group);
+    EXPECT_NE(0, client_crypto_params.peer_signature_algorithm);
+
+    // The cipher suite and key exchange group should match on the client and
+    // server.
+    EXPECT_EQ(client_crypto_params.cipher_suite,
+              server_crypto_params.cipher_suite);
+    EXPECT_EQ(client_crypto_params.key_exchange_group,
+              server_crypto_params.key_exchange_group);
+    // We don't support client certs on the server (yet), so the server
+    // shouldn't have a peer signature algorithm to report.
+    EXPECT_EQ(0, server_crypto_params.peer_signature_algorithm);
+  }
+
+  // Should only be called when using FakeProofSourceHandle.
+  FakeProofSourceHandle::SelectCertArgs last_select_cert_args() const {
+    QUICHE_CHECK(server_handshaker_ &&
+                 server_handshaker_->fake_proof_source_handle());
+    QUICHE_CHECK(!server_handshaker_->fake_proof_source_handle()
+                      ->all_select_cert_args()
+                      .empty());
+    return server_handshaker_->fake_proof_source_handle()
+        ->all_select_cert_args()
+        .back();
+  }
+
+  // Should only be called when using FakeProofSourceHandle.
+  FakeProofSourceHandle::ComputeSignatureArgs last_compute_signature_args()
+      const {
+    QUICHE_CHECK(server_handshaker_ &&
+                 server_handshaker_->fake_proof_source_handle());
+    QUICHE_CHECK(!server_handshaker_->fake_proof_source_handle()
+                      ->all_compute_signature_args()
+                      .empty());
+    return server_handshaker_->fake_proof_source_handle()
+        ->all_compute_signature_args()
+        .back();
+  }
+
+ protected:
+  // Setup the client to send a (self-signed) client cert to the server, if
+  // requested. InitializeFakeClient() must be called after this to take effect.
+  bool SetupClientCert() {
+    auto client_proof_source = std::make_unique<DefaultClientProofSource>();
+
+    CertificatePrivateKey client_cert_key(
+        MakeKeyPairForSelfSignedCertificate());
+
+    CertificateOptions options;
+    options.subject = "CN=subject";
+    options.serial_number = 0x12345678;
+    options.validity_start = {2020, 1, 1, 0, 0, 0};
+    options.validity_end = {2049, 12, 31, 0, 0, 0};
+    std::string der_cert =
+        CreateSelfSignedCertificate(*client_cert_key.private_key(), options);
+
+    quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+        client_cert_chain(new ClientProofSource::Chain({der_cert}));
+
+    if (!client_proof_source->AddCertAndKey({"*"}, client_cert_chain,
+                                            std::move(client_cert_key))) {
+      return false;
+    }
+
+    client_crypto_config_->set_proof_source(std::move(client_proof_source));
+    return true;
+  }
+
+  // Every connection gets its own MockQuicConnectionHelper and
+  // MockAlarmFactory, tracked separately from the server and client state so
+  // their lifetimes persist through the whole test.
+  std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
+  std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
+
+  // Server state.
+  PacketSavingConnection* server_connection_;
+  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
+  // Only set when initialized with InitializeServerWithFakeProofSourceHandle.
+  NiceMock<TestTlsServerHandshaker>* server_handshaker_ = nullptr;
+  TestTicketCrypter* ticket_crypter_;  // owned by proof_source_
+  FakeProofSource* proof_source_;      // owned by server_crypto_config_
+  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+  QuicCompressedCertsCache server_compressed_certs_cache_;
+  QuicServerId server_id_;
+  ClientCertMode initial_client_cert_mode_ = ClientCertMode::kNone;
+
+  // Client state.
+  PacketSavingConnection* client_connection_;
+  std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
+  std::unique_ptr<TestQuicSpdyClientSession> client_session_;
+
+  crypto_test_utils::FakeClientOptions client_options_;
+  // How many handshake messages have been moved from client to server and
+  // server to client.
+  std::pair<size_t, size_t> moved_messages_counts_ = {0, 0};
+
+  // Which QUIC versions the client and server support.
+  ParsedQuicVersionVector supported_versions_;
+};
+
+INSTANTIATE_TEST_SUITE_P(TlsServerHandshakerTests,
+                         TlsServerHandshakerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(TlsServerHandshakerTest, NotInitiallyConected) {
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsServerHandshakerTest, ConnectedAfterTlsHandshake) {
+  CompleteCryptoHandshake();
+  EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertSuccess) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  CompleteCryptoHandshake();
+
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertFailure) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::FAIL_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  // Check that the server didn't send any handshake messages, because it failed
+  // to handshake.
+  EXPECT_EQ(moved_messages_counts_.second, 0u);
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertAndSignature) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_ASYNC);
+
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  // A select cert operation is now pending.
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  EXPECT_EQ(server_handshaker_->expected_ssl_error(),
+            SSL_ERROR_PENDING_CERTIFICATE);
+
+  // Complete the pending select cert. It should advance the handshake to
+  // compute a signature, which will also be saved as a pending operation.
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  // A compute signature operation is now pending.
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  EXPECT_EQ(server_handshaker_->expected_ssl_error(),
+            SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
+
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  CompleteCryptoHandshake();
+
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSignature) {
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
+  // asynchronously.
+  proof_source_->Activate();
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
+  proof_source_->InvokePendingCallback(0);
+
+  CompleteCryptoHandshake();
+
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, CancelPendingSelectCert) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->CancelOutstandingCallbacks();
+  ASSERT_FALSE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  // CompletePendingOperation should be noop.
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+}
+
+TEST_P(TlsServerHandshakerTest, CancelPendingSignature) {
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
+  // asynchronously.
+  proof_source_->Activate();
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
+  server_session_ = nullptr;
+
+  proof_source_->InvokePendingCallback(0);
+}
+
+TEST_P(TlsServerHandshakerTest, ExtractSNI) {
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni,
+            "test.example.com");
+}
+
+TEST_P(TlsServerHandshakerTest, HostnameForCertSelectionAndComputeSignature) {
+  // Client uses upper case letters in hostname. It is considered valid by
+  // QuicHostnameUtils::IsValidSNI, but it should be normalized for cert
+  // selection.
+  server_id_ = QuicServerId("tEsT.EXAMPLE.CoM", kServerPort, false);
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni,
+            "test.example.com");
+
+  EXPECT_EQ(last_select_cert_args().hostname, "test.example.com");
+  EXPECT_EQ(last_compute_signature_args().hostname, "test.example.com");
+}
+
+TEST_P(TlsServerHandshakerTest, SSLConfigForCertSelection) {
+  InitializeServerWithFakeProofSourceHandle();
+
+  // Disable early data.
+  server_session_->set_early_data_enabled(false);
+
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  EXPECT_FALSE(last_select_cert_args().ssl_config.early_data_enabled);
+}
+
+TEST_P(TlsServerHandshakerTest, ConnectionClosedOnTlsError) {
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED, _, _, _));
+
+  // Send a zero-length ClientHello from client to server.
+  char bogus_handshake_message[] = {
+      // Handshake struct (RFC 8446 appendix B.3)
+      1,        // HandshakeType client_hello
+      0, 0, 0,  // uint24 length
+  };
+
+  // Install a packet flusher such that the packets generated by
+  // |server_connection_| in response to this handshake message are more likely
+  // to be coalesced and/or batched in the writer.
+  //
+  // This is required by TlsServerHandshaker because without the flusher, it
+  // tends to generate many small, uncoalesced packets, one per
+  // TlsHandshaker::WriteMessage.
+  QuicConnection::ScopedPacketFlusher flusher(server_connection_);
+  server_stream()->crypto_message_parser()->ProcessInput(
+      absl::string_view(bogus_handshake_message,
+                        ABSL_ARRAYSIZE(bogus_handshake_message)),
+      ENCRYPTION_INITIAL);
+
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsServerHandshakerTest, ClientSendingBadALPN) {
+  const std::string kTestBadClientAlpn = "bad-client-alpn";
+  EXPECT_CALL(*client_session_, GetAlpnsToOffer())
+      .WillOnce(Return(std::vector<std::string>({kTestBadClientAlpn})));
+
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED,
+                              static_cast<QuicIetfTransportErrorCodes>(
+                                  CRYPTO_ERROR_FIRST + 120),
+                              "TLS handshake failure (ENCRYPTION_INITIAL) 120: "
+                              "no application protocol",
+                              _));
+
+  AdvanceHandshakeWithFakeClient();
+
+  EXPECT_FALSE(client_stream()->one_rtt_keys_available());
+  EXPECT_FALSE(client_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+  EXPECT_FALSE(server_stream()->encryption_established());
+}
+
+TEST_P(TlsServerHandshakerTest, CustomALPNNegotiation) {
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+
+  const std::string kTestAlpn = "A Custom ALPN Value";
+  const std::vector<std::string> kTestAlpns(
+      {"foo", "bar", kTestAlpn, "something else"});
+  EXPECT_CALL(*client_session_, GetAlpnsToOffer())
+      .WillRepeatedly(Return(kTestAlpns));
+  EXPECT_CALL(*server_session_, SelectAlpn(_))
+      .WillOnce(
+          [kTestAlpn, kTestAlpns](const std::vector<absl::string_view>& alpns) {
+            EXPECT_THAT(alpns, testing::ElementsAreArray(kTestAlpns));
+            return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
+          });
+  EXPECT_CALL(*client_session_, OnAlpnSelected(absl::string_view(kTestAlpn)));
+  EXPECT_CALL(*server_session_, OnAlpnSelected(absl::string_view(kTestAlpn)));
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, RejectInvalidSNI) {
+  server_id_ = QuicServerId("invalid!.example.com", kServerPort, false);
+  InitializeFakeClient();
+  static_cast<TlsClientHandshaker*>(
+      QuicCryptoClientStreamPeer::GetHandshaker(client_stream()))
+      ->AllowInvalidSNIForTests();
+
+  // Run the handshake and expect it to fail.
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsServerHandshakerTest, Resumption) {
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->ResumptionAttempted());
+
+  // Now do another handshake
+  InitializeServer();
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
+  EXPECT_NE(server_stream()->IsResumption(), GetParam().disable_resumption);
+  EXPECT_NE(server_stream()->ResumptionAttempted(),
+            GetParam().disable_resumption);
+}
+
+TEST_P(TlsServerHandshakerTest, ResumptionWithAsyncDecryptCallback) {
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  ticket_crypter_->SetRunCallbacksAsync(true);
+  // Now do another handshake
+  InitializeServer();
+  InitializeFakeClient();
+
+  AdvanceHandshakeWithFakeClient();
+  if (GetParam().disable_resumption) {
+    ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 0u);
+    return;
+  }
+  // Test that the DecryptCallback will be run asynchronously, and then run it.
+  ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
+  ticket_crypter_->RunPendingCallback(0);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_TRUE(client_stream()->IsResumption());
+  EXPECT_TRUE(server_stream()->IsResumption());
+  EXPECT_TRUE(server_stream()->ResumptionAttempted());
+}
+
+TEST_P(TlsServerHandshakerTest, AdvanceHandshakeDuringAsyncDecryptCallback) {
+  if (GetParam().disable_resumption) {
+    return;
+  }
+
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  ticket_crypter_->SetRunCallbacksAsync(true);
+  // Now do another handshake
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+  InitializeFakeClient();
+
+  AdvanceHandshakeWithFakeClient();
+
+  // Ensure an async DecryptCallback is now pending.
+  ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(server_connection_);
+    server_handshaker_->AdvanceHandshake();
+  }
+
+  // This will delete |server_handshaker_|.
+  server_session_ = nullptr;
+
+  ticket_crypter_->RunPendingCallback(0);  // Should not crash.
+}
+
+TEST_P(TlsServerHandshakerTest, ResumptionWithFailingDecryptCallback) {
+  if (GetParam().disable_resumption) {
+    return;
+  }
+
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  ticket_crypter_->set_fail_decrypt(true);
+  // Now do another handshake
+  InitializeServer();
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsResumption());
+  EXPECT_TRUE(server_stream()->ResumptionAttempted());
+}
+
+TEST_P(TlsServerHandshakerTest, ResumptionWithFailingAsyncDecryptCallback) {
+  if (GetParam().disable_resumption) {
+    return;
+  }
+
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  ticket_crypter_->set_fail_decrypt(true);
+  ticket_crypter_->SetRunCallbacksAsync(true);
+  // Now do another handshake
+  InitializeServer();
+  InitializeFakeClient();
+
+  AdvanceHandshakeWithFakeClient();
+  // Test that the DecryptCallback will be run asynchronously, and then run it.
+  ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
+  ticket_crypter_->RunPendingCallback(0);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsResumption());
+  EXPECT_TRUE(server_stream()->ResumptionAttempted());
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeFailsWithFailingProofSource) {
+  InitializeServerConfigWithFailingProofSource();
+  InitializeServer();
+  InitializeFakeClient();
+
+  // Attempt handshake.
+  AdvanceHandshakeWithFakeClient();
+  // Check that the server didn't send any handshake messages, because it failed
+  // to handshake.
+  EXPECT_EQ(moved_messages_counts_.second, 0u);
+}
+
+TEST_P(TlsServerHandshakerTest, ZeroRttResumption) {
+  std::vector<uint8_t> application_state = {0, 1, 2, 3};
+
+  // Do the first handshake
+  server_stream()->SetServerApplicationStateForResumption(
+      std::make_unique<ApplicationState>(application_state));
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsZeroRtt());
+
+  // Now do another handshake
+  InitializeServer();
+  server_stream()->SetServerApplicationStateForResumption(
+      std::make_unique<ApplicationState>(application_state));
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
+  EXPECT_NE(server_stream()->IsZeroRtt(), GetParam().disable_resumption);
+}
+
+TEST_P(TlsServerHandshakerTest, ZeroRttRejectOnApplicationStateChange) {
+  std::vector<uint8_t> original_application_state = {1, 2};
+  std::vector<uint8_t> new_application_state = {3, 4};
+
+  // Do the first handshake
+  server_stream()->SetServerApplicationStateForResumption(
+      std::make_unique<ApplicationState>(original_application_state));
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsZeroRtt());
+
+  // Do another handshake, but change the application state
+  InitializeServer();
+  server_stream()->SetServerApplicationStateForResumption(
+      std::make_unique<ApplicationState>(new_application_state));
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
+  EXPECT_FALSE(server_stream()->IsZeroRtt());
+}
+
+TEST_P(TlsServerHandshakerTest, RequestClientCert) {
+  ASSERT_TRUE(SetupClientCert());
+  InitializeFakeClient();
+
+  initial_client_cert_mode_ = ClientCertMode::kRequest;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_TRUE(server_handshaker_->received_client_cert());
+  } else {
+    EXPECT_FALSE(server_handshaker_->received_client_cert());
+  }
+}
+
+TEST_P(TlsServerHandshakerTest, RequestClientCertByDelayedSslConfig) {
+  ASSERT_TRUE(SetupClientCert());
+  InitializeFakeClient();
+
+  QuicDelayedSSLConfig delayed_ssl_config;
+  delayed_ssl_config.client_cert_mode = ClientCertMode::kRequest;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      delayed_ssl_config);
+
+  AdvanceHandshakeWithFakeClient();
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_TRUE(server_handshaker_->received_client_cert());
+  } else {
+    EXPECT_FALSE(server_handshaker_->received_client_cert());
+  }
+}
+
+TEST_P(TlsServerHandshakerTest, RequestClientCert_NoCert) {
+  initial_client_cert_mode_ = ClientCertMode::kRequest;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(server_handshaker_->received_client_cert());
+}
+
+TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert) {
+  ASSERT_TRUE(SetupClientCert());
+  InitializeFakeClient();
+
+  initial_client_cert_mode_ = ClientCertMode::kRequire;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_TRUE(server_handshaker_->received_client_cert());
+  } else {
+    EXPECT_FALSE(server_handshaker_->received_client_cert());
+  }
+}
+
+TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCertByDelayedSslConfig) {
+  ASSERT_TRUE(SetupClientCert());
+  InitializeFakeClient();
+
+  QuicDelayedSSLConfig delayed_ssl_config;
+  delayed_ssl_config.client_cert_mode = ClientCertMode::kRequire;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      delayed_ssl_config);
+
+  AdvanceHandshakeWithFakeClient();
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_TRUE(server_handshaker_->received_client_cert());
+  } else {
+    EXPECT_FALSE(server_handshaker_->received_client_cert());
+  }
+}
+
+TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert_NoCert) {
+  initial_client_cert_mode_ = ClientCertMode::kRequire;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_CALL(*server_connection_,
+                CloseConnection(QUIC_TLS_CERTIFICATE_REQUIRED, _, _, _));
+  }
+  AdvanceHandshakeWithFakeClient();
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_handshaker_->received_client_cert());
+}
+
+TEST_P(TlsServerHandshakerTest, CloseConnectionBeforeSelectCert) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::
+          FAIL_SYNC_DO_NOT_CHECK_CLOSED,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          FAIL_SYNC_DO_NOT_CHECK_CLOSED);
+
+  EXPECT_CALL(*server_handshaker_, OverrideQuicConfigDefaults(_))
+      .WillOnce(testing::Invoke([](QuicConfig* config) {
+        QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(config,
+                                                            /*max_streams=*/0);
+      }));
+
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _))
+      .WillOnce(testing::Invoke(
+          [this](QuicErrorCode error, const std::string& details,
+                 ConnectionCloseBehavior connection_close_behavior) {
+            server_connection_->ReallyCloseConnection(
+                error, details, connection_close_behavior);
+            ASSERT_FALSE(server_connection_->connected());
+          }));
+
+  AdvanceHandshakeWithFakeClient();
+  if (!GetQuicReloadableFlag(quic_tls_no_select_cert_if_disconnected)) {
+    // SelectCertificate is called when flag is false.
+    EXPECT_FALSE(server_handshaker_->fake_proof_source_handle()
+                     ->all_select_cert_args()
+                     .empty());
+    return;
+  }
+
+  EXPECT_TRUE(server_handshaker_->fake_proof_source_handle()
+                  ->all_select_cert_args()
+                  .empty());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/uber_quic_stream_id_manager.cc b/quiche/quic/core/uber_quic_stream_id_manager.cc
new file mode 100644
index 0000000..f659291
--- /dev/null
+++ b/quiche/quic/core/uber_quic_stream_id_manager.cc
@@ -0,0 +1,176 @@
+// Copyright (c) 2018 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 "quiche/quic/core/uber_quic_stream_id_manager.h"
+
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+
+UberQuicStreamIdManager::UberQuicStreamIdManager(
+    Perspective perspective,
+    ParsedQuicVersion version,
+    QuicStreamIdManager::DelegateInterface* delegate,
+    QuicStreamCount max_open_outgoing_bidirectional_streams,
+    QuicStreamCount max_open_outgoing_unidirectional_streams,
+    QuicStreamCount max_open_incoming_bidirectional_streams,
+    QuicStreamCount max_open_incoming_unidirectional_streams)
+    : version_(version),
+      bidirectional_stream_id_manager_(delegate,
+                                       /*unidirectional=*/false,
+                                       perspective,
+                                       version,
+                                       max_open_outgoing_bidirectional_streams,
+                                       max_open_incoming_bidirectional_streams),
+      unidirectional_stream_id_manager_(
+          delegate,
+          /*unidirectional=*/true,
+          perspective,
+          version,
+          max_open_outgoing_unidirectional_streams,
+          max_open_incoming_unidirectional_streams) {}
+
+bool UberQuicStreamIdManager::MaybeAllowNewOutgoingBidirectionalStreams(
+    QuicStreamCount max_open_streams) {
+  return bidirectional_stream_id_manager_.MaybeAllowNewOutgoingStreams(
+      max_open_streams);
+}
+bool UberQuicStreamIdManager::MaybeAllowNewOutgoingUnidirectionalStreams(
+    QuicStreamCount max_open_streams) {
+  return unidirectional_stream_id_manager_.MaybeAllowNewOutgoingStreams(
+      max_open_streams);
+}
+void UberQuicStreamIdManager::SetMaxOpenIncomingBidirectionalStreams(
+    QuicStreamCount max_open_streams) {
+  bidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
+}
+void UberQuicStreamIdManager::SetMaxOpenIncomingUnidirectionalStreams(
+    QuicStreamCount max_open_streams) {
+  unidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
+}
+
+bool UberQuicStreamIdManager::CanOpenNextOutgoingBidirectionalStream() const {
+  return bidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
+}
+
+bool UberQuicStreamIdManager::CanOpenNextOutgoingUnidirectionalStream() const {
+  return unidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
+}
+
+QuicStreamId UberQuicStreamIdManager::GetNextOutgoingBidirectionalStreamId() {
+  return bidirectional_stream_id_manager_.GetNextOutgoingStreamId();
+}
+
+QuicStreamId UberQuicStreamIdManager::GetNextOutgoingUnidirectionalStreamId() {
+  return unidirectional_stream_id_manager_.GetNextOutgoingStreamId();
+}
+
+bool UberQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
+    QuicStreamId id,
+    std::string* error_details) {
+  if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
+    return bidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+        id, error_details);
+  }
+  return unidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      id, error_details);
+}
+
+void UberQuicStreamIdManager::OnStreamClosed(QuicStreamId id) {
+  if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
+    bidirectional_stream_id_manager_.OnStreamClosed(id);
+    return;
+  }
+  unidirectional_stream_id_manager_.OnStreamClosed(id);
+}
+
+bool UberQuicStreamIdManager::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& frame,
+    std::string* error_details) {
+  if (frame.unidirectional) {
+    return unidirectional_stream_id_manager_.OnStreamsBlockedFrame(
+        frame, error_details);
+  }
+  return bidirectional_stream_id_manager_.OnStreamsBlockedFrame(frame,
+                                                                error_details);
+}
+
+bool UberQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
+  if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
+    return bidirectional_stream_id_manager_.IsAvailableStream(id);
+  }
+  return unidirectional_stream_id_manager_.IsAvailableStream(id);
+}
+
+QuicStreamCount
+UberQuicStreamIdManager::GetMaxAllowdIncomingBidirectionalStreams() const {
+  return bidirectional_stream_id_manager_.incoming_initial_max_open_streams();
+}
+
+QuicStreamCount
+UberQuicStreamIdManager::GetMaxAllowdIncomingUnidirectionalStreams() const {
+  return unidirectional_stream_id_manager_.incoming_initial_max_open_streams();
+}
+
+QuicStreamId UberQuicStreamIdManager::GetLargestPeerCreatedStreamId(
+    bool unidirectional) const {
+  if (unidirectional) {
+    return unidirectional_stream_id_manager_.largest_peer_created_stream_id();
+  }
+  return bidirectional_stream_id_manager_.largest_peer_created_stream_id();
+}
+
+QuicStreamId UberQuicStreamIdManager::next_outgoing_bidirectional_stream_id()
+    const {
+  return bidirectional_stream_id_manager_.next_outgoing_stream_id();
+}
+
+QuicStreamId UberQuicStreamIdManager::next_outgoing_unidirectional_stream_id()
+    const {
+  return unidirectional_stream_id_manager_.next_outgoing_stream_id();
+}
+
+QuicStreamCount UberQuicStreamIdManager::max_outgoing_bidirectional_streams()
+    const {
+  return bidirectional_stream_id_manager_.outgoing_max_streams();
+}
+
+QuicStreamCount UberQuicStreamIdManager::max_outgoing_unidirectional_streams()
+    const {
+  return unidirectional_stream_id_manager_.outgoing_max_streams();
+}
+
+QuicStreamCount UberQuicStreamIdManager::max_incoming_bidirectional_streams()
+    const {
+  return bidirectional_stream_id_manager_.incoming_actual_max_streams();
+}
+
+QuicStreamCount UberQuicStreamIdManager::max_incoming_unidirectional_streams()
+    const {
+  return unidirectional_stream_id_manager_.incoming_actual_max_streams();
+}
+
+QuicStreamCount
+UberQuicStreamIdManager::advertised_max_incoming_bidirectional_streams() const {
+  return bidirectional_stream_id_manager_.incoming_advertised_max_streams();
+}
+
+QuicStreamCount
+UberQuicStreamIdManager::advertised_max_incoming_unidirectional_streams()
+    const {
+  return unidirectional_stream_id_manager_.incoming_advertised_max_streams();
+}
+
+QuicStreamCount UberQuicStreamIdManager::outgoing_bidirectional_stream_count()
+    const {
+  return bidirectional_stream_id_manager_.outgoing_stream_count();
+}
+
+QuicStreamCount UberQuicStreamIdManager::outgoing_unidirectional_stream_count()
+    const {
+  return unidirectional_stream_id_manager_.outgoing_stream_count();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/uber_quic_stream_id_manager.h b/quiche/quic/core/uber_quic_stream_id_manager.h
new file mode 100644
index 0000000..7af942a
--- /dev/null
+++ b/quiche/quic/core/uber_quic_stream_id_manager.h
@@ -0,0 +1,107 @@
+// Copyright (c) 2018 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_UBER_QUIC_STREAM_ID_MANAGER_H_
+#define QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
+
+#include "quiche/quic/core/quic_stream_id_manager.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+namespace test {
+class QuicSessionPeer;
+class UberQuicStreamIdManagerPeer;
+}  // namespace test
+
+class QuicSession;
+
+// This class comprises two QuicStreamIdManagers, which manage bidirectional and
+// unidirectional stream IDs, respectively.
+class QUIC_EXPORT_PRIVATE UberQuicStreamIdManager {
+ public:
+  UberQuicStreamIdManager(
+      Perspective perspective,
+      ParsedQuicVersion version,
+      QuicStreamIdManager::DelegateInterface* delegate,
+      QuicStreamCount max_open_outgoing_bidirectional_streams,
+      QuicStreamCount max_open_outgoing_unidirectional_streams,
+      QuicStreamCount max_open_incoming_bidirectional_streams,
+      QuicStreamCount max_open_incoming_unidirectional_streams);
+
+  // Called on |max_open_streams| outgoing streams can be created because of 1)
+  // config negotiated or 2) MAX_STREAMS received. Returns true if new
+  // streams can be created.
+  bool MaybeAllowNewOutgoingBidirectionalStreams(
+      QuicStreamCount max_open_streams);
+  bool MaybeAllowNewOutgoingUnidirectionalStreams(
+      QuicStreamCount max_open_streams);
+
+  // Sets the limits to max_open_streams.
+  void SetMaxOpenIncomingBidirectionalStreams(QuicStreamCount max_open_streams);
+  void SetMaxOpenIncomingUnidirectionalStreams(
+      QuicStreamCount max_open_streams);
+
+  // Returns true if next outgoing bidirectional stream ID can be allocated.
+  bool CanOpenNextOutgoingBidirectionalStream() const;
+
+  // Returns true if next outgoing unidirectional stream ID can be allocated.
+  bool CanOpenNextOutgoingUnidirectionalStream() const;
+
+  // Returns the next outgoing bidirectional stream id.
+  QuicStreamId GetNextOutgoingBidirectionalStreamId();
+
+  // Returns the next outgoing unidirectional stream id.
+  QuicStreamId GetNextOutgoingUnidirectionalStreamId();
+
+  // Returns true if the incoming |id| is within the limit.
+  bool MaybeIncreaseLargestPeerStreamId(QuicStreamId id,
+                                        std::string* error_details);
+
+  // Called when |id| is released.
+  void OnStreamClosed(QuicStreamId id);
+
+  // Called when a STREAMS_BLOCKED frame is received.
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
+                             std::string* error_details);
+
+  // Returns true if |id| is still available.
+  bool IsAvailableStream(QuicStreamId id) const;
+
+  QuicStreamCount GetMaxAllowdIncomingBidirectionalStreams() const;
+
+  QuicStreamCount GetMaxAllowdIncomingUnidirectionalStreams() const;
+
+  QuicStreamId GetLargestPeerCreatedStreamId(bool unidirectional) const;
+
+  QuicStreamId next_outgoing_bidirectional_stream_id() const;
+  QuicStreamId next_outgoing_unidirectional_stream_id() const;
+
+  QuicStreamCount max_outgoing_bidirectional_streams() const;
+  QuicStreamCount max_outgoing_unidirectional_streams() const;
+
+  QuicStreamCount max_incoming_bidirectional_streams() const;
+  QuicStreamCount max_incoming_unidirectional_streams() const;
+
+  QuicStreamCount advertised_max_incoming_bidirectional_streams() const;
+  QuicStreamCount advertised_max_incoming_unidirectional_streams() const;
+
+  QuicStreamCount outgoing_bidirectional_stream_count() const;
+  QuicStreamCount outgoing_unidirectional_stream_count() const;
+
+ private:
+  friend class test::QuicSessionPeer;
+  friend class test::UberQuicStreamIdManagerPeer;
+
+  ParsedQuicVersion version_;
+  // Manages stream IDs of bidirectional streams.
+  QuicStreamIdManager bidirectional_stream_id_manager_;
+
+  // Manages stream IDs of unidirectional streams.
+  QuicStreamIdManager unidirectional_stream_id_manager_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
diff --git a/quiche/quic/core/uber_quic_stream_id_manager_test.cc b/quiche/quic/core/uber_quic_stream_id_manager_test.cc
new file mode 100644
index 0000000..4f7562b
--- /dev/null
+++ b/quiche/quic/core/uber_quic_stream_id_manager_test.cc
@@ -0,0 +1,340 @@
+// Copyright (c) 2018 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 "quiche/quic/core/uber_quic_stream_id_manager.h"
+
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+struct TestParams {
+  explicit TestParams(ParsedQuicVersion version, Perspective perspective)
+      : version(version), perspective(perspective) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version), "_",
+      (p.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (!version.HasIetfQuicFrames()) {
+      continue;
+    }
+    params.push_back(TestParams(version, Perspective::IS_CLIENT));
+    params.push_back(TestParams(version, Perspective::IS_SERVER));
+  }
+  return params;
+}
+
+class MockDelegate : public QuicStreamIdManager::DelegateInterface {
+ public:
+  MOCK_METHOD(void,
+              SendMaxStreams,
+              (QuicStreamCount stream_count, bool unidirectional),
+              (override));
+};
+
+class UberQuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
+ protected:
+  UberQuicStreamIdManagerTest()
+      : manager_(perspective(),
+                 version(),
+                 &delegate_,
+                 0,
+                 0,
+                 kDefaultMaxStreamsPerConnection,
+                 kDefaultMaxStreamsPerConnection) {}
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                                    Perspective::IS_CLIENT) +
+           QuicUtils::StreamIdDelta(transport_version()) * n;
+  }
+
+  QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
+    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
+                                                     Perspective::IS_CLIENT) +
+           QuicUtils::StreamIdDelta(transport_version()) * n;
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                                    Perspective::IS_SERVER) +
+           QuicUtils::StreamIdDelta(transport_version()) * n;
+  }
+
+  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
+    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
+                                                     Perspective::IS_SERVER) +
+           QuicUtils::StreamIdDelta(transport_version()) * n;
+  }
+
+  QuicStreamId GetNthPeerInitiatedBidirectionalStreamId(int n) {
+    return ((perspective() == Perspective::IS_SERVER)
+                ? GetNthClientInitiatedBidirectionalId(n)
+                : GetNthServerInitiatedBidirectionalId(n));
+  }
+  QuicStreamId GetNthPeerInitiatedUnidirectionalStreamId(int n) {
+    return ((perspective() == Perspective::IS_SERVER)
+                ? GetNthClientInitiatedUnidirectionalId(n)
+                : GetNthServerInitiatedUnidirectionalId(n));
+  }
+  QuicStreamId GetNthSelfInitiatedBidirectionalStreamId(int n) {
+    return ((perspective() == Perspective::IS_CLIENT)
+                ? GetNthClientInitiatedBidirectionalId(n)
+                : GetNthServerInitiatedBidirectionalId(n));
+  }
+  QuicStreamId GetNthSelfInitiatedUnidirectionalStreamId(int n) {
+    return ((perspective() == Perspective::IS_CLIENT)
+                ? GetNthClientInitiatedUnidirectionalId(n)
+                : GetNthServerInitiatedUnidirectionalId(n));
+  }
+
+  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
+                               Perspective perspective,
+                               bool bidirectional) {
+    return ((bidirectional) ? QuicUtils::GetFirstBidirectionalStreamId(
+                                  transport_version(), perspective)
+                            : QuicUtils::GetFirstUnidirectionalStreamId(
+                                  transport_version(), perspective)) +
+           ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
+  }
+
+  ParsedQuicVersion version() { return GetParam().version; }
+  QuicTransportVersion transport_version() {
+    return version().transport_version;
+  }
+
+  Perspective perspective() { return GetParam().perspective; }
+
+  testing::StrictMock<MockDelegate> delegate_;
+  UberQuicStreamIdManager manager_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         UberQuicStreamIdManagerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(UberQuicStreamIdManagerTest, Initialization) {
+  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
+            manager_.next_outgoing_bidirectional_stream_id());
+  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
+            manager_.next_outgoing_unidirectional_stream_id());
+}
+
+TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreams) {
+  const size_t kNumMaxOutgoingStream = 123;
+  // Set the uni- and bi- directional limits to different values to ensure
+  // that they are managed separately.
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
+      kNumMaxOutgoingStream));
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
+      kNumMaxOutgoingStream + 1));
+  EXPECT_EQ(kNumMaxOutgoingStream,
+            manager_.max_outgoing_bidirectional_streams());
+  EXPECT_EQ(kNumMaxOutgoingStream + 1,
+            manager_.max_outgoing_unidirectional_streams());
+  // Check that, for each directionality, we can open the correct number of
+  // streams.
+  int i = kNumMaxOutgoingStream;
+  while (i) {
+    EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
+    manager_.GetNextOutgoingBidirectionalStreamId();
+    EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+    manager_.GetNextOutgoingUnidirectionalStreamId();
+    i--;
+  }
+  // One more unidirectional
+  EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+  manager_.GetNextOutgoingUnidirectionalStreamId();
+
+  // Both should be exhausted...
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
+}
+
+TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenIncomingStreams) {
+  const size_t kNumMaxIncomingStreams = 456;
+  manager_.SetMaxOpenIncomingUnidirectionalStreams(kNumMaxIncomingStreams);
+  // Do +1 for bidirectional to ensure that uni- and bi- get properly set.
+  manager_.SetMaxOpenIncomingBidirectionalStreams(kNumMaxIncomingStreams + 1);
+  EXPECT_EQ(kNumMaxIncomingStreams + 1,
+            manager_.GetMaxAllowdIncomingBidirectionalStreams());
+  EXPECT_EQ(kNumMaxIncomingStreams,
+            manager_.GetMaxAllowdIncomingUnidirectionalStreams());
+  EXPECT_EQ(manager_.max_incoming_bidirectional_streams(),
+            manager_.advertised_max_incoming_bidirectional_streams());
+  EXPECT_EQ(manager_.max_incoming_unidirectional_streams(),
+            manager_.advertised_max_incoming_unidirectional_streams());
+  // Make sure that we can create kNumMaxIncomingStreams incoming unidirectional
+  // streams and kNumMaxIncomingStreams+1 incoming bidirectional streams.
+  size_t i;
+  for (i = 0; i < kNumMaxIncomingStreams; i++) {
+    EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+        GetNthPeerInitiatedUnidirectionalStreamId(i), nullptr));
+    EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+        GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));
+  }
+  // Should be able to open the next bidirectional stream
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));
+
+  // We should have exhausted the counts, the next streams should fail
+  std::string error_details;
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedUnidirectionalStreamId(i), &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat(
+                "Stream id ", GetNthPeerInitiatedUnidirectionalStreamId(i),
+                " would exceed stream count limit ", kNumMaxIncomingStreams));
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedBidirectionalStreamId(i + 1), &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat("Stream id ",
+                         GetNthPeerInitiatedBidirectionalStreamId(i + 1),
+                         " would exceed stream count limit ",
+                         kNumMaxIncomingStreams + 1));
+}
+
+TEST_P(UberQuicStreamIdManagerTest, GetNextOutgoingStreamId) {
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(10));
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(10));
+  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
+            manager_.GetNextOutgoingBidirectionalStreamId());
+  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(1),
+            manager_.GetNextOutgoingBidirectionalStreamId());
+  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
+            manager_.GetNextOutgoingUnidirectionalStreamId());
+  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(1),
+            manager_.GetNextOutgoingUnidirectionalStreamId());
+}
+
+TEST_P(UberQuicStreamIdManagerTest, AvailableStreams) {
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedBidirectionalStreamId(3), nullptr));
+  EXPECT_TRUE(
+      manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(1)));
+  EXPECT_TRUE(
+      manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(2)));
+
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedUnidirectionalStreamId(3), nullptr));
+  EXPECT_TRUE(
+      manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(1)));
+  EXPECT_TRUE(
+      manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(2)));
+}
+
+TEST_P(UberQuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      StreamCountToId(manager_.max_incoming_bidirectional_streams(),
+                      QuicUtils::InvertPerspective(perspective()),
+                      /* bidirectional=*/true),
+      nullptr));
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      StreamCountToId(manager_.max_incoming_bidirectional_streams(),
+                      QuicUtils::InvertPerspective(perspective()),
+                      /* bidirectional=*/false),
+      nullptr));
+
+  std::string expected_error_details =
+      perspective() == Perspective::IS_SERVER
+          ? "Stream id 400 would exceed stream count limit 100"
+          : "Stream id 401 would exceed stream count limit 100";
+  std::string error_details;
+
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
+      StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
+                      QuicUtils::InvertPerspective(perspective()),
+                      /* bidirectional=*/true),
+      &error_details));
+  EXPECT_EQ(expected_error_details, error_details);
+  expected_error_details =
+      perspective() == Perspective::IS_SERVER
+          ? "Stream id 402 would exceed stream count limit 100"
+          : "Stream id 403 would exceed stream count limit 100";
+
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
+      StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
+                      QuicUtils::InvertPerspective(perspective()),
+                      /* bidirectional=*/false),
+      &error_details));
+  EXPECT_EQ(expected_error_details, error_details);
+}
+
+TEST_P(UberQuicStreamIdManagerTest, OnStreamsBlockedFrame) {
+  QuicStreamCount stream_count =
+      manager_.advertised_max_incoming_bidirectional_streams() - 1;
+
+  QuicStreamsBlockedFrame frame(kInvalidControlFrameId, stream_count,
+                                /*unidirectional=*/false);
+  EXPECT_CALL(delegate_,
+              SendMaxStreams(manager_.max_incoming_bidirectional_streams(),
+                             frame.unidirectional))
+      .Times(0);
+  EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
+
+  stream_count = manager_.advertised_max_incoming_unidirectional_streams() - 1;
+  frame.stream_count = stream_count;
+  frame.unidirectional = true;
+
+  EXPECT_CALL(delegate_,
+              SendMaxStreams(manager_.max_incoming_unidirectional_streams(),
+                             frame.unidirectional))
+      .Times(0);
+  EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
+}
+
+TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreamsPlusFrame) {
+  const size_t kNumMaxOutgoingStream = 123;
+  // Set the uni- and bi- directional limits to different values to ensure
+  // that they are managed separately.
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
+      kNumMaxOutgoingStream));
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
+      kNumMaxOutgoingStream + 1));
+  EXPECT_EQ(kNumMaxOutgoingStream,
+            manager_.max_outgoing_bidirectional_streams());
+  EXPECT_EQ(kNumMaxOutgoingStream + 1,
+            manager_.max_outgoing_unidirectional_streams());
+  // Check that, for each directionality, we can open the correct number of
+  // streams.
+  int i = kNumMaxOutgoingStream;
+  while (i) {
+    EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
+    manager_.GetNextOutgoingBidirectionalStreamId();
+    EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+    manager_.GetNextOutgoingUnidirectionalStreamId();
+    i--;
+  }
+  // One more unidirectional
+  EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+  manager_.GetNextOutgoingUnidirectionalStreamId();
+
+  // Both should be exhausted...
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/uber_received_packet_manager.cc b/quiche/quic/core/uber_received_packet_manager.cc
new file mode 100644
index 0000000..b6a7eb2
--- /dev/null
+++ b/quiche/quic/core/uber_received_packet_manager.cc
@@ -0,0 +1,248 @@
+// Copyright 2019 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 "quiche/quic/core/uber_received_packet_manager.h"
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+UberReceivedPacketManager::UberReceivedPacketManager(QuicConnectionStats* stats)
+    : supports_multiple_packet_number_spaces_(false) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_connection_stats(stats);
+  }
+}
+
+UberReceivedPacketManager::~UberReceivedPacketManager() {}
+
+void UberReceivedPacketManager::SetFromConfig(const QuicConfig& config,
+                                              Perspective perspective) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.SetFromConfig(config, perspective);
+  }
+}
+
+bool UberReceivedPacketManager::IsAwaitingPacket(
+    EncryptionLevel decrypted_packet_level,
+    QuicPacketNumber packet_number) const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].IsAwaitingPacket(packet_number);
+  }
+  return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                       decrypted_packet_level)]
+      .IsAwaitingPacket(packet_number);
+}
+
+const QuicFrame UberReceivedPacketManager::GetUpdatedAckFrame(
+    PacketNumberSpace packet_number_space,
+    QuicTime approximate_now) {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].GetUpdatedAckFrame(approximate_now);
+  }
+  return received_packet_managers_[packet_number_space].GetUpdatedAckFrame(
+      approximate_now);
+}
+
+void UberReceivedPacketManager::RecordPacketReceived(
+    EncryptionLevel decrypted_packet_level,
+    const QuicPacketHeader& header,
+    QuicTime receipt_time) {
+  if (!supports_multiple_packet_number_spaces_) {
+    received_packet_managers_[0].RecordPacketReceived(header, receipt_time);
+    return;
+  }
+  received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                decrypted_packet_level)]
+      .RecordPacketReceived(header, receipt_time);
+}
+
+void UberReceivedPacketManager::DontWaitForPacketsBefore(
+    EncryptionLevel decrypted_packet_level,
+    QuicPacketNumber least_unacked) {
+  if (!supports_multiple_packet_number_spaces_) {
+    received_packet_managers_[0].DontWaitForPacketsBefore(least_unacked);
+    return;
+  }
+  received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                decrypted_packet_level)]
+      .DontWaitForPacketsBefore(least_unacked);
+}
+
+void UberReceivedPacketManager::MaybeUpdateAckTimeout(
+    bool should_last_packet_instigate_acks,
+    EncryptionLevel decrypted_packet_level,
+    QuicPacketNumber last_received_packet_number,
+    QuicTime last_packet_receipt_time, QuicTime now,
+    const RttStats* rtt_stats) {
+  if (!supports_multiple_packet_number_spaces_) {
+    received_packet_managers_[0].MaybeUpdateAckTimeout(
+        should_last_packet_instigate_acks, last_received_packet_number,
+        last_packet_receipt_time, now, rtt_stats);
+    return;
+  }
+  received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                decrypted_packet_level)]
+      .MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
+                             last_received_packet_number,
+                             last_packet_receipt_time, now, rtt_stats);
+}
+
+void UberReceivedPacketManager::ResetAckStates(
+    EncryptionLevel encryption_level) {
+  if (!supports_multiple_packet_number_spaces_) {
+    received_packet_managers_[0].ResetAckStates();
+    return;
+  }
+  received_packet_managers_[QuicUtils::GetPacketNumberSpace(encryption_level)]
+      .ResetAckStates();
+  if (encryption_level == ENCRYPTION_INITIAL) {
+    // After one Initial ACK is sent, the others should be sent 'immediately'.
+    received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
+        kAlarmGranularity);
+  }
+}
+
+void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport(
+    Perspective perspective) {
+  if (supports_multiple_packet_number_spaces_) {
+    QUIC_BUG(quic_bug_10495_1)
+        << "Multiple packet number spaces has already been enabled";
+    return;
+  }
+  if (received_packet_managers_[0].GetLargestObserved().IsInitialized()) {
+    QUIC_BUG(quic_bug_10495_2)
+        << "Try to enable multiple packet number spaces support after any "
+           "packet has been received.";
+    return;
+  }
+  // In IETF QUIC, the peer is expected to acknowledge packets in Initial and
+  // Handshake packets with minimal delay.
+  if (perspective == Perspective::IS_CLIENT) {
+    // Delay the first server ACK, because server ACKs are padded to
+    // full size and count towards the amplification limit.
+    received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
+        kAlarmGranularity);
+  }
+  received_packet_managers_[HANDSHAKE_DATA].set_local_max_ack_delay(
+      kAlarmGranularity);
+
+  supports_multiple_packet_number_spaces_ = true;
+}
+
+bool UberReceivedPacketManager::IsAckFrameUpdated() const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].ack_frame_updated();
+  }
+  for (const auto& received_packet_manager : received_packet_managers_) {
+    if (received_packet_manager.ack_frame_updated()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+QuicPacketNumber UberReceivedPacketManager::GetLargestObserved(
+    EncryptionLevel decrypted_packet_level) const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].GetLargestObserved();
+  }
+  return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                       decrypted_packet_level)]
+      .GetLargestObserved();
+}
+
+QuicTime UberReceivedPacketManager::GetAckTimeout(
+    PacketNumberSpace packet_number_space) const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].ack_timeout();
+  }
+  return received_packet_managers_[packet_number_space].ack_timeout();
+}
+
+QuicTime UberReceivedPacketManager::GetEarliestAckTimeout() const {
+  QuicTime ack_timeout = QuicTime::Zero();
+  // Returns the earliest non-zero ack timeout.
+  for (const auto& received_packet_manager : received_packet_managers_) {
+    const QuicTime timeout = received_packet_manager.ack_timeout();
+    if (!ack_timeout.IsInitialized()) {
+      ack_timeout = timeout;
+      continue;
+    }
+    if (timeout.IsInitialized()) {
+      ack_timeout = std::min(ack_timeout, timeout);
+    }
+  }
+  return ack_timeout;
+}
+
+bool UberReceivedPacketManager::IsAckFrameEmpty(
+    PacketNumberSpace packet_number_space) const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].IsAckFrameEmpty();
+  }
+  return received_packet_managers_[packet_number_space].IsAckFrameEmpty();
+}
+
+QuicPacketNumber UberReceivedPacketManager::peer_least_packet_awaiting_ack()
+    const {
+  QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
+  return received_packet_managers_[0].peer_least_packet_awaiting_ack();
+}
+
+size_t UberReceivedPacketManager::min_received_before_ack_decimation() const {
+  return received_packet_managers_[0].min_received_before_ack_decimation();
+}
+
+void UberReceivedPacketManager::set_min_received_before_ack_decimation(
+    size_t new_value) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_min_received_before_ack_decimation(new_value);
+  }
+}
+
+void UberReceivedPacketManager::set_ack_frequency(size_t new_value) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_ack_frequency(new_value);
+  }
+}
+
+const QuicAckFrame& UberReceivedPacketManager::ack_frame() const {
+  QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
+  return received_packet_managers_[0].ack_frame();
+}
+
+const QuicAckFrame& UberReceivedPacketManager::GetAckFrame(
+    PacketNumberSpace packet_number_space) const {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces_);
+  return received_packet_managers_[packet_number_space].ack_frame();
+}
+
+void UberReceivedPacketManager::set_max_ack_ranges(size_t max_ack_ranges) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_max_ack_ranges(max_ack_ranges);
+  }
+}
+
+void UberReceivedPacketManager::set_save_timestamps(bool save_timestamps) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_save_timestamps(
+        save_timestamps, supports_multiple_packet_number_spaces_);
+  }
+}
+
+void UberReceivedPacketManager::OnAckFrequencyFrame(
+    const QuicAckFrequencyFrame& frame) {
+  if (!supports_multiple_packet_number_spaces_) {
+    QUIC_BUG(quic_bug_10495_3)
+        << "Received AckFrequencyFrame when multiple packet number spaces "
+           "is not supported";
+    return;
+  }
+  received_packet_managers_[APPLICATION_DATA].OnAckFrequencyFrame(frame);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/uber_received_packet_manager.h b/quiche/quic/core/uber_received_packet_manager.h
new file mode 100644
index 0000000..1eb15d9
--- /dev/null
+++ b/quiche/quic/core/uber_received_packet_manager.h
@@ -0,0 +1,111 @@
+// Copyright 2019 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_UBER_RECEIVED_PACKET_MANAGER_H_
+#define QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
+
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_received_packet_manager.h"
+
+namespace quic {
+
+// This class comprises multiple received packet managers, one per packet number
+// space. Please note, if multiple packet number spaces is not supported, only
+// one received packet manager will be used.
+class QUIC_EXPORT_PRIVATE UberReceivedPacketManager {
+ public:
+  explicit UberReceivedPacketManager(QuicConnectionStats* stats);
+  UberReceivedPacketManager(const UberReceivedPacketManager&) = delete;
+  UberReceivedPacketManager& operator=(const UberReceivedPacketManager&) =
+      delete;
+  virtual ~UberReceivedPacketManager();
+
+  void SetFromConfig(const QuicConfig& config, Perspective perspective);
+
+  // Checks if we are still waiting for the packet with |packet_number|.
+  bool IsAwaitingPacket(EncryptionLevel decrypted_packet_level,
+                        QuicPacketNumber packet_number) const;
+
+  // Called after a packet has been successfully decrypted and its header has
+  // been parsed.
+  void RecordPacketReceived(EncryptionLevel decrypted_packet_level,
+                            const QuicPacketHeader& header,
+                            QuicTime receipt_time);
+
+  // Retrieves a frame containing a QuicAckFrame. The ack frame must be
+  // serialized before another packet is received, or it will change.
+  const QuicFrame GetUpdatedAckFrame(PacketNumberSpace packet_number_space,
+                                     QuicTime approximate_now);
+
+  // Stop ACKing packets before |least_unacked|.
+  void DontWaitForPacketsBefore(EncryptionLevel decrypted_packet_level,
+                                QuicPacketNumber least_unacked);
+
+  // Called after header of last received packet has been successfully processed
+  // to update ACK timeout.
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             EncryptionLevel decrypted_packet_level,
+                             QuicPacketNumber last_received_packet_number,
+                             QuicTime last_packet_receipt_time, QuicTime now,
+                             const RttStats* rtt_stats);
+
+  // Resets ACK related states, called after an ACK is successfully sent.
+  void ResetAckStates(EncryptionLevel encryption_level);
+
+  // Called to enable multiple packet number support.
+  void EnableMultiplePacketNumberSpacesSupport(Perspective perspective);
+
+  // Returns true if ACK frame has been updated since GetUpdatedAckFrame was
+  // last called.
+  bool IsAckFrameUpdated() const;
+
+  // Returns the largest received packet number.
+  QuicPacketNumber GetLargestObserved(
+      EncryptionLevel decrypted_packet_level) const;
+
+  // Returns ACK timeout of |packet_number_space|.
+  QuicTime GetAckTimeout(PacketNumberSpace packet_number_space) const;
+
+  // Get the earliest ack_timeout of all packet number spaces.
+  QuicTime GetEarliestAckTimeout() const;
+
+  // Return true if ack frame of |packet_number_space| is empty.
+  bool IsAckFrameEmpty(PacketNumberSpace packet_number_space) const;
+
+  QuicPacketNumber peer_least_packet_awaiting_ack() const;
+
+  size_t min_received_before_ack_decimation() const;
+  void set_min_received_before_ack_decimation(size_t new_value);
+
+  void set_ack_frequency(size_t new_value);
+
+  bool supports_multiple_packet_number_spaces() const {
+    return supports_multiple_packet_number_spaces_;
+  }
+
+  // For logging purposes.
+  const QuicAckFrame& ack_frame() const;
+  const QuicAckFrame& GetAckFrame(PacketNumberSpace packet_number_space) const;
+
+  void set_max_ack_ranges(size_t max_ack_ranges);
+
+  void OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame);
+
+  void set_save_timestamps(bool save_timestamps);
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::UberReceivedPacketManagerPeer;
+
+  // One received packet manager per packet number space. If
+  // supports_multiple_packet_number_spaces_ is false, only the first (0 index)
+  // received_packet_manager is used.
+  QuicReceivedPacketManager received_packet_managers_[NUM_PACKET_NUMBER_SPACES];
+
+  bool supports_multiple_packet_number_spaces_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
diff --git a/quiche/quic/core/uber_received_packet_manager_test.cc b/quiche/quic/core/uber_received_packet_manager_test.cc
new file mode 100644
index 0000000..96b951f
--- /dev/null
+++ b/quiche/quic/core/uber_received_packet_manager_test.cc
@@ -0,0 +1,561 @@
+// Copyright 2019 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 "quiche/quic/core/uber_received_packet_manager.h"
+
+#include <utility>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class UberReceivedPacketManagerPeer {
+ public:
+  static void SetAckDecimationDelay(UberReceivedPacketManager* manager,
+                                    float ack_decimation_delay) {
+    for (auto& received_packet_manager : manager->received_packet_managers_) {
+      received_packet_manager.ack_decimation_delay_ = ack_decimation_delay;
+    }
+  }
+};
+
+namespace {
+
+const bool kInstigateAck = true;
+const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
+const QuicTime::Delta kDelayedAckTime =
+    QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+class UberReceivedPacketManagerTest : public QuicTest {
+ protected:
+  UberReceivedPacketManagerTest() {
+    manager_ = std::make_unique<UberReceivedPacketManager>(&stats_);
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    rtt_stats_.UpdateRtt(kMinRttMs, QuicTime::Delta::Zero(), QuicTime::Zero());
+    manager_->set_save_timestamps(true);
+  }
+
+  void RecordPacketReceipt(uint64_t packet_number) {
+    RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number);
+  }
+
+  void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
+    RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number, receipt_time);
+  }
+
+  void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
+                           uint64_t packet_number) {
+    RecordPacketReceipt(decrypted_packet_level, packet_number,
+                        QuicTime::Zero());
+  }
+
+  void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
+                           uint64_t packet_number,
+                           QuicTime receipt_time) {
+    QuicPacketHeader header;
+    header.packet_number = QuicPacketNumber(packet_number);
+    manager_->RecordPacketReceived(decrypted_packet_level, header,
+                                   receipt_time);
+  }
+
+  bool HasPendingAck() {
+    if (!manager_->supports_multiple_packet_number_spaces()) {
+      return manager_->GetAckTimeout(APPLICATION_DATA).IsInitialized();
+    }
+    return manager_->GetEarliestAckTimeout().IsInitialized();
+  }
+
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             uint64_t last_received_packet_number) {
+    MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
+                          ENCRYPTION_FORWARD_SECURE,
+                          last_received_packet_number);
+  }
+
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             EncryptionLevel decrypted_packet_level,
+                             uint64_t last_received_packet_number) {
+    manager_->MaybeUpdateAckTimeout(
+        should_last_packet_instigate_acks, decrypted_packet_level,
+        QuicPacketNumber(last_received_packet_number), clock_.ApproximateNow(),
+        clock_.ApproximateNow(), &rtt_stats_);
+  }
+
+  void CheckAckTimeout(QuicTime time) {
+    QUICHE_DCHECK(HasPendingAck());
+    if (!manager_->supports_multiple_packet_number_spaces()) {
+      QUICHE_DCHECK(manager_->GetAckTimeout(APPLICATION_DATA) == time);
+      if (time <= clock_.ApproximateNow()) {
+        // ACK timeout expires, send an ACK.
+        manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+        QUICHE_DCHECK(!HasPendingAck());
+      }
+      return;
+    }
+    QUICHE_DCHECK(manager_->GetEarliestAckTimeout() == time);
+    // Send all expired ACKs.
+    for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+      const QuicTime ack_timeout =
+          manager_->GetAckTimeout(static_cast<PacketNumberSpace>(i));
+      if (!ack_timeout.IsInitialized() ||
+          ack_timeout > clock_.ApproximateNow()) {
+        continue;
+      }
+      manager_->ResetAckStates(
+          QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
+    }
+  }
+
+  MockClock clock_;
+  RttStats rtt_stats_;
+  QuicConnectionStats stats_;
+  std::unique_ptr<UberReceivedPacketManager> manager_;
+};
+
+TEST_F(UberReceivedPacketManagerTest, DontWaitForPacketsBefore) {
+  EXPECT_TRUE(manager_->IsAckFrameEmpty(APPLICATION_DATA));
+  RecordPacketReceipt(2);
+  EXPECT_FALSE(manager_->IsAckFrameEmpty(APPLICATION_DATA));
+  RecordPacketReceipt(7);
+  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                         QuicPacketNumber(3u)));
+  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                         QuicPacketNumber(6u)));
+  manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
+                                     QuicPacketNumber(4));
+  EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                          QuicPacketNumber(3u)));
+  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                         QuicPacketNumber(6u)));
+}
+
+TEST_F(UberReceivedPacketManagerTest, GetUpdatedAckFrame) {
+  QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  RecordPacketReceipt(2, two_ms);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+
+  QuicFrame ack =
+      manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
+  manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  // When UpdateReceivedPacketInfo with a time earlier than the time of the
+  // largest observed packet, make sure that the delta is 0, not negative.
+  EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
+  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
+
+  QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
+  ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, four_ms);
+  manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  // When UpdateReceivedPacketInfo after not having received a new packet,
+  // the delta should still be accurate.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
+            ack.ack_frame->ack_delay_time);
+  // And received packet times won't have change.
+  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
+
+  RecordPacketReceipt(999, two_ms);
+  RecordPacketReceipt(4, two_ms);
+  RecordPacketReceipt(1000, two_ms);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, two_ms);
+  manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  // UpdateReceivedPacketInfo should discard any times which can't be
+  // expressed on the wire.
+  EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
+}
+
+TEST_F(UberReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  RecordPacketReceipt(1);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  RecordPacketReceipt(6);
+  RecordPacketReceipt(2,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+
+  EXPECT_EQ(4u, stats_.max_sequence_reordering);
+  EXPECT_EQ(1000, stats_.max_time_reordering_us);
+  EXPECT_EQ(1u, stats_.packets_reordered);
+}
+
+TEST_F(UberReceivedPacketManagerTest, LimitAckRanges) {
+  manager_->set_max_ack_ranges(10);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  for (int i = 0; i < 100; ++i) {
+    RecordPacketReceipt(1 + 2 * i);
+    EXPECT_TRUE(manager_->IsAckFrameUpdated());
+    manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
+    EXPECT_GE(10u, manager_->ack_frame().packets.NumIntervals());
+    EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
+              manager_->ack_frame().packets.Max());
+    for (int j = 0; j < std::min(10, i + 1); ++j) {
+      ASSERT_GE(i, j);
+      EXPECT_TRUE(manager_->ack_frame().packets.Contains(
+          QuicPacketNumber(1 + (i - j) * 2)));
+      if (i > j) {
+        EXPECT_FALSE(manager_->ack_frame().packets.Contains(
+            QuicPacketNumber((i - j) * 2)));
+      }
+    }
+  }
+}
+
+TEST_F(UberReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  RecordPacketReceipt(1, QuicTime::Zero());
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  EXPECT_EQ(1u, manager_->ack_frame().received_packet_times.size());
+  RecordPacketReceipt(2,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(2u, manager_->ack_frame().received_packet_times.size());
+  RecordPacketReceipt(3, QuicTime::Zero());
+  EXPECT_EQ(2u, manager_->ack_frame().received_packet_times.size());
+}
+
+TEST_F(UberReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  // Should ack immediately, since this fills the last hole.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 4);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+}
+
+TEST_F(UberReceivedPacketManagerTest, OutOfOrderAckReceiptCausesNoAck) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 2);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 1);
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(UberReceivedPacketManagerTest, AckReceiptCausesAckSend) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 1);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 2);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  clock_.AdvanceTime(kDelayedAckTime);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 4);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 5);
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(UberReceivedPacketManagerTest, AckSentEveryNthPacket) {
+  EXPECT_FALSE(HasPendingAck());
+  manager_->set_ack_frequency(3);
+
+  // Receives packets 1 - 39.
+  for (size_t i = 1; i <= 39; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 3 == 0) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+}
+
+TEST_F(UberReceivedPacketManagerTest, AckDecimationReducesAcks) {
+  EXPECT_FALSE(HasPendingAck());
+
+  // Start ack decimation from 10th packet.
+  manager_->set_min_received_before_ack_decimation(10);
+
+  // Receives packets 1 - 29.
+  for (size_t i = 1; i <= 29; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i <= 10) {
+      // For packets 1-10, ack every 2 packets.
+      if (i % 2 == 0) {
+        CheckAckTimeout(clock_.ApproximateNow());
+      } else {
+        CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+      }
+      continue;
+    }
+    // ack at 20.
+    if (i == 20) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kMinRttMs * 0.25);
+    }
+  }
+
+  // We now receive the 30th packet, and so we send an ack.
+  RecordPacketReceipt(30, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 30);
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(UberReceivedPacketManagerTest, SendDelayedAckDecimation) {
+  EXPECT_FALSE(HasPendingAck());
+  // The ack time should be based on min_rtt * 1/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(UberReceivedPacketManagerTest,
+       SendDelayedAckDecimationUnlimitedAggregation) {
+  EXPECT_FALSE(HasPendingAck());
+  QuicConfig config;
+  QuicTagVector connection_options;
+  // No limit on the number of packets received before sending an ack.
+  connection_options.push_back(kAKDU);
+  config.SetConnectionOptionsToSend(connection_options);
+  manager_->SetFromConfig(config, Perspective::IS_CLIENT);
+
+  // The ack time should be based on min_rtt/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // 18 packets will not cause an ack to be sent.  19 will because when
+  // stop waiting frames are in use, we ack every 20 packets no matter what.
+  for (int i = 1; i <= 18; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(ack_time);
+}
+
+TEST_F(UberReceivedPacketManagerTest, SendDelayedAckDecimationEighthRtt) {
+  EXPECT_FALSE(HasPendingAck());
+  UberReceivedPacketManagerPeer::SetAckDecimationDelay(manager_.get(), 0.125);
+
+  // The ack time should be based on min_rtt/8, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.125;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(UberReceivedPacketManagerTest,
+       DontWaitForPacketsBeforeMultiplePacketNumberSpaces) {
+  manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_CLIENT);
+  EXPECT_FALSE(
+      manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE).IsInitialized());
+  EXPECT_FALSE(
+      manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE).IsInitialized());
+  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 2);
+  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 4);
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 7);
+  EXPECT_EQ(QuicPacketNumber(4),
+            manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(7),
+            manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE));
+
+  EXPECT_TRUE(
+      manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
+  EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                          QuicPacketNumber(3)));
+  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                         QuicPacketNumber(4)));
+
+  manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
+                                     QuicPacketNumber(5));
+  EXPECT_TRUE(
+      manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
+  EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                          QuicPacketNumber(4)));
+}
+
+TEST_F(UberReceivedPacketManagerTest, AckSendingDifferentPacketNumberSpaces) {
+  manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_SERVER);
+  EXPECT_FALSE(HasPendingAck());
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+
+  RecordPacketReceipt(ENCRYPTION_INITIAL, 3);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 3);
+  EXPECT_TRUE(HasPendingAck());
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() +
+                  QuicTime::Delta::FromMilliseconds(25));
+  // Send delayed handshake data ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(25));
+  CheckAckTimeout(clock_.ApproximateNow());
+  EXPECT_FALSE(HasPendingAck());
+
+  // Second delayed ack should have a shorter delay.
+  RecordPacketReceipt(ENCRYPTION_INITIAL, 4);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 4);
+  EXPECT_TRUE(HasPendingAck());
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() +
+                  QuicTime::Delta::FromMilliseconds(1));
+  // Send delayed handshake data ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  CheckAckTimeout(clock_.ApproximateNow());
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 3);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_HANDSHAKE, 3);
+  EXPECT_TRUE(HasPendingAck());
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() +
+                  QuicTime::Delta::FromMilliseconds(1));
+  // Send delayed handshake data ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  CheckAckTimeout(clock_.ApproximateNow());
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 3);
+  EXPECT_TRUE(HasPendingAck());
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 2);
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 2);
+  // Application data ACK should be sent immediately.
+  CheckAckTimeout(clock_.ApproximateNow());
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(UberReceivedPacketManagerTest,
+       AckTimeoutForPreviouslyUndecryptablePackets) {
+  manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_SERVER);
+  EXPECT_FALSE(HasPendingAck());
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+
+  // Received undecryptable 1-RTT packet 4.
+  const QuicTime packet_receipt_time4 = clock_.ApproximateNow();
+  // 1-RTT keys become available after 10ms because HANDSHAKE 5 gets received.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 5);
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_HANDSHAKE, 5);
+  EXPECT_TRUE(HasPendingAck());
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 4);
+  manager_->MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE,
+                                  QuicPacketNumber(4), packet_receipt_time4,
+                                  clock_.ApproximateNow(), &rtt_stats_);
+
+  // Send delayed handshake ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  EXPECT_TRUE(HasPendingAck());
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Verify ACK delay is based on packet receipt time.
+    CheckAckTimeout(clock_.ApproximateNow() -
+                    QuicTime::Delta::FromMilliseconds(11) + kDelayedAckTime);
+  } else {
+    // Delayed ack is scheduled.
+    CheckAckTimeout(clock_.ApproximateNow() -
+                    QuicTime::Delta::FromMilliseconds(1) + kDelayedAckTime);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/web_transport_interface.h b/quiche/quic/core/web_transport_interface.h
new file mode 100644
index 0000000..ea8747d
--- /dev/null
+++ b/quiche/quic/core/web_transport_interface.h
@@ -0,0 +1,153 @@
+// Copyright (c) 2021 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.
+
+// This header contains interfaces that abstract away different backing
+// protocols for WebTransport.
+
+#ifndef QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
+#define QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_datagram_queue.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+// Visitor that gets notified about events related to a WebTransport stream.
+class QUIC_EXPORT_PRIVATE WebTransportStreamVisitor {
+ public:
+  virtual ~WebTransportStreamVisitor() {}
+
+  // Called whenever the stream has readable data available.
+  virtual void OnCanRead() = 0;
+  // Called whenever the stream is not write-blocked and can accept new data.
+  virtual void OnCanWrite() = 0;
+
+  // Called when RESET_STREAM is received for the stream.
+  virtual void OnResetStreamReceived(WebTransportStreamError error) = 0;
+  // Called when STOP_SENDING is received for the stream.
+  virtual void OnStopSendingReceived(WebTransportStreamError error) = 0;
+  // Called when the write side of the stream is closed and all of the data sent
+  // has been acknowledged ("Data Recvd" state of RFC 9000).
+  virtual void OnWriteSideInDataRecvdState() = 0;
+};
+
+// A stream (either bidirectional or unidirectional) that is contained within a
+// WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportStream {
+ public:
+  struct QUIC_EXPORT_PRIVATE ReadResult {
+    // Number of bytes actually read.
+    size_t bytes_read;
+    // Whether the FIN has been received; if true, no further data will arrive
+    // on the stream, and the stream object can be soon potentially garbage
+    // collected.
+    bool fin;
+  };
+
+  virtual ~WebTransportStream() {}
+
+  // Reads at most |buffer_size| bytes into |buffer|.
+  ABSL_MUST_USE_RESULT virtual ReadResult Read(char* buffer,
+                                               size_t buffer_size) = 0;
+  // Reads all available data and appends it to the end of |output|.
+  ABSL_MUST_USE_RESULT virtual ReadResult Read(std::string* output) = 0;
+  // Writes |data| into the stream.  Returns true on success.
+  ABSL_MUST_USE_RESULT virtual bool Write(absl::string_view data) = 0;
+  // Sends the FIN on the stream.  Returns true on success.
+  ABSL_MUST_USE_RESULT virtual bool SendFin() = 0;
+
+  // Indicates whether it is possible to write into stream right now.
+  virtual bool CanWrite() const = 0;
+  // Indicates the number of bytes that can be read from the stream.
+  virtual size_t ReadableBytes() const = 0;
+
+  // An ID that is unique within the session.  Those are not exposed to the user
+  // via the web API, but can be used internally for bookkeeping and
+  // diagnostics.
+  virtual QuicStreamId GetStreamId() const = 0;
+
+  // Resets the stream with the specified error code.
+  virtual void ResetWithUserCode(WebTransportStreamError error) = 0;
+  virtual void ResetDueToInternalError() = 0;
+  virtual void SendStopSending(WebTransportStreamError error) = 0;
+  // Called when the owning object has been garbage-collected.
+  virtual void MaybeResetDueToStreamObjectGone() = 0;
+
+  virtual WebTransportStreamVisitor* visitor() = 0;
+  virtual void SetVisitor(
+      std::unique_ptr<WebTransportStreamVisitor> visitor) = 0;
+};
+
+// Visitor that gets notified about events related to a WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportVisitor {
+ public:
+  virtual ~WebTransportVisitor() {}
+
+  // Notifies the visitor when the session is ready to exchange application
+  // data.
+  virtual void OnSessionReady(const spdy::SpdyHeaderBlock& headers) = 0;
+
+  // Notifies the visitor when the session has been closed.
+  virtual void OnSessionClosed(WebTransportSessionError error_code,
+                               const std::string& error_message) = 0;
+
+  // Notifies the visitor when a new stream has been received.  The stream in
+  // question can be retrieved using AcceptIncomingBidirectionalStream() or
+  // AcceptIncomingUnidirectionalStream().
+  virtual void OnIncomingBidirectionalStreamAvailable() = 0;
+  virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
+
+  // Notifies the visitor when a new datagram has been received.
+  virtual void OnDatagramReceived(absl::string_view datagram) = 0;
+
+  // Notifies the visitor that a new outgoing stream can now be created.
+  virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
+  virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
+};
+
+// An abstract interface for a WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportSession {
+ public:
+  virtual ~WebTransportSession() {}
+
+  // Closes the WebTransport session in question with the specified |error_code|
+  // and |error_message|.
+  virtual void CloseSession(WebTransportSessionError error_code,
+                            absl::string_view error_message) = 0;
+
+  // Return the earliest incoming stream that has been received by the session
+  // but has not been accepted.  Returns nullptr if there are no incoming
+  // streams.
+  virtual WebTransportStream* AcceptIncomingBidirectionalStream() = 0;
+  virtual WebTransportStream* AcceptIncomingUnidirectionalStream() = 0;
+
+  // Returns true if flow control allows opening a new stream.
+  virtual bool CanOpenNextOutgoingBidirectionalStream() = 0;
+  virtual bool CanOpenNextOutgoingUnidirectionalStream() = 0;
+  // Opens a new WebTransport stream, or returns nullptr if that is not possible
+  // due to flow control.
+  virtual WebTransportStream* OpenOutgoingBidirectionalStream() = 0;
+  virtual WebTransportStream* OpenOutgoingUnidirectionalStream() = 0;
+
+  virtual MessageStatus SendOrQueueDatagram(
+      quiche::QuicheMemSlice datagram) = 0;
+  // Returns a conservative estimate of the largest datagram size that the
+  // session would be able to send.
+  virtual QuicByteCount GetMaxDatagramSize() const = 0;
+  // Sets the largest duration that a datagram can spend in the queue before
+  // being silently dropped.
+  virtual void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
